正所謂撒了一個謊就需要撒更多的謊來彌補它
目前已經在使用 sentry 來做集中管理
sentry 非常棒,簡單清爽容易設定介面又漂亮,預設就有通知和人員管理等功能
sentry 設定上比 logstash 簡單10倍,但是對於系統 log 還沒支援,客製化功能也比較少
logstash 的特色就是可以自定輸出規則、過濾規則,自定 log 頁面、圖表等等
一開始最簡單的管理方法的寫個 cron job 把 log 檔案傳到同一個伺服器
或是透過 syslog
一般 system log 是透過 syslog 服務,比進階的有 rsyslog & syslog-ng
rsyslog & syslog-ng 這兩個都是 syslog-based,可以做到集中化,ssh tcp/udp 傳輸等
但是這些方法還是不利於搜尋管理和監控
於是找到了 logstash with elasticsearch and kibana
logstash 主要由三個元件構成 input, filter, output
input 來源可以是 file, stdin, syslog, udp, redis, elasticsearch, etc.
filter 主要用來"操作"這些 input
output 則是把最後的資料放到某個地方 stdout, syslog, elasticsearch, file, etc
所以可以想像 logstash 可以被放在 centrialized server / cluster / instances
但是佔用的記憶體可不小,至少也要 200mb 才堪用
所以我的作法是用 rsyslog 蒐集資料後吐給 centrialized logstash 後存到 elasticsearch server
app server 上面使用老牌 rsyslog 搭配嘻哈 logstash 這樣的組合
Installation 安裝 logstash and elastic search
雖然 logstash jar 自帶一組 embedded elasticsearch,應該算是測試用的還是自己裝一個 elastic search吧
install elastic search
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.5.noarch.rpm
sudo yum install elasticsearch-0.90.5.noarch.rpm
sudo service elasticsearch start
curl http://localhost:9200
參考 http://logstash.net/docs/1.2.2/tutorials/getting-started-simple
wget https://download.elasticsearch.org/logstash/logstash/logstash-1.2.2-flatjar.jar
vi simple.conf
java -jar logstash-1.2.2-flatjar.jar agent -f simple.conf
grok
grok 是 regex 的進階,grok 是為了讓 regex 更能夠被重複使用和理解但是實際上在使用的時候一直在查表,花了許多時間
grok 可以參考
https://github.com/logstash/logstash/blob/v1.2.2/patterns/grok-patterns
gork 小工具
http://grokdebug.herokuapp.com/
不過小工具也不是完全正確,不是實際上在使用的 syntax parser
像是 YEAR 有時候最多對應到 2 位數,但是一些使用 YEAR 的延伸 grok 像是一些 DATESTAMP/TIMESTAMP 有時候卻可以對應到 4 位數
實際上 jar 使用的 parser 有非常多 bug,許多 regex 無法正確的轉換成 grok
尤其是在 -- web 的時候
更糟糕的是,debugger 非常的鳥,不管有什麼地方錯誤大概八成都是回報第一行錯誤
所以在寫 regex to grok pattern 的時候盡量拆分成小的 grok pattern 一球一球對決
grok pattern 也盡量做成另外的檔案和 logstash.conf 拆開
常見的鳥 bug 像是%符號如果緊黏著前面的字符很容易出錯,log 中有空白字元就盡量直接寫出來
最後發現罪魁禍首是內建的 web ,不用之後才沒有 grok syntax 問題
logstash config
範例
mkdir patterns
vi patterns/nginx.grok
nginx.grok
# nginx
NGINXACCESS %{SYSLOGHOST:syslog_hostname} %{SYSLOGPROG}:%{IPORHOST:addr} - %{USERNAME} \[%{HTTPDATE:date}\] "(%{DATA:method} %{DATA:uri} %{DATA:protocol}|%{DATA})" %{INT:status} %{INT} %{QS:referer};? %{QS:user_agent} %{QS}
logstash.conf 範例,假設這裡只看nginx log
java -jar logstash-1.2.2-flatjar.jar agent -f logstash.conf
run logstash as service
mv logstash /opt/
vi logstash.sh
sudo mv logstash.sh /etc/init.d/logstash
sudo chmod +x /etc/init.d/logstash
一些其他可以改進小地方像是修改 nginx.conf 關閉不需要的 log
log_format main '$remote_addr - $remote_user [$time_iso8601] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
以上是接收端(log server)的部份, 發送端可以使用 rsyslog 並參考 http://cookbook.logstash.net/recipes/rsyslog-agent/
$ModLoad imfile # Load the imfile input module
$ModLoad imudp
$ModLoad imuxsock
#$ModLoad imklog
$template RemoteHost, "%HOSTNAME% %syslogtag%%msg%"
# watch nginx access log
$InputFileName /var/log/nginx/access.log
$InputFileTag prod-nginx-access:
$InputFileStateFile state-nginx-access
$InputRunFileMonitor
$InputFilePollInterval 10
#discard health check, can be deprecated if I stop nginx log by user agent
if $programname == 'dhclient' or \
$programname == 'kernel' then ~
:msg, contains, "Amazon Route 53 Health Check Service" ~
:msg, contains, "ELB-HealthChecker" ~
*.* @my.log.server:5544;RemoteHost
"@"代表使用 udp 傳輸,"@@"代表使用 tcp$InputFileTag 就是 $programname
以上這樣的設定會建議在 Virtual Private Cloud 裡面運作,以免資料被別人看光光
Debug
rsyslog debug 請參考 http://www.rsyslog.com/doc/troubleshoot.html基本上就是停掉服務改用 native mode
sudo service rsyslog stop
sudo /sbin/rsyslogd -c5 -dn -f /etc/rsyslog.conf |grep error > r.log
logstash date format
http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html
沒有留言:
張貼留言