TAKT の observability は opt-in です。無効時は workflow 実行、session log、provider events、既存の logging.usage_events 出力の挙動を変えません。
ローカルの observability stack を起動します。
docker compose -f docker-compose.observability.yml up -d
~/.takt/config.yaml または .takt/config.yaml で TAKT の observability を有効化します。
observability:
enabled: true
monitor: true
session_log_exporter: true
usage_events_phase: true
monitor: true は run ごとの metrics スナップショットを .takt/runs/<run>/monitor.json に、session_log_exporter: true は OTel 由来の shadow session log を .takt/runs/<run>/logs/<session>-otel-session-shadow.jsonl に出力します。どちらもローカルファイルへの出力で、OTLP endpoint は不要です。
OpenTelemetry HTTP exporter の送信先をローカル collector に向けて TAKT を実行します。
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
takt run
observability.enabled: true かつ OTEL_EXPORTER_OTLP_ENDPOINT が設定されている場合、TAKT は config で有効化したローカル exporter を維持したまま、span と metric を OTLP で送信します。OTEL_EXPORTER_OTLP_ENDPOINT が未設定の場合はローカル exporter のみを使い、ネットワーク送信は行いません。observability.enabled: false の場合はOTLP 環境変数が設定されていても OpenTelemetry SDK を初期化しません。
Grafana は http://127.0.0.1:3000 で開き、takt service を確認します。trace は既存の workflow span tree(workflow.<name> の下に step.<name>、さらに phase.<step>.<phaseName> / judge_stage.<step>.<stage>.<method> という名前の phase / judge span)として表示され、metric はローカルの monitor.json 出力と並走して送信されます。
TAKT は observability.enabled: true の場合だけ、次の counter を送信します。
| Metric | 主な属性 | 送信条件 |
|---|---|---|
takt.token.input_tokens |
takt.run.id, takt.provider.name, takt.model.name, takt.step.name |
phase または judge_stage.* span が provider の input / output usage を持って終了した場合。 |
takt.token.output_tokens |
takt.run.id, takt.provider.name, takt.model.name, takt.step.name |
phase または judge_stage.* span が provider の input / output usage を持って終了した場合。 |
takt.token.cached_input_tokens |
takt.run.id, takt.provider.name, takt.model.name, takt.step.name |
phase または judge_stage.* span に cached input token が含まれる場合。 |
takt.token.estimated_cost_usd |
takt.run.id, takt.provider.name, takt.model.name, takt.step.name |
provider、model、usage、既知の価格定義が揃う場合。未知 model や model 名欠落時は送信しません。 |
takt.provider.errors |
takt.run.id, takt.provider.name, takt.model.name, takt.provider.error_type |
providerErrorType(response) でプロバイダ起因の failure に分類された場合だけ provider failure として記録します。分類できない例外や、同関数で分類されない error response は含みません。response.retryCount がある場合の retry は error_type = retry として別途計上します。 |
takt.quality_gate.results |
takt.run.id, takt.workflow.name, takt.step.name, takt.quality_gate.name, takt.quality_gate.result |
command quality gate が pass / fail した場合。manual / text quality gate は対象外です。takt.quality_gate.name は sanitize 済みの gate.name があればそれを使い、なければ (unnamed) を使います。 |
takt.workflow.loops_detected |
takt.run.id, takt.workflow.name, takt.step.name |
loop detector が current step について警告した場合。 |
takt.workflow.cycles_detected |
takt.run.id, takt.workflow.name, takt.step.name |
設定済み loop monitor の cycle threshold に到達した場合。 |
token counter は input / output token usage を必要とします。OpenAI の long-context cost tier は input token 数が 270,000 以上の場合に選択します。token counter と provider error counter は provider default model が使われ、model 名が解決されていない場合に takt.model.name = "(default)" を使います。cost 推定は best-effort counter であり、未知 model、model 名欠落、cache token の不整合がある場合は 0 として送らず、送信しません。
workflow がまだ実行中の場合、OpenTelemetry exporter は長時間生存する root workflow.<name> span が終了する前に、完了済みの child span を送信することがあります。Tempo でその active trace を見つけやすくするため、TAKT は root workflow span の下に短命の workflow_start.<workflowName> span も送信します。この補助 span は takt.workflow.status = running を含む workflow / run 属性を持ちますが、root、step、phase、judge span を置き換えたり改名したりしません。trace discovery 専用であり、shadow session log の canonical record には変換されません。
active workflow を探す Tempo TraceQL filter 例:
{ resource.service.name = "takt" && span."takt.workflow.name" = "takt-default" }
{ resource.service.name = "takt" && span."takt.run.id" = "<run-id>" }
{ resource.service.name = "takt" && span."takt.task.pr_number" = 826 }
{ resource.service.name = "takt" && span."takt.task.issue_number" = 792 }
{ resource.service.name = "takt" && span."takt.git.branch" = "takt/816/implement-review-flow" }
{ resource.service.name = "takt" && span."takt.task.summary" =~ ".*review flow.*" }
{ resource.service.name = "takt" && name =~ "workflow_start\\..*" }
workflow の完了時または中断時、observability が有効なら TAKT は TraceQL discovery: ブロックを出力します。同じ discovery 情報は .takt/runs/<run>/meta.json の observability.traceDiscovery に保存され、後から run を探すために使えます。生成される query は常に takt.run.id を含み、利用可能な task / git metadata に応じて takt.task.pr_number、takt.task.issue_number、takt.git.branch の filter を追加します。
CLI 出力例:
TraceQL discovery:
{ resource.service.name = "takt" && span."takt.run.id" = "<run-id>" }
{ resource.service.name = "takt" && span."takt.task.pr_number" = 826 }
{ resource.service.name = "takt" && span."takt.task.issue_number" = 792 }
{ resource.service.name = "takt" && span."takt.git.branch" = "takt/816/implement-review-flow" }
workflow が abort/error で終わった場合、root workflow.<name> span には step-level の failure 属性も記録されます。
| 属性 | 意味 |
|---|---|
takt.failure.kind |
step_error、runtime_error、iteration_limit などの abort 種別 |
takt.failure.step |
ネストした workflow をまたいで保持される最深の failing step |
takt.failure.reason |
sanitize 済みの abort reason |
OTLP export には base endpoint が必要です。
| 環境変数 | 用途 |
|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
必須の opt-in endpoint。TAKT はここから /v1/traces と /v1/metrics を派生させます。 |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
任意の trace endpoint 上書き。OTEL_EXPORTER_OTLP_ENDPOINT も設定されている場合だけ使用します。 |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT |
任意の metric endpoint 上書き。OTEL_EXPORTER_OTLP_ENDPOINT も設定されている場合だけ使用します。 |
TAKT が明示的に解決・検証するのはこの endpoint 3種だけです。その他の標準 OTEL_EXPORTER_OTLP_* 環境変数(_HEADERS、_TIMEOUT、_COMPRESSION など)は TAKT では解釈せず、OpenTelemetry SDK にはそのまま届きます。子プロセスへの伝播はより厳格で、資格情報を含む変数(_HEADERS、クライアント証明書、クライアント鍵)は TAKT が渡す環境から除外され、非機微な変数のみ通過します。
OTLP export に使用する endpoint は絶対 http または https URL である必要があります。trace / metric 個別 endpoint だけを設定して base endpoint を設定していない場合、OTLP export には opt-in せず、TAKT はローカル exporter のみを使います。base endpoint が設定されている場合は個別 endpoint 上書きも run 開始前に検証されます。起動後に collector が停止しているなどの export 送信失敗が起きても、workflow run は阻害しません。
observability の各フラグはconfig ファイルを編集せずにプロセス単位で上書きできます。
| 環境変数 | 上書き対象 |
|---|---|
TAKT_OBSERVABILITY_ENABLED |
observability.enabled |
TAKT_OBSERVABILITY_MONITOR |
observability.monitor |
TAKT_OBSERVABILITY_SESSION_LOG_EXPORTER |
observability.session_log_exporter |
TAKT_OBSERVABILITY_USAGE_EVENTS_PHASE |
observability.usage_events_phase |
各変数は true または false を受け付け、~/.takt/config.yaml と .takt/config.yaml の値より優先されます。
command gate から起動される nested takt run にはobservability 設定と OTLP endpoint がこれらの環境変数経由で自動的に伝播します。credential を含む exporter 変数(_HEADERS、client certificate、client key)は伝播から除外されます。
~/.takt/config.yaml または .takt/config.yaml に次を追加します。
observability:
enabled: true
usage_events_phase: true
phase 粒度の usage events は次に出力されます。
.takt/runs/<run>/logs/<session>-usage-events.phase.jsonl
この出力は既存の logging.usage_events とは別ファイルです。logs/<session>-usage-events.jsonl は置き換えません。
record は workflow phase ごとに分かれます。
| Phase | 意味 |
|---|---|
phase1_execute |
step 本体の実行 |
phase2_report |
output contract / report 生成 |
phase3_structured |
structured output による status judgment |
phase3_tag |
tag fallback による status judgment |
phase3_fallback |
AI judge fallback による status judgment |
usage を取得できない場合は usage_missing: true と reason を記録します。分析コマンドでは missing usage を 0 token として扱わず、token 統計から除外します。
各 record にはstep で定義されている場合に persona と tags も含まれます。persona は文字列、tags は文字列配列で、値がない場合はフィールド自体を省略します。
先に build します。
npm run build
その後、ファイルまたは run directory を渡して集計します。
npm run analyze:usage -- .takt/runs/<run>/logs/*-usage-events.phase.jsonl
npm run analyze:usage -- .takt/runs/<run>
デフォルト出力は step x phase x provider x model で集計した Markdown table です。
CSV が必要な場合は --format csv を使います。
npm run analyze:usage -- --format csv .takt/runs/<run> > usage.csv
出力列は次の通りです。
| Column | 意味 |
|---|---|
step / phase / provider / model |
集計キー |
runs |
unique な run_id 数 |
calls |
phase usage record 数 |
missing |
usage を取得できなかった record 数 |
input_tokens / output_tokens / total_tokens |
usage を取得できた record の token 合計 |
cached_input_tokens / cache_creation_input_tokens / cache_read_input_tokens |
cache 関連 token 合計 |
avg_total_tokens / median_total_tokens / stddev_total_tokens |
missing usage を除外した call 単位の total token 統計 |
before/after 比較ではそれぞれの run directory 群に対して別々にコマンドを実行し、出力された table または CSV を比較します。
tools/token-usage.sh を使うと、worktree とローカルの全ランのトークン使用量をタスク×ステップ単位で一覧できます。
./tools/token-usage.sh # 直近10件(mock除外)
./tools/token-usage.sh --top 20 # 直近20件
./tools/token-usage.sh --csv # CSV出力
./tools/token-usage.sh --all # mock/0トークンのランも含む
./tools/token-usage.sh /path/to/dir # 指定ディレクトリをスキャン
デフォルトでは ../takt-worktrees/ と .takt/runs/ の両方をスキャンします。observability.usage_events_phase: true が設定されている必要があります。
CSV 出力では step の後に persona と tags の列を追加します。tags は | で連結し、persona または tags が異なる record は別の行として集計します。
依存: node, jq