square.gif GroundWork Foundation

homeicon.gif Print Page Send Comments

チュートリアル:理論から導入へ:実用的なSNMPトラップ用アダプター

目次 表示

Tutorialについて

Foundation アダプターの開発

以下のテキストは、カスタマイズされたデータストリームを Foundation フレームワークに入れるための、新規フィーダーとアダプターの開発方法を説明します。ソースを入力するとSNMPトラップになるでしょう。

開発環境

アダプターは、JAVA ライブラリ(jarファイル)として配布されており、アダプターのコンパイルとパッケージのために JAVA SDK が必要です。チュートリアルでは構築ツールとして、ANT および MAVEN を使用します。Apache のサイトから ANT Maven のバイナリを取得することができます。チュートリアルでは、  http://sourceforge.net/projects/gwfoundation から利用可能なFoundationのソース配布を使用します。

A. 始める前に

  1. 開発ツールとFoundation のインストールと設定を行います。

  2. Foundation がエラーなく起動することを確認します。

  3. 統合される必要のあるデータを定義します。

  4. アプリケーションについて - SNMP トラップは別のアプリケーションとして扱われるので、新規 ApplicationType、SNMPTRAP を作成する必要があります。

  5. エンティティタイプについ -  SNMP トラップのメッセージは LogMessage テーブルに保存されるので、EntityType は LOG_MESSAGE になります。

  6. 保存されるフィールドデータについて - アプリケーションによって生成される属性を定義し、必要であれば値を特定し、必要ではない場合はデフォルト値にします。

    表: 属性の定義

属性

タイプ

プロパティ

必要性/デフォルト値

 

Host

String

No

必須

Severity

Class Severity

No

必須

IpAddress

String

Yes

必須

MonitorStatus

Class Severity

No

Severityと同じ

ReportDate

Date

No

挿入された時間をデフォルトで設定

LastInsertDate

Date

No

挿入された時間をデフォルトで設定。SNMP_LOG messageで設定が可能です。

Event_OID_numeric

String

Yes

不要。NULL値がデフォルト。

Event_OID_symbolic

String

Yes

不要。NULL値がデフォルト。

Event_Name

String

Yes

 

不要。NULL値がデフォルト。

Category

String

Yes

不要。NULL値がデフォルト。

Variable_Bindings

String

Yes

不要。NULL値がデフォルト。

TextMessage

String

No

不要。NULL値がデフォルト。

  1. アプリケーション固有のフィールドを選択します。フィールド一覧は定義が必要であり、エンティティタイプとして定義されるテーブルに付属するプロパティです。プロパティは、アプリケーション固有であり基本テーブルの一部ではありません。SNMP トラップに対する次のフィールドとタイプが格納されます。

    表:属性の定義

プロパティ/名前

タイプ

IpAddress

String

Event_OID_numeric

String

Event_OID_symbolic

String

Event_Name

String

Category

String

Variable_Bindings

String

  1. データ統合のためのフィールドを選択します。この機能により LogMessage テーブル内の同一メッセージの件数が減ります。XML ストリームのフラグが統合判断基準の名前に設定(consolidate="SNMPTRAP")されていれば、データ挿入の際、統合判断基準が入ってくるメッセージに適応されます。デフォルトではどの判断基準も適応していません。もし判断基準が Log Message テーブル内にある既存のメッセージと合致した場合、既存メッセージのカウンターはインクリメントされ、データフィールドは以下のようにアップデートされます:
    表:属性の定義

フィールド

変更

FirstInsertDate

変更なし

LastInsertDate

ReportDate

ReportDate

System (現在時間)

以下はメッセージが統合される前、合致する必要のあるフィールドです:

データセットが定義されてプロパティと統合判断基準が定義されると、次のステップではデータベース Metadata をアップデートし、SNMP データ正規化のためのアダプターを書きます。

B. データベースのアップデート

以下のデータベースアップデートは、新規アダプターとともに配布される1つのデータベーススクリプトにまとめることができます。データベースにエントリーを挿入する前に、そのエントリの存在をチェックすることは常に必要です。すでにエントリが存在すると、異常終了します。しかし、チュートリアルの読みやすさから、これらのステップはドキュメント化されていません。新しいアプリケーショが作られたので、データベースにそのアプリケーションが追加される必要があります:
INSERT INTO ApplicationType(Name, Description) VALUES ("SNMPTRAP", "SNMP Trap application").

新規プロパティを作成し、ApplicatonType とEntityType を割り当てる必要があります:

INSERT INTO PropertyType(Name, Description, isString) VALUES ("ipaddress", "ipdddress of snmp device", 1);

INSERT INTO PropertyType(Name, Description, isString) VALUES ("Event_OID_numeric", "Event_OID_numeric", 1);

上記を、すべてのプロパティタイプに対して行って下さい。

INSERT INTO ApplicationEntityProperty(ApplicationTypeID, EntityTypeID, PropertyTypeID, SortOrder) VALUES ((SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP'),(SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE'),(SELECT PropertyTypeID FROM PropertyType WHERE Name = 'ipaddress'), 1);

INSERT INTO ApplicationEntityProperty(ApplicationTypeID, EntityTypeID, PropertyTypeID, SortOrder) VALUES ((SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP'),(SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE'),(SELECT PropertyTypeID FROM PropertyType WHERE Name = 'Event_OID_numeric'), 1);

上記を、すべてのプロパティに対して行って下さい。

統合判断基準に名前をつけ、一致フィールドの判断基準はセミコロン区切りのリストにする必要があります。

INSERT INTO ConsolidationCriteria(Name, Criteria) VALUES ("SNMPTRAP", "OperationStatus;Host;Severity;ipaddress, MonitorStatus; Event_OID_numeric;Event_Name;Category;Variable_Bindings");

C. フィーダの作成

フィーダーはSNMPトラップを捕捉し、監視するすべてのフィールドが Foudation リスナーコンポーネントに対する XML アトリビュートである XML フォーマットのメッセージを送ります。リスナーはソケットにメッセージ入ってくるのを待ちます。そのソケットは構成設定可能で、デフォルトではポート番号 4913 に設定されています。XML通信のSNMPトラップは以下の様になります:

<SNMPTRAP
MonitorServerName="localhost"
Host="cisco2900.itgroundwork.com"
Severity="Normal"
MonitorStatus="Normal"
ReportDate=""2005-10-25 04:20.44"
LastInsertDate="2005-10-25 04:20.44"
ipaddress="192.168.2.203"
Event_OID_numeric=".1.3.6.1.4.1.9.0.1"
Event_OID_symbolic="enterprises.9.0.1"
Event_Name="tcpConnectionClose"
Category="Status Events"
Variable_Bindings="enterprises.9.2.9.3.1.1.1.1:5 tcpConnState.192.168.2.203.23.192.168.2.249.38591:synReceived enterprises.9.2.6.1.1.5.192.168.2.203.23.192.168.2.249.38591:600 enterprises.9.2.6.1.1.1.192.168.2.203.23.192.168.2.249.38591:70 enterprises.9.2.6.1.1.2.192.168.2.203.23.192.168.2.249.38591:101 enterprises.9.2.9.2.1.18.1:"
TextMessage="A tty trap signifies that a TCP connection, previously established with the sending protocol entity for the purposes of a tty session, has been terminated. 5 synReceived 600 70 101 " />

D. アダプターの記述

Javaプロジェクトの作成

  1. 展開したFoundationパッケージの中で、 collagefeeder/adapter ディレクトリへ移動して、新しいフォルダ snmp を作成します。

  2. snmp ディレクトリ内に入り、source/java ディレクトリを作成します。

  3. 新たに maven.xml ファイルを作成します。以下を参照してください:

<project default="jar:install"

        xmlns:j="jelly:core"

        xmlns:maven="jelly:maven"

        xmlns:ant="jelly:ant">

                <goal name='distro'>

   <attainGoal name='clean'/>

   <attainGoal name='jar'/>

   <delete dir='./dist' />

   <mkdir dir='./dist' />

   <mkdir dir='./dist/lib' />

   <copy todir="./dist/lib" file="${maven.build.dir}/${maven.final.name}.jar"/>

   <j:forEach var="lib" items="${pom.artifacts}">

       <j:set var="dep" value="${lib.dependency}"/>

       <j:if test="${dep.getProperty('war.bundle')=='true'}">

           <copy todir="./dist/lib" file="${lib.path}"/>

       </j:if>

   </j:forEach>

 </goal>

  <goal name='allBuild'>

 <attainGoal name='distro'/>

 </goal>

</project>

  1. 以下のような project.xml ファイルを作成します。バージョンとライブラリは、主要プロジェクトファイルから継承されることに留意してください:

<project>

 <pomVersion>3</pomVersion>

 <extend>../project.xml</extend>

 <id>collage-adapter-snmp</id>

 <name>Groundwork Collage Adapters for SNMP</name>

 <package>com.groundwork.feeder</package>

   <build>

   <sourceDirectory>src/java</sourceDirectory>

    <resources>

     <resource>

       <directory>${basedir}/src/java</directory>

       <excludes>

         <exclude>**/*.java</exclude>

       </excludes>

     </resource>

   </resources>

 </build>

 </project>

 

  1. src/java ディレクトリの下に下記のディレクトリを作成することで、新しいパッケージを作成します:com.groundwork.feeder.adapter.impl  

    ここで、SNMP アダプターを盛り込むための新しい java プロジェクトのセットアップが完了しました。次のステップではどのクラスを導入する必要があるかを示します。

クラスとメソッドの上書き

アダプターは、クラス作成の adapter-api の一部であるFeederBase インタフェースを導入する必要があります:

  1. 新しいクラス SNMPTrap を FeederBase(注意:AdapterBase に名前変更されます)を導入する com/groundwork/feeder/adapter/impl の下に作成します。

  2. アダプタ名を返す GetName を導入します。名前はリスナーに送信した XML フラグメントのノード名と一致する必要があります。SNMP トラップについては、それは SNMPTRAP です。

  3. フレームワークによってアダプターがロードされ、アンロードされた場合に実行する必要があるすべてのアクションに initialize( ) と uninitialize( ) を導入します

  4. アダプター名が SNMPTRAP である各入力 XML ストリームについて、フレームワークによって呼ばれるメソッド process( ) を導入します。このメソッドは、XML メッセージをデータベースの呼び出しに変換する正規化コードになります。主なステップとしては:

SNMPTrapアダプタ用のSpringアセンブリ

新規の SNMPTrap アダプタは、Springコンテナへ読み込まれます。src/java/META-INF ディレクトリで作成される spring アセンブリファイルが、JAR ファイルに含まれている必要があります:

  1. snmp/src/java ディレクトリの内に、新規フォルダ META-INF を作成します。

  2. META-INF の内に、assembly-adapter-snmptrap.xml ファイルを新規作成します。ファイルのサンプルは、「SNMPTrap アダプタのための Spring アセンブリ(Spring Assembly for SNMPTRAP Adapter)」下記ので参照が可能です。

アダプターパッケージの作成

adapter/snmp ディレクトリ内で、maven.jar を実行します。これにより、指定のディレクトリ内に jar ファイルが作成されます。maven.jar:install を実行します。これにより、jar ファイルがローカルレポジトリにコピーされます。

E. SNMPTRAPアダプタのインストールと構成設定

アダプタのコンパイルが完了したら、それをリスナーのインストールに配備する必要があり、adapter.properties は、新しいアダプターのエントリとともにアップデートされる必要があります。

  1. jar ファイル  collage-adapter-snmp-1.1.jar をリスナーのライブラリパス /usr/local/groundwork/collage/feeder/lib にコピーします。

  2. 新規のアダプター用に、adapter.properties を以下のように編集します:
    最初にアセンブリのカウンターを増やします:

     

# Spring assemblies

nb.assemblies = 3

アセンブリの名前とBean プロパティの名前を追加します:

# SNMPTrap Beans

adapter.assembly3 = META-INF/assembly-adapter-snmptrap.xml

adapter.properties.assembly3 = SNMPTrapAdapterProperties

  1. リスナーを起動します。

  2. データをリスナーに読み込ませ、データベースにデータが出力されるかを確認します。エラーの有無についてログファイルをチェックします。

F. SNMPメタデータ作成用のSQLスクリプト

# Database changes for SNMPTRAP messages

# Add new ApplicationType for SNMPTRAP

DELETE FROM ApplicationEntityProperty WHERE ApplicationTypeID = (SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP') %% EntityTypeID = (SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE');

REPLACE INTO ApplicationType (Name, Description) VALUES ("SNMPTRAP","SNMP Trap application");

# Add the properties specific to SNMPTRAP

REPLACE INTO PropertyType(Name, Description, isString) VALUES ("IpAddress", "ipadddress of snmp device", 1);

 

REPLACE INTO PropertyType(Name, Description, isString) VALUES ("Event_OID_numeric", "Event_OID_numeric", 1);

 

REPLACE INTO PropertyType(Name, Description, isString) VALUES ("Event_OID_symbolic", "Event_OID_symbolic of snmp device", 1);

 

REPLACE INTO PropertyType(Name, Description, isString) VALUES ("Event_Name", "Event_Name", 1);

 

REPLACE INTO PropertyType(Name, Description, isString) VALUES ("Category", "Category of snmp device", 1);

 

REPLACE INTO PropertyType(Name, Description, isString) VALUES ("Variable_Bindings", "Variable_Bindings", 1);

# Assign the SNMP properties to Application Type SNMPTRAP and Entity LOG_MESSAGE

REPLACE INTO ApplicationEntityProperty(ApplicationTypeID, EntityTypeID, PropertyTypeID, SortOrder) VALUES ((SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP'),(SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE'), (SELECT PropertyTypeID FROM PropertyType WHERE Name = 'IpAddress'), 1);

 

REPLACE INTO ApplicationEntityProperty(ApplicationTypeID, EntityTypeID, PropertyTypeID, SortOrder) VALUES ((SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP'),(SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE'), (SELECT PropertyTypeID FROM PropertyType WHERE Name = 'Event_OID_numeric'), 1);

 

REPLACE INTO ApplicationEntityProperty(ApplicationTypeID, EntityTypeID, PropertyTypeID, SortOrder) VALUES ((SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP'),(SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE'),(SELECT PropertyTypeID FROM PropertyType WHERE Name = 'Event_OID_symbolic'), 1);

 

REPLACE INTO ApplicationEntityProperty(ApplicationTypeID, EntityTypeID, PropertyTypeID, SortOrder) VALUES ((SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP'), (SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE'),(SELECT PropertyTypeID FROM PropertyType WHERE Name = 'Event_Name'), 1);

 

REPLACE INTO ApplicationEntityProperty(ApplicationTypeID, EntityTypeID, PropertyTypeID, SortOrder) VALUES ((SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP'), (SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE'), (SELECT PropertyTypeID FROM PropertyType WHERE Name = 'Category'), 1);

 

REPLACE INTO ApplicationEntityProperty(ApplicationTypeID, EntityTypeID, PropertyTypeID, SortOrder) VALUES ((SELECT ApplicationTypeID FROM ApplicationType WHERE Name='SNMPTRAP'),(SELECT EntityTypeID FROM EntityType WHERE Name='LOG_MESSAGE'),(SELECT PropertyTypeID FROM PropertyType WHERE Name = 'Variable_Bindings'), 1);

#Create consolidation criteria

REPLACE INTO ConsolidationCriteria(Name, Criteria) VALUES ('SNMPTRAP', 'Host;Severity;IpAddress;MonitorStatus;Event_OID_numeric;Event_Name;Category;Variable_Bindings')

G. SNMPトラップアダプタ用のSpringアセンブリ

次のファイル assembly-adapter-snmptrap.xml は、META-INF内部のSNMPトラップアダプタのために  jar パッケージに含まれる必要があります:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!--

List all the BeanID that have implemented the initialize method. The bean ID's defined as a comma

separated list will be called during the loading of the assembly

-->

<bean id="SNMPTrapAdapterProperties" class="com.groundwork.feeder.adapter.impl.AdapterProperties">

<constructor-arg type="java.lang.String"><value>adapter.snmptrap</value></constructor-arg>

 </bean>

<bean id="adapter.snmptrap" singleton="false"

      class="com.groundwork.feeder.adapter.impl.SNMPTrap" />

</beans>

H. LOG4Jのフィーダー作成とログアダプターの使用方法

Foundation アダプターはデータが保存される前に、アプリケーションからのデータを正規化する Java で書かれたプラグインモジュールです。複雑なデータ構造については正規化が必要ですが、アプリケーションログを含む多くの外部からのログメッセージについては、いくつかの定義済みのフィールドを持つ簡単で一般的なアダプターで十分かもしれません。FoudationによってGenericLogアダプターが提供され、コードを記述しなくてもログデータをFoundationへ追加することができます。定義済みのフィールドに割り当てられた値は、ユーザが定義したアプリケーションタイプとしてデータベースに保管されます。以下の例は、(アプリケーションサーバに使用される)LOG4J を Foundation に読み込ませる方法を示しています。

一般的なログアダプターのインストールと使用

一般的なログアダプターは、Foundation のすべてのディストリビューションに含まれています。

定義

ログデータに対するアダプターの ApplicationType を定義しなくてはなりません。この例の場合、ApplicationType は LOG4J になりますが、これはユーザによる定義であり、他のタイプに調整してもかまいません。

アダプターのインプット

次の属性は、XML フィードの一部として必須です。設定がされていない場合、メッセージは受け取れません: ApplicationType, MonitorServerName, Device, Severity, TextMessage

必須のプロパティに加えて、次のプロパティは任意ですが、使用可能です: Host, MonitorStatus, ReportDate, OperationStatus, ApplicationSeverity, Component, Priority, ServiceDescription, Priority, TypeRule

フィールドについての注意:

システム設定

データベース内に新規の ApplicationType(LOG4J) を作成します:

リスナーを停止して、データベースを SQL 構文でアップデートします。GroundWork Monitor 内ではこのような記述は有効です:

コマンドラインから gwservices を停止してください:

# /usr/local/groundwork/ctlscript.sh stop gwservices

 MySQL command line:

> mysql -uroot -p GWCollageDB

 mysql> INSERT INTO ApplicationType (Name, Description) VALUES("LOG4J","LOG4J Events");

mysql> exit

GWService をスタートしてください:

# /usr/local/groundwork/ctlscript.sh start gwservices

I. フィーダーコード例

これはあるメッセージをEventテーブルに送る際に使用する、一番シンプルなスクリプトの例です:

#!/usr/local/groundwork/bin/perl --

#

#Copyright 2003-2004 Groundwork Open Source Solution.

#http://www.itgroundwork.com

#  

#Unless required by applicable law or agreed to in writing, software

#distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

#WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

#License for the specific language governing permissions and limitations under the License.

#

use IO::Socket;

my $debug =1 ;

my $remote_host = "localhost";

my $remote_port = 4913;

my $socket;

if ( $socket = IO::Socket::INET->new(PeerAddr => $remote_host,

                                                 PeerPort => $remote_port,

                                                 Proto    => "tcp",

                                                 Type     => SOCK_STREAM)

) {

my $xml_message = "<GENERICLOG ApplicationType='LOG4J' MonitorServerName='localhost' Host='dashboard.itgroundwork.com' Device='dashboard.itgroundwork.com' Severity='WARNING' MonitorStatus='WARNING' ErrorType='LogRotation' SubComponent='LOG4J Integrator' TextMessage='16:15:54,593 [WARN ] com.groundwork.collage.impl.LogMessageDAOImpl - Consolidation criteria matches with more than one record. Make sure the criteria is better defined. If the consolidation criteria was turned on after identical messages were inserted you have to run consolidate existing messages. Contact support for more information about database maintenance.' />" ;

              print $xml_message."\n\n" if $debug;

              print $socket $xml_message;

              my $xml_message = "<SERVICE-MAINTENANCE command=\"close\" />";

              print $xml_message."\n\n" if $debug;

              print $socket $xml_message;

             }  else {

      print "Couldn't connect to $remote_host:$remote_port : $@\n";

}