mcpField
T
tencentcloud-cls

tencentcloud-cls

github.com/acedatacloudクラウド・DevOps17211 回インストール今日更新
リポジトリ

tencentcloud-cls について

tencentcloud-clsは、Tencent Cloud CLSのログ検索・分析スキルです。サービスの動作やリクエスト追跡を調べる運用担当者向けで、CLIによる検索と、SDKを使った高度な取得・追尾に対応します。

主な機能

  1. 01CLSトピックの一覧表示
  2. 02CQLまたはLuceneでのログ検索
  3. 03ログに対するSQL分析
  4. 04複数トピックでのTrace ID検索
  5. 05最近のログの追尾
  6. 06大量結果のページ取得

活用シーン

  1. 01最近のエラーや5xx応答の検索
  2. 02ログトピックをまたいだリクエスト追跡
  3. 03API名ごとの利用状況集計
  4. 04請求・監査向けフィールドの抽出

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/acedatacloud/skills --skill tencentcloud-cls

インストール後、Claude Code で/tencentcloud-clsを入力して読み込まれたか確認します。

同梱ファイルscripts/cls.py

詳細

Tencent Cloud CLS(Log Service)—検索と分析

Tencent Cloud CLS のログトピックで、CQL/SQL 分析を検索・実行します。

セットアップ: tencentcloud authentication を参照してください。SDK は環境変数から TENCENTCLOUD_SECRET_ID / TENCENTCLOUD_SECRET_KEY / TENCENTCLOUD_REGION を読み込みます。

関連スキル: アラームポリシー/通知グループ/シールドの管理には tencentcloud-cls-alarm を使用してください。このスキルはログ内容の検索のみを対象とします。

CLI(推奨)

このスキルには、一般的な操作に対応した自己完結型 CLI scripts/cls.py が含まれています。

# $SKILL_DIR can point at another skill loaded this turn — anchor on our own
# script (re-run this at the top of every fresh-shell Bash block).
CLS="$SKILL_DIR/scripts/cls.py"; [ -f "$CLS" ] || CLS=$(find /tmp -maxdepth 8 -path '*/skills/*/scripts/cls.py' 2>/dev/null | head -1)
[ -f "$CLS" ] || { echo "tencentcloud-cls script not found (SKILL_DIR=$SKILL_DIR)" >&2; exit 1; }

python3 $CLS topics                                              # list topics
python3 $CLS search --topic <topic-id> --query 'level:ERROR' --time 1h
python3 $CLS search --topic <topic-id> --trace-id <uuid>
python3 $CLS search --topic <topic-id> --time 1d \
    --query '* | SELECT api_name, count(*) AS cnt GROUP BY api_name ORDER BY cnt DESC LIMIT 20' \
    --format json

--time には 30m / 1h / 6h / 1d / 7d を指定できます。--query はデフォルトで CQL です。方言を切り替えるには --lucene を指定してください。クエリに | SELECT ... GROUP BY ... を追加すると、SQL 分析を実行できます。

CLI で対応していない操作(カスタムフィールドの投影、ページネーションを使用した生データの走査、Context ベースのテーリング)には、以下の SDK 呼び出しを使用してください。

使用する場面

  • サービスの最近のエラー/5xx レスポンスを検索する
  • 複数のトピックからトレース ID で単一のリクエストを検索する
  • CQL フィルターを実行する(status_code:>=500 AND service:"openai")
  • SQL 分析を実行する(SELECT api_name, COUNT(*) GROUP BY api_name)
  • トレースログをつなぎ合わせて、リクエストのライフサイクルを再構成する
  • 請求/監査レポート用に特定のフィールドを抽出する

依存関係

pip install tencentcloud-sdk-python

クイックスタート

import os
import json
from tencentcloud.common import credential
from tencentcloud.cls.v20201016 import cls_client, models

cred = credential.EnvironmentVariableCredential().get_credential()
client = cls_client.ClsClient(cred, os.environ["TENCENTCLOUD_REGION"])

ワークフロー

トピックを確認する
req = models.DescribeTopicsRequest()
resp = client.DescribeTopics(req)
for t in resp.Topics:
    print(t.TopicId, t.TopicName, t.LogsetId)

ヒント:あらかじめユーザーにトピック ID を尋ねてください。トピック ID は 751a7350-dc5d-41c3-a6ca-c178bae05807 のような形式で、サービス名から推測することはできません。

ログを検索する(CQL)
import time

req = models.SearchLogRequest()
req.TopicId = "<topic-id>"
req.From = int((time.time() - 3600) * 1000)   # 1 hour ago, ms epoch
req.To = int(time.time() * 1000)
req.Query = 'status_code:>=500 AND service:"openai"'
req.Limit = 100
req.Sort = "desc"
req.SyntaxRule = 1                             # 1 = CQL, 0 = Lucene

resp = client.SearchLog(req)
for line in resp.Results:
    fields = {f.Key: f.Value for f in line.LogJson and []}  # see below
    print(line.Time, line.PkgLogId, fields.get("status_code"), fields.get("api_name"))

CLS は、各レコードの LogJson が JSON 文字列になっている Results を返します。json.loads(line.LogJson) でデコードすると、そのトピックに保存されているインデックス付きフィールドすべてを含むフラットな辞書を取得できます。

複数のトピックからトレース ID を検索する
TRACE_ID = "34341776-0835-422a-956d-ac8d5b404db1"
TOPICS = {
    "trace": "<trace-topic-id>",
    "api-usages": "<api-usages-topic-id>",
}

for label, topic_id in TOPICS.items():
    req = models.SearchLogRequest()
    req.TopicId = topic_id
    req.From = int((time.time() - 86400) * 1000)
    req.To = int(time.time() * 1000)
    req.Query = f'trace_id:"{TRACE_ID}"'
    req.Limit = 100
    req.SyntaxRule = 1
    resp = client.SearchLog(req)
    print(f"--- {label}: {len(resp.Results)} records ---")
    for line in resp.Results:
        print(line.Time, line.LogJson)
SQL 分析

CLS は、集計向けの SQL on Logs のサブセットをサポートしています。CQL フィルターに | <SQL> を追加してください。

req.Query = '* | SELECT api_name, count(*) AS cnt GROUP BY api_name ORDER BY cnt DESC LIMIT 20'
req.SyntaxRule = 1
resp = client.SearchLog(req)
# When the query has a `|`, results land in resp.Analysis (rows of column→value)
for row in resp.AnalysisResults or []:
    print(row)
最近のログをテーリングする
# Poll every 5s for new lines after the last cursor
last_cursor = None
while True:
    req = models.SearchLogRequest()
    req.TopicId = topic_id
    req.From = int((time.time() - 30) * 1000)
    req.To = int(time.time() * 1000)
    req.Query = 'level:ERROR'
    req.Limit = 100
    req.Sort = "asc"
    req.SyntaxRule = 1
    if last_cursor:
        req.Context = last_cursor
    resp = client.SearchLog(req)
    for line in resp.Results:
        print(line.Time, line.LogJson)
    last_cursor = resp.Context
    time.sleep(5)

CQL チートシート

パターン意味
status_code:500完全一致
status_code:>=500範囲
status_code:[500 TO 599]上限と下限を指定した範囲
service:"openai"引用符で囲んだフレーズ(スペースを含む値に使用)
NOT level:DEBUG否定
service:openai AND status_code:>=400論理積
(api:foo OR api:bar)グループ化
`*SELECT ... GROUP BY ...`

ページネーション

CLS は1回の呼び出しにつき最大1000件のレコードを返します。結果セットがそれより大きい場合は、Context を使って反復処理してください。

all_records = []
context = None
while True:
    req = models.SearchLogRequest()
    req.TopicId = topic_id
    req.From = ...
    req.To = ...
    req.Query = '...'
    req.Limit = 1000
    req.SyntaxRule = 1
    if context:
        req.Context = context
    resp = client.SearchLog(req)
    all_records.extend(resp.Results)
    context = resp.Context
    if not context or len(resp.Results) < 1000:
        break

エラーパターン

症状考えられる原因
InvalidParameter.QueryError: またはスペースを含むフレーズを引用符で囲んでください。SyntaxRule がクエリと一致していることを確認してください
LimitExceeded同時に実行した SearchLog 呼び出しが30 QPSのクォータを超えています。間隔を空けて再試行してください
OperationDenied.AccountIsolated請求上の理由で CLS サービスが停止されています。コンソールを確認してください
コンソールではログが表示されるのに Results が空時間範囲が正しくありません(From / To は秒ではなくミリ秒単位のエポックです)。または、トピックのフィールド名がクエリで想定されているものと異なります

コンソールへのリンク

コメント