目次 表示
以下のテキストは、カスタマイズされたデータストリームを Foundation フレームワークに入れるための、新規フィーダーとアダプターの開発方法を説明します。ソースを入力するとSNMPトラップになるでしょう。
アダプターは、JAVA ライブラリ(jarファイル)として配布されており、アダプターのコンパイルとパッケージのために JAVA SDK が必要です。チュートリアルでは構築ツールとして、ANT および MAVEN を使用します。Apache のサイトから ANT Maven のバイナリを取得することができます。チュートリアルでは、 http://sourceforge.net/projects/gwfoundation から利用可能なFoundationのソース配布を使用します。
開発ツールとFoundation のインストールと設定を行います。
Foundation がエラーなく起動することを確認します。
統合される必要のあるデータを定義します。
アプリケーションについて - SNMP トラップは別のアプリケーションとして扱われるので、新規 ApplicationType、SNMPTRAP を作成する必要があります。
エンティティタイプについ - SNMP トラップのメッセージは LogMessage テーブルに保存されるので、EntityType は LOG_MESSAGE になります。
保存されるフィールドデータについて - アプリケーションによって生成される属性を定義し、必要であれば値を特定し、必要ではない場合はデフォルト値にします。
表: 属性の定義
属性 |
タイプ |
プロパティ |
必要性/デフォルト値
|
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値がデフォルト。 |
アプリケーション固有のフィールドを選択します。フィールド一覧は定義が必要であり、エンティティタイプとして定義されるテーブルに付属するプロパティです。プロパティは、アプリケーション固有であり基本テーブルの一部ではありません。SNMP トラップに対する次のフィールドとタイプが格納されます。
表:属性の定義
プロパティ/名前 |
タイプ |
IpAddress |
String |
Event_OID_numeric |
String |
Event_OID_symbolic |
String |
Event_Name |
String |
Category |
String |
Variable_Bindings |
String |
データ統合のためのフィールドを選択します。この機能により LogMessage テーブル内の同一メッセージの件数が減ります。XML ストリームのフラグが統合判断基準の名前に設定(consolidate="SNMPTRAP")されていれば、データ挿入の際、統合判断基準が入ってくるメッセージに適応されます。デフォルトではどの判断基準も適応していません。もし判断基準が Log Message テーブル内にある既存のメッセージと合致した場合、既存メッセージのカウンターはインクリメントされ、データフィールドは以下のようにアップデートされます:
表:属性の定義
フィールド |
変更 |
FirstInsertDate |
変更なし |
LastInsertDate |
ReportDate |
ReportDate |
System (現在時間) |
以下はメッセージが統合される前、合致する必要のあるフィールドです:
OperationStatus
Host
Severity
IPaddress
MonitorStatus
Event_OID_numeric
Event_Name
Category
Variable_Bindings
データセットが定義されてプロパティと統合判断基準が定義されると、次のステップではデータベース Metadata をアップデートし、SNMP データ正規化のためのアダプターを書きます。
以下のデータベースアップデートは、新規アダプターとともに配布される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");
フィーダーは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 " />
展開したFoundationパッケージの中で、 collagefeeder/adapter ディレクトリへ移動して、新しいフォルダ snmp を作成します。
snmp ディレクトリ内に入り、source/java ディレクトリを作成します。
新たに 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>
以下のような 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>
src/java ディレクトリの下に下記のディレクトリを作成することで、新しいパッケージを作成します:com.groundwork.feeder.adapter.impl
ここで、SNMP アダプターを盛り込むための新しい java プロジェクトのセットアップが完了しました。次のステップではどのクラスを導入する必要があるかを示します。
アダプターは、クラス作成の adapter-api の一部であるFeederBase インタフェースを導入する必要があります:
新しいクラス SNMPTrap を FeederBase(注意:AdapterBase に名前変更されます)を導入する com/groundwork/feeder/adapter/impl の下に作成します。
アダプタ名を返す GetName を導入します。名前はリスナーに送信した XML フラグメントのノード名と一致する必要があります。SNMP トラップについては、それは SNMPTRAP です。
フレームワークによってアダプターがロードされ、アンロードされた場合に実行する必要があるすべてのアクションに initialize( ) と uninitialize( ) を導入します
アダプター名が SNMPTRAP である各入力 XML ストリームについて、フレームワークによって呼ばれるメソッド process( ) を導入します。このメソッドは、XML メッセージをデータベースの呼び出しに変換する正規化コードになります。主なステップとしては:
XML ストリームを解析して、属性を抽出します。utils.getAttributes()メソッドを使用します。
bean ファクトリから呼び出してAPI オブジェクトを取得します。
プロパティマップを作成し、API を呼び出します。
新規の SNMPTrap アダプタは、Springコンテナへ読み込まれます。src/java/META-INF ディレクトリで作成される spring アセンブリファイルが、JAR ファイルに含まれている必要があります:
snmp/src/java ディレクトリの内に、新規フォルダ META-INF を作成します。
META-INF の内に、assembly-adapter-snmptrap.xml ファイルを新規作成します。ファイルのサンプルは、「SNMPTrap アダプタのための Spring アセンブリ(Spring Assembly for SNMPTRAP Adapter)」下記ので参照が可能です。
adapter/snmp ディレクトリ内で、maven.jar を実行します。これにより、指定のディレクトリ内に jar ファイルが作成されます。maven.jar:install を実行します。これにより、jar ファイルがローカルレポジトリにコピーされます。
アダプタのコンパイルが完了したら、それをリスナーのインストールに配備する必要があり、adapter.properties は、新しいアダプターのエントリとともにアップデートされる必要があります。
jar ファイル collage-adapter-snmp-1.1.jar をリスナーのライブラリパス /usr/local/groundwork/collage/feeder/lib にコピーします。
新規のアダプター用に、adapter.properties を以下のように編集します:
最初にアセンブリのカウンターを増やします:
# Spring assemblies
nb.assemblies = 3
アセンブリの名前とBean プロパティの名前を追加します:
# SNMPTrap Beans
adapter.assembly3 = META-INF/assembly-adapter-snmptrap.xml
adapter.properties.assembly3 = SNMPTrapAdapterProperties
リスナーを起動します。
データをリスナーに読み込ませ、データベースにデータが出力されるかを確認します。エラーの有無についてログファイルをチェックします。
# 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')
次のファイル 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>
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
フィールドについての注意:
OperationStatus が定義されない場合、Open に設定されます。
ReportDate が設定されない場合、現在時間 (system) が使用されます。
MonitorStatus が定義されない場合、UNKNWON に設定されます。MonitorStatus はコンソール上では色で定義されます:OK = 緑, DOWN = 赤, WARNING = 黄, UNKNOWN = 青.
Host と ServiceDescription アトリビュートのために FeederScript に値を定義した場合、LogMessage は合致するServiceStatusに(Foreign Keyを経由して)リンクされます。これはイベントメッセージからサービスステータスへリンクするために、GroundWork Monitor Professional の UI の中で使用できます。
Host が設定された場合、LogMessage は HostStatus にリンクされます。
Host とService Description が設定されると、メッセージは既存の ServiceStatus エントリーにリンクされます。
FeederScript に Host アトリビュートのために値を定義すると、LogMessage は合致する HostStatus に(Foreign Keyを経由して)リンクされます。
データベース内に新規の 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
これはあるメッセージを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";
}