Download PDF
Download page IoT Java SDKでのアプリケーションのインストゥルメンテーション.
IoT Java SDKでのアプリケーションのインストゥルメンテーション
IoT Java SDK は、ゲートウェイ、POS、車のインフォテインメント センターなどのエッジデバイスで実行されている IoT Java アプリケーションに含めることができます。ここでは、Java SDK をインストールし、IoT アプリケーションをインストゥルメント化する方法について説明します。
EUM アプリケーションキーを取得し、IoT C/C++ アプリケーションをインストゥルメント化するには、次の手順を実行します。
この Java SDK は、よりローエンドデバイス向けに特別に設計された非常に軽量なライブラリである点で、AppDynamics Java エージェントとは異なります。また、イベント情報を拡張でき、インストゥルメンテーション コードを設定および制御できるように多くの柔軟性が組み込まれています。
要件の確認
開始する前に、次の要件を満たしていることを確認します。
デバイスが次のいずれかのバージョンの Java ランタイムを実行していること。
Java SE 7
Java SE Embedded 7
Java SE 8
Java SE Embedded 8
- EUM サーバにビーコンを送信する HTTPS インターフェイス
- EUM アプリケーションキー
IoT Java SDK の取得
Java SDK は、GitHub から IoT Java SDK を複製またはダウンロードすることによって取得できます。「Build the SDK」に記載されている手順に従って、IoT Java SDK をビルドします。
IntelliJ IDE を使用している場合は、「Working with module dependencies」に記載されている手順に従ってファイル lib/appd-iot-sdk.jar
をプロジェクトに追加します。IntelliJ プロジェクトの [External Projects] の下に JAR ファイルが表示されていることを確認します。
IoT Java SDK のアップグレード
GitHub から IoT Java SDK のクローンのルートディレクトリで、次のようにします。
- 次のリポジトリを更新します。
$ git pull origin master
- 「Build the SDK」に記載されている手順に従って、IoT Java SDK を再構築します。
Gradle 構成への SDK 依存関係の追加
build.gradle
ファイルに以下を追加します。
dependencies {
runtime group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
runtime group: 'com.google.guava', name:'guava', version:'18.0'
runtime group: 'com.google.code.gson', name: 'gson', version: '2.8.0'
}
インストゥルメンテーション コードの追加
IoT SDK のインポート
アプリケーションファイルで、Java IoT SDK を含む import
ステートメントを追加します。
import com.appdynamics.iot.Instrumentation;
IoT Java エージェントの構成
EUM アプリケーションキーと URL を EUM コレクタに提供することによってインストゥルメンテーションを構成します。EUM コレクタ URL が指定されていない場合は、デフォルトの SaaS コレクタ URL が使用されます。
各地域の EUM コレクタ URL については、「Cisco AppDynamics SaaS Domains and IP Ranges」を参照してください。EUM コレクタ URL が指定されていない場合は、デフォルトの SaaS コレクタ URL が使用されます。
import com.appdynamics.iot.AgentConfiguration;
AgentConfiguration.Builder agentConfigBuilder = AgentConfiguration.builder();
AgentConfiguration agentConfig = agentConfigBuilder
.withAppKey(<EUM_APP_KEY>)
.build();
デバイス情報の設定
デバイスの名前と ID を設定する必要があります。名前は、「EV Model 3」や「Thermostat Model Star7」など、デバイスのタイプとモデルを識別する短い文字列で構成されている必要があります。デバイス ID は、UUID、車の VIN 番号、またはデバイスの MAC アドレスなど、デバイスの一意の識別子である必要があります。
次のコード例では、デバイス ID をランダム UUID に、名前を「Smart Shelf」に設定しています。
import java.util.UUID;
import com.appdynamics.iot.DeviceInfo;
...
DeviceInfo.Builder deviceInfoBuilder = DeviceInfo.builder("Smart Shelf P1", UUID.randomUUID().toString());
DeviceInfo deviceInfo = deviceInfoBuilder.withDeviceName("Smart Shelf").build();
バージョン情報の設定
次に示すように、ファームウェア、ハードウェア、OS、およびソフトウェアのバージョンを設定できます。
import com.appdynamics.iot.VersionInfo;
...
VersionInfo.Builder versionInfoBuilder = VersionInfo.builder();
VersionInfo versionInfo = versionInfoBuilder
.withFirmwareVersion("2.3.4")
.withHardwareVersion("1.6.7")
.withOsVersion("8.9.9")
.withSoftwareVersion("3.1.1").build();
エージェントの初期化
エージェントを初期化するには、AgentConfiguration
オブジェクト、DeviceInfo
オブジェクト、および VersionInfo
オブジェクトを start
メソッドに渡します。
Instrumentation.start(agentConfig, deviceInfo, versionInfo);
アプリケーションの構築と実行
お気に入りの Java IDE または CLI 環境を使用し、アプリケーションを構築して実行します。AppDynamics IoT Java SDK は、ビルドおよびランタイムのクラスパスにある必要があることに注意してください。
クラスパスにライブラリを追加する手順については、次を参照してください。
IntelliJ IDE:「Creating a library」
Eclipse:「Classpath Variables」
Linux/Mac/Windows:「PATH and CLASSPATH」
アプリケーションを構築して実行する手順については、次を参照してください。
- IntelliJ:「Building and Running the Application」
- Eclipse:「Running your programs」
- Gradle:「Building Java Projects with Gradle」
イベントの追加と送信
以下のセクションでは、サポートされているイベント(カスタム、ネットワークリクエスト、エラー)を作成して送信する方法について説明します。
基本的なカスタムイベントの作成
カスタムイベントを使用すると、パフォーマンス、デバイス、またはビジネスロジックデータを報告できます。これは、使用できる最も一般的で設定可能かつ柔軟性の高いデータ型です。
カスタムイベントビルダーには 2 つの必須パラメータがあります。
- Event Type:短くわかりやすいイベントの説明(「FL Pressure Drop」など)。
- Description:イベントを説明する文字列(「Front Left Tire Pressure Drop」など)。
このイベントの報告を有意義にするには、タイムスタンプと、1 つ以上のデータ型を指定することを推奨します。
基本的なカスタムイベントを作成します。
import com.appdynamics.iot.events.CustomEvent; ... CustomEvent.Builder builder = CustomEvent.builder("FL Pressure Drop", "Front Left Tire Pressure Drop"); long eventStartTime = System.currentTimeMillis(); long duration = 6000; builder.withTimestamp(eventStartTime).withDuration(duration); builder.addLongProperty("PSI Drop", 37); CustomEvent customEvent = builder.build();
JAVA追加の情報は
CustomEvent
に追加できます。詳細については、最新の Java IoT SDK ドキュメントのCustomEvent
クラスを参照してください。カスタムイベントをインストゥルメンテーションに追加します(これにより、インメモリバッファに追加されます)。
Instrumentation.addEvent(customEvent);
JAVAすべてのイベントを EUM サーバに送信します。これはブロッキングコールであるため、アプリケーションは上記のように別のスレッドで送信できます。
Instrumentation.sendAllEvents();
JAVA
ネットワークイベントの送信
HttpRequestTracker
クラスを使用してネットワーク リクエスト イベントを報告します。このコールはインメモリバッファにイベントを自動的に追加するため、クラスを明示的にインポートする必要があります。import com.appdynamics.iot.HttpRequestTracker; ... String url = "http://ip.jsontest.com/?callback=showMyIP"; // Add a Network Event try { URL thisUrl = new URL(url); // [AppDynamics Instrumentation] Get a Tracker HttpURLConnection con = (HttpURLConnection) thisUrl.openConnection(); final HttpRequestTracker tracker = Instrumentation.beginHttpRequest(thisUrl); con.setRequestMethod("POST"); con.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); int responseCode = con.getResponseCode(); con.setDoInput(true); con.setDoOutput(true); DataOutputStream wr = new DataOutputStream(con.getOutputStream()); wr.flush(); wr.close(); System.out.println("Response Code :" + responseCode); // [AppDynamics Instrumentation] Retrieve the headers from the response Map<String, List<String>> headerFields = null; System.out.println("Sending 'POST' request to URL :" + url); BufferedReader in; String inputLine; new InputStreamReader(con.getErrorStream())); if (responseCode >= 200 && responseCode < 300) { in = new BufferedReader(new InputStreamReader(con.getInputStream())); } else { in = new BufferedReader( } StringBuffer response = new StringBuffer(); if (headerFields != null && headerFields.size() > 0){ while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); // [AppDynamics Instrumentation] Initiate adding NetworkRequestEvent if (responseCode >= 200 && responseCode < 300) { tracker.withResponseCode(responseCode).withError(response.toString()).reportDone(); .withResponseHeaderFields(headerFields) .reportDone(); } else { tracker.withResponseCode(responseCode).reportDone(); } } else { tracker.withResponseCode(responseCode) } // End: Add for AppDynamics Instrumentation - Initiate adding NetworkRequestEvent } catch (MalformedURLException e) { e.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); }
JAVAすべてのイベントを EUM サーバに送信します。これはブロッキングコールです。アプリケーションは、別のスレッドで送信できます。
sendAllEvents
メソッドを呼び出す前に、複数のイベントをまとめてバッチ処理することを推奨します。Instrumentation.sendAllEvents();
JAVA
エラーイベントの送信
API を使用してエラーイベントを報告します。
try { //Force creating an exception float f = (5 / 0); } catch (Throwable t) { Instrumentation.addErrorEvent(t, Instrumentation.Severity.ALERT); }
JAVAすべてのイベントを EUM サーバに送信します。これはブロッキングコールです。アプリケーションは、別のスレッドで送信できます。
Instrumentation.sendAllEvents();
JAVA
コントローラ UI でのインストゥルメンテーションの確認
「IoT アプリケーションがコントローラにデータをレポートしたことの確認」を参照してインストゥルメンテーションを確認します。
ビジネストランザクションをネットワークリクエストと関連付ける(オプション)
ビジネストランザクション(BT)をネットワークリクエストと関連付けるには、ビジネスアプリケーションをインストゥルメント化し、コントローラ UI でビジネストランザクションを有効にしておく必要があります。詳細については、「IoT モニタリング用のビジネストランザクションの相関」を参照してください。
次の手順では、BT 応答ヘッダーを取得し、それらを使用して、その BT を IoT ネットワーク リクエスト イベントと関連付ける方法について説明します。
AppDynamics HTTP リクエストヘッダー
ADRUM
とADRUM_1
を含むネットワークリクエストをビジネスアプリケーションの 1 つに対して作成します。import com.appdynamics.iot.HttpRequestTracker; ... // Create a network request to the business app. String url = "<url_to_business_application>"; URL thisUrl = new URL(url); [AppDynamics Instrumentation] Get a Tracker HttpURLConnection con = (HttpURLConnection) thisUrl.openConnection(); final HttpRequestTracker tracker = Instrumentation.beginHttpRequest(thisUrl); con.setRequestMethod("POST"); // Some HTTP method: GET, POST, PUT... // Add the AppDynamics HTTP headers ADRUM and ADRUM_1 to the request. con.setRequestProperty("ADRUM", "isAjax:true"); con.setRequestProperty("ADRUM_1", "isMobile:true"); // Make the request to your business app. con.setDoInput(true);
JAVAコールは、関連するビジネストランザクションの情報を含む応答ヘッダーを返します。これらの BT 応答ヘッダーを出力する場合は、次のように表示されます。
{ ADRUM_1=[globalAccountName:customer1_78203698-278e-428f-8726-bb381219c6cb], null=[HTTP/1.1 200 OK], ADRUM_0=[clientRequestGUID:2ff45113-6746-4c94-b6d0-4af26055613c], ADRUM_3=[btERT:269], ADRUM_2=[btId:4423], Server=[Jetty(9.4.z-SNAPSHOT)], ADRUM_5=[btDuration:327], ADRUM_4=[serverSnapshotType:f], Content-Length=[514], }
JAVABT 応答ヘッダーを含むビーコンを EUM サーバに送信します。
// Fetch the response headers, which will include the BT headers (ADRUM_0, ADRUM_1, ...). Map<String, List<String>> headerFields = con.getHeaderFields(); // Add the BT response headers to the request body of the Network Request event. // that you're reporting. tracker.withResponseCode(responseCode).withError(response.toString()).reportDone(); .withResponseHeaderFields(headerFields) .reportDone(); // Report the Network Request event to the EUM Server. Instrumentation.sendAllEvents();
JAVAコントローラ UI では、関連するビジネストランザクションを [Device Details] ダイアログで確認できます。
SDK のロギングを有効にする(オプション)
IoT Java SDK は、ロギングフレームワークとして Java(SLF4J)用シンプルロギングファサードを使用します。SLF4J と互換性のあるお気に入りのロギングエンジンを使用できます。
クラスパスでバインドが見つからない場合、SLF4J はデフォルトで非動作の実装になり、次のようなコンソールメッセージが表示されます。
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation // SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
java.util.logging
エンジンを使用するには、build.gradle
ファイルに次の行を追加します。
dependencies {
....
runtime group: 'org.slf4j', name: 'slf4j-jdk14', version: '1.7.25'
....
}
ライブラリからすべてのデバッグメッセージを表示するには、ファイル /Library/Java/JavaVirtualMachines/<your-jdk-version>/Contents/Home/jre/lib/logging.properties
の下部に次の行を追加します。
com.appdynamics.iot.level = FINEST
IoT Java インストゥルメンテーションのカスタマイズ(オプション)
IoT Java SDK を使用して、IoT Java インストゥルメンテーションをさらにカスタマイズできます。最新の IoT Java SDK ドキュメント、または以下に記載されている以前のバージョンを参照してください。
- https://sdkdocs.appdynamics.com/javadocs/iot-java-sdk/4.5/4.5.0/
- https://sdkdocs.appdynamics.com/javadocs/iot-java-sdk/4.5/4.5.1/
- https://sdkdocs.appdynamics.com/javadocs/iot-java-sdk/4.5/4.5.2/
- https://sdkdocs.appdynamics.com/javadocs/iot-java-sdk/4.5/4.5.4/
サンプル Java アプリケーションの実行
サンプル Java アプリケーションは、カスタム、ネットワークリクエスト、およびエラーイベントのサンプルデータを送信します。データは、スマート カー アプリケーションをモックし、使用状況情報、ネットワークパフォーマンス、およびエラーをキャプチャします。
サンプルアプリケーションを実行するには、iot-java sdk GitHub リポジトリに記載されている「Getting Started」の手順に従います。
IoT Java SDK のトラブルシューティング
ここでは、一般的な問題をデバッグする手順について説明します。
IoT Java エージェントをリンクできません
IoT Java エージェントをリンクしようとしたときに次のエラーが発生した場合は、log4j.
での依存関係が原因です。
loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of com/intellij/ide/plugins/cl/PluginClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of com/intellij/util/lang/UrlClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of com/intellij/ide/plugins/cl/PluginClassLoader) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of com/intellij/util/lang/UrlClassLoader) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:273)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:241)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:254)
at com.appdynamics.iot.Instrumentation.<clinit>(Instrumentation.java:39)
...
この問題を修正するには、ロギングを有効にするために追加した依存関係を削除する必要があります。したがって、次に示すグループ org.slf4j
を指定する行を dependencies:
から削除します。
dependencies {
....
runtime group: 'org.slf4j', name: 'slf4j-jdk14', version: '1.7.25'
....
}