
日志服務(
SLS)是阿裡集團自研的一站式日志平台,它包含資料實時采集、資料加工、智能查詢分析以及資料分發四大基礎功能,使用者無需開發就能能夠開箱即用地使用它來提升運維、營運效率,建立 DT 時代海量日志處理能力。
為了讓大家對日志服務有更直覺的感受,本文将帶着大家體驗一下這些基礎功能,以最常見的 Linux Syslog 作為對象,看看如何簡單快速地實作對它的采集、加工、查詢分析以及可視化。
Linux Syslog
Syslog 是 Unix 類作業系統上非常常見的一種日志,廣泛應用于系統日志,但同樣可作為應用輸出日志的一種形式。在許多 Linux 發行版上,部分 Syslog 預設會被存放在本地目錄
/var/log/
中,其中包含
messages
、
kern
secure
等多個分别用于存放不同類似日志的檔案。
本文将以最常見的
/var/log/messages
作為實驗目标,以下是一些示例日志:
# OOM 日志
[ 1074.669060] Out of memory: Kill process 20680 (perl) score 487 or sacrifice child
[ 1074.669089] Killed process 20680 (perl), UID 0, total-vm:1072528kB, anon-rss:943192kB, file-rss:0kB, shmem-rss:0kB
# 應用日志
Mar 16 12:04:08 clusterx-master systemd: Removed slice libcontainer_8947_systemd_test_default.slice.
Mar 16 12:04:08 clusterx-master systemd: Scope libcontainer-8952-systemd-test-default-dependencies.scope has no PIDs. Refusing.
# 登入日志(特殊應用)
Mar 13 12:29:25 clusterx-master sshd[13501]: Accepted publickey for root from 192.168.56.1 port 64934 ssh2: RSA SHA256:W8j/QK8kV0Ab8/yTENQko8
Mar 13 12:29:25 clusterx-master sshd[13501]: pam_unix(sshd:session): session opened for user root by (uid=0)
Mar 13 13:19:08 clusterx-master sshd[13501]: Received disconnect from 192.168.56.1 port 64934:11: disconnected by user
Apr 16 20:00:50 clusterx-master sshd[718]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.56.1 user=root
Apr 16 20:00:52 clusterx-master sshd[718]: Failed password for root from 192.168.56.1 port 54469 ssh2: RSA SHA256:W8j/QK8kV0Ab8/yTENQko8
資料實時采集
首先,我們需要實作對這些日志的采集。由于系統日志需要外部事件觸發,産生時機不太确定,是以,我們針對上述的示例日志編寫了一個生成器以保證明驗過程持續有日志産生。
在機器上運作生成器,即會不斷地有日志輸出到檔案
/var/log/mock_messages
。
$ mkdir mock-syslog; cd mock-syslog
$ wget http://baoze-oss-bj.oss-cn-beijing.aliyuncs.com/mock-syslog/raw_data
$ wget http://baoze-oss-bj.oss-cn-beijing.aliyuncs.com/mock-syslog/mock_messages.py
$ chmod +x mock_messages.py
$ nohup ./mock_messages.py /var/log/mock_messages &
$ tail /var/log/mock_messages
為了存放日志,我們需要先開通日志服務,并在控制台上建立相應的 project/logstore,過程可參考
快速入門中的步驟 1。對于文本日志,我們可通過 SLS 自研的采集 agent
Logtail來實作采集。
操作步驟如下:
- 建立 Logtail 采集配置,選擇【單行-文本日志】
日志服務(SLS)初體驗:采集、加工、查詢分析及可視化
- 在機器上安裝 logtail,對于 ECS 機器,可直接在控制台上進行勾選,點選【立即執行】後即可完成安裝
日志服務(SLS)初體驗:采集、加工、查詢分析及可視化 - 安裝完成後,勾選機器 IP 會被自動加入到機器組清單中,在填寫名稱後即可完成建立機器組建立
日志服務(SLS)初體驗:采集、加工、查詢分析及可視化 - 填寫配置
日志服務(SLS)初體驗:采集、加工、查詢分析及可視化 - 跟随向導完成配置,點選【立即嘗試】進入查詢界面
日志服務(SLS)初體驗:采集、加工、查詢分析及可視化
資料查詢
進入查詢界面後,隻需稍等一會兒,待采集配置下發到 logtail 後,即可通過點選【查詢/分析】按鈕浏覽日志内容。借助 SLS 針對日志的極緻優化,我們可以通過關鍵詞快速地從海量日志中查詢我們感興趣的日志。比如:
通過關鍵詞
sshd
查詢登入日志
Out of memory
查詢 OOM 日志
除了基礎的關鍵字查詢外,SLS 還提供了 and/or/not 等謂詞進行組合查詢(
文檔),能夠滿足更為豐富的查詢場景。
資料加工
在完成資料的采集和查詢後,我們會發現,因為日志是單行采集上來的,日志的所有内容都被放在了單一的
content
字段中,相對來說會比較混亂。在這種情況下,我們很難對日志的内容進行進一步地分析,比如有哪些應用輸出了系統日志、最近一天是否有應用發生 OOM、發生次數等等。
假設我們期望通過分析日志來得到以下資訊:
- 哪些程序産生了系統日志,分别産生了多少?如果産生了較多日志的話,可能說明應用存在一些異常?
- 其中的哪些應用發生過 OOM ?頻繁 OOM 的應用需要得到關注。
- 僅檢視程序 sshd 産生的登入日志,檢查短時間内是否有較多的密碼登入失敗(可能是入侵攻擊)?如果有,IP 和端口是什麼?
如果要完成上述需求,從資料分析的角度來說,我們需要識别出:
- 每條日志所屬的程序名
- 哪些日志是 OOM 日志
- 哪些日志是 sshd 密碼登入失敗?
通過資料加工,我們可以非常簡單地完成上述需求,通過增加額外的字段來标記對需要識别的内容。
1. 标記 OOM 日志
[ 1074.669060] Out of memory: Kill process 20680 (perl) score 487 or sacrifice child
[ 1074.669089] Killed process 20680 (perl), UID 0, total-vm:1072528kB, anon-rss:943192kB, file-rss:0kB, shmem-rss:0kB
從示例來看,OOM 日志有兩個關鍵字
Out of memory
和
Killed process
,并且都包含了發生 OOM 的程序 ID 和程序名。是以,我們可以通過資料加工 DSL 中的正則提取來完成字段抽取,如下:
# 解析 oom_kill 日志
e_if(op_or(
regex_match(v("content"), "Out of memory"),
regex_match(v("content"), "Killed process")),
e_compose(
e_set("log_type", "oom_kill"),
e_regex("content", "process (?<pid>[0-9]*) \((?<process>[a-zA-Z0-9_]*)\)")))
借助資料加工的預覽功能,我們可以快速地判斷上面的處理是否滿足需求。
測試資料及處理邏輯
結果
可以看到,兩條日志都增加了
log_type:oom_kill
的字段,并通過
process
pid
兩個字段記錄了發生 OOM 的程序名和 PID。
2. 解析 Syslog 基本字段
雖然 Syslog 的輸出格式并未嚴格統一,但大部分 Linux 發行版下,都由時間、主機名、程序名、可選的程序 PID 以及日志内容幾部分組成,其中,最後的日志内容完全由應用定義。
為了能夠分析各個應用輸出日志的情況,我們可以按照上面的格式來對所有日志進行字段提取。類似地,我們借助 DSL 正則提取來實作:
# 解析 syslog 基本字段
e_regex("content", "(?<system_time>[a-zA-Z 0-9:]{15}) (?<hostname>[a-zA-Z0-9\-]*) (?<process>([a-zA-Z0-9\-]*))(\[(?<pid>[0-9]*)\])?: (?<message>.*)")
同樣地,借助預覽功能進行快速驗證,确認日志被提取成我們所期望的
system_time
hostname
process
pid
message
字段。
3. 豐富登入日志
從前面的示例日志我們可以知道,登入日志的
message
字段内容并不固定,不同内容向我們展示了不同資訊,比如:
- Accepted publickey 告訴我們有人成功使用密鑰完成對某個使用者的登入;
- Failed password 告訴我們有人使用密碼登入某個使用者失敗;
- Received disconnect 告訴我們有人斷開了連接配接。
而這些日志同時也有共性,它們記錄了期望登入的使用者、登入的 IP、端口等資訊。基于這些特點,我們可以對 sshd 的日志進行進一步地處理,提取出這些公共字段,并根據展示内容進行特殊标記。
e_if(e_search('process=="sshd"'),
e_compose(
e_regex("content", grok('%{IP:ip}')),
e_regex("content", "port (?<port>[0-9]*)"),
e_if(regex_match(v("content"), "Received disconnect from"),
e_set("sshd_action" , "client_disconnect")),
e_if(regex_match(v("content"), "Failed password"),
e_set("sshd_action" , "client_password_fail")),
e_if(regex_match(v("content"), "Accepted publickey"),
e_set("sshd_action" , "client_login"))
))
結果如下:
4. 輸出到新目标
在完成了上述所有規則的調試後,我們可以把它們合并在一起,并為處理後的日志指定一個新的 logstore(命名為 processed_syslog,需要手動建立)作為輸出目标。
在【加工結果頁】中,點選【儲存資料加工】即可将規則進行儲存。
當加工任務啟動後,我們就可以在新 logstore 中看到處理後的日志。
資料分析以及可視化
在借助資料加工完成資料處理後,我們就可以開始前面提到的分析工作了。SLS 提供了支援 SQL92 标準的分析文法,可以友善地支撐我們完成各類場景下的分析需求。
0. 快速建立索引
為了使用分析功能,我們首先需要對待分析的字段建立相應的索引,這一過程可以使用控制台提供的自動建立索引功能快速完成。
在建立完索引後,我們就可以使用 SQL 對先前提到的需求進行分析。
1. 分析應用日志分布
not log_type:oom_kill | select process, count(*) as c group by process order by c desc
通過上面的分析語句,我們即可得到每個程序分别輸出了多少條日志,如下:
除了最基本的預覽圖表外,SLS 控制台提供了非常豐富的可視化能力,并且我們能夠将對應的可視化圖表以儀表盤的形式儲存下來。比如使用餅圖來呈現上面的結果:
儀表盤效果
2. 分析 OOM 應用
統計最近 10 分鐘發生 OOM 的次數,并同比 10 分鐘前的情況,以單值圖的形式展示。
# 同環比
log_type:oom_kill | select diff[1] as today, round((diff [3] -1.0) * 100, 2) as growth from (select compare(count, 600) as diff from (select count(1) as count from log))
檢視 OOM 應用分布
log_type:oom_kill and process:* | select process, count(*) as c group by process order by c desc
3. 分析登入失敗 IP 分布
process:sshd and sshd_action:client_password_fail | select ip, count(*) as c group by ip order by c desc
根據 IP 擷取來源地(國家)
process:sshd and sshd_action:client_password_fail | select ip_to_country(ip) as country, sum(c) as c from( select ip, count(*) as c from log group by ip order by c desc) group by country