.NET下日志系统的搭建——log4net+kafka+elk
文章导航-readme
.NET下日志系统的搭建——log4net+kafka+elk
前言
我们公司的程序日志之前都是采用log4net记录文件日志的方式(有关log4net的简单使用可以看我另一篇博客),但是随着后来我们团队越来越大,项目也越来越大,我们的用户量也越来越多。慢慢系统就暴露了很多问题,这个时候我们的日志系统已经不能满足我们的要求。其主要有下面几个问题:
- 随着我们访问量的增加,我们的日志文件急剧增加
- 多且乱的文件日志,难以让我们对程序进行排错
- 文件日志的记录耗用我们应用服务器的资源,导致我们的应用服务器的处理用户请求的能力下降
- 我们的日志分布在多台应用服务器上,当程序遇到问题时,我们的程序员都需要找运维人员要日志,随着团队越来越大,问题越来越多,于是导致了程序员们排队找运维要日志,解决问题的速度急剧下降!
起初,用户量不大的时候,上面的问题还能容忍。但任何一种小问题都会在用户量访问量变大的时候急剧的放大。终于在几波推广活动的时候,很悲剧的我们又不得不每天深夜加班来为我们之前对这些问题的不重视来买单。于是,在推广活动结束之后,在我们的程序员得到一丝喘息的机会时,我决定来搭建一个我们自己的日志系统,改善我们的日志记录方式。根据以上问题分析我们的日志系统需要有以下几点要求:
- 日志的写入效率要高不能对应用服务器造成太大的影响
- 要将日志集中在一台服务器上(或一组)
- 提供一个方便检索分析的可视化页面(这个最重要,再也受不了每天找运维要日志,拿到一堆文件来分析的日子了!)
一开始想要借助log4net AdoAppender把我们的日志写到数据库里,然后我们开发一个相应的功能,来对我们的日志来进行查询和分析。但考虑到写入关系数据库的性能问题,就放弃了,但有一个替代方案,就是写入到Mongo中,这样就解决了提高了一定的性能。但也需要我们开发一个功能来查询分析。这个时候从网上找了许多方案:
//方案1:这是我们现有的方案,优点:简单 缺点:效率低,不易查询分析,难以排错...
service-->log4net-->文件
//方案2:优点:简单、效率高、有一定的查询分析功能 缺点:增加mongodb,增加一定复杂性,查询分析功能弱,需要投入开发精力和时间
service-->log4net-->Mongo-->开发一个功能查询分析
//方案3:优点:性能很高,查询分析及其方便,不需要开发投入 缺点:提高了系统复杂度,需要进行大量的测试以保证其稳定性,运维需要对这些组件进行维护监控...
service-->log4net-->kafka-->logstash-->elasticsearch-->kibana搜索展示               
//其它方案
service-->log4net-->文件-->filebeat-->logstash-->elstaicsearch-->kibana
service-->log4net-->文件-->filebeat-->elstaicsearch-->kibana
service-->log4net-->文件-->logstash-->elstaicsearch-->kibana
最终和团队交流后决定采用方案2和方案3的结合,我增加了一个log4net for mongo的appender(这个appender,nuget上也有),另外我们的团队开发一个能支持简单查询搜索的功能。我同步来搭建方案3。关于方案2就不多介绍了,很简单。主要提一提方案3。
一. ELKB简介
- Elastic Search: 从名称可以看出,Elastic Search 是用来进行搜索的,提供数据以及相应的配置信息(什么字段是什么数据类型,哪些字段可以检索等),然后你就可以自由地使用API搜索你的数据。
- Logstash:。日志文件基本上都是每行一条,每一条里面有各种信息,这个软件的功能是将每条日志解析为各个字段。
- Kibana:提供一套Web界面用来和 Elastic Search 进行交互,这样我们不用使用API来检索数据了,可以直接在 Kibana 中输入关键字,Kibana 会将返回的数据呈现给我们,当然,有很多漂亮的数据可视化图表可供选择。
- Beats:安装在每台需要收集日志的服务器上,将日志发送给Logstash进行处理,所以Beats是一个“搬运工”,将你的日志搬运到日志收集服务器上。Beats分为很多种,每一种收集特定的信息。常用的是Filebeat,监听文件变化,传送文件内容。一般日志系统使用Filebeat就够了。
二. kafka简介
2.1 简介
kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。
2.2 适用场景
- Messaging 
 对于一些常规的消息系统,kafka是个不错的选择;partitons/replication和容错,可以使kafka具有良好的扩展性和性能优势.不过到目前为止,我们应该很清楚认识到,kafka并没有提供JMS中的"事务性""消息传输担保(消息确认机制)""消息分组"等企业级特性;kafka只能使用作为"常规"的消息系统,在一定程度上,尚未确保消息的发送与接收绝对可靠(比如,消息重发,消息发送丢失等)
- Websit activity tracking 
 kafka可以作为"网站活性跟踪"的最佳工具;可以将网页/用户操作等信息发送到kafka中.并实时监控,或者离线统计分析等
- Log Aggregation 
 kafka的特性决定它非常适合作为"日志收集中心";application可以将操作日志"批量""异步"的发送到kafka集群中,而不是保存在本地或者DB中;kafka可以批量提交消息/压缩消息等,这对producer端而言,几乎感觉不到性能的开支.此时consumer端可以使hadoop等其他系统化的存储和分析系统.
三、log4net+ELK+Kafka日志系统
3.1.简介
从上我们可以了解到,我们可以增加一个log4net kafkaappender 日志生产者通过这个appender将日志写入kafka,由于kafka批量提交、压缩的特性,因此对我们的应用服务器性能的开支很小。日志消费者端使用logstash订阅kafka中的消息,传送到elasticsearch中,通过kibana展示给我们。同时我们也可以通过kibana对我们的日志进行统计分析等。刚好可以解决我们上面的一些问题。整个流程大致如下图:

关于log4net for kafka appender,我自己写了一个,nuget上也有现成的包,大家需要可以去nuget上找一找。
3.2.搭建
简单介绍一下搭建,搭建过程中采用Docker。
3.2.1 docker 安装kafka
//下载
//下载zookeeper
docker pull wurstmeister/zookeeper
//下载kafka
docker pull wurstmeister/kafka:2.11-0.11.0.3
//启动
//启动zookeeper
docker run -d --name zookeeper --publish 2181:2181 --volume /etc/localtime:/etc/localtime wurstmeister/zookeeper
//启动kafka
docker run -d --name kafka --publish 9092:9092 \
--link zookeeper \
--env KAFKA_ZOOKEEPER_CONNECT=192.168.121.205:2181 \
--env KAFKA_ADVERTISED_HOST_NAME=192.168.121.205 \
--env KAFKA_ADVERTISED_PORT=9092  \
--volume /etc/localtime:/etc/localtime \
wurstmeister/kafka:2.11-0.11.0.3
//测试
//创建topic
bin/kafka-topics.sh --create --zookeeper 192.168.121.205:2181 --replication-factor 1 --partitions 1 --topic mykafka
//查看topic
bin/kafka-topics.sh --list --zookeeper 192.168.121.205:2181
//创建生产者
bin/kafka-console-producer.sh --broker-list 192.168.121.205:9092 --topic mykafka 
//创建消费者
bin/kafka-console-consumer.sh --zookeeper 192.168.121.205:2181 --topic mykafka --from-beginning
3.2.2 Docker安装ELK
//1.下载elk
docker pull sebp/elk
//2.启动elk
//Elasticsearch至少需要单独2G的内存
//增加了一个volume绑定,以免重启container以后ES的数据丢失
docker run -d -p 5044:5044 -p 127.0.0.1:5601:5601 -p 127.0.0.1:9200:9200 -p 127.0.0.1:9300:9300 -v /var/data/elk:/var/lib/elasticsearch --name=elk sebp/elk
//若启动过程出错一般是因为elasticsearch用户拥有的内存权限太小,至少需要262144
切换到root用户
执行命令:
sysctl -w vm.max_map_count=262144
查看结果:
sysctl -a|grep vm.max_map_count
显示:
vm.max_map_count = 262144
上述方法修改之后,如果重启虚拟机将失效,所以:
解决办法:
在   /etc/sysctl.conf文件最后添加一行
vm.max_map_count=262144
即可永久修改
启动成功之后访问:http://:5601 看到kibana页面则说明安装成功
配置使用
//进入容器
docker exec -it <container-name> /bin/bash
//执行命令
/opt/logstash/bin/logstash -e 'input { stdin { } } output { elasticsearch { hosts => ["localhost"] } }'
/*
 注意:如果看到这样的报错信息 Logstash could not be started because there is already another instance using the configured data directory.  If you wish to run multiple instances, you must change the "path.data" setting. 请执行命令:service logstash stop 然后在执行就可以了。
*/
测试
当命令成功被执行后,看到:Successfully started Logstash API endpoint {:port=>9600} 信息后,输入:this is a dummy entry 然后回车,模拟一条日志进行测试。
打开浏览器,输入:http://:9200/_search?pretty 如图,就会看到我们刚刚输入的日志内容。
3.2.3 logstash-kafka配置实例
这是我测试用的一个配置文件。
input {
        kafka{
                //此处注意:logstash5.x版本以前kafka插件配置的是zookeeper地址,5.x以后配置的是kafka实例地址
                bootstrap_servers =>["192.168.121.205:9092"]
                client_id => "test" group_id => "test"
                consumer_threads => 5
                decorate_events => true
                topics => "logstash"
        }
}
filter{
        json{
                source => "message"
        }
}
output {
        elasticsearch {
                hosts => ["192.168.121.205"]
                index=> "hslog_2"
                codec => "json"
        }
}
配置文件启动logstash方式
/opt/logstash/bin/logstash -f "配置文件地址"
结束语
如上,我们的日志系统基本搭建完毕,当然还有很多关于kafka,logstash,elstaicsearch,kibana的使用,以及我们使用的一些问题,大家自己尝试着搭建一下。当然,没有最好的方案,建议大家结合自己公司和系统的现实情况,寻找和选择解决方案。能用简单的方案解决问题,就不要使用复杂的方案。因为复杂的方案在解决问题的同时,也会给我们带来其他的问题。就像我们这个方案,虽然解决了我们当时的问题,但是也增加了我们系统的复杂度,例如:这其中的每一个组件出了问题,都将导致我们的日志系统不可用......,此外,工欲善其事必先利其器,我们虽然解决了器的问题,但是要想"善我们的事"还有很长的路要走,因为究其根本,日志记不记录,在什么地方记录,记录什么等级的日志,还是由我们选择去记录。日志记录无规范、乱记、瞎记,如何规范日志的记录才是是我们接下来要解决的大问题!欢迎大家留言,探讨这些问题!
.NET下日志系统的搭建——log4net+kafka+elk的更多相关文章
- 【7.1.1】ELK日志系统单体搭建
		ELK是什么? 一般来说,为了提高服务可用性,服务器需要部署多个实例,每个实例都是负载均衡转发的后的,如果还用老办法登录服务器去tail -f xxx.log,有很大可能错误日志未出现在当前服务器中, ... 
- ELK +Nlog 分布式日志系统的搭建 For Windows
		前言 我们为啥需要全文搜索 首先,我们来列举一下关系型数据库中的几种模糊查询 MySql : 一般情况下LIKE 模糊查询 SELECT * FROM `LhzxUsers` WHERE UserN ... 
- 03篇ELK日志系统——升级版集群之ELK日志系统整合springboot项目
		[ 前言:整个ELK日志系统已经搭建好了,接下来的流程就是: springboot项目中的logback日志配置通过tcp传输,把springboot项目中所有日志数据传到————>logsta ... 
- Windows搭建Log4Net+FileBeat+ELK日志分析系统过程
		参考博客:http://udn.yyuap.com/thread-54591-1-1.html ; https://www.cnblogs.com/yanbinliu/p/6208626.html ; ... 
- 基于Kafka+ELK搭建海量日志平台
		早在传统的单体应用时代,查看日志大都通过SSH客户端登服务器去看,使用较多的命令就是 less 或者 tail.如果服务部署了好几台,就要分别登录到这几台机器上看,等到了分布式和微服务架构流行时代,一 ... 
- 十分钟搭建和使用ELK日志分析系统
		前言 为满足研发可视化查看测试环境日志的目的,准备采用EK+filebeat实现日志可视化(ElasticSearch+Kibana+Filebeat).题目为“十分钟搭建和使用ELK日志分析系统”听 ... 
- [Asp.net 5] Logging-其他日志系统的实现
		Microsoft.Framework.Logging.NLog 使用Nlog扩展日志系统:按照我们上节说的,对于扩展的日志系统都要实现俩个接口ILogger.ILoggerProvider.所以在当 ... 
- ELK+FileBeat+Log4Net搭建日志系统
		ELK+FileBeat+Log4Net搭建日志系统 来源:https://www.zybuluo.com/muyanfeixiang/note/608470 标签(空格分隔): ELK Log4Ne ... 
- 布式实时日志系统(三) 环境搭建之centos 6.4下hadoop 2.5.2完全分布式集群搭建最全资料
		最近公司业务数据量越来越大,以前的基于消息队列的日志系统越来越难以满足目前的业务量,表现为消息积压,日志延迟,日志存储日期过短,所以,我们开始着手要重新设计这块,业界已经有了比较成熟的流程,即基于流式 ... 
随机推荐
- python语言学习--2
			第三天1. python代码缩进规则:具有相同缩进的代码被视为代码块,4个空格, 不要使用Tab,更不要混合Tab和空格,否则很容易造成因为缩进引起的语法错误. 2.list:[...] 用(名称任意 ... 
- SQL Server中sp_spaceused统计数据使用的空间总量不正确的原因
			很多时候,我们经常使用sp_spaceused来查看表的空间使用情况,上个月群里有个网友说他使用DELETE删除了数据后,使用sp_spaceused查看,发现该表的分配的空间总量(reserved) ... 
- 使用html+css+js实现简易计算器
			使用html+css+js实现简易计算器, 效果图如下: html代码如下: <!DOCTYPE html> <html lang="en"> <he ... 
- web前端(9)—— CSS属性
			属性 终于到css属性,前面就零零散散的用了什么color,font-size之类,本篇博文就专项的介绍它了 字体属性 font-family 此属性是设置字体样式的,比如微软雅黑,方正书体,华文宋体 ... 
- 关于Inception默认配置的一个坑
			本文地址:https://www.cnblogs.com/ajiangg/p/9850902.html 约半年前上线了去哪儿的开源审核工具Inception(最近发现已经闭源了.....)以及基于In ... 
- EOS智能合约存储实例讲解
			EOS智能合约存储实例 智能合约中的基础功能之一是token在某种规则下转移.以EOS提供的token.cpp为例,定义了eos token的数据结构:typedef eos::token<ui ... 
- 在Lua中提示UnityEngine.dll的方法
			我的环境 安装最新的 EmmyLua-1.2.1及以上版本 IDEA 2017.1.2 及以上版本 关于EmmlyLua的介绍可查看我之前的文章:Lua代码提示和方法跳转 说明:本文方法摘自 Emmy ... 
- C++多线程同步技巧(四)--- 信号量
			简介 信号量是维护0到指定最大值之间的同步对象.信号量状态在其计数大于0时是有信号的,而其计数是0时是无信号的.信号量对象在控制上可以支持有限数量共享资源的访问,可以用于线程同步,预防死锁等领域. 信 ... 
- Linux for python教程02
			目录 1. Linux用户及权限管理 1.1. who 1.2. 查看当前用户: whoami 1.3. 添加用户账号: useradd 1.4 切换用户 su 2.用户组 3. 修改文件权限: ch ... 
- 《Java大学教程》—第7章 类的实现
			统一建模语言(UML)用方框代表类.方框被分成3部分,第一部分是类名,第二部分是类的属性,第三部分是类的方法.类的属性(属性名称:属性类型):类的方法(方法名称(参数类型):返回值类型).静态的类的属 ... 
