今回は、Instanaで新たに登場した Integration Package Management の機能をご紹介し、サンプルパッケージのインポート手順を一緒に見ていきます。
🔍 概要:Integration Package Managementとは?
Integration Package Management(統合パッケージ管理)は、Instana環境に新しい技術やカスタム要素(ダッシュボードなど)を簡単に取り込むためのパッケージベースの管理機能です。
現在、Public Previewとして提供されており、CLIツールを用いて操作します。
この機能は、IBM Instanaチームが公式に管理する Instana Observability as Code Repository を中心に構成されています。
このリポジトリには、以下のような仕組みが含まれています:
- Instana公式の Integration Package群
- パッケージの ライフサイクルを管理するCLIツール
Integration Package は、以下のような要素をまとめた 技術ごとの拡張モジュール です:
- カスタムダッシュボード
- メトリクス可視化定義
- その他の統合要素
これにより、まだInstanaがネイティブ対応していない技術の可観測性を拡張することが可能になります。
たとえば、特定のLLM(大規模言語モデル)やOpenTelemetryベースのメトリクスを取り込むパッケージをインポートすれば、即座にInstana環境でその技術の観測が可能になります。
作成したパッケージは、中央レジストリに公開することもでき、他のユーザーと共有したり再利用することが可能です。
- チーム間での再利用性・一貫性の向上
🛠 Instana CLI for Integration Package Management
この仕組みを支えるのが、stanctl-integration
というCLIツールです。
CLIを使うことで、以下のような操作が可能になります:
- 中央レジストリから パッケージをダウンロード(download)
- 任意のInstana環境に インポート(import)
- Instana環境からの 要素のエクスポート(export)
- 自分用の 新しいカスタムパッケージを初期化(init)
- 作成したパッケージを 中央レジストリに公開(publish)
./stanctl-integration --help
Usage: index.js <command> <options>
Commands:
download パッケージをダウンロード
import パッケージを環境にインポート
export 環境からエクスポート
init 新しいパッケージの初期化
publish パッケージの公開
このCLIにより、Instanaの可観測性構成を コードとして管理・再利用:Observability as Code(OaC) できる世界が広がります。
📝 公式ドキュメント
- https://www.ibm.com/docs/en/instana-observability/current?topic=opentelemetry-integration-package-management-public-preview
- https://www.ibm.com/docs/en/instana-observability/current?topic=preview-unleashing-your-instana-observe-new-technologies
⚙️ インストール(CLIダウンロード)
1.CLIはGitHubのリリースページから取得できます。
2.ダウンロードした後で、適切な名前を変更し、実行権限を与えます。
mv ./stanctl-integration-macos ./stanctl-integration
chmod +x ./stanctl-integration
# バージョン確認
./stanctl-integration --version
# 1.2.0
📦 パッケージのダウンロード
例:Go用パッケージの取得
./stanctl-integration download --package @instana-integration/go
保存先を指定したい場合:
./stanctl-integration download --package @instana-integration/go --location ./my-packages
./stanctl-integration download --package @disha-148/llm --location ./custom-packages
🚀 パッケージのインポート(Import)
今回はサンプルとして、@disha-148/llm
パッケージにある英語表題などを日本語化したカスタマイズパッケージをインポートしてみます。
例("title": "llm-Jacky-demo"):
{
"id": "HtJoaBxfTwa8NFUlSzXXXX",
"title": "llm-Jacky-demo",
"accessRules": [
{
"accessType": "READ_WRITE",
"relationType": "GLOBAL",
"relatedId": ""
}
],
"widgets": [
{
"id": "qJ5q7vtv5i7u-SR5",
"title": "要求数",
"width": 12,
"height": 13,
"x": 0,
"y": 48,
"type": "chart",
"config": {
"shareMaxAxisDomain": false,
"y1": {
"formatter": "number.compact",
"renderer": "line",
"metrics": [
{
"lastValue": false,
"color": "",
"compareToTimeShifted": false,
"aggregation": "SUM",
"label": "",
"source": "INFRASTRUCTURE_METRICS",
"type": "oTelLLM",
"metricPath": [
"Others",
"OpenTelemetry SDK LLM"
],
"grouping": [
{
"groupBys": [
{
"groupbyTag": "metric.tag.model_id",
"groupbyTagEntity": "NOT_APPLICABLE",
"groupbyTagSecondLevelKey": ""
}
],
"maxResults": 5,
"includeOthers": false,
"direction": "DESC"
}
],
"formatter": "number.compact",
"metric": "metrics.sums.llm.request.count",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"metricLabel": "OpenTelemetry sums llm.request.count",
"crossSeriesAggregation": "SUM"
}
],
"formatterSelected": false
},
"y2": {
"formatter": "number.detailed",
"renderer": "line",
"metrics": []
},
"type": "TIME_SERIES"
}
},
{
"id": "FXcZLZA9zdvMTs6u",
"title": "コスト",
"width": 12,
"height": 13,
"x": 0,
"y": 35,
"type": "chart",
"config": {
"shareMaxAxisDomain": false,
"y1": {
"formatter": "number.compact",
"renderer": "line",
"metrics": [
{
"lastValue": false,
"color": "",
"compareToTimeShifted": false,
"aggregation": "MEAN",
"label": "Cost",
"source": "INFRASTRUCTURE_METRICS",
"type": "oTelLLM",
"metricPath": [
"Others",
"OpenTelemetry SDK LLM"
],
"grouping": [
{
"groupBys": [
{
"groupbyTag": "metric.tag.model_id",
"groupbyTagEntity": "NOT_APPLICABLE",
"groupbyTagSecondLevelKey": ""
}
],
"maxResults": 5,
"includeOthers": false,
"direction": "DESC"
}
],
"formatter": "number.compact",
"metric": "metrics.gauges.llm.usage.cost",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"metricLabel": "OpenTelemetry gauge llm.usage.cost",
"crossSeriesAggregation": "MEAN"
}
],
"formatterSelected": false
},
"y2": {
"formatter": "number.detailed",
"renderer": "line",
"metrics": []
},
"type": "TIME_SERIES"
}
},
{
"id": "OBWfaPn_PALtl1AR",
"title": "トークン",
"width": 12,
"height": 13,
"x": 0,
"y": 22,
"type": "chart",
"config": {
"shareMaxAxisDomain": false,
"y1": {
"formatter": "number.compact",
"renderer": "line",
"metrics": [
{
"lastValue": false,
"color": "",
"compareToTimeShifted": false,
"aggregation": "SUM",
"label": "",
"source": "INFRASTRUCTURE_METRICS",
"type": "oTelLLM",
"metricPath": [
"Others",
"OpenTelemetry SDK LLM"
],
"grouping": [
{
"groupBys": [
{
"groupbyTag": "metric.tag.model_id",
"groupbyTagEntity": "NOT_APPLICABLE",
"groupbyTagSecondLevelKey": ""
}
],
"maxResults": 5,
"includeOthers": false,
"direction": "DESC"
}
],
"formatter": "number.compact",
"metric": "metrics.gauges.llm.usage.total_tokens",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"metricLabel": "OpenTelemetry gauge llm.usage.total_tokens",
"crossSeriesAggregation": "SUM"
}
],
"formatterSelected": false
},
"y2": {
"formatter": "number.detailed",
"renderer": "line",
"metrics": []
},
"type": "TIME_SERIES"
}
},
{
"id": "CBNq9r7sAHAJlkIK",
"title": "モデルごとの合計要求数",
"width": 4,
"height": 16,
"x": 8,
"y": 5,
"type": "topList",
"config": {
"formatter": "number.compact",
"metricConfiguration": {
"formatter": "number.compact",
"lastValue": false,
"metric": "metrics.sums.llm.request.count",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"aggregation": "SUM",
"source": "INFRASTRUCTURE_METRICS",
"crossSeriesAggregation": "SUM",
"type": "oTelLLM",
"metricPath": [
"Others"
],
"grouping": [
{
"maxResults": 5,
"by": {
"groupbyTag": "metric.tag.model_id",
"groupbyTagEntity": "NOT_APPLICABLE",
"groupbyTagSecondLevelKey": ""
},
"includeOthers": false,
"direction": "DESC"
}
]
},
"formatterSelected": false
}
},
{
"id": "xyjZ3eZaH_G13egG",
"title": "モデル別の合計トークン数",
"width": 4,
"height": 16,
"x": 0,
"y": 6,
"type": "topList",
"config": {
"formatter": "number.compact",
"metricConfiguration": {
"formatter": "number.compact",
"lastValue": false,
"metric": "metrics.gauges.llm.usage.total_tokens",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"aggregation": "SUM",
"source": "INFRASTRUCTURE_METRICS",
"crossSeriesAggregation": "SUM",
"type": "oTelLLM",
"metricPath": [
"Others"
],
"grouping": [
{
"maxResults": 20,
"by": {
"groupbyTag": "metric.tag.model_id",
"groupbyTagEntity": "NOT_APPLICABLE",
"groupbyTagSecondLevelKey": ""
},
"includeOthers": false,
"direction": "DESC"
}
]
},
"formatterSelected": false
}
},
{
"id": "8g79cbK3mhWKKeVZ",
"title": "合計要求数",
"width": 4,
"height": 5,
"x": 8,
"y": 0,
"type": "bigNumber",
"config": {
"formatter": "number.compact",
"threshold": {
"thresholdEnabled": false,
"operator": ">="
},
"comparisonDecreaseColor": "greenish",
"metricConfiguration": {
"formatter": "number.compact",
"lastValue": false,
"metric": "metrics.sums.llm.request.count",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"aggregation": "SUM",
"source": "INFRASTRUCTURE_METRICS",
"crossSeriesAggregation": "SUM",
"type": "oTelLLM",
"metricPath": [
"Others"
]
},
"comparisonIncreaseColor": "redish",
"formatterSelected": false
}
},
{
"id": "NpXbaKW52_M2CqXE",
"title": "合計トークン数",
"width": 4,
"height": 5,
"x": 0,
"y": 0,
"type": "bigNumber",
"config": {
"formatter": "number.compact",
"threshold": {
"thresholdEnabled": false,
"operator": ">="
},
"comparisonDecreaseColor": "greenish",
"metricConfiguration": {
"formatter": "number.compact",
"lastValue": false,
"metric": "metrics.gauges.llm.usage.total_tokens",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"aggregation": "SUM",
"source": "INFRASTRUCTURE_METRICS",
"crossSeriesAggregation": "SUM",
"type": "oTelLLM",
"metricPath": [
"Others"
]
},
"comparisonIncreaseColor": "redish",
"formatterSelected": false
}
},
{
"id": "L3VuOuc4-Rmy1B9Y",
"title": "モデル別の合計コスト",
"width": 4,
"height": 16,
"x": 4,
"y": 5,
"type": "topList",
"config": {
"formatter": "number.compact",
"metricConfiguration": {
"formatter": "number.compact",
"lastValue": false,
"metric": "metrics.gauges.llm.usage.cost",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"aggregation": "SUM",
"source": "INFRASTRUCTURE_METRICS",
"crossSeriesAggregation": "SUM",
"type": "oTelLLM",
"metricPath": [
"Others"
],
"grouping": [
{
"maxResults": 5,
"by": {
"groupbyTag": "metric.tag.model_id",
"groupbyTagEntity": "NOT_APPLICABLE",
"groupbyTagSecondLevelKey": ""
},
"includeOthers": false,
"direction": "DESC"
}
]
},
"formatterSelected": false
}
},
{
"id": "PUjCURABk8HTyjg4",
"title": "モデル待ち時間",
"width": 12,
"height": 13,
"x": 0,
"y": 61,
"type": "chart",
"config": {
"shareMaxAxisDomain": false,
"y1": {
"formatter": "number.compact",
"renderer": "line",
"metrics": [
{
"lastValue": false,
"color": "",
"compareToTimeShifted": false,
"aggregation": "MEAN",
"label": "",
"source": "INFRASTRUCTURE_METRICS",
"type": "oTelLLM",
"metricPath": [
"Others",
"OpenTelemetry SDK LLM"
],
"grouping": [
{
"groupBys": [
{
"groupbyTag": "metric.tag.model_id",
"groupbyTagEntity": "NOT_APPLICABLE",
"groupbyTagSecondLevelKey": ""
}
],
"maxResults": 5,
"includeOthers": false,
"direction": "DESC"
}
],
"formatter": "number.compact",
"metric": "metrics.gauges.llm.response.duration",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"metricLabel": "OpenTelemetry gauge llm.response.duration",
"crossSeriesAggregation": "MEAN"
}
],
"formatterSelected": false
},
"y2": {
"formatter": "number.detailed",
"renderer": "line",
"metrics": []
},
"type": "TIME_SERIES"
}
},
{
"id": "rIMn7M2jVI7Eeiu0",
"title": "合計コスト",
"width": 4,
"height": 5,
"x": 4,
"y": 0,
"type": "bigNumber",
"config": {
"formatter": "number.compact",
"threshold": {
"thresholdEnabled": false,
"operator": ">="
},
"comparisonDecreaseColor": "greenish",
"metricConfiguration": {
"formatter": "number.compact",
"lastValue": false,
"metric": "metrics.gauges.llm.usage.cost",
"timeShift": 0,
"tagFilterExpression": {
"logicalOperator": "AND",
"elements": [],
"type": "EXPRESSION"
},
"allowedCrossSeriesAggregations": [],
"aggregation": "SUM",
"source": "INFRASTRUCTURE_METRICS",
"crossSeriesAggregation": "SUM",
"type": "oTelLLM",
"metricPath": [
"Others"
]
},
"comparisonIncreaseColor": "redish",
"formatterSelected": false
}
}
],
"ownerId": null,
"writable": true
}
上記の一部日本語化したPackageをInstana Backendにインポートします。
export INSTANA_SERVER=unitxxxx-instanatenant.instana.io
export API_TOKEN=XXXXRsup402yKyjcww
./stanctl-integration import --package @disha-148/llm --location ./custom-packages \
--server $INSTANA_SERVER \
--token $API_TOKEN
出力例:
info: Start to import the integration package from ...
info: Importing dashboards/llm.json ...
info: Applying the dashboard to https://.../api/custom-dashboard ...
info: Successfully applied ...: 200
info: Total file(s) processed: 1
Instana UIにログインし、「llm-Jacky-demo」のカスタムダッシュボードを検索し、表示します。これは日本語ラベル付きのカスタムLLMダッシュボードです:
- 📊 合計トークン数
- 💰 コスト
- ⚡ モデル別の使用量 など
📤 ダッシュボードのExportも可能!
今のInstana Backend環境にある全部カスタムダッシュボードをパッケージ化してローカル保存することもできます。
export INSTANA_SERVER=unitxxxx-instanatenant.instana.io
export API_TOKEN=XXXXRsup402yKyjcww
./stanctl-integration export --package jacky/llm --location ./custom-packages \
--server $INSTANA_SERVER \
--token $API_TOKEN
ログ出力(一部):
info: Start to get the dashboard list
...
info: Successfully got the dashboard(id=xxx): 200
info: Total dashboard(s) processed: 61