日志收集系統(tǒng)方案對比&選型&實現(xiàn)

背景

我們這邊應用部署的環(huán)境比較復雜枉侧,主要有以下幾種:

  • 機器直接部署
  • 通過kubernates集群部署

部署環(huán)境不統(tǒng)一官紫,導致查看應用日志很不方便肛宋。

業(yè)界日志系統(tǒng)架構

image.png
  • Collector的作用是:

    • 清洗、匯聚數(shù)據(jù)束世,減少對于后端集群的壓力酝陈。
    • 安全,不允許Agent直連kafka等內部集群毁涉,保證一定的安全性沉帮,即使后端發(fā)生調整也能保證對于Agent連接、認證方式的穩(wěn)定贫堰。
  • MQ的作用是削峰填谷穆壕、解耦、多次消費其屏。

    組件選擇

    選擇組件喇勋,我們這邊主要是從以下幾個方面進行考量的:

    1. 組件對應的開源生態(tài)完整、活躍度高
    2. 運維成本
    3. 易部署漫玄、性能好

    Agent: 主要比較下相對熟悉的Logstash和filebeat茄蚯。

    指標 Logstash filebeat Log-pilot
    內存
    背壓敏感協(xié)議
    插件
    功能 從多種輸入端采集并實時解析和轉換數(shù)據(jù)并輸出到多種輸出端 傳輸 支持收集容器的標準輸出日志和文件
    輕重
    過濾功能 強大的過濾功能 有過濾功能但較弱 Log-pilot支持不同的插件收集日志( Filebeat PluginFluentd Plugin
    集群 單節(jié)點 單節(jié)點 單節(jié)點
    輸出到多個接收方 支持 支持 支持
    原理 Logstash使用管道的方式進行日志的搜集和輸出,分為輸入input-->處理filter(不是必須的)-->輸出output睦优,每個階段都有不同的替代方式 開啟進程后會啟動一個或者多個探測器(prospectors)去檢測指定的日志目錄或者文檔建,對于探測器找出的每個日志文件,filebeat啟動收割進程(harvester),每個收割進程讀取一個日志文件的新內容壮不,并發(fā)送這些新的日志數(shù)據(jù)到處理程序(spooler)汗盘,處理程序會集合這些事件,最后filebeat會發(fā)送集合的數(shù)據(jù)到你指定的地點

    一個好的agent應該是資源占用少询一,性能好隐孽,不依賴別的組件,可以獨立部署健蕊。而Logstash明顯不符合這幾點要求菱阵,也許正是基于這些考慮elastic推出了Filebeat。目前l(fā)og-pilot文檔相對較少缩功,如果要對filebeat做特定的配置晴及,需要重新對log-pilot鏡像配置完以后重打鏡像(譬如異常日志多行合并),且目前l(fā)og-pilot阿里目前已經不再維護了嫡锌,社區(qū)活躍度不夠虑稼。綜上所述琳钉,還是采用原生的Filebeat進行日志收集。

    Collector暫時不用蛛倦,直接來看看MQ
    MQ:
    filebeat的輸出管道類型包括:
    Elasticsearch Service歌懒、ElasticsearchLogstash溯壶、Kafka及皂、RedisFile且改、Console目前的方案采用的是kafka作削峰填谷躲庄、解耦。
    ETL:采用Logstash
    Storage and Search:采用ElasticSearch钾虐、Kibana
    到這里噪窘,基本可以看出我們的架構如下:

    image.png

    具體實現(xiàn)
    Agent日志收集方案:
    k8s日志收集filebeat日志收集方案:

編號 方案 優(yōu)點 缺點
1 每個app的鏡像中都集成日志收集組件 部署方便,kubernetes的yaml文件無須特別配置效扫,可以為每個app自定義日志收集配置 強耦合倔监,不方便應用和日志收集組件升級和維護且會導致鏡像過大
2 單獨創(chuàng)建一個日志收集組件跟app的容器一起運行在同一個pod中 低耦合,擴展性強菌仁,方便維護和升級 需要對kubernetes的yaml文件進行單獨配置浩习,略顯繁瑣
3 將所有的Pod的日志都掛載到宿主機上,每臺主機上單獨起一個日志收集Pod 完全解耦济丘,性能最高谱秽,管理起來最方便 需要統(tǒng)一日志收集規(guī)則,目錄和輸出方式
4 將所有的Pod的日志掛載到nfs-server上摹迷,在nfs-server上單獨啟一個日志收集Pod 是方案3的升級版 需要統(tǒng)一日志收集規(guī)則疟赊,目錄和輸出方式,如果日志收集pod失效峡碉,會導致整個日志收集停止近哟,影響范圍比方案3大

綜合以上優(yōu)缺點,我們選擇使用方案三鲫寄。

統(tǒng)一日志格式:

日志類型 描述 日志包含的因子 日志格式 備注
biz日志 用于業(yè)務中打印的info/warn 全局鏈路線程號吉执、消費者IP、提供者IP地来、調用者應用名稱戳玫、消費者應用名稱、客戶號未斑、接口名稱咕宿、具體日志輸出的所在行、日志打印的內容 僅在代碼中l(wèi)ogger.info/warn輸出才會打印
err 日志 用于業(yè)務輸出的error 全局鏈路線程號、消費者IP荠列、提供者IP类浪、調用者應用名稱、消費者應用名稱肌似、客戶號费就、接口名稱、具體日志輸出的所在行川队、日志打印的堆棧信息 僅在代碼中l(wèi)ogger.error輸出才會打印
io 日志 用于接口的輸入輸出參數(shù) 全局鏈路線程號力细、消費者IP、提供者IP固额、調用者應用名稱眠蚂、消費者應用名稱、客戶號斗躏、接口名稱逝慧、具體日志輸出的所在行、輸入輸出的參數(shù)啄糙、接口耗時 僅配置了注解笛臣,出入參才不會打印
monitor日志 用于監(jiān)控接口耗時、接口數(shù)據(jù)量 全局鏈路線程號隧饼、消費者IP沈堡、提供者IP、調用者應用名稱燕雁、消費者應用名稱诞丽、客戶號、接口名稱拐格、具體日志輸出的所在行僧免、數(shù)據(jù)量、接口耗時禁荒、結果標識(成功 or 失敗 ) 默認全部打印

需要解決的問題:

1猬膨、日志歷史歸檔壓縮(未做)

2、日志敏感數(shù)據(jù)脫敏(未做)

3呛伴、異步日志打印

目前已對日志格式做了調整,增加了異步日志谒所,且將日志文件放到nacos上热康,可動態(tài)配置。

image.png

日志打印時間 | 線程號 | traceId | [調用方IP | 調用方 | 提供方IP | 提供方] | [請求url] | 日志打印類 [日志打印行號] - 日志內容

Filebeat配置:
vim /opt/filebeat-6.8.9-linux-x86_64/filebeat-all.yml
文件內容如下:

fields:
  ip_inside: 10.210.100.141
fields_under_root: true
filebeat.config.inputs:
  enabled: true
  path: /opt/filebeat-6.8.9-linux-x86_64/conf/*/*.yml
  reload.enabled: true
  reload.period: 10s
logging.files:
  keepfiles: 3
  name: filebeat
  path: /opt/filebeat-6.8.9-linux-x86_64/log/ 
logging.level: info
logging.to_files: true
output.kafka:
  bluk_max_size: 4096
  compression: gzip
  compression_level: 7
  hosts:
    - 10.210.98.112:9092
  partition.round_robin:
    reachable_only: true 
  required_acks: 1
  timeout: 45
  topic: 'bi-sit'
  worker: 1
processors:
 - drop_fields:
     fields: ["prospector","beat","host","source","log"]
queue.mem:
  events: 4096
  flush.min_events: 512
  flush.timeout: 5s

參數(shù)說明:

序號 參數(shù) 說明
1 fields.ip_inside 存儲日志的宿主機IP
2 filebeat.config.inputs.path 宿主機日志采集配置文件劣领,統(tǒng)一在/opt/filebeat-6.8.9-linux-x86_64/conf文件夾下
3 output.kafka.topic 日志在Kafka中使用的Topic
4 output.kafka.hosts Kafka宿主機IP和Port姐军,檢測當前日志宿主機與Kafka宿主機是否可正常通信:telnet 10.210.98.112 9092

日志采集配置:
mkdir /opt/filebeat-6.8.9-linux-x86_64/conf
新建各個級別日志采集配置文件
以bi系統(tǒng)測試環(huán)境為例:新建文件夾:bi-sit
mkdir /opt/filebeat-6.8.9-linux-x86_64/conf/bi-sit
新建info日志采集配置文件bqx-bi-info.yml,文件內容如下:

- enabled: true
  exclude_files:
  - .gz$
  fields:
    log_type: err
    server_name: bqx-bi
    tags : bi-sit
  fields_under_root: true
  multiline.match: after
  multiline.negate: true
  multiline.pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3} 
  paths:
  -  /u01/bqx-bi/logs/info/bqx-bi-service-info*.log 
  type: log

參數(shù)說明:

序號 參數(shù) 說明
1 fields.server_name 服務名稱
2 fields.tags 服務標簽
3 paths 對應級別日志所在的路徑

Logstash配置:

# Sample Logstash configuration for creating a simple
# Beats -> Logstash -> Elasticsearch pipeline.

input {
  kafka{
        bootstrap_servers => ["10.210.3.68:9092"]
        client_id => "logger"
    group_id => "logger"
    auto_offset_reset => "latest"
    consumer_threads => 5
    decorate_events => true
    topics => ["logger"]
        codec => json {
                         charset => "UTF-8" }
  }
 
  kafka{
        bootstrap_servers => ["10.210.3.68:9092"]
        client_id => "activity"
        group_id => "activity"
        auto_offset_reset => "latest"
        consumer_threads => 1 
        decorate_events => true
        topics => ["activity"]
        codec => json {
                         charset => "UTF-8" }
  }

  kafka{
        bootstrap_servers => ["10.210.3.68:9092"]
        client_id => "mysqlslowlog"
        group_id => "mysqlslowlog"
        auto_offset_reset => "latest"
        consumer_threads => 1 
        decorate_events => true
        topics => ["mysqlslowlog"]
        codec => json {
                         charset => "UTF-8" }
  }
  
   kafka{
        bootstrap_servers => ["10.210.3.68:9092"]
        client_id => "bi-prd"
        group_id => "bi-prd"
        auto_offset_reset => "latest"
        consumer_threads => 2 
        decorate_events => true
        topics => ["bi-prd"]
        codec => json {
                         charset => "UTF-8" }
  }


}


filter {
        grok{
           match => ["message","(?<logdate>%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME})",
                     "message","# Time: (?<time>[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2})"
           ]
           }
        date{
           match => [ "logdate", "yyyy-MM-dd HH:mm:ss,SSS"]
           locale => "en"
           timezone => "Asia/Shanghai"
        }
       mutate{
           remove_field => ["logdate","@metadata"]
       }
}

output {
  elasticsearch {
    hosts => ["http://10.210.3.68:9200"]
    index => "%{[tags]}-log-%{+YYYY.MM.dd}"
    user => "es用戶名"
    password => "es密碼"
    #ssl => true
    #ssl_certificate_verification => false
  }
}

output中user和password,如果有用戶名和密碼的話奕锌,需要設置著觉,沒有可以去掉

針對過期的index需要通過定時任務將對應的index刪除掉
腳本如下:

#!/bin/bash

#刪除早于15天的ES集群的索引
function delete_indices() {
param=$(echo $1)
#截取索引的日期部分(用于下面的日期比較是否小于15日),我的索引是com-字符串后面的部分為日期惊暴, 比如: www.test.com-2020.08.08
dateValue=$(echo ${param#*com-})
#截取日期的前部分作為索引的名稱(后續(xù)需要替換-為.饼丘, 然后和日期拼接起來成為一個真正的索引名稱,用于刪除)
name=$(echo  $2)

echo "name=$name date=$dateValue" 
comp_date=`date -d "15 day ago" +"%Y-%m-%d"`
date1="$dateValue 00:00:00"
date2="$comp_date 00:00:00"

t1=`date -d "$date1" +%s` 
t2=`date -d "$date2" +%s`

if [ $t1 -le $t2 ]; then
echo "$1時間早于$comp_date辽话,進行索引刪除"
#轉換一下格式肄鸽,將類似www-test-com格式轉化為www.test.com

#轉換一下格式,將類似2020-10-01格式轉化為2020.10.01
format_date=`echo $dateValue| sed 's/-/\./g'`
#拼接成索引名稱
indexName="$name-$format_date"

curl -u admin:admin -k -XDELETE http://10.210.3.68:9200/$indexName
#刪除索引
echo "$indexName刪除成功"
fi
}

curl -u admin:admin -k http://10.210.3.68:9200/_cat/indices?v | awk -F" " '{print $3}' |egrep prod|awk -F"-" '{print $NF}' | egrep "[0-9]*\.[0-9]*\.[0-
9]*" | sort | uniq  | sed 's/\./-/g'| while read LINE
do
#調用索引刪除函數(shù)油啤, 結果打印到日志
delete_indices $LINE prod-log >> /home/logs/delete_indices.log
done

curl -u admin:admin -k http://10.210.3.68:9200/_cat/indices?v | awk -F" " '{print $3}' |egrep activity|awk -F"-" '{print $NF}' | egrep "[0-9]*\.[0-9]*\
.[0-9]*" | sort | uniq  | sed 's/\./-/g'| while read LINE
do
#調用索引刪除函數(shù)典徘, 結果打印到日志
delete_indices $LINE activity-log >> /home/logs/delete_indices.log
done

匹配邏輯需要根據(jù)你自己的索引規(guī)范來做適當調整

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市益咬,隨后出現(xiàn)的幾起案子逮诲,更是在濱河造成了極大的恐慌,老刑警劉巖幽告,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梅鹦,死亡現(xiàn)場離奇詭異,居然都是意外死亡评腺,警方通過查閱死者的電腦和手機帘瞭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒿讥,“玉大人蝶念,你說我怎么就攤上這事∮蟪瘢” “怎么了媒殉?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摔敛。 經常有香客問我廷蓉,道長,這世上最難降的妖魔是什么马昙? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任桃犬,我火速辦了婚禮,結果婚禮上行楞,老公的妹妹穿的比我還像新娘攒暇。我一直安慰自己,他們只是感情好子房,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布形用。 她就那樣靜靜地躺著就轧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪田度。 梳的紋絲不亂的頭發(fā)上妒御,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機與錄音镇饺,去河邊找鬼乎莉。 笑死,一個胖子當著我的面吹牛兰怠,可吹牛的內容都是我干的梦鉴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼揭保,長吁一口氣:“原來是場噩夢啊……” “哼肥橙!你這毒婦竟也來了?” 一聲冷哼從身側響起秸侣,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤存筏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后味榛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椭坚,經...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年搏色,在試婚紗的時候發(fā)現(xiàn)自己被綠了善茎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡频轿,死狀恐怖垂涯,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情航邢,我是刑警寧澤耕赘,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站膳殷,受9級特大地震影響操骡,放射性物質發(fā)生泄漏。R本人自食惡果不足惜赚窃,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一册招、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧勒极,春花似錦跨细、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掀鹅,卻和暖如春散休,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背乐尊。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工戚丸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扔嵌。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓限府,卻偏偏與公主長得像,于是被迫代替她去往敵國和親痢缎。 傳聞我的和親對象是個殘疾皇子胁勺,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內容