.NET下日志系统的搭建——log4net+kafka+elk
.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-->kibanaservice-->log4net-->文件-->filebeat-->elstaicsearch-->kibanaservice-->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-beginning3.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 => 5decorate_events => truetopics => "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的使用,以及我們使用的一些問題,大家自己嘗試著搭建一下。當然,沒有最好的方案,建議大家結合自己公司和系統的現實情況,尋找和選擇解決方案。能用簡單的方案解決問題,就不要使用復雜的方案。因為復雜的方案在解決問題的同時,也會給我們帶來其他的問題。就像我們這個方案,雖然解決了我們當時的問題,但是也增加了我們系統的復雜度,例如:這其中的每一個組件出了問題,都將導致我們的日志系統不可用......,此外,工欲善其事必先利其器,我們雖然解決了器的問題,但是要想"善我們的事"還有很長的路要走,因為究其根本,日志記不記錄,在什么地方記錄,記錄什么等級的日志,還是由我們選擇去記錄。日志記錄無規范、亂記、瞎記,如何規范日志的記錄才是是我們接下來要解決的大問題!歡迎大家留言,探討這些問題!
轉載于:https://www.cnblogs.com/hunternet/p/9607850.html
總結
以上是生活随笔為你收集整理的.NET下日志系统的搭建——log4net+kafka+elk的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GWT interface的使用例子
- 下一篇: codevs 3164 质因数分解