博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ELK集成Log4net 重写一个TcpAppender
阅读量:6908 次
发布时间:2019-06-27

本文共 12889 字,大约阅读时间需要 42 分钟。

 最近搞了下ELK,三个工具部署完毕,想再集成上log4net。没想到.net core版Log4net竟然没有直接Tcp发送消息的appender。醉了。

1.RemotingAppender:core已经不支持。

2.RemoteSysLogAppender:只监听 udp的514端口。【:The BSD syslog protocol is used to remotely log to a syslog daemon. The syslogd listens for for messages on UDP port 514.】

3.UdpAppender:udp协议传输数据

4.TelnetAppender:一开始以为肯定是这个可以用了。官网没有examples。。***翻了config。里面竟然只有port配置没有remotingAddress等(黑人问号)???。官网解释这个东西怎么玩的【:The TelnetAppender accepts socket connections and streams logging messages back to the client. The output is provided in a telnet-friendly way so that a log can be monitored over a TCP/IP socket. This allows simple remote monitoring of application logging.】

也就是它是开了一个监听。监听别人给他发的日志数据,然后记录数据然后再发回去。。。What???。我要的是你发出去。混蛋。下面去反编译看看他的源码。。

namespace log4net.Appender{  public class TelnetAppender : AppenderSkeleton  {    private static readonly Type declaringType = typeof (TelnetAppender);    private int m_listeningPort = 23;    private TelnetAppender.SocketHandler m_handler;    public int Port    {      get      {        return this.m_listeningPort;      }      set      {        if (value < 0 || value > (int) ushort.MaxValue)          throw SystemInfo.CreateArgumentOutOfRangeException("value", (object) value, "The value specified for Port is less than " + 0.ToString((IFormatProvider) NumberFormatInfo.InvariantInfo) + " or greater than " + ((int) ushort.MaxValue).ToString((IFormatProvider) NumberFormatInfo.InvariantInfo) + ".");        this.m_listeningPort = value;      }    }    protected override bool RequiresLayout    {      get      {        return true;      }    }    protected override void OnClose()    {      base.OnClose();      if (this.m_handler == null)        return;      this.m_handler.Dispose();      this.m_handler = (TelnetAppender.SocketHandler) null;    }    public override void ActivateOptions()    {      base.ActivateOptions();      try      {        LogLog.Debug(TelnetAppender.declaringType, "Creating SocketHandler to listen on port [" + (object) this.m_listeningPort + "]");        this.m_handler = new TelnetAppender.SocketHandler(this.m_listeningPort);      }      catch (Exception ex)      {        LogLog.Error(TelnetAppender.declaringType, "Failed to create SocketHandler", ex);        throw;      }    }    protected override void Append(LoggingEvent loggingEvent)    {      if (this.m_handler == null || !this.m_handler.HasConnections)        return;      this.m_handler.Send(this.RenderLoggingEvent(loggingEvent));    }    protected class SocketHandler : IDisposable    {      private ArrayList m_clients = new ArrayList();      private const int MAX_CONNECTIONS = 20;      private Socket m_serverSocket;      public bool HasConnections      {        get        {          ArrayList clients = this.m_clients;          if (clients != null)            return clients.Count > 0;          return false;        }      }      public SocketHandler(int port)      {        this.m_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);        this.m_serverSocket.Bind((EndPoint) new IPEndPoint(IPAddress.Any, port));        this.m_serverSocket.Listen(5);        this.AcceptConnection();      }      private void AcceptConnection()      {        this.m_serverSocket.AcceptAsync().ContinueWith(new Action
>(this.OnConnect), TaskScheduler.Default); } public void Send(string message) { foreach (TelnetAppender.SocketHandler.SocketClient client in this.m_clients) { try { client.Send(message); } catch (Exception ex) { client.Dispose(); this.RemoveClient(client); } } } private void AddClient(TelnetAppender.SocketHandler.SocketClient client) { TelnetAppender.SocketHandler socketHandler = this; bool lockTaken = false; try { Monitor.Enter((object) socketHandler, ref lockTaken); ArrayList arrayList = (ArrayList) this.m_clients.Clone(); arrayList.Add((object) client); this.m_clients = arrayList; } finally { if (lockTaken) Monitor.Exit((object) socketHandler); } } private void RemoveClient(TelnetAppender.SocketHandler.SocketClient client) { TelnetAppender.SocketHandler socketHandler = this; bool lockTaken = false; try { Monitor.Enter((object) socketHandler, ref lockTaken); ArrayList arrayList = (ArrayList) this.m_clients.Clone(); arrayList.Remove((object) client); this.m_clients = arrayList; } finally { if (lockTaken) Monitor.Exit((object) socketHandler); } } private void OnConnect(Task
acceptTask) { try { Socket result = acceptTask.GetAwaiter().GetResult(); LogLog.Debug(TelnetAppender.declaringType, "Accepting connection from [" + result.RemoteEndPoint.ToString() + "]"); TelnetAppender.SocketHandler.SocketClient client = new TelnetAppender.SocketHandler.SocketClient(result); int count = this.m_clients.Count; if (count < 20) { try { client.Send("TelnetAppender v1.0 (" + (object) (count + 1) + " active connections)\r\n\r\n"); this.AddClient(client); } catch { client.Dispose(); } } else { client.Send("Sorry - Too many connections.\r\n"); client.Dispose(); } } catch { } finally { if (this.m_serverSocket != null) this.AcceptConnection(); } } public void Dispose() { foreach (TelnetAppender.SocketHandler.SocketClient client in this.m_clients) client.Dispose(); this.m_clients.Clear(); Socket serverSocket = this.m_serverSocket; this.m_serverSocket = (Socket) null; try { serverSocket.Shutdown(SocketShutdown.Both); } catch { } try { CompatibilityExtensions.Close(serverSocket); } catch { } } protected class SocketClient : IDisposable { private Socket m_socket; private StreamWriter m_writer; public SocketClient(Socket socket) { this.m_socket = socket; try { this.m_writer = new StreamWriter((Stream) new NetworkStream(socket)); } catch { this.Dispose(); throw; } } public void Send(string message) { this.m_writer.Write(message); this.m_writer.Flush(); } public void Dispose() { try { if (this.m_writer != null) { CompatibilityExtensions.Close(this.m_writer); this.m_writer = (StreamWriter) null; } } catch { } if (this.m_socket == null) return; try { this.m_socket.Shutdown(SocketShutdown.Both); } catch { } try { CompatibilityExtensions.Close(this.m_socket); } catch { } this.m_socket = (Socket) null; } } } }}
View Code

那就没办法。。我自己再重写一个直接发送的TcpAppender吧。。写法是完全看udpAppender源码改的。暴露出来的配置和udp基本一致。把local的去除了

internal class TcpAppender : AppenderSkeleton    {        private Encoding _encoding = Encoding.Unicode;        private IPAddress _remoteAddress;        private int _remotePort;        private IPEndPoint _remoteEndPoint;        private TcpClient _client;        public IPAddress RemoteAddress        {            get            {                return this._remoteAddress;            }            set            {                this._remoteAddress = value;            }        }        public int RemotePort        {            get            {                return this._remotePort;            }            set            {                if (value < 0 || value > (int)ushort.MaxValue)                    throw SystemInfo.CreateArgumentOutOfRangeException("value", (object)value, "The value specified is less than " + 0.ToString((IFormatProvider)NumberFormatInfo.InvariantInfo) + " or greater than " + ((int)ushort.MaxValue).ToString((IFormatProvider)NumberFormatInfo.InvariantInfo) + ".");                this._remotePort = value;            }        }        public Encoding Encoding        {            get            {                return this._encoding;            }            set            {                this._encoding = value;            }        }        protected TcpClient Client        {            get            {                return this._client;            }            set            {                this._client = value;            }        }        protected IPEndPoint RemoteEndPoint        {            get            {                return this._remoteEndPoint;            }            set            {                this._remoteEndPoint = value;            }        }        protected override bool RequiresLayout        {            get            {                return true;            }        }        public override void ActivateOptions()        {            base.ActivateOptions();            if (this.RemoteAddress == null)                throw new ArgumentNullException("The required property 'Address' was not specified.");            if (this.RemotePort < 0 || this.RemotePort > (int)ushort.MaxValue)                throw SystemInfo.CreateArgumentOutOfRangeException("this.RemotePort", (object)this.RemotePort, "The RemotePort is less than " + 0.ToString((IFormatProvider)NumberFormatInfo.InvariantInfo) + " or greater than " + ((int)ushort.MaxValue).ToString((IFormatProvider)NumberFormatInfo.InvariantInfo) + ".");            this.RemoteEndPoint = new IPEndPoint(this.RemoteAddress, this.RemotePort);            this.InitializeClientConnection();        }        protected override void Append(LoggingEvent loggingEvent)        {            try            {                NetworkStream ntwStream = this.Client.GetStream();                var aa = this.RenderLoggingEvent(loggingEvent).ToCharArray();                byte[] bytes = this._encoding.GetBytes(this.RenderLoggingEvent(loggingEvent).ToCharArray());                ntwStream.Write(bytes, 0, bytes.Length);            }            catch (Exception ex)            {                this.ErrorHandler.Error("Unable to send logging event to remote host " + this.RemoteAddress.ToString() + " on port " + (object)this.RemotePort + ".", ex, ErrorCode.WriteFailure);            }        }        protected override void OnClose()        {            base.OnClose();            if (this.Client == null)                return;            Client.Dispose();            this.Client = null;        }        protected virtual void InitializeClientConnection()        {            try            {                this.Client = new TcpClient(this.RemoteAddress.ToString(), this.RemotePort);            }            catch (Exception ex)            {                this.ErrorHandler.Error("Could not initialize the UdpClient connection on port " + this.RemotePort.ToString((IFormatProvider)NumberFormatInfo.InvariantInfo) + ".", ex, ErrorCode.GenericFailure);                this.Client = null;            }        }    }
View Code

用法代码。里面额外加入了一个consoleAppender 方便查看调试

1         static void Main(string[] args) 2         { 3             Test(); 4             Console.ReadKey(); 5         } 6  7         private static void Test() 8         { 9             var repo = LogManager.CreateRepository("R");10 11             var layout = new PatternLayout()12             {13                 ConversionPattern = "#%date #%level #%message#",14             };15             var tcpAppender = new TcpAppender16             {17                 Encoding = Encoding.UTF8,18                 RemoteAddress = new IPAddress(new byte[] { 192,168,132,128 }),19                 RemotePort = 8001,20                 Layout = layout21             };22             var consoleAppender = new ConsoleAppender23             {24                 Layout = layout25             };26             layout.ActivateOptions();27             tcpAppender.ActivateOptions();28             BasicConfigurator.Configure(repo, consoleAppender,tcpAppender);29 30             ILog log = LogManager.GetLogger(repo.Name, "Debug");31             log.Info("666666666666666666666");32             Console.ReadKey();33         }
View Code

 

下面是成功发送到虚拟机上的kibana的后台显示。部分数据和字段没匹配好是logstash的规则和log4net规则没对应好

 

转载于:https://www.cnblogs.com/TeemoHQ/p/8358450.html

你可能感兴趣的文章
UML类图几种关系的总结,泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖
查看>>
Intellij Idea 2016 配置Tomcat虚拟目录
查看>>
Android 调整透明度的图片查看器
查看>>
一个开源的仓储系统
查看>>
5.24 Declaring Attributes of Functions【转】
查看>>
利用SCORE法则来总结一次偷懒的单元测试过程
查看>>
angular中的 登录检查 和 过期Session清理
查看>>
基于FormsAuthentication的用户、角色身份认证
查看>>
阿里云-DRDS(转)
查看>>
Lua协程-测试3
查看>>
009-java中常用的单个键值对
查看>>
微软为AJAX和jQuery类库提供CDN服务
查看>>
LuoYun 开源云计算平台软件 0.2 Beta 版本发布 — LinuxTOY
查看>>
约会你的私人定制
查看>>
MD5 加密的两种方法
查看>>
Winfrom 控件移位绘制垂直、水平线
查看>>
如何开启to 日志
查看>>
android和iOS平台的崩溃捕获和收集
查看>>
sql执行计划[Oracle] 变量绑定
查看>>
[Swift A] - Welcome to Swift
查看>>