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

时间:2021-02-25 01:19:27

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

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

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

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 = "", //目前获取不到
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 = )
{
_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 实现日志系统的更多相关文章

  1. 安装logstash&plus;kibana&plus;elasticsearch&plus;redis搭建集中式日志分析平台

    安装logstash+kibana+elasticsearch+redis搭建集中式日志分析平台 2014-01-16 19:40:57|  分类: logstash |  标签:logstash   ...

  2. Logstash&plus;kibana&plus; ElasticSearch&plus;redis

    这是之前Logstash+kibana+ ElasticSearch+redis 安装时,自己整理的初学者容易看懂的资料,按照以下的步骤也已经完成了安装. 这里有二台服务器: 192.168.148. ...

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

    一.问题概述 如题所说,后端应用(非spring boot项目)通常用到了很多jar包,比如spring系列.mybatis.hibernate.各类连接数据库的客户端的jar包.可能这个jar包用的 ...

  4. Logstash&plus;ElasticSearch&plus;Kibana处理nginx访问日志(转)

    ELK似乎是当前最为流行的日志收集-存储-分析的全套解决方案. 去年年初, 公司里已经在用, 当时自己还山寨了一个统计系统(postgresql-echarts, 日志无结构化, json形式存储到p ...

  5. 【转】ELK&lpar;ElasticSearch&comma; Logstash&comma; Kibana&rpar;搭建实时日志分析平台

    [转自]https://my.oschina.net/itblog/blog/547250 摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticS ...

  6. 【Big Data - ELK】ELK&lpar;ElasticSearch&comma; Logstash&comma; Kibana&rpar;搭建实时日志分析平台

    摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticSearch,一款基于Apache Lucene的开源分布式搜索引擎)中便于查找和分析,在研究 ...

  7. &lbrack;Big Data - ELK&rsqb; ELK&lpar;ElasticSearch&comma; Logstash&comma; Kibana&rpar;搭建实时日志分析平台

    ELK平台介绍 在搜索ELK资料的时候,发现这篇文章比较好,于是摘抄一小段: 以下内容来自: http://baidu.blog.51cto.com/71938/1676798 日志主要包括系统日志. ...

  8. 基于ELK5&period;1&lpar;ElasticSearch&comma; Logstash&comma; Kibana&rpar;的一次整合测试

    前言开源实时日志分析ELK平台(ElasticSearch, Logstash, Kibana组成),能很方便的帮我们收集日志,进行集中化的管理,并且能很方便的进行日志的统计和检索,下面基于ELK的最 ...

  9. 基于ELK5&period;1&lpar;ElasticSearch&comma; Logstash&comma; Kibana&rpar;的一次整合

    前言开源实时日志分析ELK平台(ElasticSearch, Logstash, Kibana组成),能很方便的帮我们收集日志,进行集中化的管理,并且能很方便的进行日志的统计和检索,下面基于ELK的最 ...

随机推荐

  1. &lbrack;资料分享&rsqb;Java35期基础班和就业班

    直接上链接:https://pan.baidu.com/s/1jI8p2Xw 密码:gr9x

  2. 查询数据库表大小sql

    SELECT a.name, b.rowsFROM sysobjects AS a INNER JOIN sysindexes AS b ON a.id = b.idWHERE (a.type = ' ...

  3. Ruby--strftime

    -- [17 Oct 2016 05:37:18AM]:%e %b %Y %H:%M:%S%p -- [Oct 17, 2016]:%b %d, %Y -- [10-17-16 05:37]:%m-% ...

  4. Java基础知识强化之集合框架笔记50:Map集合之Map集合的概述和特点

    1. Map集合的概述: public interface Map<K,V> 作为学生来说,是根据学号来区分不同的学生的,那么假设我现在已经知道了学生的学号,我要根据学号去获取学生姓名,请 ...

  5. django 创建一个通用视图

    创建一个通用视图   抽取出我们代码*性的东西是一个很好的编程习惯. 比如,像以下的两个Python函数:     def say_hello(person_name): print 'Hello, ...

  6. yii DbCriteria相关属性常用方法

    $criteria = new CDbCriteria; //函数方式 $criteria->addCondition("id=1"); //查询条件,即where id = ...

  7. 对 Kotlin 与 Java 编程语言的思考

    从长远来看,排名前10的也基本上是Java.C.C++.Python.C#.VB.PHP.JavaScript.至于Kotlin的排名,11月份在编程语言仅排41名,Ratings仅有0.216%. ...

  8. Android -- 动态添加布局

    在做项目的时候,遇到了scrollView与listView结合的使用,导致了滑动的混乱,但是有一个办法可以解决掉这个问题,就是手写listView的高度,还有另外一种方法,传送门:<Andro ...

  9. 4&period;ubuntu实现linux与windows的互相复制与粘贴

    为了能够在linux和windows之间直接进行互相复制粘贴,给出下面的解决办法. 系统环境: ubuntu12.04(linux), win7系统 以下指令都是在超级用户的执行权限下执行的. 要解决 ...

  10. 蓝屏代码大全 &amp&semi; 蓝屏全攻略

    转载自http://diybbs.zol.com.cn/15/86_141447.html 一.蓝屏含义 1.故障检查信息 ***STOP 0x0000001E(0xC0000005,0xFDE38A ...