dt-obs-logs について
dt-obs-logsは、DQLを使ったDynatraceログの調査と監視を支援するスキルです。ログの検索、絞り込み、集計、JSON解析に加え、エラー率や傾向の分析を扱います。
主な機能
- 01重大度、内容、エンティティによる絞り込み
- 02ログテキストやフレーズの検索
- 03エラー率と統計の算出
- 04JSON形式ログの解析
- 05ディメンションや時間ごとの集計
活用シーン
- 01指定時間帯のエラーログ検索
- 02頻出エラーメッセージの特定
- 03ログ傾向とエラー率の分析
- 04プロセスグループ別の問題調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ dynatrace/ dynatrace-for-ai --skill dt-obs-logsインストール後、Claude Code で/dt-obs-logsを入力して読み込まれたか確認します。
詳細
ログ分析スキル
DQL を使用して Dynatrace のログデータをクエリ、フィルタリング、分析し、トラブルシューティングやモニタリングに役立てます。
このスキルでできること
- 重大度、内容、エンティティによるログの取得とフィルタリング
- パターンマッチングを使用したログメッセージの検索
- エラー率と統計情報の計算
- ログのパターンと傾向の分析
- ディメンションごとのログデータのグループ化と集計
複数ソースの結合が必要な場合: クエリでログとホスト属性 (OS の種類、ホスト名、IP アドレス、クラウドプロバイダー)を結合する必要がある場合は、クエリを作成する前に
dt-dql-essentials/references/smartscape-topology-navigation.mdも参照してください。
ユースケース
次のような要望がある場合に、このスキルを使用します。
- 特定のログエントリを見つける(例:「過去 1 時間のエラーログを表示して」)
- 重大度、プロセスグループ、または内容でログをフィルタリングする
- 特定のキーワードやフレーズをログから検索する
- エラー率やログの統計情報を計算する
- よくあるエラーメッセージやパターンを特定する
- 時間の経過に伴うログの傾向を分析する
- ログデータを使用して問題をトラブルシューティングする
主な概念
ログデータモデル
- timestamp:ログエントリが作成された時刻
- content:ログメッセージのテキスト
- status:ログレベル(ERROR、FATAL、WARN、INFO など)
- dt.process_group.id:関連付けられたプロセスグループのエンティティ
- dt.process_group.detected_name:プロセスグループ ID を人が読み取れる名前に変換します
クエリパターン
- fetch logs:ログデータにアクセスするための主要コマンド
- 時間範囲:時間範囲の指定には
from:now() - <duration>を使用します - フィルタリング:重大度、内容、エンティティのフィルターを適用します
- 集計:ログデータをグループ化して要約します
- パターン検出:内容の検索には
matchesPhrase()とcontains()を使用します
一般的な操作
- 重大度によるフィルタリング(単一または複数のレベル)
- 内容検索(単純検索と全文検索)
- エンティティによるフィルタリング(プロセスグループ)
- 時系列分析(バケット化、ソート)
- エラー率の計算
- パターン分析(例外、タイムアウトなど)
主なワークフロー
1. ログの検索
時刻、重大度、内容で特定のログエントリを見つけます。
一般的な手順:
- 時間範囲を定義する
- 重大度でフィルタリングする(任意)
- 内容からキーワードを検索する
- 関連するフィールドを選択する
- 結果をソートして件数を制限する
例:
fetch logs, from:now() - 1h
| filter status == "ERROR"
| fields timestamp, content, process_group = dt.process_group.detected_name
| sort timestamp desc
| limit 100
2. ログのフィルタリング
複数の条件(重大度、エンティティ、内容)を使用してログを絞り込みます。
一般的な手順:
- 時間範囲を指定してログを取得する
- 重大度フィルターを適用する
- エンティティ(process_group)でフィルタリングする
- 内容フィルターを適用する
- 出力を整形してソートする
例:
fetch logs, from:now() - 2h
| filter in(status, {"ERROR", "FATAL", "WARN"})
| summarize count(), by: {dt.process_group.id, dt.process_group.detected_name}
| fieldsAdd process_group = dt.process_group.detected_name
| sort `count()` desc
3. パターン分析
ログデータのパターン、傾向、異常を特定します。
一般的な手順:
- 時間範囲を指定してログを取得する
- パターン検出フィールドを追加する
- エンティティまたは時刻で集計する
- 統計情報と比率を計算する
- 頻度または率でソートする
例:
fetch logs, from:now() - 2h
| filter status == "ERROR"
| fieldsAdd
has_exception = if(matchesPhrase(content, "exception"), true, else: false),
has_timeout = if(matchesPhrase(content, "timeout"), true, else: false)
| summarize
count(),
exception_count = countIf(has_exception == true),
timeout_count = countIf(has_timeout == true),
by: {process_group = dt.process_group.detected_name}
主な関数
フィルタリング
filter status == "ERROR"- ステータスレベルでフィルタリングしますin(status, {"ERROR", "FATAL", "WARN"})- 複数のステータスでフィルタリングします(リテラルセットには波括弧を使用します)contains(content, "keyword")- 部分文字列を単純検索しますmatchesPhrase(content, "exact phrase")- 全文フレーズ検索を行います
エンティティ操作
dt.process_group.detected_name- 人が読み取れるプロセスグループ名を取得しますfilter process_group == "service-name"- 特定のエンティティでフィルタリングします
集計
count()- すべてのログエントリをカウントしますcountIf(condition)- 条件付きでカウントしますby: {dimension}- エンティティまたは時間バケットでグループ化しますbin(timestamp, 5m)- 傾向分析のために時間をバケット化します
フィールド操作
fields timestamp, content, status- 特定のフィールドを選択しますfieldsAdd name = expression- 計算フィールドを追加しますif(condition, true_value, else: false_value)- 条件分岐を行います
よく使うパターン
内容検索
部分文字列の単純検索:
fetch logs, from:now() - 1h
| filter contains(content, "database")
| fields timestamp, content, status
全文フレーズ検索:
fetch logs, from:now() - 1h
| filter matchesPhrase(content, "connection timeout")
| fields timestamp, content, process_group = dt.process_group.detected_name
エラー率の計算
時間の経過に伴うエラー率を計算します:
fetch logs, from:now() - 2h
| summarize
total_logs = count(),
error_logs = countIf(status == "ERROR"),
by: {time_bucket = bin(timestamp, 5m)}
| fieldsAdd error_rate = (error_logs * 100.0) / total_logs
| sort time_bucket asc
上位のエラーメッセージ
最も頻繁に発生するエラーを見つけます:
fetch logs, from:now() - 24h
| filter status == "ERROR"
| summarize error_count = count(), by: {content}
| sort error_count desc
| limit 20
プロセスグループ固有のログ
プロセスグループでログをフィルタリングします:
fetch logs, from:now() - 1h
| fieldsAdd process_group = dt.process_group.detected_name
| filter process_group == "payment-service"
| filter status == "ERROR"
| fields timestamp, content, status
| sort timestamp desc
構造化ログ/JSON ログの解析
多くのアプリケーションは、JSON 形式のログ行を出力します。生の内容をそのまま出力するのではなく、parse を使ってフィールドを抽出します。
fetch logs, from:now() - 1h
| filter status == "ERROR"
| parse content, "JSON:log"
| fieldsAdd level = log[level], message = log[msg], error = log[error]
| fields timestamp, level, message, error
| sort timestamp desc
| limit 50
解析したフィールドで集計します。
fetch logs, from:now() - 4h
| filter status == "ERROR"
| parse content, "JSON:log"
| fieldsAdd message = log[msg]
| summarize error_count = count(), by: {message}
| sort error_count desc
| limit 20
注意:
parse content, "JSON:log"はレコードフィールドlogを作成します。log[key]を使ってネストされた値にアクセスします- 解析のオーバーヘッドを減らすため、
parseの前にcontains()でログをフィルタリングします contentだけでなく、JSON 構造を持つあらゆるフィールドで動作します
ベストプラクティス
- 必ず時間範囲を指定する -
from:now() - <duration>を使ってデータを限定します - フィルターを早い段階で適用する - 集計の前に重大度とエンティティでフィルタリングします
- 適切な検索方法を使う - 単純な検索には
contains()、完全一致にはmatchesPhrase()を使います - 結果を制限する - 出力が多くなりすぎないよう、
| limit 100を追加します - 適切な基準で並べ替える - 最近のログにはタイムスタンプ、上位のエラーには件数で並べ替えます
- エンティティに名前を付ける - 人が読みやすい出力には
dt.process_group.detected_nameまたはgetNodeName()を使います - 傾向分析には時間バケットを使う - 時系列分析には
bin(timestamp, 5m)を使います
統合ポイント
- エンティティモデル:サービスの相関付けに
dt.process_group.idを使います - 時系列:
bin()と時間範囲を使った時間分析をサポートします - コンテンツ検索:
matchesPhrase()による全文検索機能を提供します - 集計:
summarizeと条件関数を使って統計分析を行います
制限事項と注意
- ログを利用できるかどうかは、OneAgent の設定とログ取り込みに依存します
- 全文検索(
matchesPhrase)は、大規模なデータセットではパフォーマンスに影響する場合があります - エンティティ名を解決するには、OneAgent による適切な監視が必要です
- 妥当な時間範囲を指定してください(範囲を限定しないクエリは避けてください)
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| ログが返されない | 時間範囲がない、または狭すぎる | from: の範囲を広げ、ログの取り込みが有効であることを確認します |
getNodeName() が null を返す | OneAgent がエンティティを監視していない、またはエンティティがまだ解決されていない | OneAgent がデプロイされ、エンティティが検出されていることを確認します。信頼できる代替手段として dt.process_group.detected_name を使います |
大量のデータで matchesPhrase() が遅い | 事前にフィルタリングせずに全文検索している | matchesPhrase() の前に filter status == "ERROR" を追加します |
フィールド名 log.level が誤っている | よくある間違い | 重大度には(ドットなしの)loglevel を使います。dt-dql-essentials を参照してください |
content フィールドが空 | ログ行が空だった、または取り込まれなかった | OneAgent のログソース設定を確認します |
関連スキル
- dt-dql-essentials - ログクエリの基本的な DQL 構文とクエリ構造
- dt-obs-tracing - トレース ID を使ってログと分散トレースを関連付けます
- dt-obs-problems - ログと DAVIS が検出した問題を関連付けます
コメント
Markdown 対応