天天看點

在生産環境中使用Graylog日志系統所踩過的坑

1.日志系統概述

1.1應用程式日志的作用:

應用程式日志的作用:日志分析并不僅僅包括系統産生的錯誤日志,異常,同時也包括業務邏輯,或者任何文本類型的分析。而基于日志的分析,具有重要的現實意義,典型地,

  • 問題排查
  • 開發和運維需要快速的定位問題,甚至防微杜漸,把問題殺死在搖籃。日志分析技術顯然問題排查的基石。基于日志進行問題排查,還有一個很帥的技術,叫全鍊路追蹤。
  • 監控和預警

    日志,監控,預警是相輔相成的。基于日志的監控,預警使得運維有自己的機械戰隊,大大節省人力以及延長運維的壽命

  • 關聯事件

    多個資料源産生的日志進行關聯分析,通過某種分析算法,就能夠解決生活中各個問題,病毒分析,金融欺詐等

  • 資料分析

    資料就是一個企業的重要财富,尤其對于資料分析師,算法工程師都是有所裨益的

1.2 集中式日志系統

在網際網路時代,分布式應用程式是主流的架構,它能快簡單地,快速地,便捷地提供服務的并發性,容災性,可用性。但是這就帶來若幹問題,

  • 應用程式的日志分散在不同的機器上,這些機器可能是實體機,可能是内網vm,也可能是公有雲,分散性較大。
  • 随着服務的持續運作,日志檔案将變得越來越大。
  • 如果伺服器磁盤損壞,日志檔案将丢失

由此可見,傳統的日志記錄方式不利于問題的定位,日志的搜尋,日志的儲存。我們需要尋找一種新的記錄日志的手段,集中式日志系統應運而生

所謂集中式:即将所有相關日志收集,彙總到一起,并使之結構化,可搜尋,可持久化存儲。

業界著名的解決方案有:

  • Splunk: 企業級的日志收集引擎
  • ELK: elastic公司提供的一套完整的日志收集以及展示的解決方案,是三個産品的首字母縮寫ElasticSearch、Logstash 和 Kibana
  • Graylog: 開源的完整日志管理工具,功能和ELK類似,但比ELK簡單。本文重點介紹

2.鳥瞰Graylog

2.1相關元件

  • Elasticsearch: 日志内容的實際存儲地,提供搜尋等功能。部署es伺服器的記憶體越大已經磁盤速度越高,es提供搜尋的性能也就越高。
  • MongoDB:用于存儲基本的元資訊以及配置資訊,沒有太高的硬體需求。
  • Graylog:日志API的提供者,面向浏覽器以及應用程式,cpu密集型任務。

2.2Graylog架構

2.2.1 極簡的部署方案

上圖展示的是Graylog極簡的部署方案,沒有任何備援的元件,全都都是單點,不建議在生産環境使用,但是對于了解,測試graylog,這種方案以及足夠了。

應用程式通過Graylog元件提供api,進而進行日志的傳輸,同時,Graylog還提供的界面友好的web系統,使得開發者可以查詢,搜尋日志,并提供諸如過濾,告警,圖表等進階功能。

Graylog将日志進行一定的處理後,存入es中,而在MongoDB中存放在使用者等配置資訊。

2.2.2 生産環境的部署方案

我們使用es叢集代替單幾點的es,這将極大的提高資料的安全性,以及服務的性能,高可用性,另外我們将啟用多個Graylog服務,并将其挂載在負載均衡(LB)的後面,LB不僅能分流,減輕單個節點的壓力,同時具有健康檢查的能力,定期的檢查後端Graylog服務的健康情況,将異常節點剔除出叢集。

2.3Graylog部署

Graylog官方提供了ubuntu,centos等主流os的安裝包,大家可以根據實際情況予以安裝,為了簡單,高效,筆者這裡提供Docker的部署方案,可供參考,在linux ,mac下通用。這裡以ubuntu18系統為例說明

相關依賴:
(一)安裝docker:  apt-get install –y docker
(二)啟動docker服務: sudo systemctl start docker
(三)設定docker指令免sudo:  sudo groupaddß docker && sudo gpasswd -a ${USER} docker && newgrp – docker
(四)安裝 docker-compose: docker編排工具,将相關的容器集中管理,如果系統安裝的 python的裝包工具pip可以直接執行
pip install docker-compose,或者 sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose
docker-compose 通過一個yaml檔案來描述需要啟動的容器資訊。筆者已經準備好,執行如下指令:
mkdir TestGraylog  && cd TestGraylog && git clone https://code.*****.com/users/graylog.git  修複配置檔案中GRAYLOG_HTTP_EXTERNAL_URI配置項 ,将ip改為自己伺服器的ip           

接着鍵入: docker-compose up –d ,一鍵啟動 graylog,es,mongodb服務,

通過docker-compose ps指令檢視服務啟動情況

第三列State 為UP 表明三個服務均正常啟動

檢視伺服器9000端口是否處于listen狀态

Graylog 将在此端口運作web界面服務,以及接受rest api請求。

在浏覽器中輸入:

http://ip:9000

,輸入賬号 admin/admin 将看到類似下圖所示畫面,說明Graylog服務啟動正常

注意: docker-compose.yaml檔案中預設開啟9000/tcp, 12201/tcp 12201/udp等端口,注意防火牆的設定

3.如何搜集日志

如果Graylog中不能收集/存儲日志資料,它将失去存在的意義,本節将說明如何将應用程式的日志發送到Graylog系統中。

3.1Graylog input

Graylog input ,它負責接收日志檔案,我需要在web界面設定input ,在配置完成後及時生效,并不需要重新開機Graylog服務。

Input的種類很多,這裡以GELF UDP類型予以說明

GELF是一種日志組織格式,後文具體說明;UDP表明應用程式通過UDP協定将日志發送給Graylog,雖然UDP意味着,不可靠的,不保序的,無連接配接的。但是在我們的日志系統中,UDP仍然具有優勢。

  • UDP沒有要建立,維持,撤銷連接配接的開銷
  • Graylog服務出現異常時,不影響自身應用
  • 除了GELF格式,還可以選擇文本格式,syslog等,除了UDP協定,還可以選擇TCP,HTTP,AMQP,Kafka等當然這些應對應用程式透明。
  • 接下來,配置一下input的具體内容

Bind address:鍵入部署Graylog服務所在的ip

Port: 鍵入需要監聽的端口

注意Port一定要在docker-compose.yaml檔案中配置,

點選save按鈕,這樣就完成了一個input的設定,這意味着:Graylog在12201端口接受通過UDP協定傳輸的GELF格式的日志消息

3.2GELF格式

傳輸給Graylog 系統的日志格式可以各種各樣,限于篇幅的原因,我們選取其中廣泛使用的GELF格式, The Graylog Extended Log Format(GELF) 這種格式克服了傳統syslog檔案的諸多缺點,

syslog限制單條日志檔案的長度為1024bytes

syslog日志沒有資料類型,你通常區分不了這是數字還是字元串

雖然 RFCs對syslog有嚴格的定義,但syslog的諸多實作并不完全遵守,這就導緻我們的應用程式不可能解析所有的情況

Syslog沒有壓縮功能:當使用UDP作為傳輸協定時,GEFL消息能夠使用GZIP OR ZLIB壓縮,這有利于消息體積和快速傳輸,當然這會消耗一些cpu資源,不過這是值得的。

Syslog能夠勝任記錄系統或者網絡裝置的任務,顯然GELF更适合記錄應用程式産生的日志,Graylog 提供了多種語言的Lib,友善接入,你甚至通過Graylog發送異常日志,同時由于UDP協定,進而不用考慮逾時,連接配接等問題導緻自身應用的故障。

GELF格式其實是一個json字元串,包含下表所示的字段

字元名稱    含義    類型    是否可選
version    Graylog使用的版本    字元串    否
host    産生日志所在主機的名稱    字元串    否
short_message    對一條消息的簡短描述    字元串    否
full_message    消息的詳盡描述    字元串    是
timestamp    Unix時間戳    整數數字    否
level    日志消息的級别    整數    否
file    産生消息日志檔案的路徑    字元串    是
line    産生日志在源碼檔案中的行數    整數    是
_[additional field]    字首為_的字段名稱也會添加到Graylog中    任意    是           
{
  "version": "1.1",
  "host": "example.org",
  "short_message": "A short message that helps you identify what is going on",
  "full_message": "A full message here\n\nmore stuff",
  "timestamp": 1385053862,
  "level": 1,
  "_user_id": 9001,
  "_some_info": "foo",
  "_some_env_var": "bar"
}           

下面使用netcat工具,向graylog發送一條日志檔案

echo -n '{ "version": "1.1", "host": "******.com", "short_message": "******* is a Promising company", "level": 5, "_user_name”: "******",”_user_id”:7798 }' | nc -w0 -u 127.0.0.1 12201           

然後打開web界面就可以看到格式化的日志了

3.3應用程式接入日志系統

上一節中我們通過netcat指令行工具,向graylog發送一條GELF格式的消息。這是我們需要手動構造,消息格式,指定udp協定(參數-u),指定ip和端口,多次發送日志檔案時,顯得繁瑣。由于公司絕大部分業務都是使用python和golang開發,本節對此分别給出示例

3.3.1python

筆者在第三方的基礎上自行封裝一個python使用的lib,能夠和python标準的logging庫無縫對接,對應用程式的入侵極小

首先我們一定義一個log hander

我們指明graylog handler的類(這個筆者已經放到公司python的公用倉庫中),同時指定graylog的ip以及監聽端口,協定類型。

具體打日志時,

debug表明日志的等級,第一個參數是message字段的内容,extra參數中的字段是額外的資訊,便于搜尋,後文有例子說明。

Demo使用方式:

下載下傳代碼 git clone git@code.******.com:users/demo_for_graylog.git
cd python  && pip install -r requirements.txt
python main.py           

3.3.2 golang

直接使用官方提供的 graylog-golang lib

Demo 使用方式:

下載下傳代碼 git clone git@code.******.com:users/demo_for_graylog.git
cd golang && go build 
./graylog           

檢視效果

有此圖可知,UDP的确不保序,但對于日志系統通常沒有什麼影響。

4 強大而簡單的搜尋文法

如前文,現在日志已經成功錄入Graylog系統中,這并沒有什麼了不起的,mysql, mongo都能做。Graylog最令人心動是,簡單而強大的搜尋功能。

在web系統的首頁,我們可以選擇搜尋的時間範圍,比如最近5分鐘,2小時前,目前你也可以精确的指定事件範圍,注意預設是 UTC的時間,選擇時間範圍将減少搜到範圍,提高搜尋的速度,是以請盡可能的不要全局搜尋。

第二個框,我們可以指定搜尋的條件,總結起來有如下幾條規則,

a)預設搜尋所有的消息字段,如果不顯式指定搜尋字段名稱: 當我們鍵入this 關鍵字時,将傳回所選時間範圍内,所有消息字段中包含 this的日志

b)當多個關鍵字用空格分開時,表示or的語義:鍵入 this message 傳回所有消息字段包含 this 或者message的日志

c)當需要精确比對時,加上引号: 鍵入”this message” 傳回消息字段中包含this message的日志

d)指定消息的字段,減少搜尋範圍:鍵入 user_id:7789 傳回消息中包含user_id字段且值為7789的日志,鍵入user_id:(7789 OR 7798):傳回user_id為7789 或者7798 的日志,注意 OR需要大寫

e)多個搜尋條件之間支援邏輯操作 AND NOT OR, 例如:level:<=3 AND user_id:12

f)支援wildcard文法的模糊查找,鍵入req_path:api 傳回包含req_path字段 且值包含api字元串

更多的搜尋文法參見官方文檔