スクリプトプラグイン
Javaエージェントが提供するプラグインオプションを通じて、ユーザーが希望するコードをトレースデータに注入するか、メソッド実行前後に付加情報を追加する方法を提供します。メソッドの開始・終了時点で特定のコードを実行する場所を設定するオプションと、ユーザー定義型poolをモニタリングするためのクラス設定方法が含まれます。実際のプラグインの適用事例を通じて具体的な活用方法を提示し、モニタリングの柔軟性と細さを高める様々な設定例とAPIの使い方を案内します。
プラグインオプション
Javaエージェントプラグインは、メソッドの開始/終了部分に挿入して実行します。プラグインを適用する場所(クラス、メソッド)は、エージェントオプションで設定できます。
-
hook_trace_helper_start_patterns
メソッドの開始部分にトレースプラグインを挿入するポイント(クラス、メソッド)を設定します。プラグインコードは、_
$WHATAP_HOME
/plugin/TraceHelperStart.x_ファイルに記述してください。 -
hook_trace_helper_end_patterns
メソッドの最後にトレースプラグインを挿入するポイント(クラス、メソッド)を設定します。プラグインコードは、_
$WHATAP_HOME
/plugin/TraceHelperEnd.x_ファイルに記述してください。 -
hook_trace_helper_patterns
メソッドの開始/終了の両方にトレースプラグインを挿入するポイント(クラス、メソッド)を設定します。プラグインコードは、
$WHATAP_HOME
/plugin/TraceHelperStart.x, _$WHATAP_HOME
/plugin/TraceHelperEnd.x_ファイルにそれぞれ記述してください。 -
custom_pool_classes
ユーザー定義プールをモニタリングするには、プール使用量の情報を含むクラスを設定します。プラグインコードは、_
$/WHATAP_HOME
/plugin/CustomPool.x_に作成します。
プラグインの設定例
複数のクラスを設定する場合は、コンマ(,)を区切り文字として利用してください。パッケージ名の文字列の一部または全部を「*」に置き換えることができます。
-
パッケージとメソッド名を設定する場合
whatap.bytecode.instrument.PluginTestA.testA,whatap.bytecode.instrument.PluginTestB.testB
-
パッケージとメソッド名を
*
に置き換える場合*PluginTestA.testA,whatap.bytecode.instrument.PluginTestB.*
*.testA, *PluginTestB.testB
-
全体を対象とする場合
*.*
-
Custom Poolを設定する場合
Custom Poolは、識別子@パッケージ名の形に設定します。
例)Class名の前に
whatap_plugin_guide
という識別子を設定します。識別子とクラスは@で区切ります。whatap_plugin_guide@com.ibm.ws.connectionpool.monitor.ConnectionPoolStats
プラグインコードの作成例
ほとんどの場合はオブジェクトを返すので、明示的な型変換処理が必要です。以下はプラグインコードの作成例です。
設定したメソッド開始時間をトレースに記録する
-
Javaエージェント
hook_trace_helper_patterns
オプションに適用するメソッドをwhatap.confファイルに記述してください。$WHATAP_HOME/whatap.confhook_trace_helper_patterns=org.apache.catalina.connector.RequestFacade.*
-
TraceHelperStart.xファイルにプラグインコードを作成します。
$WHATAP_HOME/plugin/TraceHelperStart.x// String prefixにクラス名、メソッド名を代入します。
String prefix = $point.class1 + "." + $point.method;
// WhaTapトレース属性名称を`prefix` + "st"にして現在の時間を設定します。
$ctx.setAttribute(prefix + "st", new Long(System.currentTimeMillis()));
// トレース情報に現在の時間を追加します。
$ctx.profile(prefix + " Start", new java.util.Date().toString());
トレース履歴にメソッドの開始時間を次のように表示します。
設定したメソッド終了時間と実行時間をトレースに記録する
-
Javaエージェント
hook_trace_helper_patterns
オプションに適用するメソッドをwhatap.confファイルに記述してください。$WHATAP_HOME/whatap.confhook_trace_helper_patterns=org.apache.catalina.connector.RequestFacade.*
-
_TraceHelperEnd.x_ファイルにプラグインコードを作成します。
$WHATAP_HOME/plugin/TraceHelperEnd.xString prefix = $point.class1 + "." + $point.method;
// TraceHelperStart.xファイルで追加したトレース属性を取得します。
long st = ((Long) $ctx.getAttribute(prefix + "st")).longValue();
long gap = System.currentTimeMillis() - st;
StringBuilder sb = new StringBuilder();
sb.append(new java.util.Date().toString() + " (Gap:" + gap + " milliseconds)");
// トレース情報に開始時間と現在時間とのGap(実行時間)を追加します。
$ctx.profile(prefix + " End", sb.toString());
トレース履歴にメソッド終了時間と実行時間を次のように表示します。
プラグインAPI
プラグインAPIは、共通項目である$ctx
、$point
、$req
、$res
で区分します。トランザクション開始/終了時、HTTPC間隔、特定メソッドの実行間隔などに適用できます。
プラグインAPIを使用して個人識別情報の保存を禁止し、個人情報収集時にその内容を個人情報処理方針に明示する必要があります。
パラメータ提供 - 共通プラグインファイル
パラメータ | メソッド/変数 | 説明 |
---|---|---|
$ctx | 属性管理 | |
void setAttribute(String key, Object value) | Attributeを設定します。 | |
Object getAttribute(String key) | Attributeの値を取得します。 | |
トレースデータ | ||
void profile(String desc) | トレースメッセージ記録 | |
void profile(String name, String msg) | トレースStep名、メッセージの記録 | |
void profile(String name, String msg, int elapsed) | トレースStep名、メッセージ、実行時間の記録 | |
void profile(String name, String msg, int elapsed, int value) | トレースStep名、メッセージ、実行時間、順序の記録 | |
HTTP Request | ||
String service() | サービス名をリターン | |
void service(String name) | サービス名の設定 | |
int serviceHash() | サービス名のHash値リターン | |
String remoteIp() | サービスリクエストIPリターン | |
void remoteIp(String ip) | サービスリクエストIPを設定 | |
boolean isError() | エラーの有無のリターン | |
void login(String id) | ログインID設定 | |
String login() | ログインIDのリターン | |
String httpMethod() | HTTP Methodリターン | |
String httpQuery() | HTTP Queryリターン | |
String httpContentType() | HTTP ContentTypeリターン | |
String userAgent() | User-Agentリターン | |
int status() | HTTP statusリターン | |
$point | String class1 | クラス名 |
String method | メソッド名 | |
Object this1 | Hooking対象クラス・メソッド | |
Object[] args | ファクター | |
Object return1 | リターン |
パラメータ未指定 - 共通プラグインファイル
パラメータ | メソッド/変数 | 説明 |
---|---|---|
無し | void log(Object c) | LoggerによるLogging |
void println(Object c) | System.out.println()で出力 | |
Object field(Object o, String field) | Field値をリターン | |
Object method(Object o, String method) | Invokeメソッド | |
Object method(Object o, String method, String param) | Invokeメソッド | |
String toString(Object o) | ObjectをtoSting() にリターン | |
String toString(Object o, String def) | ObjectをtoSting() にリターン、nullの場合def リターン | |
int syshash(Object o) | hash値リターン | |
int syshash(HookArgs hook, int x) | x番目のargumentのhash 値リターン | |
int syshash(HookArgs hook) | argumentのhash値リターン | |
int cint(Object o) | intでリターン | |
float cfloat(Object o) | floatでリターン | |
String cString(Object o) | Stringでリターン | |
long clong(Object o) | longでリターン | |
double cdouble(Object o) | doubleとしてリターン | |
String desc(Object o) | Class signatureをリターン | |
String toJson(Object o) | jsonでリターン | |
void shell(final String cmd, final String env) | shell実行 |
デーモンおよびバッチ
デーモン、バッチなどのアプリケーション サーバーをモニタリングする場合、開始点として設定したメソッドに適用するAPIです。次のファイルにコードを作成します。
- サービス開始部分適用:
$WHATAP_HOME
/plugin/AppServiceStart.x - サービス終了部分適用:
$WHATAP_HOME
/plugin/AppServiceEnd.x
プラグインファイル | パラメータ | メソッド/変数 | 説明 |
---|---|---|---|
AppServiceStart.x | $ctx | 共通属性を参照 | |
$point | 共通属性を参照 | ||
AppServiceEnd.x | $ctx | 共通属性を参照 |
HTTPサービス
javax.servlet.http.HTTPServlet
クラスを使用する一般的なウェブアプリケーションに適用できるAPIです。次のファイルにコードを作成します。
- サービス開始部分適用:
$WHATAP_HOME
/plugin/HttpServiceStart.x - サービス終了部分適用:
$WHATAP_HOME
/plugin/HttpServiceEnd.x
プラグインファイル | パラメータ | メソッド/変数 | 説明 |
---|---|---|---|
HttpServiceStart.x/ HttpServiceEnd.x | $ctx | 共通属性を参照 | |
$req | String getCookie(String key) | Cookie値リターン | |
String getRequestURI() | RequestURIリターン | ||
String getRemoteAddr() | RemoteAddrリターン | ||
String getMethod() | HTTP Methodリターン | ||
String getQueryString() | HTTP QueryStringリターン | ||
String getParameter(String key) | Parameter値リターン | ||
Object getAttribute(String key) | Attribute値リターン | ||
String getHeader(String key) | Header値リターン | ||
Enumeration getParameterNames() | getParameterNamesリターン | ||
Enumeration getHeaderNames() | getHeaderNamesリターン | ||
WrSession getSession() | Session Wrapperリターン | ||
Set getSessionNames() | getSessionNamesリターン | ||
Object getSessionAttribute(String key) | getSessionAttributeリターン | ||
boolean isOk() | Plugin状態リターン | ||
Throwable error() | Errorリターン | ||
$res | String getContentType() | ContentTypeリターン | |
String getCharacterEncoding() | CharacterEncodingリターン | ||
boolean isOk() | Plugin状態リターン | ||
Throwable error() | Errorリターン |
HTTP Outbound
HttpClient
などのライブラリを使用してHTTP Outbound Callを実行するときに適用できるAPIです。次のファイルにコードを作成します。
- サービス開始部分適用:
$WHATAP_HOME
/plugin/HttpCallStart.x - サービス終了部分適用:
$WHATAP_HOME
/plugin/HttpCallEnd.x
プラグインファイル | パラメータ | メソッド/変数 | 説明 |
---|---|---|---|
HttpCallStart.x | $ctx | 共通属性を参照 | |
$req | String url() | URLリターン | |
String host() | Hostnameリターン | ||
int port() | Portリターン | ||
boolean isOk() | Plugin状態リターン | ||
Throwable error() | Errorリターン | ||
HttpCallEnd.x | $ctx | 共通属性を参照 | |
$res | String getContentType() | ContentTypeリターン | |
String getCharacterEncoding() | CharacterEncodingリターン | ||
boolean isOk() | Plugin状態リターン | ||
Throwable error() | Errorリターン |
特定メソッド
Javaエージェントオプション(hook_trace_helper_*
)で設定したメソッドに適用するAPIです。
プラグインファイル | パラメータ | メソッド/変数 | 説明 |
---|---|---|---|
TraceHelperStart.x | $ctx | 共通属性を参照 | |
$point | 共通属性を参照 | ||
TraceHelperEnd.x | $ctx | 共通属性を参照 | |
$point | 共通属性を参照 |
ユーザー定義Pool
ユーザー定義プールをモニタリングするためのAPIです。プール使用量の情報を使用してメソッドを設定すると、WhaTapモニタリングサービスで監視し、統計情報を確認できます。
プラグインファイル | パラメータ | メソッド/変数 | 説明 |
---|---|---|---|
CustomPool.x | $id | custom_pool_classesに設定したID値 | |
$pool | custom_pool_classesに設定したclass | ||
$result | active(Object o) | Active Pool Count設定 | |
int idle(Object o) | Idle Pool Count設定 |
プラグインの適用例
以下は、実際プラグインの適用例です。
Elasticsearchエンジンの検索要求モニタリング
Elasticsearch(以下ES) エンジンは、サブレットエンジンではないため、非定型モニタリングを行う必要があります。他の製品が指標中心のモニタリングをする場合、WhaTapのプラグインを使用して、ESの要請および処理時間、検索キーワードを追跡できます。
# トランザクションEndPointとしてorg.elasticsearch.search.SearchService.executeQueryPhaseを設定します。
hook_service_patterns=org.elasticsearch.search.SearchService.executeQueryPhase
# hook_trace_helper_start_patternsに登録されたメソッドが実行されるたびにTraceHelperStart.xファイルのコードを実行します。
hook_trace_helper_start_patterns=org.elasticsearch.search.query.QueryPhase.execute
if ($ctx.inner() == null) {
return;
}
try {
String tclass = "org.elasticsearch.search.query.QueryPhase";
String tmethod = "execute";
if (tclass.equals($point.class1) && tmethod.equals($point.method)) {
// 一番目のargumentのqueryメソッドの呼び出し結果をString queryに保存、
// org.elasticsearch.search.query.QueryPhase.execute(SearchContext searchContext)です。
// それから、SearchContext.query()メソッドをinvokeした結果をString queryに保存します。
String query = " " + method($point.args[0], "query");
// String queryをトレース情報として出力
$ctx.profile(query);
}
} catch(Exception e) {
$ctx.profile(e.toString());
}
特定のIPで流入されるトランザクションの収集を除外
Health Check、内部ユーザーによるトランザクションの収集を除外する場合は、プラグインを使用できます。
// ignoreIP値を収集するIPとして設定します。
String ignoreIP = "123.234.123.234";
String remoteIP = $req.getRemoteAddr();
if ($ctx.ok() && remoteIP != null) {
if (remoteIP.equals(ignoreIP)) {
$ctx.ignore();
}
}
Atomikos Poolモニタリング
API文書を参照して適用してください。
custom_pool_classes=atomikos@com.atomikos.jdbc.internal.AbstractDataSourceBean
int total = cint(method($pool,"poolTotalSize"));
int avail = cint(method($pool,"poolAvailableSize"));
$result.active(total - avail);
$result.idle(avail);
トレースにCookie値を表現
クッキーの値をトレースから確認できます。
// $req.getCookie() パラメータで確認したいCookieを設定してください。
String cookie = $req.getCookie("AWSALB");
if ($ctx.ok()) {
if (cookie != null) {
$ctx.profile(cookie);
}
}