log4net.redis+logstash+kibana+elasticsearch+redis 实现日志系统

前端时间写了个随笔 log4net.NoSql +ElasticSearch 实现日志记录 ,因项目原因需要把日志根java平台的同事集成采用logstash+kibana+elasticsearch+redis结构实现日志统计分析,所以需要一个将log4net日志输出到redis的组件。没有找到现成的,就自己动手了。参考了 log4net.NoSql 的代码。

redis的C#客户端使用了 ServiceStackRedis,json序列化使用 RestSharp。代码结构如下:

JsonLayout.cs代码:

  public class JsonLayout : LayoutSkeleton
    {
        public readonly string HostName;
        private readonly ITextTransform _transform;

        public string LogType { get; set; }
        public string AppName { get; set; }

        public JsonLayout()
            : base()
        {
            HostName = Dns.GetHostName();
            _transform = TextTransform.Instance;
        }

        public override string ContentType
        {
            get { return "application/json"; }
        }

        public override void ActivateOptions()
        {
            //nothing to do here
        }

        public override void Format(TextWriter writer, LoggingEvent loggingEvent)
        {
            var info = loggingEvent.LocationInformation;
            var loggingEventJson = _transform.Serialize(new JsonLogMessage
                {
                    class_method = info.MethodName,
                    class_name = info.ClassName,
                    host_ip = HostName,
                    line_number = info.LineNumber,
                    log_level = loggingEvent.Level.DisplayName,
                    log_message = loggingEvent.MessageObject.ToString(),
                    exception = BuildExceptionMessage(loggingEvent),
                    log_time = loggingEvent.TimeStamp.ToString("yyyy-MM-dd HH:mm:ss"),
                    logger_name = loggingEvent.LoggerName,
                    run_time = "0", //目前获取不到
                    thread_name = loggingEvent.ThreadName,
                    host = HostName,
                    log_type = this.LogType,
                    app_name = this.AppName,
                    path = ""
                });

            writer.Write(loggingEventJson);
        }

        private JsonLogException BuildExceptionMessage(LoggingEvent loggingEvent)
        {
            if (loggingEvent.ExceptionObject == null)
                return new JsonLogException { exception_class = "", exception_message = "", exception_stacktrace = "" };

            var exception = loggingEvent.ExceptionObject;
            return
                new JsonLogException
                {
                    exception_class = exception.Source,
                    exception_message = exception.Message,
                    exception_stacktrace = exception.StackTrace
                };
        }
    }

RedisAppender.cs

 public class RedisAppender : AppenderSkeleton
    {
        private volatile PooledRedisClient _pooledRedisClient;
        private readonly object _padlock = new object();

        public string Host { get; set; }
        public string Port { get; set; }
        public string ListId { get; set; }
        public string MaxPoolSize { get; set; }

        public RedisAppender()
        {
        }

        private PooledRedisClient Client
        {
            get
            {
                if (_pooledRedisClient != null) return _pooledRedisClient;

                lock (_padlock)
                {
                    if (_pooledRedisClient == null)
                    {
                        _pooledRedisClient = new PooledRedisClient(this.Host, int.Parse(this.Port), int.Parse(this.MaxPoolSize));
                    }
                }
                return _pooledRedisClient;
            }
        }

        protected override void Append(LoggingEvent loggingEvent)
        {
            var sb = new StringBuilder();
            var writer = new StringWriter(sb);
            base.Layout.Format(writer, loggingEvent);
            this.Client.AddItemToListAsync(ListId, writer.ToString());
        }
    }

PooledRedisClient.cs

  public class PooledRedisClient
    {
        private readonly string _baseUri;
        private readonly PooledRedisClientManager _clientManager;
        /// <summary>
        /// 实例化连接池客户端
        /// </summary>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <param name="maxPoolSize">默认值10</param>
        public PooledRedisClient(string host, int port, int maxPoolSize = 10)
        {
            _baseUri = string.Format("{0}:{1}", host, port);
            var config = new RedisClientManagerConfig();
            config.MaxReadPoolSize = maxPoolSize;
            config.MaxWritePoolSize = maxPoolSize;
            _clientManager = new PooledRedisClientManager(new string[] { _baseUri }, new string[] { _baseUri }, config);
        }
        /// <summary>
        /// 异步记录
        /// </summary>
        /// <param name="listId"></param>
        /// <param name="log"></param>
        public void AddItemToListAsync(string listId, string log)
        {
            //使用Task任务异步执行
            var task = new Task(() =>
            {
                try
                {
                    using (var clinet = _clientManager.GetClient())
                    {
                        clinet.AddItemToList(listId, log);
                    }
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(ex.Message);
                }
            });
            task.Start();
        }

    }

在RedisClient连接时用了连接池,写日志时用Task做了异步。这种写法不知道会不会存在问题?!

配置文件

<?xml version="1.0"?>
<log4net>
  <!--Redis日志记录-->
  <appender name="redisAppender" type="log4net.Redis.Appender.RedisAppender, log4net.Redis">
    <Host value="192.168.0.10" />
    <Port value="6379" />
    <MaxPoolSize value="500" />
    <ListId value="logstash" />
    <layout type="log4net.Redis.Layout.JsonLayout,log4net.Redis" >
      <LogType value="iis_log" />
      <AppName value="Demo" />
    </layout>
  </appender>
  <root>
    <level value="ALL" />
    <appender-ref ref="redisAppender" />
  </root>
</log4net>

Layout和Appender里的属性配置和代码里属性配置名称一致,Log4net的框架就可以读取配置数据反射到实体属性上。

代码下载地址:

http://download.csdn.net/detail/zbl131/7702673

参考文章:

1.用Kibana和logstash快速搭建实时日志查询、收集与分析系统

http://storysky.blog.51cto.com/628458/1158707/

2.使用ServiceStackRedis链接Redis简介

http://www.cnblogs.com/daizhj/archive/2011/02/17/1956860.html

3.ServiceStack.Redis的问题与修正

http://blog.csdn.net/susubuhui/article/details/8930417

4.对ServiceStack.Redis的连接池进行故障转移改造

http://www.cnblogs.com/smark/archive/2013/05/24/3096488.html

log4net.redis+logstash+kibana+elasticsearch+redis 实现日志系统

时间: 2024-08-14 02:47:38

log4net.redis+logstash+kibana+elasticsearch+redis 实现日志系统的相关文章

安装logstash+kibana+elasticsearch+redis搭建集中式日志分析平台

本文是参考logstash官方文档实践的笔记,搭建环境和所需组件如下: Redhat 5.7 64bit / CentOS 5.x JDK 1.6.0_45 logstash 1.3.2 (内带kibana) elasticsearch 0.90.10 redis 2.8.4 搭建的集中式日志分析平台流程如下: elasticsearch 1.下载elasticsearch. wget https://download.elasticsearch.org/elasticsearch/elasti

Logstash+kibana+ ElasticSearch+redis

这是之前Logstash+kibana+ ElasticSearch+redis 安装时,自己整理的初学者容易看懂的资料,按照以下的步骤也已经完成了安装. 这里有二台服务器: 192.168.148.201 logstash index,redis,ElasticSearch,kibana,JDK 192.168.148.129 logstash agent,JDK 1 系统各部分应用介绍 Logstash:一个完全开源对日志进行收集.分析和存储的工具.他可以做系统的log收集,转载的工具.同时

logstash kibana elasticsearch环境部署

ElasticSearch 下载地址: https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.4.1.tar.gz 依赖环境: java 参考地址:https://www.elastic.co/downloads/elasticsearch 解压软件包 tar -xvf elasticsearch-5.4.1.tar.gz 进入解压目录 cd elasticsearch-5.4.1 编辑配置文件 config/e

面试题:应用中很多jar包,比如spring、mybatis、redis等等,各自用的日志系统各异,怎么用slf4j统一输出?

一.问题概述 如题所说,后端应用(非spring boot项目)通常用到了很多jar包,比如spring系列.mybatis.hibernate.各类连接数据库的客户端的jar包.可能这个jar包用的是logback.那个用的是log4j.那个又是log4j2, 这时候,怎么才能保证各jar包的日志都能输出,且能以统一的格式输出呢? 为什么要强调非spring boot项目,可参考第四节. 二.几种日志框架的简单介绍 来源:https://juejin.im/post/5a7c5d5751882

[Big Data - ELK] ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台

ELK平台介绍 在搜索ELK资料的时候,发现这篇文章比较好,于是摘抄一小段: 以下内容来自: http://baidu.blog.51cto.com/71938/1676798 日志主要包括系统日志.应用程序日志和安全日志.系统运维和开发人员可以通过日志了解服务器软硬件信息.检查配置过程中的错误及错误发生的原因.经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误. 通常,日志被分散的储存不同的设备上.如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志.这

ELK(ElasticSearch+Logstash+Kibana)日志分析工具

日志主要包括系统日志.应用程序日志和安全日志.系统运维和开发人员可以通过日志了解服务器软硬件信息.检查配置过程中的错误及错误发生的原因.经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误. 通常,日志被分散的储存不同的设备上.如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志.这样是不是感觉很繁琐和效率低下.当务之急我们使用集中化的日志管理,例如:开源的syslog,将所有服务器上的日志收集汇总. 集中化管理日志后,日志的统计和检索又成为一件比较麻烦的事

CentOS7使用Elasticsearch+ Logstash+kibana快速搭建日志分析平台

CentOS7使用Elasticsearch+ Logstash+kibana快速搭建日志分析平台 介绍: 安装logstash,elasticsearch,kibana三件套,搜索程序一般由索引链及搜索组件组成. 索引链功能的实现需要按照几个独立的步骤依次完成:检索原始内容.根据原始内容来创建对应的文档.对创建的文档进行索引. 搜索组件用于接收用户的查询请求并返回相应结果,一般由用户接口.构建可编程查询语句的方法.查询语句执行引擎及结果展示组件组成. Elasticsearch是个开源分布式搜

Filebeat +Redis+ELK处理Nginx日志系统

(一)简述: filebeat:具有日志收集功能,是下一代的Logstash收集器,但是filebeat更轻量,占用资源更少,适合客户端使用. redis:Redis 服务器通常都是用作 NoSQL 数据库,不过 logstash 只是用来做消息队列. logstash:主要是用来日志的搜集.分析.过滤日志的工具,支持大量的数据获取方式.一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤.修改等操作在一并发往elasticsearch

基于ELK5.1(ElasticSearch, Logstash, Kibana)的一次整合测试

前言开源实时日志分析ELK平台(ElasticSearch, Logstash, Kibana组成),能很方便的帮我们收集日志,进行集中化的管理,并且能很方便的进行日志的统计和检索,下面基于ELK的最新版本5.1进行一次整合测试. ElasticSearch1.概述:ElasticSearch是一个高可扩展的开源的全文搜索分析引擎.它允许你快速的存储.搜索和分析大量数据.ElasticSearch通常作为后端程序,为需要复杂查询的应用提供服务.Elasticsearch是一个基于Lucene的开