• ELK集成Log4net 重写一个TcpAppender


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

    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<Task<Socket>>(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<Socket> 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)
    
    ");
                  this.AddClient(client);
                }
                catch
                {
                  client.Dispose();
                }
              }
              else
              {
                client.Send("Sorry - Too many connections.
    ");
                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 TcpAppender
    16             {
    17                 Encoding = Encoding.UTF8,
    18                 RemoteAddress = new IPAddress(new byte[] { 192,168,132,128 }),
    19                 RemotePort = 8001,
    20                 Layout = layout
    21             };
    22             var consoleAppender = new ConsoleAppender
    23             {
    24                 Layout = layout
    25             };
    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规则没对应好

  • 相关阅读:
    arcgis要素折点转点
    arcgis问题数据判断
    arcgis根据位置信息查找一个点周围的线(根据交点,查找)
    GIS算法-最短路径-连通性-网络分析-路径规划
    Arcgis直连SQLServer数据库,通过REST修改数据ArcMap中更新数据库数据不更新,数据不统一
    None和NULL
    ArcPy属性查询
    WGS84转gcj02
    ArcGIS Server跨域
    MySQL中数据类型宽度有什么用, INT(11)有什么意义?
  • 原文地址:https://www.cnblogs.com/TeemoHQ/p/8358450.html
Copyright © 2020-2023  润新知