我試了試用 SQL查 Linux日誌,好用到飛起

你們好,我是小富~java

最近發現點好玩的工具,火燒眉毛的想跟你們分享一下。mysql

你們平時都怎麼查Linux日誌呢? 像我平時會用tailheadcatsedmoreless這些經典系統命令,或者awk這類三方數據過濾工具,配合起來查詢效率很高。但在使用過程當中有一點讓我比較頭疼,那就是命令參數規則太多了,記的人腦袋疼。git

那查日誌有沒有一種通用的方式,好比用SQL查詢,畢竟這是程序員都比較熟悉的表達式。程序員

今天分享的工具q,就實現了以寫SQL的方式來查詢、統計文本內容,一塊兒看看這貨到底有什麼神奇之處。github

搭個環境

q是一個命令行工具,容許咱們在任意文件或者查詢結果,好比能夠在ps -ef查詢進程命令的結果集上,直接執行SQL語句查詢。sql

宗旨就是文本即數據庫表,額~,固然這句話是我本身理解的,哈哈哈shell

它將普通文件或者結果集看成數據庫表,幾乎支持全部的SQL結構,如WHEREGROUP BYJOINS等,支持自動列名和列類型檢測支持跨文件鏈接查詢,這兩個後邊詳細介紹,支持多種編碼。數據庫

安裝比較簡單,在Linux CentOS環境,只要以下三步搞定,Windows環境更是隻需安裝個exe就能夠用了。服務器

wget https://github.com/harelba/q/releases/download/1.7.1/q-text-as-data-1.7.1-1.noarch.rpm #下載版本

sudo rpm -ivh q-text-as-data-1.7.1-1.noarch.rpm # 安裝

q --version  #查看安裝版本

官方文檔:https://harelba.github.io/qless

語法

q支持全部SQLiteSQL語法,標準命令行格式q + 參數命令 + "SQL"

q <命令> "<SQL>"

我要查詢myfile.log文件的內容,直接q "SELECT * FROM myfile.log"

q "SELECT * FROM myfile.log"

q不附加參數使用是徹底沒有問題的,但利用參數會讓顯示結果更加美觀,因此這裏簡單瞭解一下,它的參數分爲 2種。

input輸入命令:指的是對要查詢的文件或結果集進行操做,好比:-H命令,表示輸入的數據包含標題行。

q -H "SELECT * FROM myfile.log"

在這種狀況下,將自動檢測列名,並可在查詢語句中使用。若是未提供此選項,則列將自動命名爲cX,以c1起始以此類推。

q  "select c1,c2 from ..."
  • output輸出命令:做用在查詢輸出的結果集,好比:-O,讓查詢出來的結果顯示列名。
[root@iZ2zebfzaequ90bdlz820sZ software]# ps -ef | q -H "select count(UID) from - where UID='root'"
104
[root@iZ2zebfzaequ90bdlz820sZ software]# ps -ef | q -H -O "select count(UID) from - where UID='root'"
count(UID)
104

還有不少參數就不一一列舉了,感興趣的同窗在官網上看下,接下來咱們重點演示一下使用SQL如何應對各類查詢日誌的場景。

玩法賊多

下邊我們一塊兒看幾個查詢日誌的常常場景中,這個SQL該如何寫。

一、關鍵字查詢

關鍵字檢索,應該是平常開發使用最頻繁的操做,不過我我的認爲這一點q並無什麼優點,由於它查詢時必須指定某一列。

[root@iZ2zebfzaequ90bdlz820sZ software]# q "select * from douyin.log where c9 like '%待解析%'"
2021-06-11 14:46:49.323 INFO 22790 --- [nio-8888-exec-2] c.x.douyin.controller.ParserController : 待解析URL :url=https%3A%2F%2Fv.douyin.com%2Fe9g9uJ6%2F                                             
2021-06-11 14:57:31.938 INFO 22790 --- [nio-8888-exec-5] c.x.douyin.controller.ParserController : 待解析URL :url=https%3A%2F%2Fv.douyin.com%2Fe9pdhGP%2F                                             
2021-06-11 15:23:48.004 INFO 22790 --- [nio-8888-exec-2] c.x.douyin.controller.ParserController : 待解析URL :url=https%3A%2F%2Fv.douyin.com%2Fe9pQjBR%2F                                             
2021-06-11 2

而用grep命令則是全文檢索。

[root@iZ2zebfzaequ90bdlz820sZ software]# cat douyin.log | grep '待解析URL'
2021-06-11 14:46:49.323  INFO 22790 --- [nio-8888-exec-2] c.x.douyin.controller.ParserController   : 待解析URL :url=https%3A%2F%2Fv.douyin.com%2Fe9g9uJ6%2F
2021-06-11 14:57:31.938  INFO 22790 --- [nio-8888-exec-5] c.x.douyin.controller.ParserController   : 待解析URL :url=https%3A%2F%2Fv.douyin.com%2Fe9pdhGP%2F

二、模糊查詢

like模糊搜索,若是文本內容列有名字直接用列名檢索,沒有則直接根據列號c一、c二、cN。

[root@iZ2zebfzaequ90bdlz820sZ software]# cat test.log 
abc
2
3
4
5
23
24
25
[root@iZ2zebfzaequ90bdlz820sZ software]# q -H -t "select * from test.log where abc like '%2%'"
Warning: column count is one - did you provide the correct delimiter?
2
23
24
25

三、交集並集

支持UNIONUNION ALL操做符對多個文件取交集或者並集。

以下建了test.logtest1.log兩個文件,裏邊的內容有重疊,用union進行去重。

q -H -t "select * from test.log union select * from test1.log"

[root@iZ2zebfzaequ90bdlz820sZ software]# cat test.log 
abc
2
3
4
5
[root@iZ2zebfzaequ90bdlz820sZ software]# cat test1.log 
abc
3
4
5
6
[root@iZ2zebfzaequ90bdlz820sZ software]# q -H -t "select * from test.log union select * from test1.log"
Warning: column count is one - did you provide the correct delimiter?
Warning: column count is one - did you provide the correct delimiter?
2
3
4
5
6

四、內容去重

好比統計某個路徑下的./clicks.csv文件中,uuid字段去重後出現的總個數。

q -H -t "SELECT COUNT(DISTINCT(uuid)) FROM ./clicks.csv"

五、列類型自動檢測

注意:q會理解每列是數字仍是字符串,判斷是根據實數值比較,仍是字符串比較進行過濾,這裏會用到-t命令。

q -H -t "SELECT request_id,score FROM ./clicks.csv WHERE score > 0.7 ORDER BY score DESC LIMIT 5"

六、字段運算

讀取系統命令查詢結果,計算/tmp目錄中每一個用戶和組的總值。能夠對字段進行運算處理。

sudo find /tmp -ls | q "SELECT c5,c6,sum(c7)/1024.0/1024 AS total FROM - GROUP BY c5,c6 ORDER BY total desc"

[root@iZ2zebfzaequ90bdlz820sZ software]# sudo find /tmp -ls | q "SELECT c5,c6,sum(c7)/1024.0/1024 AS total FROM - GROUP BY c5,c6 ORDER BY total desc"
www www 8.86311340332
root root 0.207922935486
mysql mysql 4.76837158203e-06

七、數據統計

統計系統擁有最多進程數的前 3個用戶ID,按降序排序,這就須要和系統命令配合使用了,先查詢全部進程再利用SQL篩選,這裏的q命令就至關grep命令。

ps -ef | q -H "SELECT UID,COUNT(*) cnt FROM - GROUP BY UID ORDER BY cnt DESC LIMIT 3"

[root@iZ2zebfzaequ90bdlz820sZ software]# ps -ef | q -H "SELECT UID,COUNT(*) cnt FROM - GROUP BY UID ORDER BY cnt DESC LIMIT 3"
root 104
www 16
rabbitmq 4
[root@iZ2zebfzaequ90bdlz820sZ software]# ps -ef | q -H -O "SELECT UID,COUNT(*) cnt FROM - GROUP BY UID ORDER BY cnt DESC LIMIT 3"
UID cnt
root 110
www 16
rabbitmq 4

咱們看到加與不加-O命令的區別就是否顯示查詢結果的標題。

8,連文件查

通常狀況下,咱們的日誌文件會按天分割成不少個固定容量的子文件,在沒有統一的日誌收集服務器的狀況下,若是不給個報錯時間區間去查一個關鍵詞,那麼無異於大海撈針。 若是能夠將全部文件內容合併後在查就會省事不少,q支持將文件像數據庫表那樣聯合查詢。

q -H "select * from douyin.log a join douyin-2021-06-18.0.log b on (a.c2=b.c3) where b.c1='root'"

總結

看完可能會有人擡槓:q寫這麼多代碼直接用awk不香嗎?額~ 介紹這個工具的初衷並非說要替換現有哪一種工具,而是多提供一種更爲便捷的查日誌方法。

我也有在用awk確實很強大沒得說,但這裏邊涉及到一個學習成本的問題,琳琅滿目的命令、匹配規則想玩轉仍是要下點功夫的。而對於新手程序員稍微有點數據庫經驗,寫SQL問題都不大,上手q則會容易的多。


整理了幾百本各種技術電子書,送給小夥伴們。關注公號回覆【666】自行領取。和一些小夥伴們建了一個技術交流羣,一塊兒探討技術、分享技術資料,旨在共同窗習進步,若是感興趣就加入咱們吧!

電子書地址

相關文章
相關標籤/搜索