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的最 ...
随机推荐
- Groovy学习笔记(二)
在上一篇文章中我们主要学习了如何搭建Groovy开发环境,为我们的Groovy之旅做好了准备工作,不知道你是否准备好了?接下来我们就一起看看Groovy与我们熟悉的Java有什么异同. Groovy是 ...
- URL中文乱码处理总结(转)
转自:http://www.cnblogs.com/xirongliu/archive/2012/09/06/2674196.html 问题:传递中文参数的时候,接收页面出现乱码问题?当跨域操作,两套 ...
- cellspacing,cellpadding什么区别
cellspacing设置为“0”,显示的结果就是第一个表格的每个单元格之间的距离为0.若将表格边框设为“0”,则单元格 的距离就是0了cellpadding属性用来指定单元格内容与单元格边界之间的空 ...
- paper 97:异质人脸识别进展的资讯
高新波教授团队异质人脸图像识别研究取得新突破,有望大大降低刑侦过程人力耗费并提高办案效率 近日,西安电子科技大学高新波教授带领的研究团队,在异质人脸图像识别研究领域取得重要进展,其对香 ...
- AJAX-----08jsonp跨域请求
jsonp跨域请求其实我个人感觉并非传统上的ajax,因为传统的ajax几乎都是采用了xmlhttprequest这个对象来进行发送数据或者接收数据而已, 而jsop是通过双方约定成一个接口文件,然后 ...
- html5,表单与label标签配套使用
<form action=""><input type="checkbox" name="dx" value=" ...
- 如何用css做一个细虚线边框表格
<style type="text/css"> <!-- .dashed_tbl { border-top: 1px dashed #333333; border ...
- Linux基础命令介绍七:网络传输与安全 wget curl rsync iptables
本篇接着介绍网络相关命令:wget 文件下载工具.curl 网络数据传输工具.rsync 文件传输工具等. 本篇接着介绍网络相关命令 1.wget 文件下载工具 wget [option]... [U ...
- python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息,抓取政府网新闻内容
python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI,采用Python语言编写 ...
- Python之检查URL
# -*- coding: utf-8 -*- import os,sys import time import sys import pycurl #URL="http://www.bai ...