背景知識:
- 《Perl讀取wtmpx記錄檔》;
- logger命令;
- Syslog日誌;
- crontab命令;
參考書籍:
求助:
- Sys::Syslog模組處理系統日誌編譯警告:your vendor has not defined the Sys::Syslog macro _PATH_LOG...
求各位大大解惑,不勝感激。
源碼如下:
#!/usr/bin/perl -w######################################################################################### 檔案:wtmpx2.pl# 功能:從wtmpx日誌裡找出最近登入資訊寫到系統日誌裡;# 作者:半點鐘閑# 時間:2012-11-11 11:55 光棍節快樂# 系統:SCO_SV scosysv 3.2 5.0.6 i386 Perl5.6.0 built for i486-pc-sco3.2v5.0# 說明:所使用的系統日誌功能很弱無法提供登入到系統使用者的資訊,結合cron定時執行本程式,將提取到# 的登入資訊寫到系統日誌裡.同時,機房採用"集中Log Service器"統一接收系統發送到遠端日誌進行集中分# 析處理.## 進一步說明:# 系統比較陳舊,因是生產用機即不能升級現在又無法更換在,使用Sys::Syslog模組處理系統日誌時,# 在Ubuntu+Perl5.14正常的代碼,在本機上無法編輯通過提示:# your vendor has not defined the Sys::Syslog macro _PATH_LOG...# <<Perl網路編程>>書中找到一段話:在Perl5.6之前,為了運行這個模組需要syslog.ph標頭檔,# 但這個檔案不和Perl發布版一起提供,需要使用h2ph工具手工產生.在使用Sys::Syslog之前應當# 升級5.6或更高版本。# 我的Perl版本按書上所說是滿足要求的,難道好事都讓我遇到了,不解!想起Perl名言"TMOTWTDI"# 日誌部分暫時交給shell的logger命令處理.# --------------------------------------------------------------------------------------# 修改:2012-11-12# BUG1:時間精度缺失造成重複記錄的問題;# BUG語句:# my ($sec,$min,$hour,$mday,$mon,$year_off) = (localtime)[0..5];# ($sec,$min,$hour,$mday,$mon,$year_off) = (localtime $tv_sec)[0..5];# 影響語句:next if($first_time >= $tv_time);# 描述:如目前時間為11:00:00用做數字寫入檔案時為1100,此時,wtmpx檔案中若有登入時間為10:01:01# 將造成(1100>=100101)返回假值.# 更正:全部以字元方式運算# $sec = sprintf "%02d",$sec;#不足2位補0# $min = sprintf "%02d",$min;# $hour = sprintf "%02d",$hour;# 同時修改下述語句:# next if($current_date ne $tv_date);# next if($first_time ge $tv_time);########################################################################################use strict;$SIG {__WARN__} = \&log_warn;sub log_warn(){#warn資訊也寫到日誌裡;system "echo '@_' | logger -it wtmpx -p auth.info";}my $wtmpx_file = '/var/adm/wtmpx';my $first_file = "/var/adm/first";#記錄前一次查詢的時間my $template = 'A32 A4 A32 s s s s l l l x20 s Z257 x';#ScoUnix5模版my $recordsize = length( pack( $template, () ) );my ($sec,$min,$hour,$mday,$mon,$year_off) = (localtime)[0..5];my $current_date = $year_off + 1900 . $mon + 1 . $mday;$sec = sprintf "%02d",$sec;#不足2位補0$min = sprintf "%02d",$min;$hour = sprintf "%02d",$hour;my $session = open FIRST_FILE, '+<', $first_file or warn "Unable to open $first_file:$!\n";my $first_time;#前次查詢的時間if ($session){$first_time = <FIRST_FILE>;#擷取先前的時間seek FIRST_FILE, 0, 0;#移到檔案頭print FIRST_FILE "$hour$min$sec";close FIRST_FILE or warn "Unable to close $first_file:$!\n";} else {$first_time = "$hour$min$sec";#使用目前時間$session = open FIRST_FILE, '>', $first_file or warn "err2:Unable to open $first_file:$!\n";if ($session){print FIRST_FILE $first_time;close FIRST_FILE or warn "err2:Unable to close $first_file:$!\n";}}open WTMP, '<', $wtmpx_file or die "Unable to open wtmpx:$!\n";my ($ut_user, $ut_id,$ut_line, $ut_pid,$ut_type, $ut_e_termination,$ut_e_exit, $tv_sec,$tv_usec, $ut_session, $ut_syslen, $ut_host) = ();my $record;while( read( WTMP, $record, $recordsize ) ) {($ut_user, $ut_id,$ut_line, $ut_pid,$ut_type, $ut_e_termination,$ut_e_exit, $tv_sec,$tv_usec, $ut_session,$ut_syslen, $ut_host) = unpack( $template, $record );next if $ut_type == 8;#忽略退出的使用者($sec,$min,$hour,$mday,$mon,$year_off) = (localtime $tv_sec)[0..5];my $tv_date = $year_off + 1900 . $mon + 1 . $mday;$sec = sprintf "%02d",$sec;$min = sprintf "%02d",$min;$hour = sprintf "%02d",$hour;my $tv_time = "$hour$min$sec";next if($current_date ne $tv_date);#跳過非當前系統日期的記錄(當字串進行比較)next if($first_time ge $tv_time);#跳過前次查詢過的記錄(此句只能放在日期比較後面)if ($ut_id eq 'ftp'){$ut_user = "FTP LOGIN $ut_user";} else { $ut_user = "LOGIN $ut_user"; }my $format_record = "$ut_user:$ut_id:$ut_line:PID:$ut_pid:TYPE:$ut_type:HOST:$ut_host:$tv_date $hour:$min:$sec";system "echo '$format_record' | logger -it wtmpx -p auth.info";}close WTMP;
寫入Syslog日誌:
Log Service器接收: