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 = "", //目前获取不到
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 实现日志系统的更多相关文章
- 安装logstash+kibana+elasticsearch+redis搭建集中式日志分析平台
安装logstash+kibana+elasticsearch+redis搭建集中式日志分析平台 2014-01-16 19:40:57| 分类: logstash | 标签:logstash ...
- Logstash+kibana+ ElasticSearch+redis
这是之前Logstash+kibana+ ElasticSearch+redis 安装时,自己整理的初学者容易看懂的资料,按照以下的步骤也已经完成了安装. 这里有二台服务器: 192.168.148. ...
- 面试题:应用中很多jar包,比如spring、mybatis、redis等等,各自用的日志系统各异,怎么用slf4j统一输出?(上)
一.问题概述 如题所说,后端应用(非spring boot项目)通常用到了很多jar包,比如spring系列.mybatis.hibernate.各类连接数据库的客户端的jar包.可能这个jar包用的 ...
- Logstash+ElasticSearch+Kibana处理nginx访问日志(转)
ELK似乎是当前最为流行的日志收集-存储-分析的全套解决方案. 去年年初, 公司里已经在用, 当时自己还山寨了一个统计系统(postgresql-echarts, 日志无结构化, json形式存储到p ...
- 【转】ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台
[转自]https://my.oschina.net/itblog/blog/547250 摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticS ...
- 【Big Data - ELK】ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台
摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticSearch,一款基于Apache Lucene的开源分布式搜索引擎)中便于查找和分析,在研究 ...
- [Big Data - ELK] ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台
ELK平台介绍 在搜索ELK资料的时候,发现这篇文章比较好,于是摘抄一小段: 以下内容来自: http://baidu.blog.51cto.com/71938/1676798 日志主要包括系统日志. ...
- 基于ELK5.1(ElasticSearch, Logstash, Kibana)的一次整合测试
前言开源实时日志分析ELK平台(ElasticSearch, Logstash, Kibana组成),能很方便的帮我们收集日志,进行集中化的管理,并且能很方便的进行日志的统计和检索,下面基于ELK的最 ...
- 基于ELK5.1(ElasticSearch, Logstash, Kibana)的一次整合
前言开源实时日志分析ELK平台(ElasticSearch, Logstash, Kibana组成),能很方便的帮我们收集日志,进行集中化的管理,并且能很方便的进行日志的统计和检索,下面基于ELK的最 ...
随机推荐
- 原生js快速渲染dom节点
function renderDom(str){ var _div = document.createElement('div'); _div.innerHTML = str; var dom_tem ...
- Android 开机启动
创建一个Receiver,用来监听开机完毕: public class MyReceiver extends BroadcastReceiver { static final String actio ...
- Web Servic和Web API的区别
Web Service:1.它是基于SOAP协议的,数据格式是XML2.只支持HTTP协议3.它不是开源的,但可以被任意一个了解XML的人使用4.它只能部署在IIS上Web API:1.这是一个简单的 ...
- 关于input内容监听(change)
js的话利用input的onchange事件 而jquery的话利用change()函数,代码如下: <!DOCTYPE html> <html> <head> & ...
- MMAP和DIRECT IO区别【转】
转自:http://www.cnblogs.com/zhaoyl/p/5901680.html 看完此文,题目不言自明.转自 http://blog.chinaunix.net/uid-2710571 ...
- Knights of the Round Table-POJ2942(双连通分量+交叉染色)
Knights of the Round Table Description Being a knight is a very attractive career: searching for the ...
- Android Fragment 真正的完全解析(上)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37970961 自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fra ...
- ms sql 经典语句【珍藏】
数据库中字段中有不需要"[演示数据请勿真实购买]" 例如: update Hishop_Products set ProductName = replace(ProductName ...
- Cheatsheet: 2015 09.01 ~ 09.30
Web A Guide to Vanilla Ajax Without jQuery Gulp for Beginners A Detailed Walkthrough of ASP.net MVC ...
- php : 匿名函数(闭包) [一]
摘自: http://www.cnblogs.com/starlion/p/3894578.html 一:匿名函数 (在php5.3.0 或以上才能使用) php中的匿名函数(Anonymous fu ...