方案描述: 该方案是基于ITM UA产品的二次开发过程中的工具包,实现背景是面对ITM产品UA不支持操作系统平台SGI Irix64 6.5操作系统而进行的。由于UA没有直接支持IRIX的agent,因此我们需要通过Universal Agent来进行二次开发。解决方法:ITM部署有几个层次: 1、第一个层次;TEPS(Tivoli Enterprice Portal Server)作为一个展现最终系统监控的portal 2、第二个层次:HUB-TEMS作为一个集中的管理服务器,它管理着多个客户端、agent、remote-TEMS,连接着BI职责的RDBMS、warehouse。 3、第三个层次:remote-TEMS作为一个远程的管理端可以运用在分布式环境下,并对若干Universal Agent进行管理。描述对象: 由于以上第三个层次的部署,所以我们需要考虑如何将Universal Agent不支持的Irix进行信息收集,并通过一定的格式按照UA提供的API,传递执行结果给UA,传递的方式有很多种,比如:套接字、SNMP。这里我们提供的tool kit使用套接字方式。我们可以使用C、C++、Java、Perl。在这里我们使用Perl
该解决方案种包括一个Perl脚本代码。内有一个file.pm,连同一个日志文件和一个配置文件。该解决方案基于ITM 6.1 和OMEGAMON XE 产品技术构建而成,它能够工作在Windows, AIX, Solaris, HP/UX, Linux等操作系统平台。
用法:1、使用UaSocketClient.pm ,你可以理解为这个文件是一个Socket必须的包。 (1)按照以下的风格和步骤来初始化UaSocketClient my $uaClient = new UaSocketClient(); $uaClient->appl($system); $uaClient->host($host); $uaClient->port($port); $uaClient->locl($locl); $uaClient->connect(); (2)一旦数据已经准备就绪,发送到SOCKET,它将使用$uaClient->send(@data);来调用并通过该数据所在的一个数组。 (3)在mdl文件种定义每一个数组数据中的元素,你可以以变量形式来创建它,比如你可以使用3个变量来定义Severity, Time, Data
。如: Severity D 20 @ Severity Level of event Time D 20 @ Time Stamp hh:mm:ss,ccc Data Z 256 @ Data2、使用本解决方案 (1)确保你的UA上的socket data provider已经可以使用 (2)添加snmp到你的kumenv文件中:KUMA_STARTUP_DP=asfs (3)导入一个元数据文件到环境中:CSA_CoreLog.mdl (4)编辑CSA_CoreLog.mdl文件中的//SOURCE SOCK localhost,这里以发送数据系统的IP和机器名来编辑。 (5)把*.mdl文件放到<install dir>/tmaitm6/metafiles目录。 (6)导入元数据文件: Windows平台, 使用命令行:"kumpcon import *.mdl" UNIX平台,使用命令行:"bin/kumpcon import *.mdl" (7)编辑本地日志配置文件。 (8)运行LogMonitor.pl (9)一旦UA正常运行,请你自定义并创建你期望的场景的workspaces
以下是本解决方案涉及到的5个核心文件:
///UaSocketClient.pm /// package UaSocketClient;use IO::Socket; use strict;
######################################## Constructor ########################################sub new { my $proto = shift; my $class = ref($proto) || $proto; my $this = (); $this->{HOST} = undef; $this->{PORT} = undef; $this->{LOCL} = undef; $this->{APPL} = ""; $this->{SOCK} = undef; $this->{STATE} = 'disconnected'; bless ($this, $class); return $this;}
######################################## Setter/Getter Methods ########################################sub host { my $this = shift; if (@_) { $this->{HOST} = shift } return $this->{HOST};}
######################################## Setter/Getter Methods ########################################sub port { my $this = shift; if (@_) { $this->{PORT} = shift } return $this->{PORT};}
sub locl { my $this = shift; if (@_) { $this->{LOCL} = shift } return $this->{LOCL};}
######################################## Setter/Getter Methods ########################################sub appl { my $this = shift; if (@_) { $this->{APPL} = shift } return $this->{APPL};}
####################################### Connect to the UA Server #######################################sub connect { my $this = shift;
my $bytesOut = 0; while ( ! $bytesOut ) { $this->{SOCK} = undef; while( ! $this->{SOCK} ) { $this->{SOCK} = new IO::Socket::INET( PeerAddr => $this->{HOST}, PeerPort => $this->{PORT}, LocalPort => $this->{LOCL}, Proto => 'tcp') or sleep(1); } $this->{STATE} = 'connected'; $bytesOut = send( $this->{SOCK}, "$this->{APPL}/n", 0); } printf "Connected to %s:%s as application %s/n", $this->{HOST}, $this->{PORT}, $this->{APPL};
return $this->{STATE};}
######################################## Send an event ########################################sub send { my $this = shift; my @lines = @_; my $count = 0; my $bytesOut = 0; if ( $this->{STATE} =~ /^connected$/ ) { foreach my $line (@lines) { if ( $line ) { local $SIG{PIPE} = 'IGNORE'; chomp($line); while ( ! send( $this->{SOCK}, "$line/n", 0) ) { print "Reconnecting.../n"; $this->connect(); } $count++; } } } return $count;}
######################################## Houskeeping ########################################sub disconnect { my $this = shift; syswrite $this->{SOCK}, "//END-DP-INPUT/n"; close $this->{SOCK}; $this->{STATE} = 'disconnected';}
1;
///LogMonitor.pl//#!/usr/bin/perl -w # LogMonitor.pl# Monitors the indicated file using the indicated UA Configuration#---------------- use strict;use UaSocketClient;use File;
#--------------------------# Get Configuration File - See Sample.cfg#--------------------------my $configFile = $ARGV[0] || "LogMonitor.cfg";while ( ! ( $configFile =~ /^/S+/.cfg$/ ) ) { print "Please enter the Configuration File (Must end with .cfg): "; $configFile = <STDIN>; chomp($configFile);}
#--------------------------# Read Configuration#--------------------------open (MYFILEIN, $configFile) || die "cannot open $configFile to read: $!/n";my $line = <MYFILEIN>;close (MYFILEIN);my ($system, $host, $port, $locl, $sleep, $fileName) = split(//s+/, $line);
#--------------------------# Initilize UA Connection#--------------------------my $uaClient = new UaSocketClient();$uaClient->appl($system);$uaClient->host($host);$uaClient->port($port);$uaClient->locl($locl);$uaClient->connect();
#--------------------------# Initilize File to be monitored#--------------------------my $file = new File();$file->name($fileName);
#--------------------------# Main processing loop#--------------------------my $running = 1;while ( $running ) { my @lines = $file->newLines(); $uaClient->send(@lines); print @lines; print "===================/n"; for ( my $i = 0; $i < $sleep && $running; $i++ ) { sleep(1); open RUNFILE, "LogMonitor.run" or $running = undef; close RUNFILE; }}
#--------------------------# Houskeeping#--------------------------$uaClient->disconnect();print "done!/n";
/LogMonitor.cfg//
//CSA_CoreLog localhost 7500 25252 5 G:/prod/corelogfiles/core.log
///File.pm///package File;use strict;use File;
######################################## Constructor ########################################sub new { my $proto = shift; my $class = ref($proto) || $proto; my $file = (); $file->{NAME} = undef; $file->{SIZE} = 0; $file->{FIELDKEY} = ""; $file->{RECORDKEY} = ""; $file->{MODE} = "START"; bless ($file, $class); return $file;}
######################################## Serialize attributes to string ########################################sub serialize { my $this = shift; my $name = sprintf("%-50s",$this->{NAME}); my $size = sprintf("%-10s",$this->{SIZE}); my $fkey = sprintf("%-10s",$this->{FIELDKEY}); my $rkey = sprintf("%-80s",$this->{RECORDKEY}); my $mode = sprintf("%-10s",$this->{MODE}); my $string = join('', $name, $size, $fkey, $rkey, $mode); return $string;}
######################################## Setter/Getter Methods ########################################sub name { my $this = shift; if (@_) { $this->{NAME} = shift; my $bla; ($bla, $bla, $bla, $bla, $bla, $bla, $bla, $this->{SIZE}, $bla ) = stat($this->{NAME}); if ( ! $this->{SIZE} ) { $this->{SIZE}=0; } } printf "Monitoring File: %s, Starting Size: %s/n", $this->{NAME}, $this->{SIZE}; return $this->{NAME};}
sub size { my $this = shift; if (@_) { $this->{SIZE} = shift } return $this->{SIZE};}
sub fieldkey { my $this = shift; if (@_) { $this->{FIELDKEY} = shift } return $this->{FIELDKEY};}
sub recordkey { my $this = shift; if (@_) { $this->{RECORDKEY} = shift } return $this->{RECORDKEY};}
sub mode { my $this = shift; if (@_) { $this->{MODE} = shift } return $this->{MODE};}
######################################## Get New Records Method ########################################sub newRecords { my $this = shift; my @lines = $this->newLines(); my $newLine; my @outLines; $newLine = ''; foreach my $line (@lines) { chomp($line); if ( $line =~ /$this->{RECORDKEY}/ ) { if ( ! ( $newLine =~ /^s*$/ )) { push @outLines, "$newLine/n"; } $newLine = $line; } else { if ( ! ( $line =~ /^s*$/ )) { $newLine = join($this->{FIELDKEY}, $newLine, $line); } } } if ( ! ( $newLine =~ /^s*$/ )) { push @outLines, "$newLine/n"; } return @outLines;}######################################## Get New Lines Method ########################################sub newLines { my $this = shift; my $newSize = 0; my $bla; my @lines; ($bla, $bla, $bla, $bla, $bla, $bla, $bla, $newSize, $bla ) = stat($this->{NAME});
if ( $newSize ) { if ( $newSize != $this->{SIZE} ) { open (MYFILEIN, $this->{NAME}) || die "cannot open $this->{NAME} to read: $!/n"; if ( $newSize > $this->{SIZE} ) { seek (MYFILEIN, $this->{SIZE}, 0); } $this->{SIZE} = $newSize; @lines = <MYFILEIN>; close (MYFILEIN); } } return @lines;}
1; ///CSA_CoreLog.mdl/////APPL AAA_Log //NAME LogData E 1800 //SOURCE SOCK localhost//ATTRIBUTES Severity D 20 @ Severity Level of eventDate D 20 @ Date StampTime D 20 @ Time Stamp hh:mm:ss,cccThread D 50 @ Thread NameClass D 50 @ Class that raised eventEventData Z 256 @ Event Data
