面向IBM Tivoli Monitor 6.1 Universal Agent的Socket解决方案(Perl语言实现)

    技术2022-05-11  70

    方案描述: 该方案是基于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


    最新回复(0)