2010年6月9日 星期三

Mysql 系統訊息集中監控(syslog, syslog-ng)


Mysql 的系統訊息,在早期算是個孤兒,在/var/log/下的種種訊息檔,看不到mysql的(除了mysql自己寫的),
當然更遑論syslog/syslog-ng的監控作法上,更沒辦法做這一塊
在mysql 5.1.20版出來後,這件事情終於獲得解決(怎麼等這麼久),不過對於之前的版本系統維護人員只好自己想辦法了
[mysql訊息記錄在syslog/syslog-ng的方法]
這篇不是要講5.1.20之後的系統訊息集中監控,畢竟我們公司的系統是早期的5.0.X版,所以就寫舊版的方法
舊版的方法用的比較老土,簡單講,要放入syslog/syslog-ng,那就用tail + logger來實現,例如

tail -f -n 0 /var/log/mysqld.log | logger -p daemon.info -t mysql

-n 0: 是為了在啟動tail時,不想把原本的訊息又丟一次
/var/log/mysqld.log: 請自行決定要放入去的mysql錯誤訊息檔名
-p daemon.info: 這個是設定要放到syslog/syslog-ng的facility.priority
-t mysql: 把所指定的檔名資料都給予一個標記字串(tag),如果沒給,就會放上user id
| :用(pipe)的原因為要把tail的結果餵給logger(廢話,應該都知道吧)
以上的命令可以加在自己寫的/etc/init.d/mysqld裡,在啟動mysql之前先tail過
當然也可以在cronjob裡,定期去檢查, tail指令是否還存在(可以自定pid檔來確認),不在就再啟動tail指令

注意:syslog/syslog-ng的port預設是udp:514(/etc/services的syslog,/etc/syslog-ng/syslog-ng.conf)

[syslog集中訊息]


一般,Linux安裝完後預設就是syslogd來管控訊息記錄,在進行syslog集中(centerlization)訊息時,
可以朝以下步驟方向執行
(1)選定1台當syslog center server
在這台server的 /etc/sysconfig/syslog設定如下(注意SYSLOGD_OPTIONS多了-r)
Options to syslogd
# -m 0 disables 'MARK' messages.
# -r enables logging from remote machines
# -x disables DNS lookups on messages recieved with -r
# See syslogd(8) for more details
SYSLOGD_OPTIONS="-m 0 -r"
# Options to klogd
# -2 prints all kernel oops messages twice; once for klogd to decode, and
# once for processing with 'ksymoops'
# -x disables all klogd processing of oops messages entirely
# See klogd(8) for more details
KLOGD_OPTIONS="-x"
#
SYSLOG_UMASK=077
# set this to a umask value to use for all log files as in umask(1).
# By default, all permissions are removed for "group" and "other".
(2)訊息集中
剩下的其他主機設定要把log丟給center server,在這些機器的/etc/syslog.conf設定如下
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.* /dev/console

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages

# The authpriv file has restricted access.
authpriv.* /var/log/secure

# Log all the mail messages in one place.
mail.* -/var/log/maillog


# Log cron stuff
cron.* /var/log/cron

# Everybody gets emergency messages
*.emerg *

# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler

# Save boot messages also to boot.log
local7.* /var/log/boot.log

*.* @1.1.1.10

(3)如果系統訊息還要導到其他主機,例如在windows 2003上的kiwi syslog server,
可以在/etc/syslog.conf最後一行增加設定如下(假設kiwi syslog server的IP為1.1.1.20)
*.* @1.1.1.20

很重要的一點是,設定*.*是為了避免遺漏了任何訊息,但是*.*的話訊息量真的很多,
在網路上流動的訊息也會很多,另外就是訊息內容的格式也沒辦法更改

[syslog-ng集中訊息]


syslog-ng的好處是他的訊息跟syslog互通,所以kiwi也能吃這個訊息,另外,他的設定更加彈性
syslog-ng官網:http://www.balabit.com/
(1)source設定,可以設定各種來源管道的訊息
source { sourcedriver params; sourcedriver params; ... };
含義:
:一個消息源的標識
sourcedriver:消息源驅動器,可以支持若干參數,並使用分號「;」隔離多個消息源驅動器

消息源驅動器有:
file (filename) : 從指定的文件讀取日誌訊息
unix-dgram (filename) : 打開指定的SOCK_DGRAM模式的unix socket,接收日誌訊息
unix-stream (filename) : 打開指定的SOCK_STREAM模式的unix socket,接收日誌訊息
udp ( (ip),(port) ) : 在指定的UDP接收日誌訊息
tcp ( (ip),(port) ) : 在指定的TCP接收日誌訊息
sun-streams (filename) : 在solaris系統中,打開一個(多個)指定的STREAM設備,從其中讀取日誌訊息
internal() : syslog-ng內部產生的訊息
pipe(filename),fifo(filename) : 從指定的管道或者FIFO設備,讀取日誌訊息

例如:
source s_sys {
file ("/proc/kmsg" log_prefix("kernel: "));
unix-stream ("/dev/log");
internal();
# udp(ip(0.0.0.0) port(514)); #如果取消註釋,則可以從udp的514 port獲得訊息
};
其他部份不多做解釋,可以在網路上找到syslog-ng administrative guide

(2)filter
filter { expression; };
含義:
:一個過濾器標識
expression:表達式

表達式支持:
邏輯操作符:and(和)、or(或)、not(非);
函數:可使用正規表達式描述內容

過濾函數有:
facility(,): 根據facility(設備)選擇日誌消息,使用逗號分割多個facility
level(,): 根據level(優先級)選擇日誌消息,使用逗號分割多個level,或使用「..」表示一個範圍
program(regexp): 日誌消息的程序名是否匹配一個正則表達式
host(regexp): 日誌消息的主機名是否和一個正則表達式匹配
match(regexp): 對日誌消息的內容進行正則匹配
filter(): 調用另一條過濾規則並判斷它的值

例如:
filter f_filter2 { level(info..emerg) and
not facility(mail,authpriv,cron); };

※這裡的level定義info,相當於syslog的.=info,並不包括更低的等級;
若需要包括更低的等級,請使用「..」表示一個等級範圍;
另外,filter(DEFAULT),用於捕獲所有沒有匹配上的日誌消息。filter(*)是無效的。

(3)destination
destination { destdriver params; destdriver params; ... ;};

含義:
:一個目的地的標識
destdriver :目的地驅動器

目的地驅動器有:
file (filename) :把日誌消息寫入指定的文件
unix-dgram (filename) :把日誌消息寫入指定的SOCK_DGRAM模式的unix套接字
unix-stream (filename) :把日誌消息寫入指定的SOCK_STREAM模式的unix套接字
udp (ip),(port) :把日誌消息發送到指定的UDP端口
tcp (ip),(port) :把日誌消息發送到指定的TCP端口
usertty(username) :把日誌消息發送到已經登陸的指定用戶終端窗口
pipe(filename),fifo(filename) :把日誌消息發送到指定的管道或者FIFO設備
program(parm) :啟動指定的程序,並把日誌消息發送到該進程的標準輸入

舉例:
destination d_mesg { file("/var/log/messages"); };
destination d_syslog { udp ("192.168.228.225" port(514)); };

※配合使用udp或tcp即可實現syslog-ng/syslog center server。注意,udp函數的寫法上和source語法中的定義不同。

(4)log
log { source S1; source S2; ... filter F1; filter F2; ... destination
D1; destination D2; ... };

把消息源、過濾器、消息目的組合起來就形成一條完整的指令。日誌路徑中的成員是順序執行的。
凡是來源於指定的消息源,匹配所有指定的過濾器,並送到指定的地址。
※同樣的,每條日誌消息都會經過所有的消息路徑,並不是匹配後就不再往下執行的,請留意。

舉例:
log { source(s_sys); filter(f_default); destination(d_syslogd); };

(5)options
options { opt1; opt2; ... };


選項有:
引用
chain_hostnames(yesno) :是否打開主機名鏈功能,打開後可在多網絡段轉發日誌時有效
long_hostnames(yesno) :是chain_hostnames的別名,已不建議使用
keep_hostname(yesno) :是否保留日誌消息中保存的主機名稱,否時,總是使用來源主機來作重寫日誌的主機名
use_dns(yesno) :是否打開DNS查詢功能,應使用防火牆保護使用syslog-ng的節點安全,
並確認所有主機都是可以通過dns解釋的,否則請關閉該選項。
use_fqdn(yesno) :是否使用完整的域名
check_hostname(yesno) :是否檢查主機名有沒有包含不合法的字符
bad_hostname(regexp) :可通過正規表達式指定某主機的信息不被接受
dns_cache(yesno) :是否打開DNS緩存功能
dns_cache_expire(n) :DNS緩存功能打開時,一個成功緩存的過期時間
dns_cache_expire_failed(n) :DNS緩存功能打開時,一個失敗緩存的過期時間
dns_cache_size(n) :DNS緩存保留的主機名數量
create_dirs(yesno) :當指定的目標目錄不存在時,是否創建該目錄
dir_owner(uid) :目錄的UID
dir_group(gid) :目錄的GID
dir_perm(perm) :目錄的權限,使用八進制方式標註,例如0644
owner(uid) :文件的UID
group(gid) :文件的GID
perm(perm) :文件的權限,同樣,使用八進制方式標註
gc_busy_threshold(n) :當syslog-ng忙時,其進入垃圾信息收集狀態的時間。
一旦分派的對象達到這個數字,syslog-ng就啟動垃圾信息收集狀態。默認值是:3000。
gc_idle_threshold(n) :當syslog-ng空閒時,其進入垃圾信息收集狀態的時間。
一旦被分派的對象到達這個數字,syslog-ng就會啟動垃圾信息收集狀態,默認值是:100
log_fifo_size(n) :輸出隊列的行數
log_msg_size(n) :消息日誌的最大值(bytes)
mark(n) :多少時間(秒)寫入兩行MARK信息供參考,目前沒有實現
stats(n) :多少時間(秒)寫入兩行STATUS信息供,默認值是:600
sync(n) :緩存多少行的信息再寫入文件中,0為不緩存,局部參數可以覆蓋該值。
time_reap(n) :在沒有消息前,到達多少秒,即關閉該文件的連接
time_reopen(n) :對於死連接,到達多少秒,會重新連接
use_time_recvd(yesno) :宏產生的時間是使用接受到的時間,還是日誌中記錄的時間;
建議使用R_的宏代替接收時間,S_的宏代替日誌記錄的時間,而不要依靠該值定義。

例如:
options {
sync (0);
time_reopen (10);
log_fifo_size (1000);
long_hostnames (off);
use_dns (no);
use_fqdn (no);
create_dirs (no);
keep_hostname (yes);
};

(6)template
template是配合destination的一個設定,可以對輸出訊息進行格式化,使用tempate時,
可以指定使用以下參數
$MACRO_NAME
description/type
example

$FACILITY
syslog facility name
daemon

$PRIORITY
the syslog priority name
debug

$LEVEL ; same output as $PRIORITY

$TAG
Hex representaiton of the 32-bit priority/facility pair (see
/usr/include/sys/syslog.h)
1f

(1f is the output for "daemon/debug" as above)

$DATE
The local system time
Jan 19 23:27:21

$FULLDATE
Same as $DATE but with %Y appended,
2001 Jan 19 23:27:21

$ISODATE
ISO-standard format date (strftime format "%Y-%m-%dT%H:%M:%S%z")
2001-01-19T23:27:21+1000

$YEAR
4-digit year string
2001

$MONTH
2-digit month string
01

$DAY
2-digit day string
19

$HOUR
2-digit hour string
23

$MIN
2-digit minutes string
27

$SEC
2-digit seconds string
21

$HOST
host string; not sure how to decode this function, in my example it's the
same as fullhost (?)
avrio

$FULLHOST
"full hostname" (msg->host->data)
avrio

$PROGRAM
If syslog-ng has pulled a 'program name' out of the message, this will
return that
qpage

$MSG $MESSAGE
The full syslog message
qpage[9366]: processing the page queue

例如:
destination d_format_test { file("/var/log/test" template("$FACILITY $PRIORITY \
$LEVEL $TAG $DATE $FULLDATE $ISODATE $YEAR $MONTH $DAY $HOUR $MIN $SEC $HOST \
$FULLHOST $PROGRAM $MSG\n")); };

要設定syslog-ng集中化訊息架構的方法說明如下:
(1)選定1台當syslog-ng center server
選定後,在這台server上安裝syslog-ng(用rpm安裝比較容易)
安裝後理論上syslog/klog的服務會自動卸載,不過還是檢查一下好
在下次開機時,也記得啟動syslog-ng
service syslog stop
chkconfig syslog off
service syslog status
chkconfig --list syslog
service syslog-ng start
chkconfig syslog-ng on

設定syslog-ng當syslog server,所以要修改/etc/syslog-ng/syslog-ng.conf
範例如下:
# syslog-ng configuration file.
#
# This should behave pretty much like the original syslog on RedHat. But
# it could be configured a lot smarter.
#
# See syslog-ng(8) and syslog-ng.conf(5) for more information.
#

options {
sync (0);
time_reopen (10);
log_fifo_size (1000);
long_hostnames (off);
use_dns (no);
use_fqdn (no);
create_dirs (no);
keep_hostname (yes);
};

source s_sys {
file ("/proc/kmsg" log_prefix("kernel: "));
unix-stream ("/dev/log");
internal();
#打開對514 udp來源的訊息接收
udp(ip(0.0.0.0) port(514));

# udp(ip(0.0.0.0) port(514));
};

destination d_cons { file("/dev/console"); };
#destination d_syslogd { file("/tmp/syslogd"); };
destination d_mysql { udp("1.1.1.20" port(514)); };

destination d_mesg { file("/var/log/messages"); };
destination d_auth { file("/var/log/secure"); };
destination d_mail { file("/var/log/maillog" sync(10)); };
destination d_spol { file("/var/log/spooler"); };
destination d_boot { file("/var/log/boot.log"); };
destination d_cron { file("/var/log/cron"); };
destination d_kern { file("/var/log/kern"); };
destination d_mlal { usertty("*"); };
destination d_format_test { file("/var/log/test" template("2|HTS-TEST|$HOUR:$MIN:$SEC\t$PROGRAM\t$MSG\n")); };


filter f_mysql { facility(daemon) and level(info) and match("mysql"); };
#filter f_mysql { match("mysql"); };

filter f_kernel { facility(kern); };
filter f_default { level(info..emerg) and
not (facility(mail)
or facility(authpriv)
or facility(cron)); };
filter f_auth { facility(authpriv); };
filter f_mail { facility(mail); };
filter f_emergency { level(emerg); };
filter f_news { facility(uucp) or
(facility(news)
and level(crit..emerg)); };
filter f_boot { facility(local7); };
filter f_cron { facility(cron); };
#log { source(s_sys); filter(f_kernel); destination(d_cons); };
#log { source(s_sys); filter(f_syslogd); destination(d_syslogd); };
#這個log範例是重新格式化系統訊息,並寫到指定檔案
log { source(s_sys); filter(f_mysql); destination(d_format_test); };
#這個log範例是把訊息再導到1.1.1.20
log { source(s_sys); filter(f_mysql); destination(d_mysql);
#如果要把重新格式化的訊息丟到1.1.1.20,那就綜合上面的destination設定};

log { source(s_sys); filter(f_kernel); destination(d_kern); };
log { source(s_sys); filter(f_default); destination(d_mesg); };
log { source(s_sys); filter(f_auth); destination(d_auth); };
log { source(s_sys); filter(f_mail); destination(d_mail); };
log { source(s_sys); filter(f_emergency); destination(d_mlal); };
log { source(s_sys); filter(f_news); destination(d_spol); };
log { source(s_sys); filter(f_boot); destination(d_boot); };
log { source(s_sys); filter(f_cron); destination(d_cron); };

# vim:ft=syslog-ng:ai:si:ts=4:sw=4:et:
設定完成後,要讓syslog-ng順利重啟
service syslog-ng restart

注意:如果syslog-ng要另外記錄檔名,請設定成logrotate,以免LOG太大佔空間

(2)訊息集中
剩下的其他主機設定要把log丟給center server,在這些機器的/etc/syslog.conf最後一行新增如下
*.* @1.1.1.10

[kiwi syslogd使用說明]
kiwi syslogd是windows下一個不錯用的工具,有免費版跟完整版2種.
持著使用綠色軟體的前提下,免費版當然受限功能. 如果能使用完整版,應該可以不要用syslog-ng
官網:http://www.kiwisyslog.com/

設定說明如下:
1.從File選單-> Setup,進入Setup對話框
2-1.選擇Formatting->Custom file formats, 在Custom file formats上按滑鼠右鍵,選Add new custom file format
2-2.只鉤選左邊的Message text欄位(意思只要訊息就好),Apply之後會多一個New Format項目

3-1.選擇Rules->Default->Log to file
3-2.在log file format 下拉式選單選擇Custom1 New Format

4.套用後,訊息便會在畫面(因為有鉤選Display)以及Logs目錄下(也有鉤選Log to file)產生
預設的路徑應該在c:\program files\syslogd\logs\下
如果要依照每天存一個檔,可以在Log to file的檔名設定如下
c:\program files\syslogd\logs\%DateY4%DateM2%DateD2.log
如果是2010年6月9日,檔名就會顯示成
c:\program files\syslogd\logs\20100609.log

注意:
1.kiwi在機器啟動時,要跟著帶起來
2.Log to file的檔案記得定期要清檔,以免吃硬碟空間

假使系統自己的monitor agent是利用讀檔的方式,把訊息傳給Monitor Server,那就可以在kiwi設定中,
在Log to file的設定時,把檔案寫到agent所指定的檔名跟位置,而訊息的格式內容則透過syslog-ng的
template來指定,就可以達到想要的結果

[使用相關的套件有]
1. Windows
Kiwi_Syslogd_8.1.6.setup.exe
2. syslog (@rhel 5.4)
預設的syslog套件
3. syslog-ng (@rhel 5.4)
syslog-ng-2.1.4-1.el5.i386.rpm

沒有留言:

張貼留言

文章分類