このページでは、Go SDK の使用手順と概要を説明します。Go SDK には、AppDynamics のビジネストランザクション、トランザクション スナップショット、バックエンド、終了コールの作成と管理を行うためのルーチンが用意されています。 

はじめる前に

Go SDK を使用してアプリケーションをインストゥルメント化する前に、Go SDK の最新バージョンを入手する必要があります。SDK をインストールするには、「Go SDK のインストール」および「Cisco AppDynamics ソフトウェアのダウンロード」を参照してください。  

アプリケーションへの Splunk AppDynamics パッケージのインポート

SDK をダウンロードすると、Go アプリケーションに Splunk AppDynamics インストゥルメンテーションを追加する準備ができます。最初のステップでは、Splunk AppDynamics パッケージをインポートします。

import appd "appdynamics"
CODE

コントローラ構成の初期化

コントローラ情報の設定では、 SDKからコントローラへの接続が許可されています。一部の設定はすべてのアプリケーションで必須ですが、その他の設定は特定のタイプのアプリケーション環境でのみ必要です。たとえば、 SDK からネットワーク内の内部プロキシ経由でコントローラに接続する必要がある場合は、プロキシの接続設定を行います。設定および必須の設定の完全なリストについては、「Go SDK 参考資料」を参照してください。

アプリケーションで、必須の設定に値を割り当てます。コントローラの接続情報を設定する例:

cfg := appd.Config{}
 
cfg.AppName = "exampleapp"
cfg.TierName = "orderproc"
cfg.NodeName = "orderproc01"
cfg.Controller.Host = "my-appd-controller.example.org"
cfg.Controller.Port = 8090
cfg.Controller.UseSSL = false
cfg.Controller.Account = "customer1"
cfg.Controller.AccessKey = "secret"
cfg.InitTimeoutMs = 1000  // Wait up to 1s for initialization to finish
CPP


[InitTimeoutMs] フィールドに注意してください。構成を初期化したら、
InitSDK() を使用してエージェントを初期化するコールに構成オブジェクトを渡します。[InitTimeoutMs] フィールドには、次の値を設定できます。

  • 0 に設定すると(デフォルト)、InitSDK() 関数は非同期アクションとして動作するので、初期化コールはプログラムをブロックしません。 
  • 値を -1 に設定すると、エージェントがコントローラ構成を受信するまで無期限に待機するようにプログラムが指示されます。つまり、InitSDK() メソッドは control を返します。アプリケーションの起動時に発生する短時間のビジネストランザクションをキャプチャし、コントローラから構成が送信されるまでの待機時間が延びても問題ない場合は、役に立ちます。 
  • または、待機する特定のミリ秒数に設定します。 

マルチテナントコントローラ(SaaS またはオンプレミスマルチテナント)を使用する場合は、AddAppContextToConfig() メソッドを使用してマルチテナント環境用のコンテキストを作成する必要があります。これによりコンテキストは、特定の操作(ビジネストランザクションの開始やカスタムメトリックの追加など)を実行するメソッドへのパラメータとして渡すことができます。AddAppContextToConfig() および関連メソッドの詳細については、「Go SDK 参考資料」を参照してください。

エージェントの初期化

main 関数で、InitSDK() に構成構造体を渡してエージェントを初期化します。

InitSDK()nil を返す場合、エージェントは正常に初期化されています。エラーが返ってくる場合は、エージェントがコントローラに接続できなかった可能性が高くなります。

たとえば、SDK を初期化するには、次の手順を実行します。

if err := appd.InitSDK(&cfg); err != nil {
	fmt.Printf("Error initializing the AppDynamics SDK\n")
} else {
	fmt.Printf("Initialized AppDynamics SDK successfully\n")
}
CPP

ビジネストランザクションの作成

StartBT() コールと EndBT() コールの間に、モニター対象のリクエストで構成されるコードを囲んで、ビジネストランザクションを定義します。そのビジネストランザクションが影響を受ける後続のルーチンで使用されるハンドルが StartBT() から返されます。 

アップストリームのビジネストランザクションと相関するビジネストランザクションを作成する場合は、アップストリームのトランザクションの相関ヘッダーを渡して、作成する新しいトランザクションと関連付けることができます。GetExitcallCorrelationHeader() については、「Go SDK 参考資料」を参照してください。トランザクションと別のトランザクションを相関させる必要がない場合は、相関ヘッダーパラメータとして空の文字列を渡します。

オプションで、ビジネス トランザクション ハンドルを GUID とともにグローバル ハンドル レジストリに格納すると、後で StoreBT() を使用して簡単に取得できます。using GetBT() によって、グローバル ハンドル レジストリからハンドルを取得します。

たとえば、ビジネストランザクションを設定するには、次の手順を実行します。

// start the "Checkout" transaction
btHandle := appd.StartBT("Checkout", "")

// Optionally store the handle in the global registry
appd.StoreBT(btHandle, my_bt_guid)
... 

// Retrieve a stored handle from the global registry
myBtHandle = appd.GetBT(my_bt_guid)

// end the transaction
appd.EndBT(btHandle)
CPP

トランザクションの開始と終了の間に、ビジネストランザクションへのエラーの追加、トランザクション スナップショット属性の定義、バックエンドと終了コールの追加などの操作を実行できます。 

EndBT() へのコールによってビジネストランザクションが終了すると、エージェントはビジネストランザクションのメトリックの報告を停止します。

ビジネストランザクションエラーの追加

AddBTError() を使用してビジネストランザクションのエラーを報告します。この関数の markBTAsError パラメータを設定すると、トランザクションはエラーが発生した際にエラートランザクションとして報告されます。

SDK には、エラーレベルを APPD_LEVEL_NOTICEAPPD_LEVEL_WARNING、または APPD_LEVEL_ERROR として分類する定数が用意されています。

ビジネストランクションスナップショットの管理

エージェントは、ビジネストランザクションをモニターするときにトランザクション スナップショットを使用したビジネス トランザクション パフォーマンスのトラブルシューティングを自動的に作成します。トランザクション スナップショットは、特定の時点でのビジネストランザクションのインスタンスを記述するため、パフォーマンスの低下のトラブルシューティングに役立ちます。 

ビジネストランザクションを作成する以外に、スナップショットの作成に変更することは何もありませんが、以下を実行するコールを追加できます。

  • スナップショットが取得されているかを確認
  • スナップショットに追加データを提供
  • スナップショットにURLを設定

エージェントが現在スナップショットを取得しているかを確認

コストが高いため、エージェントはスクリーンショットを常に収集しません。デフォルトではスナップショットは10分ごとに収集されますが、このスケジュールは構成可能です。「スナップショットの定期的な収集頻度の構成」を参照してください。

エージェントがスナップショットを収集している場合に true を返す IsBTSnapshotting() を使用して、スナップショットが現在取得されているかどうかを確認できます。このメソッドは、スナップショットが収集されていない場合にスナップショットのユーザデータを収集したりスナップショット URL を設定したりする無駄なオーバーヘッドを回避します。

ビジネストランザクションユーザーデータの追加

必要に応じて、トランザクション スナップショットにデータを追加できます。たとえば、多数のエラーが発生しているユーザ、応答時間が遅くなっているリージョンやどのメソッドが遅いのかを把握できます。データは、コントローラ UI のトランザクション スナップショットの [USER DATA] タブに表示されます。

スナップショットが発生しているときは、AddUserDataToBT() を使用してスナップショットに収集させるデータのキーと値を渡します。

スナップショットURLの追加

スナップショットが発生しているときに、SetBTURL() を使用して、URL を現在のスナップショットに設定できます。

スナップショットの設定例

func setSnapshotAttributes(bt appd.BtHandle, key, value string) {
	if appd.IsBTSnapshotting(bt) {
		appd.AddUserDataToBT(bt, key, value)
		appd.SetBTURL(bt, "user/login")
	}
}
CPP

バックエンドの作成

バックエンドは、データベースまたはアプリケーションが使用するメッセージキュー、HTTP サービス、またはキャッシュサービスなどのリモートサービスです。バックエンドコンポーネント自体はアプリケーションエージェントにより監視されませんが、エージェントはインストゥルメント化されたサーバーからの呼び出しを監視します。インストゥルメント化された環境でエージェントがバックエンドを登録するようにバックエンドを作成する必要があります。インストゥルメント化されたアプリケーションを作成し、バックエンドに追加するには、以下が必要となります。

  • バックエンドの命名
  • 識別プロパティの設定
  • 必要に応じて、コントローラ UI におけるバックエンド表示方法の構成

識別プロパティ

バックエンドには識別プロパティが設定されています。これらのプロパティは、バックエンドのタイプおよび表示する情報のタイプによって異なります。コントローラでは、バックエンドのダッシュボードに識別プロパティが表示されます。追加するバックエンドのタイプに少なくとも 1 つの識別プロパティを設定する必要があります。 

次に、OracleデータベースのコントローラUIのバックエンドプロパティを示します。

Backend Properties

ティアへの転換

バックエンドの例

次のリストに、データベースバックエンドの設定例を示します。 

backendName := "Cart Product Database"
backendType := "DB"
backendProperties := map[string]string {
	"DATABASE": "sqlite3",
}
resolveBackend := false
 
appd.AddBackend(backendName, backendType, backendProperties, resolveBackend)
CPP

終了コールの管理

アプリケーションが別のコンポーネント(検出されたバックエンドまたは別のアプリケーションサーバなど)を呼び出すと、エージェントはこれらの呼び出しに関するメトリックを報告します。

StartExitCall()EndExitcall() コールの間に終了コールを構成するコードを囲み、終了コールを定義します。StartExitcall() はその終了コールに影響を与える後続のルーチンで使用するハンドルを返します。終了コールは、ビジネストランザクションのコンテキスト内で発生します。

オプションで、終了コールハンドルを GUID とともにグローバル ハンドル レジストリに格納すると、後で StoreExitcall() を使用して簡単に取得できます。using GetExitcall() によって、グローバル ハンドル レジストリからハンドルを取得します。

必要に応じて、SetExitcallDetails() を使用して任意の文字列として終了コールに詳細を追加できます。詳細はコントローラUIのトランザクションスナップショットの終了コール詳細に報告されます。

Exit Calls

AddExitcallError() を使用して exit コールにエラーを追加することもできます。エラーレベルには列挙型を使用します。また、エラーメッセージを追加することもできます。

単純な終了コールの例

// start the exit call to backendName
ecHandle := appd.StartExitcall(btHandle, backendName)

...

// optionally store the handle in the global registry
appd.StoreExitcall(ecHandle, my_ec_guid)

...
// retrieve a stored handle from the global registry
myEcHandle := appd.GetExitcall(my_ec_guid)
 
// set the exit call details
if err := appd.SetExitcallDetails(myEcHandle, "Exitcall Detail String"); err != nil {
	log.Print(err)
}

// add an error to the exit call
appd.AddExitcallError(myEcHandle, appd.APPD_LEVEL_ERROR, "exitcall error!", true)

// end the exit call
appd.EndExitcall(myEcHandle)
CPP

他のビジネストランザクションとの相関

相関ヘッダーには、エージェントが複数のティアにわたるビジネストランザクションのフローを継続できるようにする情報が含まれています。

SDK エージェントは、他の SDK エージェントや特定のタイプのエントリポイントとイグジットポイントに対して自動で相関を実行する他の Splunk AppDynamics エージェント(Java、.NET、PHP など)と相互に関連付けることができます。 

アップストリームティアとの相関

インストゥルメント化されたプロセスが、自動相関に対応するアップストリームエージェントからの継続的なトランザクションを受信したら、以下を行います。

  1. サードパーティの Header.Get() 関数を使用して、受信 HTTP ペイロードから APPD_CORRELATION_HEADER_NAME という名前のヘッダーを抽出します。

  2. ヘッダーを StartBT() に渡す。例:

    hdr := req.Header.Get(appd.APPD_CORRELATION_HEADER_NAME)
    bt := appd.StartBT("Fraud Detection", hdr)
    CPP

Header.Get() 関数で取得したヘッダーが有効な場合、StartBT() コールにより開始したビジネストランザクションは、アップストリームサービスにより開始したビジネストランザクションを継続します。

ダウンストリームティアとの相関

ダウンストリーム エージェントは、HTTP ペイロード内にある singularityheader  という名前の相関ヘッダーをモニターしています。

SDKエージェントが、自動相関に対応するダウンストリームエージェントへの終了コールを行っている場合は、以下を実行します。

  1. APPD_CORRELATION_HEADER_NAME を使用して相関ヘッダーの名前を設定します。
  2. 終了コールを開始。
  3. GetExitcallCorrelationHeader() 関数を使用して exit コールから相関ヘッダーを取得します。
  4. サードパーティのHTTP関数を使用して、HTTP POST要求を準備。
  5. ステップ 3 で取得した相関ヘッダーの値とともに、APPD_CORRELATION_HEADER_NAME という名前のヘッダーを HTTP リクエストの送信ペイロードに挿入します。
  6. リクエストを実行することができます。 {{2}}は特定の属性を識別し、 {{3}} はこの属性に割り当てる新規の値を指定します。

    inventoryEcHandle := appd.StartExitcall(btHandle, "Inventory DB")
    hdr := appd.GetExitcallCorrelationHeader(inventoryEcHandle)
     
    client := &http.Client{
    	CheckRedirect: redirectPolicyFunc,
    }
    
    req, err := http.NewRequest("POST", "https://inventory/holds/xyz", nil)
    // ...
    req.Header.Add(appd.APPD_CORRELATION_HEADER_NAME, hdr)
    resp, err := client.Do(req)
    // ...
    
    ...
    CPP

エージェントの終了

アプリケーションが終了する直前にエージェントを終了します。

appd.TerminateSDK()
CPP