好久没有更新博客啦,昨天在群里面和一起大神讨论一些关于日志系统搭建,所碰到 的一些问题吧导致没有搭建成功,幸好我也是最近研究了一些用ELK来搭建一些日志系统,这个日志系统环境搭建是一个比较初级的,使用ELK搭建的,我们用.Net log4net 进入日志记录写进ES中,好了 废话不说了 开始进入正题

1 ELK是什么

elk是 Elasticsearch,Logstash,Kibana 三大开源框架的简写

ELK日志采集工具设计 elk日志系统搭建_ELK日志采集工具设计

上面的图形只是对三大开源框架的一个简单分析 大概先了解下,

ELK安装

安装着是三个框架需要有Java环境 ,要安装JDK ,先检查本地是否有Java环境 如果没有先安装JDK:

JDK安装:

ELK日志采集工具设计 elk日志系统搭建_System_02


如果有Java环境 那我们现在开始安装,首先先安装ES

ES下载 选择与自己对应的版本

ELK日志采集工具设计 elk日志系统搭建_Common_03


下载好之后解压 进入bin目录找到elastucsearch.bat双击就可以运行 ES ,

ES默认端口是9200

ELK日志采集工具设计 elk日志系统搭建_Common_04


下图是ES启动成功

ELK日志采集工具设计 elk日志系统搭建_System_05

安装LogStash

LogStash下载 选择对应的版本

ELK日志采集工具设计 elk日志系统搭建_Common_06


下载后之后在bin目录下添加一个配置文件图下图

ELK日志采集工具设计 elk日志系统搭建_System_07


把下面这段代码写到tcp.conf里面去

input {
       tcp {
                port => "4567"
                mode => "server"
                type => "tcplog"
			ssl_enable => false
    	codec =>  "json"
        }
}

output{
        elasticsearch{
             hosts => "127.0.0.1:9200"
             index => "tcplog-%{+YYYY.MM.dd}"
        }
}

简单介绍上面配置说明
input :是输入 ,我的理解就是从哪个位置读取数据😄
tcp:是配置一tcp的形式进行数据收集,

codec :是指收集数据的编码, 他的值有 plain ,json plan 是普通文本格式数据 json 传json的数据
output:输出,意思是通过读取过来的数据,放在哪里存储,配置中我们放在了ES里面,
hosts是es所在的位置和端口(es默认端口是9200可以通过配置文件进行修改)
index是ES的索引名称

安装Kibana

Kibana 下载

进入bin目录 启动即可 有点慢 (机子太烂)

ELK日志采集工具设计 elk日志系统搭建_ELK日志采集工具设计_08

下图启动成功

ELK日志采集工具设计 elk日志系统搭建_Common_09


在浏览器输入

http://127.0.0.1:5601/ 访问

准备工作已经好了 ,现在我们开始写程序把
我们建立一个控制台程序 导入log4net包,配置log4net.config,平时我们用的日志不是写库就是把日志写进文件,那么今天我们把日志已tcp的形式写进服务器,下面是配置把日志已TCP的协议写进服务器

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
<!--日志相关配置-->
<log4net>
<!--把日志文件已网络的形式传输  -->
<appender name="SocketAppender" type="log4net.Appender.SocketAppender, Log4netSocketAppender">
	  <RemoteAddress value="127.0.0.1"/>
	  <RemotePort value="4567" />
	  <AddressFamily value="InterNetwork" />
	  <SocketType value="Stream" />
	  <ProtocolType value="Tcp" />
	  <ConAttemptsCount value="5" />
	  <ConAttemptsWaitingTimeMilliSeconds value="3000" />
	  <UseThreadPoolQueue value="true" />
	    <layout type="TestLogStash.Log.BusinessIDPatternLayout">
 <conversionPattern value="%SystemLogFrom" />
	</layout>
	</appender>
  <!--引入-->
  <root>
    <level value="ALL" />
<appender-ref ref="SocketAppender" />
  </root>
</log4net>
</configuration>

解释下上面的配置:
RemoteAddress:是你服务器地址
RemotePort: 端口
SocketType;类型
ProtocolType:协议类型
注意:
TestLogStash.Log.BusinessIDPatternLayout 这个类是我自定义的 格式输出,把配置文件放到项目bin目录下
1.导入logHelper.cs

using log4net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Common.Utility
{
    public static class Log
    {
       
       
        public static void Debug(object message)
        {
           
            LogManager.GetLogger(Common.Utility.Log.GetCurrentMethodFullName()).Debug(message);

        }
       

        public static void Debug(object message, Exception ex)
        {
        
            LogManager.GetLogger(Common.Utility.Log.GetCurrentMethodFullName()).Debug(message, ex);
        }

        public static void Error(object message)
        {
        
            LogManager.GetLogger(Common.Utility.Log.GetCurrentMethodFullName()).Error(message);
        }

        public static void Error(object message, Exception exception)
        {
        
            LogManager.GetLogger(Common.Utility.Log.GetCurrentMethodFullName()).Error(message, exception);
        }



        public static void Info(object message)
        {
        
            LogManager.GetLogger(Common.Utility.Log.GetCurrentMethodFullName()).Info(message);
        }

        public static void Info(object message, Exception ex)
        {
        
            LogManager.GetLogger(Common.Utility.Log.GetCurrentMethodFullName()).Info(message, ex);
        }

        public static void Warn(object message)
        {
        
            LogManager.GetLogger(Common.Utility.Log.GetCurrentMethodFullName()).Warn(message);
        }

        public static void Warn(object message, Exception ex)
        {
        
            LogManager.GetLogger(Common.Utility.Log.GetCurrentMethodFullName()).Warn(message, ex);
        }

        private static string GetCurrentMethodFullName()
        {
            StackFrame frame;
            string str;
            string str1;
            bool flag;
            try
            {
                int num = 2;
                StackTrace stackTrace = new StackTrace();
                int length = stackTrace.GetFrames().Length;
                do
                {
                    int num1 = num;
                    num = num1 + 1;
                    frame = stackTrace.GetFrame(num1);
                    str = frame.GetMethod().DeclaringType.ToString();
                    flag = (!str.EndsWith("Exception") ? false : num < length);
                }
                while (flag);
                string name = frame.GetMethod().Name;
                str1 = string.Concat(str, ".", name);
            }
            catch
            {
                str1 = null;
            }
            return str1;
        }
    }
}

重写Log4net格式输出类 PropresPatternConvert:`

using log4net.Core;
using log4net.Layout.Pattern;
using System;
using System.IO;
using Newtonsoft.Json;
using System.Text;
namespace TestLogStash.Log
{
    public class PropresPatternConvert : PatternLayoutConverter
    {
        //自定义输出模版
        protected override void Convert(TextWriter tw, LoggingEvent loggingEvent)
        {
            //StringBuilder sb = new StringBuilder();
            //日志输出换行符
            string lineOperator = "\r\n";
            var businessID = loggingEvent.MessageObject as BusinessLog;
            if (businessID == null) return;
            //sb.Append("======================SystemLogFrom:" + businessID.SystemLogFrom+ "==========================="+ lineOperator);
            //sb.Append("Message==========>" + businessID.Message + lineOperator);
            //sb.Append("DateTime==========>" + businessID.Date + lineOperator);
            //sb.Append("Exception==========>" + businessID.Exception + lineOperator);
            //sb.Append("=================================================================" + lineOperator);
           var str = "{\"LogData\":{\"SystemLogFrom\":\"" + businessID.SystemLogFrom + "\"," +
               "\"Message\":\"" + businessID.Message + "\", " + "\"DateTime\":\"" + businessID.Date +
               "\"," + "\"Exception\":\"" + businessID.Exception + "\"}}";
            tw.Write(str);
        }
    }
    //输出
    public class BusinessIDPatternLayout : log4net.Layout.PatternLayout
    {
        public BusinessIDPatternLayout()
        {
            this.AddConverter("SystemLogFrom", typeof(PropresPatternConvert));
        }
    }
    //封装日志参数
    class BusinessLog {
        public string SystemLogFrom { get; set; }
        public string Message { get; set; }
        public DateTime Date { get; set; }
        public Exception Exception { get; set; }
        public BusinessLog(string SystemLogFrom,string Message , DateTime Date, Exception Exception) {
            this.SystemLogFrom = SystemLogFrom;
            this.Message = Message;
            this.Date = Date;
            this.Exception = Exception;
        }
        public override string ToString()
        {
            return base.ToString();
        }
    }
}

//下面是主程序`

using Common.Utility;
using log4net.Appender;
using log4net.Config;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TestLogStash.Log;
using TradingSystemBackgroundApp.Config;
namespace TestLogStash
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var str = Console.ReadLine();
                new LogIni();
                Common.Utility.Log.Debug(new BusinessLog("交易系统", str, DateTime.Now, new Exception("异常")));
                Console.ReadLine();
            }    
            catch (Exception)
            {

                throw;
            }
            
        }
        public  void LogIni()
        {
            string logConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
            XmlConfigurator.Configure(new FileStream(logConfigPath, FileMode.Open));
        }
    }
}

进入Kibana 查看索引

ELK日志采集工具设计 elk日志系统搭建_Common_10


现在我们启动程序 开始进行写日志

ELK日志采集工具设计 elk日志系统搭建_ELK日志采集工具设计_11


进入Kibana查看

ELK日志采集工具设计 elk日志系统搭建_Common_12


LogIni 方法:`

using log4net.Config;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TradingSystemBackgroundApp.Config
{
    /// <summary>
    /// 日志初始化
    /// </summary>
   public  class LogIni
    {
        public LogIni() {
            string logConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");
            XmlConfigurator.Configure(new FileStream(logConfigPath, FileMode.Open));
        }
    }
}

好了 简单的ELK日志搭建 环境已经好了 在这里简单记录一下