mcpField
C
clickstack-otel-collector

clickstack-otel-collector

github.com/clickhouseクラウド・DevOps5624.9k 回インストール1 週間前に更新
リポジトリ

clickstack-otel-collector について

ClickHouse Cloud の Managed ClickStack に OpenTelemetry Collector を設定し、データが ClickStack で見えることを確認するスキルです。ローカルへの新規デプロイと既存 Collector の設定に対応し、クラウド操作と SQL 実行には `clickhousectl` を使います。

主な機能

  1. 01ClickStack Collector のローカルデプロイまたは既存 Collector の設定
  2. 02ログ、トレース、メトリクスを `otel` データベースへ転送
  3. 03認証情報の生成と安全な保存
  4. 04合成テレメトリの送信と表示確認
  5. 05クラウド操作と SQL 実行に `clickhousectl` を使用

活用シーン

  1. 01新しいローカル Collector を Managed ClickStack に接続
  2. 02既存のゲートウェイ Collector に ClickHouse exporter を設定
  3. 03テレメトリが ClickStack に届いたことを確認

インストール

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

$npx skills add https://github.com/clickhouse/agent-skills --skill clickstack-otel-collector

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

同梱ファイルmetadata.json

詳細

Managed ClickStack 用 OpenTelemetry コレクターのセットアップ

このスキルでは、ClickHouse Cloud 上で稼働する Managed ClickStack サービスに OpenTelemetry コレクターを接続し、豊富な合成テレメトリを送信して、データが ClickStack に実際に表示されることを確認します。クラウドと SQL のすべての操作には clickhousectl を使用します。

対象範囲。 このスキルでは、Step 0 で選択する次の 2 つの方法に対応しています。

  1. ローカルに新しいコレクターをデプロイする方法です。個別の docker コマンド、または docker compose ファイルの 2 通りがあります(推奨:コマンドが少なく、起動・停止に使うファイルが 1 つで済みます)。最初に両方の方法をユーザーに伝え、Step 0 で選んでもらってください。通常の docker を使う前提で進めないでください。どちらの方法でも、Managed ClickStack 用に事前設定された ClickStack ディストリビューションのコレクターを実行します。
  2. 既存の独自コレクターを設定する方法です。ClickHouse エクスポーターの設定を追加します。追加する正確な設定を提示するので、コレクターを再読み込みします。すでにゲートウェイとしてコレクターを運用している場合は、この方法を使用してください。

Kubernetes への完全なデプロイ(Helm、K8s Secrets でのシークレット管理)は対象外です。方法 2 で生成する設定は、どこで実行されているコレクターにも適用できます。

最終的な状態は次のとおりです。

  • 対象サービスに、コレクターが必要とする権限だけを付与された専用の hyperdx_ingest SQL ユーザーが作成されています(初回の書き込み時に otel.* スキーマを作成します)。
  • 新しくローカルにデプロイした ClickStack コレクター、または既存のコレクターが、ログ、トレース、メトリクスをサービス上の otel データベースに転送しています。
  • 複数のサービス、重大度、スパンのステータス、メトリクスの種類にわたる豊富な合成テレメトリがあり、ClickStack の検索、サービスマップ、ダッシュボードに表示できるデータが揃っています。
  • サービスが起動中であることを確認し、ユーザーと一緒に Cloud コンソールで ClickStack のオンボーディングを進めて、データを実際に確認できる状態になっています。

シークレット(OTLP 認証トークンと SQL パスワード)はローカルで生成し、0600 の env ファイルに一度だけ書き込み、--env-file を介して Docker に渡します。シークレットをチャットに貼り付けたり、docker run -e で渡したり、作成後に表示し直したりすることはありません。

以下の手順を順番に実行してください。各手順は、前の手順で確立した状態を前提としています。


Step 0:方法を選択する

後の手順を決めるため、ほかの作業を始める前に、ユーザーに簡潔な質問を 2 つしてください。

質問 1:ゲートウェイとして稼働する OpenTelemetry コレクターをすでにお持ちですか?

  • いいえ、セットアップしてください。 → new-collector の方法です。質問 2 に進みます。
  • はい、あります。 → existing-collector の方法です。質問 2 は該当しないため省略し、Step 6 では新しいコレクターをデプロイせず、既存のコレクターを設定します。

質問 2(new-collector の方法のみ):個別の Docker コマンドと Docker Compose ファイルのどちらでコレクターを実行しますか?

  • Docker Compose(推奨)。 コマンドが少なく、起動・停止に使うファイルが 1 つで、再実行も最も簡単です。docker compose を利用できる場合に最適です。
  • 個別の Docker コマンド。 Compose がインストールされていない場合や、明示的なコマンドを使いたい場合に選択してください。

回答を COLLECTOR_PATH(new または existing)として記録してください。また、new の方法を選択した場合は DEPLOY_MODE(compose または run)も記録してください。Step 6 と Step 7 でこれらを参照します。


ステップ 1:最初に権限をまとめて設定する

コーディングエージェントは、シェルコマンドを初めて認識するときに承認を求めます。数ステップごとにユーザーの作業を中断しないよう、最初に一度だけ、以下のコマンドプレフィックスを許可リストに追加するよう依頼してください(エージェントの「このプロジェクト/セッションでは常に許可」オプションを選びます)。破壊的な操作はなく、このプロジェクトまたはユーザーの ClickHouse Cloud サービスの外部を対象とする操作もありません。

コマンドプレフィックス用途必要な場合
openssl rand …OTLP トークンと SQL パスワードの生成常に
clickhousectl cloud …認証、サービスの解決、Query API 経由での SQL 実行常に
jq …clickhousectl からの JSON の解析常に
docker … / docker compose …コレクターとテレメトリー生成ツールの実行/検査新しいコレクターを使用する場合と、任意のテレメトリーチェックを行う場合
curl …localhost:13133 に対するローカルのヘルスチェック(および clickhousectl がない場合のインストール)新しいコレクターを使用する場合

次の内容を、独自の言葉でユーザーに伝えてください。「エージェントが対応している場合、これらのコマンドについて初めて確認されたときに、それぞれ『常に許可』を選んでください。この手順の実行中、コレクターコンテナー以外はお使いのマシンに対して読み取り専用です。また、ClickHouse への書き込み操作は、取り込み用ユーザーと otel スキーマの作成に限られます。」

既存のコレクターを使用する場合で、任意のテレメトリーチェックを実行したくない場合は、リストから docker と curl を外してかまいません。

2 つの承認は、コマンドプレフィックスではなく操作の内容に基づいて求められるため、許可リストに追加しても事前に許可されません。 これらが表示されたら、ユーザーに明示的に承認するよう伝えてください。

  • ステップ 3 での clickhousectl のインストールでは curl … | sh を使用します。多くのエージェントのサンドボックスでは、curl の許可リスト設定にかかわらず、「信頼できないコードのダウンロードと実行」として警告されます。
  • ステップ 5 の CREATE USER / GRANT は、clickhousectl のプレフィックスルールとは関係なく、「共有本番インフラストラクチャの変更」として警告される場合があります。

どちらも上の表では解決されません。これらは一度限りの意図された操作であり、安全に承認できます。

その後、続行してください。


ステップ 2:対象サービスを確認し、シークレットファイルを作成する

ユーザーのプロンプトには、サービス ID(UUID)またはサービス名のいずれかが含まれています。 その値を SERVICE_REF として扱います。

作業ディレクトリを作成し、この実行に必要なすべての設定とシークレットを格納する 0600 の環境変数ファイルを作成します。キー名はコレクターイメージが読み取るものと完全に一致しているため、この同じファイルを Step 6 で docker run --env-file にそのまま渡すか、Compose から参照します。シークレットが一時的にも全ユーザーから読み取り可能にならないよう、厳格な umask を設定して書き込みます。

WORKDIR="${WORKDIR:-$HOME/clickstack-otel-collector}"
mkdir -p "$WORKDIR" && chmod 700 "$WORKDIR"
ENV_FILE="$WORKDIR/collector.env"

# Generate secrets WITHOUT printing them; write straight into a private file.
( umask 177
  {
    echo "SERVICE_REF=$SERVICE_REF"
    echo "OTLP_AUTH_TOKEN=$(openssl rand -hex 32)"
    echo "CLICKHOUSE_USER=hyperdx_ingest"
    echo "CLICKHOUSE_PASSWORD=$(openssl rand -hex 24)Aa1-"
    echo "HYPERDX_OTEL_EXPORTER_CLICKHOUSE_DATABASE=otel"
  } > "$ENV_FILE"
)
chmod 600 "$ENV_FILE"
ls -l "$ENV_FILE"

これらの値について、特に重要で間違いやすい点が 2 つあります。

  • キー名は正確に一致させてください。 コレクターは CLICKHOUSE_USER、CLICKHOUSE_PASSWORD、CLICKHOUSE_ENDPOINT、HYPERDX_OTEL_EXPORTER_CLICKHOUSE_DATABASE を読み取ります。SQL パスワードはカスタムのキー名ではなく、CLICKHOUSE_PASSWORD に保存してください。キーがない場合、コレクターはパスワードを空として起動し、code: 516, Authentication failed で終了します。
  • パスワードで使用できる文字は、3 つの制約を同時に満たす必要があります。 ClickHouse Cloud では、大文字と特殊文字がそれぞれ 1 文字以上含まれないパスワードは拒否されるため、単純な 16 進文字列では CREATE USER が失敗します。一方、コレクターのマイグレーションツールは接続 URL にパスワードを埋め込むため、@、:, /、?、#、% が含まれているとパスワードが破損します(症状:パスワードが「正しい」にもかかわらず起動時に code: 516 が発生します)。上記の手順では、ランダムな 16 進文字列(小文字と数字)に接尾辞 Aa1- を追加します。これにより、大文字、数字、そしてURL で予約されていない特殊文字(-)という要件を満たせます。OTLP トークンにはこのような制約がないため(ベアラートークンとして使うだけです)、単純な 16 進文字列で問題ありません。

環境変数ファイルには、引用符を付けない KEY=VALUE の行を使用してください。Docker の --env-file はシェルとして解析しないため、引用符を追加すると、それらも値の一部になります。

既存のコレクターを使う場合、OTLP_AUTH_TOKEN は使用しません(レシーバーの認証設定は独自に行います)。この値を生成するのは、後でローカルのコレクターに切り替える場合にも同じファイルを使えるようにするためだけです。CLICKHOUSE_* の値は引き続き使用します。Step 6 でコレクターに追加するエクスポーター設定に渡されます。

以降の各ステップは新しいシェルで実行されるため、WORKDIR、ENV_FILE、エクスポート済みの認証情報は引き継がれません。また、WORKDIR と ENV_FILE は環境変数ファイル内に保存されないため、ファイルを読み込んでも復元できません。 後続の各ステップでは、次の標準プリアンブルをシェルの先頭に記述してください。このプリアンブルは、決定的なデフォルト値からパスを再設定し、保存済みの認証情報(Step 3)と設定を読み込みます。

WORKDIR="${WORKDIR:-$HOME/clickstack-otel-collector}"; ENV_FILE="$WORKDIR/collector.env"
[ -f "$WORKDIR/creds.env" ] && . "$WORKDIR/creds.env"; set -a; . "$ENV_FILE"; set +a

デフォルト以外の WORKDIR を選んだ場合は、各ステップの先頭で明示的に設定してください(${WORKDIR:-…} のデフォルトが対象とするのは標準の場所だけです)。以降のステップで「標準プリアンブル」と記載しているのは、これを指します。

SERVICE_REF が正しいことをユーザーに確認してください。作業ディレクトリと、collector.env(モード 0600)に OTLP トークンと SQL パスワードが保存されたことを伝えます。どちらのシークレットも表示してはいけません。値を確認したい場合は、ファイルを参照するよう案内してください(grep OTLP_AUTH_TOKEN "$ENV_FILE")。

ユーザーが独自のトークンやパスワードを指定した場合は、生成した値の代わりにそれらをファイルに書き込みます。ただし、同じ 0600 の取り扱いを徹底し、カスタムのパスワードも上記の文字要件を満たすようにしてください。


ステップ 3:clickhousectl を認証する(デフォルトでは別のターミナル)

clickhousectl が PATH 上にあることを確認します。この存在確認はインストーラーと連結せず、単独で実行してください。|| curl … | sh の形式では、問題のない確認コマンドも複合コマンドに含まれてしまい、信頼できないコードのダウンロードとしてサンドボックスに一括で拒否されます。

which clickhousectl

何も出力されなかった場合に限り、インストールします(ユーザーが明示的に承認する必要がある場合があります。ステップ 1 を参照してください)。

curl -fsSL https://clickhouse.com/cli | sh

認証状態を確認します。

clickhousectl cloud auth status

このスキルにはAPI キー認証が必要です。OAuth は読み取り専用のため、ユーザーの作成や書き込みクエリの実行はできません。API key の行が Active でない場合、ユーザーは認証する必要があります。

API キーとシークレットをチャットに貼り付けるよう、ユーザーに求めてはいけません。 会話に貼り付けられた情報はトランスクリプトに残るため、後でローテーションが必要になります。代わりに、別のターミナルで認証してもらい、完了したら知らせてもらいます。

データ取り込み用ユーザーを作成し、データを検証するには、ClickHouse Cloud のAdmin API キーが必要です。 ここには貼り付けないでください。代わりに、次の手順を行ってください。

  1. Cloud console で Organization → API keys → New API key を開き、Admin ロールを付与します。(Developer スコープのキーでは、 cloud service query が使用するサービスごとの Query API エンドポイントをプロビジョニングできません。)

  2. 別のターミナルで、次を実行します。

    clickhousectl cloud auth login --api-key <key-id> --api-secret <key-secret>
    
  3. 完了したら知らせてください。こちらで認証状態を再確認します。

API キーの行が Active と表示されるまで確認を繰り返し、ステータステーブルを信頼するだけでなく、実際に権限が必要な呼び出しを行って確認します。ここでは参照先に依存しない呼び出しを使用してください。SERVICE_REF は名前の場合があり、cloud service get が受け付けるのは UUID だけです。そのため、get で確認すると、認証とは無関係な理由で名前を指定した場合に失敗します。cloud service list は参照先を必要とせず、API キーが機能していることを確認できます。

clickhousectl cloud auth status
clickhousectl cloud service list --json | jq -r '.[].name'

サービス一覧が返されたら認証済みです。続行してください。SERVICE_REF の名前または UUID の解決は、ステップ 4 で行います。

環境変数の認証情報が必要になることを想定してください(珍しいケースではなく、よくあります)。 多くの clickhousectl ビルドでは認証情報ファイルが保存されますが、新しく起動したシェル(ツール呼び出しを実行するシェルなど)ではそのファイルが読み込まれません。そのため、auth status が Active を示していても、直後の clickhousectl 呼び出しで No credentials found と報告されることがあります。これをまれなフォールバックとして扱うのではなく、ソース可能な小さな認証情報ファイルを一度作成し、以降の各シェルで読み込みます。これにより、後続の各シェルでは jq による再抽出を 2 回行う代わりに、. の行を 1 行だけ実行すれば済み、シークレットをチャットに出さずに済みます。

# Write a private, sourceable creds file next to collector.env.
( umask 177
  { echo "export CLICKHOUSE_CLOUD_API_KEY=$(jq -r .api_key    "$HOME/.clickhouse/credentials.json")"
    echo "export CLICKHOUSE_CLOUD_API_SECRET=$(jq -r .api_secret "$HOME/.clickhouse/credentials.json")"
  } > "$WORKDIR/creds.env"
)
chmod 600 "$WORKDIR/creds.env"

以降、clickhousectl を呼び出すシェルは、毎回 2 つのファイルを読み込んでから起動してください。 環境変数はシェル間で引き継がれません。

. "$WORKDIR/creds.env"; set -a; . "$ENV_FILE"; set +a

認証情報を読み込んだ状態で、上記の service list の確認を再実行します。今度は成功するはずです。実際の呼び出しが成功するまで先に進まないでください。(clickhousectl auth status がすでに API key … Active を示し、creds.env なしで呼び出しが成功する場合は、この手順を省略できます。ただし、ほとんどのエージェント用シェルでは必要になります。)


Step 4: サービスを解決し、HTTPS エンドポイントを取得する

標準の前置き(Step 2)を実行して、このシェルにパス、認証情報、設定をすべて読み込んでから、サービスを解決します。SERVICE_REF が UUID の場合はそのまま使用し、それ以外の場合は名前で検索します。

WORKDIR="${WORKDIR:-$HOME/clickstack-otel-collector}"; ENV_FILE="$WORKDIR/collector.env"
[ -f "$WORKDIR/creds.env" ] && . "$WORKDIR/creds.env"; set -a; . "$ENV_FILE"; set +a
# UUID form
clickhousectl cloud service get "$SERVICE_REF" --json > "$WORKDIR/svc.json"

# Name form (note the double quotes: service names can contain spaces or apostrophes,
# e.g. "Alex's test")
clickhousectl cloud service list --json \
  | jq --arg n "$SERVICE_REF" '.[] | select(.name==$n)' > "$WORKDIR/svc.json"

必要な値を抽出し、ポートを整数に変換します。ポートは浮動小数点数(8443.0)としてシリアライズされます。エンドポイントに :8443.0 が含まれると、コレクターの ClickHouse エクスポーターが接続できません。

SERVICE_ID=$(jq -r '.id' "$WORKDIR/svc.json")
SERVICE_NAME=$(jq -r '.name' "$WORKDIR/svc.json")
STATE=$(jq -r '.state' "$WORKDIR/svc.json")
CLICKHOUSE_ENDPOINT=$(jq -r '.endpoints[] | select(.protocol=="https")
  | "https://\(.host):\(.port | tonumber | floor)"' "$WORKDIR/svc.json")

# Persist the resolved values back into the env file for later steps and docker --env-file.
# Append only if the key is not already present, so a second run does not duplicate lines.
grep -q '^SERVICE_ID=' "$ENV_FILE" || echo "SERVICE_ID=$SERVICE_ID" >> "$ENV_FILE"
grep -q '^CLICKHOUSE_ENDPOINT=' "$ENV_FILE" || echo "CLICKHOUSE_ENDPOINT=$CLICKHOUSE_ENDPOINT" >> "$ENV_FILE"
printf 'service=%q state=%s endpoint=%s\n' "$SERVICE_NAME" "$STATE" "$CLICKHOUSE_ENDPOINT"

STATE は running である必要があります。stopped または starting の場合は、サービスを起動するようユーザーに依頼するか、起動するまで待ち、先へ進まないでください。ClickHouse Cloud サービスはアイドル状態になると自動停止するため、「running」のサービスでもスリープしていることがあります。次のクエリで到達可能かどうかを確認し、サービスを起動します。

clickhousectl cloud service query --id "$SERVICE_ID" --query "SELECT version()"

成功応答が返れば、サービスが起動しており、サービスごとの Query API キーがプロビジョニングされていることを確認できます。最初の呼び出し時に clickhousectl が Provisioning Query API endpoint + key for service '<name>'... と表示するのは想定された動作です。


Step 5: hyperdx_ingest SQL ユーザーを作成し、otel.* への権限を付与する

この手順はどちらの方法でも同じです。新規または既存のコレクターは、ClickHouse に hyperdx_ingest として認証します。統合読み込みでシェルを開き、$CLICKHOUSE_PASSWORD(および認証情報)が設定されていることを確認してください。

ここで承認を求めるプロンプトが表示されます。 以下の CREATE USER/GRANT 文は Cloud サービスに対する DDL であるため、clickhousectl が許可リストに登録されていても、一部のエージェント用サンドボックスでは「共有の本番インフラストラクチャの変更」として警告が表示されます。これは想定された動作です。操作の対象は専用の取り込みユーザー 1 つと otel スキーマに限定されており、プロンプトが表示された場合はユーザーが明示的に承認してください。

平文のパスワードを SQL に絶対に含めないでください。ローカルでハッシュ化し、sha256_hash を使用します。 IDENTIFIED WITH sha256_password BY '$CLICKHOUSE_PASSWORD' が使えない理由は 2 つあります。シークレットがプロセスの引数リスト(ps で確認可能)とシェル履歴に残ること、そして特に、Query API は失敗した文をエラー JSON にそのまま返すため、エラー(一時的な障害、文字セットの誤りなど)が発生すると、エージェントが出力として提示する可能性のある場所にパスワードが漏れることです。標準入力経由で渡しても解決しません。エラー応答には、引き続きその文が含まれます。代わりに、パスワードの SHA-256 ハッシュをローカルで計算します(sha256_hash は sha256_password と同じ値を保存するため、コレクターは引き続き env ファイルの平文を使ってログインできます)。そして、文にはハッシュのみを指定します。ハッシュから元の値を復元することはできないため、エラーにそのまま表示されてもパスワードは漏れません。

WORKDIR="${WORKDIR:-$HOME/clickstack-otel-collector}"; ENV_FILE="$WORKDIR/collector.env"
[ -f "$WORKDIR/creds.env" ] && . "$WORKDIR/creds.env"; set -a; . "$ENV_FILE"; set +a

# SHA-256 of the password. openssl is already a dependency; this is portable (macOS + Linux).
# Only this hash ever reaches SQL, output, or `ps`; the plaintext stays in the env file.
PW_HASH=$(printf %s "$CLICKHOUSE_PASSWORD" | openssl dgst -sha256 | awk '{print $NF}')

# Send statements ONE AT A TIME: the Query API runs over HTTP and rejects multi-statement input
# ("Multi-statements are not allowed"), so a single ; -separated batch fails.
clickhousectl cloud service query --id "$SERVICE_ID" --query \
  "CREATE USER IF NOT EXISTS hyperdx_ingest IDENTIFIED WITH sha256_hash BY '$PW_HASH'"
# Re-run safe: force the password to this run's value if the user already existed.
clickhousectl cloud service query --id "$SERVICE_ID" --query \
  "ALTER USER hyperdx_ingest IDENTIFIED WITH sha256_hash BY '$PW_HASH'"

コレクターが otel.* スキーマを作成して書き込むために必要な、最小限の権限を付与します。現在のイメージでは、スキーマのマイグレーションとそのバージョンテーブルも otel にあるため、otel.* で十分です(この文にシークレットは含まれません)。

clickhousectl cloud service query --id "$SERVICE_ID" --query \
  "GRANT SELECT, INSERT, CREATE DATABASE, CREATE TABLE, CREATE VIEW ON otel.* TO hyperdx_ingest"

古いイメージビルドの場合: 以前の一部のコレクターバージョンでは、goose のマイグレーションが default データベース内のバージョンテーブルに対して実行されていました。そのため、default.* への権限も付与されるまで、起動が ACCESS_DENIED でループしていました。コレクターのログ(Step 6)に default を参照する ACCESS_DENIED が表示された場合は、次の権限を追加してコンテナを再起動してください。

clickhousectl cloud service query --id "$SERVICE_ID" --query \
  "GRANT SELECT, INSERT, CREATE TABLE ON default.* TO hyperdx_ingest"

確認します。

clickhousectl cloud service query --id "$SERVICE_ID" --query "SHOW GRANTS FOR hyperdx_ingest"

GRANT SELECT, INSERT, CREATE DATABASE, CREATE TABLE, CREATE VIEW ON otel.* TO hyperdx_ingest と表示されるはずです。


Step 6: コレクターをセットアップする

Step 0 で選んだ方法とモードに対応する小見出しの手順に従ってください。3 つの方法はいずれも、最終的には同じ状態になります。コレクターが OTLP を受け付け、サービス上の otel データベースに書き込みます。この手順のすべてのコードブロックは、最初に標準の前置き(Step 2)を実行し、シェルに $WORKDIR、$ENV_FILE、$SERVICE_ID、およびシークレットが設定されていることを前提としています。

Docker が実行中であることを確認します(新規コレクターを使う場合のみ)。

WORKDIR="${WORKDIR:-$HOME/clickstack-otel-collector}"; ENV_FILE="$WORKDIR/collector.env"
[ -f "$WORKDIR/creds.env" ] && . "$WORKDIR/creds.env"; set -a; . "$ENV_FILE"; set +a
docker info > /dev/null
ステップ 6a: Docker Compose を使用した新しいコレクター (DEPLOY_MODE=compose)

作業ディレクトリに Compose ファイルを作成します。これはシークレット用に同じ collector.env を読み込み、 OTLP ポートとヘルスチェックポートを公開し、ステップ 7 のテレメトリージェネレーターがコンテナ名で コレクターに到達できるように名前付きネットワークを固定します。

cat > "$WORKDIR/docker-compose.yaml" <<'EOF'
name: clickstack
services:
  otel-collector:
    image: clickhouse/clickstack-otel-collector:latest
    container_name: clickstack-otel-collector
    env_file: ./collector.env
    ports:
      - "4317:4317"   # OTLP gRPC
      - "4318:4318"   # OTLP HTTP
      - "13133:13133" # health
    restart: unless-stopped
    networks: [clickstack-net]
networks:
  clickstack-net:
    name: clickstack-net
EOF

# Compose refuses to adopt a clickstack-net it did not create (a leftover from the docker run
# path, a prior failed Compose run, or a DEPLOY_MODE switch), failing with "network clickstack-net
# was found but has incorrect label". If an orphan exists with no containers attached, remove it so
# Compose can recreate it with its own labels.
if docker network inspect clickstack-net >/dev/null 2>&1 \
   && [ -z "$(docker network inspect clickstack-net -f '{{range .Containers}}{{.Name}} {{end}}')" ]; then
  docker network rm clickstack-net
fi

( cd "$WORKDIR" && docker compose up -d )

Compose は clickstack-net ネットワークを自動的に作成します (上記のガードは、まず以前の実行で孤立した ネットワークを削除します)。ヘルスチェックの確認には ステップ 6d に進んでください。

ステップ 6b: 個別の Docker コマンドを使用した新しいコレクター (DEPLOY_MODE=run)

ステップ 7 のテレメトリージェネレーターがコンテナ名でコレクターに到達できるように、ユーザー定義 ネットワークを作成します。

docker network create clickstack-net 2>/dev/null || true

コレクターを起動します。このとき、すべてのシークレットを --env-file 経由で渡します (シークレットが コマンドライン、シェル履歴、ps に露出する -e は絶対に使用しないでください)。先頭の docker rm -f により、このステップを安全に再実行できます。

docker rm -f clickstack-otel-collector 2>/dev/null || true
docker run -d \
  --name clickstack-otel-collector \
  --network clickstack-net \
  --env-file "$ENV_FILE" \
  -p 4317:4317 \
  -p 4318:4318 \
  -p 13133:13133 \
  clickhouse/clickstack-otel-collector:latest

イメージは env ファイルから OTLP_AUTH_TOKEN、CLICKHOUSE_ENDPOINT、CLICKHOUSE_USER、 CLICKHOUSE_PASSWORD、HYPERDX_OTEL_EXPORTER_CLICKHOUSE_DATABASE を読み込みます。空のスキームで OTLP レシーバー上のベアラートークン認証を有効にするため、呼び出し元は生のトークンを authorization ヘッダーとして送信します (Bearer プレフィックスは付きません)。ステップ 6d に進んでください。

ステップ 6c: 既存のコレクターを構成する (COLLECTOR_PATH=existing)

既存のコレクター構成に ClickHouse エクスポーターを追加します。以下の構成は、Session Replay (rrweb) ルーティングパスを含む ClickStack ディストリビューションの動作と一致し、ClickStack UI が 期待する otel データベースに書き込みます。

エンドポイントとパスワードは環境変数 (${env:…}) として参照し、構成ファイルにハードコードしないで ください。 contrib コレクターは読み込み時に ${env:VAR} を展開するため、平文のパスワードを構成 ファイルから排除することは、より安全であると同時に、このスキルの他の部分とも一貫しています。環境変数を 利用可能にした状態でコレクターを起動してください。最も簡単な方法は、ローカルコレクターが使用するのと 同じ --env-file です。

# When running the contrib collector in Docker, pass collector.env so ${env:CLICKHOUSE_*} resolve:
#   docker run -d --env-file "$ENV_FILE" -p 4317:4317 -p 4318:4318 \
#     -v "$WORKDIR/your-config.yaml:/etc/otelcol-contrib/config.yaml:ro" \
#     otel/opentelemetry-collector-contrib:latest
# For a non-Docker collector, export CLICKHOUSE_ENDPOINT and CLICKHOUSE_PASSWORD into its
# environment (e.g. an EnvironmentFile= in the systemd unit) before it starts.

これをコレクター構成に追加してリロードします。

receivers:
  otlp/hyperdx:
    protocols:
      grpc:
        include_metadata: true
        endpoint: "0.0.0.0:4317"
      http:
        cors:
          allowed_origins: ["*"]
          allowed_headers: ["*"]
        include_metadata: true
        endpoint: "0.0.0.0:4318"

processors:
  batch:
  memory_limiter:
    limit_mib: 1500
    spike_limit_mib: 512
    check_interval: 5s

connectors:
  routing/logs:
    default_pipelines: [logs/out-default]
    error_mode: ignore
    table:
      - context: log
        statement: route() where IsMatch(attributes["rr-web.event"], ".*")
        pipelines: [logs/out-rrweb]

exporters:
  clickhouse:
    database: otel
    endpoint: ${env:CLICKHOUSE_ENDPOINT}
    username: hyperdx_ingest
    password: ${env:CLICKHOUSE_PASSWORD}
    ttl: 720h
    timeout: 5s
    retry_on_failure:
      enabled: true
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 300s
  clickhouse/rrweb:
    database: otel
    endpoint: ${env:CLICKHOUSE_ENDPOINT}
    username: hyperdx_ingest
    password: ${env:CLICKHOUSE_PASSWORD}
    ttl: 720h
    logs_table_name: hyperdx_sessions
    timeout: 5s
    retry_on_failure:
      enabled: true
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 300s

service:
  pipelines:
    traces:
      receivers: [otlp/hyperdx]
      processors: [memory_limiter, batch]
      exporters: [clickhouse]
    metrics:
      receivers: [otlp/hyperdx]
      processors: [memory_limiter, batch]
      exporters: [clickhouse]
    logs/in:
      receivers: [otlp/hyperdx]
      exporters: [routing/logs]
    logs/out-default:
      receivers: [routing/logs]
      processors: [memory_limiter, batch]
      exporters: [clickhouse]
    logs/out-rrweb:
      receivers: [routing/logs]
      processors: [memory_limiter, batch]
      exporters: [clickhouse/rrweb]

このパスに関する注意点:

  • 独自のディストリビューションを使用する場合は、ClickHouse エクスポーターが含まれていることを確認して ください。アップストリームの contrib イメージ にはすでに含まれています。
  • OTLP レシーバー上の認証は、既存のセットアップのままです。ステップ 2 で生成された OTLP_AUTH_TOKEN は、独自の認証 (たとえば bearertokenauth) に組み込まない限り、ここでは使用されません。
  • リロード後は、以下のヘルスチェック (これはローカルコンテナに固有のものです) をスキップし、直接 ステップ 7 に進んで検証バーストを送信してください (ジェネレーターを自身のコレクターの OTLP エンドポイントに向けてください)。
ステップ 6d:ローカルコレクターが正常であることを確認する(new-collector パス)
docker ps --filter name=clickstack-otel-collector --format '{{.Status}}'
curl -fsS http://localhost:13133/ && echo
docker logs --tail 40 clickstack-otel-collector 2>&1 | tail -40

正常に起動すると、シードマイグレーションが最後まで実行され([seed] OK ... で始まる行が表示され、最後に goose: up to current file version: N が出力されます)、続いて Everything is ready. Begin running and processing data.(または同等のメッセージ)が表示されます。また、docker ps で Up ... (healthy) が報告され、 ヘルスチェックが HTTP 200 を返します。古いサーバーバージョンで ClickHouse 25.12 < 26.2, falling back to compatibility logs and traces schemas のようなシード行が表示されるのは想定内で問題ありません。エラーではないため、その対応に時間をかけないでください。 コンテナが終了する場合、原因はほぼ常にシードの手順にあります。

  • code: 516, Authentication failed: password is incorrect -> env ファイルの CLICKHOUSE_PASSWORD が空か、間違っています。よくある間違いは、別のキー名でパスワードを保存することです(キー名は必ず CLICKHOUSE_PASSWORD にしてください)。また、@ : / ? # % を含むパスワードを使用すると、マイグレーションツールの接続 URL が壊れます。
  • 「server hello」で [HTTP 403] / data size should be 0 < <huge number> が表示される -> 根本原因は同じです。HTTPS エンドポイントに対するパスワードが空か、間違っています。
  • TLS / dial エラー -> CLICKHOUSE_ENDPOINT の形式が正しくありません(https://<host>:8443 である必要があり、ポートに .0 を付けないでください)。
  • default を参照する ACCESS_DENIED -> 古いイメージビルドでのみ発生します。ステップ 5 の注記にある default.* の権限を適用して再起動してください。

ステップ 7:リッチな合成テレメトリーを送信して取り込みを確認する

telemetrygen(OpenTelemetry Collector Contrib ジェネレーター)をDocker イメージから使用することで、ホストに何もインストールせずに実行できます。単一の均一なバーストではなく、複数のサービス、重要度、スパンステータス、メトリクスタイプにわたってテレメトリーを送信し、ClickStack の Search、Service Map、ダッシュボードに、単調なデータストリームではなく、現実的で多様なデータを表示させます。

env ファイルを読み込み、トークンを使用できるようにしてから、$OTLP_AUTH_TOKEN を参照してください。以下の tg ヘルパーは、ジェネレーターの出力をすべてログファイルにリダイレクトし、終了コードのみを表示します。これは、telemetrygen が authorization ヘッダー(OTLP トークンを含みます)を含む設定全体を stdout に出力するためです。その生の出力をチャットに表示しないでください。telemetrygen のヘッダー構文では、値を引用符で囲んだ文字列にする必要があります:key="value"。

WORKDIR="${WORKDIR:-$HOME/clickstack-otel-collector}"; ENV_FILE="$WORKDIR/collector.env"
[ -f "$WORKDIR/creds.env" ] && . "$WORKDIR/creds.env"; set -a; . "$ENV_FILE"; set +a

TG_IMAGE=ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest
NET=clickstack-net
ENDPOINT=clickstack-otel-collector:4317
TG_LOG="$WORKDIR/telemetrygen.log"; : > "$TG_LOG"

tg() {
  # usage: tg <logs|traces|metrics> [extra telemetrygen flags...]
  # Output (which contains the token in the echoed config) goes to $TG_LOG, never the terminal.
  local signal="$1"; shift
  docker run --rm --network "$NET" "$TG_IMAGE" "$signal" \
    --otlp-endpoint "$ENDPOINT" \
    --otlp-insecure \
    --otlp-header "authorization=\"$OTLP_AUTH_TOKEN\"" \
    --rate 10 --duration 15s "$@" >>"$TG_LOG" 2>&1
  echo "$signal exit=$?"
}

既存のコレクターパス: NET と ENDPOINT を、ご自身のコレクターに接続できるよう設定してください。コレクターがこのホストで実行されている場合は、--network host 形式のアクセスを使用するか、ENDPOINT に公開済みのアドレスを指定し、authorization ヘッダー(またはその他の認証情報)をレシーバーが求める値に設定してください。それ以外は以下と同じです。

成功の判断には、ジェネレーターのログではなく、終了コードと行数を使用してください。 理由は 2 つあります。1 つ目は、ログに OTLP トークンが含まれているため(上記参照)、表示しないでください。2 つ目は、ログにはノイズが多く、--duration が経過すると、実行のたびに rpc error: code = Canceled desc = grpc: the client connection is closing で終了するためです。これは想定どおりの終了であり、失敗ではありません。成功すると、tg ヘルパーは <signal> exit=0 を出力します。失敗を調査する必要がある場合は、ログ全体を表示せず、実際の兆候を grep で検索してください。たとえば grep -c Unauthenticated "$TG_LOG" を実行します(件数が 0 以外で、終了コードも 0 以外の場合、authorization ヘッダーが一致していません)。以下の検証クエリで行数を確認し、全体が成功したことを確かめてください。

属性値を引用符で囲み、内側の二重引用符がシェルで保持されるようにしてください。 telemetrygen では、各属性を key="value"(二重引用符をそのまま含む形式)にする必要があります。引用符のない key=value は value should be a string wrapped in double quotes というエラーになり、受け付けられません。--otlp-attributes deployment.environment="production" と記述すると、bash が引用符を削除し、コンテナには deployment.environment=production が渡されるため、処理は失敗します。引数全体をシングルクォートで囲み、内側の二重引用符がコンテナに渡るようにしてください。これは tg ヘルパーが認証ヘッダーに対して行っている方法と同じです。

重要度と本文が異なる 2 つのサービスのログ。エラー行も含みます:

tg logs --service checkout --severity-text Info  --severity-number 9 \
  --body "checkout completed" \
  --otlp-attributes 'deployment.environment="production"' \
  --telemetry-attributes 'http.method="POST"'
tg logs --service payment  --severity-text Error --severity-number 17 \
  --body "payment gateway timeout" \
  --otlp-attributes 'deployment.environment="production"' \
  --telemetry-attributes 'http.status_code="500"'

子スパンを含むトレース、正常なサービス、エラーが発生しているサービス(これによりサービスマップとエラービューにデータが表示されます):

tg traces --service checkout --child-spans 4 --span-duration 120ms --status-code Ok \
  --otlp-attributes 'deployment.environment="production"' \
  --telemetry-attributes 'http.route="/cart"'
tg traces --service payment  --child-spans 3 --span-duration 400ms --status-code Error \
  --otlp-attributes 'deployment.environment="production"' \
  --telemetry-attributes 'http.route="/charge"'

一般的な3種類のメトリクスにわたるデータ。これにより、ダッシュボードでゲージ、カウンター、分布を確認できます:

tg metrics --service checkout --metric-type Sum
tg metrics --service checkout --metric-type Gauge
tg metrics --service payment  --metric-type Histogram

(--metric-type には Gauge、Sum、Histogram、または ExponentialHistogram を指定できます。gRPC ではなく HTTP 経路を試すには、--otlp-endpoint clickstack-otel-collector:4318 とともに --otlp-http を追加します。)

コレクターがバッチをフラッシュするまで約15秒待ち、テーブルが存在することを確認します:

clickhousectl cloud service query --id "$SERVICE_ID" --query \
  "SELECT name FROM system.tables WHERE database='otel' ORDER BY name"

次に、行が取り込まれていることを確認します。シグナルに依存せず、シグナルごとの列名をハードコードせずに済む parts.rows でカウントします:

clickhousectl cloud service query --id "$SERVICE_ID" --query \
  "SELECT table, sum(rows) AS rows
   FROM system.parts
   WHERE database='otel' AND active
     AND table IN ('otel_logs','otel_traces',
                   'otel_metrics_sum','otel_metrics_gauge',
                   'otel_metrics_histogram','otel_metrics_exponential_histogram',
                   'otel_metrics_summary')
   GROUP BY table ORDER BY table"

otel_logs、otel_traces、otel_metrics_sum、otel_metrics_gauge、otel_metrics_histogram の rows が0以外になっているはずです。シグナルが欠けている場合:

  1. コレクターのログ(docker logs --tail 50 clickstack-otel-collector)を確認し、エクスポートエラーがないか調べます。
  2. authorization ヘッダーが $OTLP_AUTH_TOKEN と一致していることを確認します:grep -c Unauthenticated "$TG_LOG"(0以外のカウントは不一致を意味します。メッセージ全文は code = Unauthenticated desc = provided authorization does not match expected scheme or token です)。ログにはトークンが含まれているため、ログを出力せずに grep してください。
  3. CLICKHOUSE_ENDPOINT のスキームが https:// で、ポートが :8443 になっていることを再確認します。
  4. メトリクスの種類によっては、フラッシュに時間がかかります。失敗と判断する前に、さらに30秒待ってからカウントを再実行してください。

期待されるすべてのシグナルで行数が0以外になるまで、先に進まないでください。


ステップ8:サービスが起動していることを確認し、ClickStack のオンボーディングを完了する

ClickHouse に行が存在することと、ユーザーが ClickStack でテレメトリを確認できることは同じではありません。ClickStack の UI では、データソースを自動検出するためのオンボーディングを一度行う必要があります。ClickHouse サービスがその間にアイドル状態で一時停止していると、この手順は失敗します。

まず、サービスが起動していることを確認します。 オンボーディングでソースが表示されない最も一般的な原因なので、この手順を省略しないでください。実際にクエリを実行し、成功することを確認します:

clickhousectl cloud service query --id "$SERVICE_ID" --query "SELECT 1"

結果が 1 なら、サービスは起動しています。温かい状態が続いている間に、すぐ下のコンソール手順に進んでください。エラーになるかタイムアウトする場合は、サービスがスリープ状態で、この呼び出しによって起動中です。数秒待って、1 が返るまで再実行してください。成功してから先に進みます。

次に、ユーザーがオンボーディングを完了できるよう、手順を明示して案内します。 単に「完了」と伝えるのではなく、ソースが表示されるのはこのフローを完了した後だけなので、クリックする箇所を一つずつ説明してください:

  1. ClickHouse Cloud コンソールに移動し、対象のサービスを開きます。
  2. 左側のメニューで ClickStack を選択します。
  3. Getting Started に進み、オンボーディングフローに従います。
  4. コレクターのセットアップや設定、または取り込みの開始を求めるプロンプトは無視してください。 これらは上記の手順ですでに完了しています。これらの画面はそのままスキップ(クリックして進む/「Next」を選択)し、ソース検出に進んでください。コンソールでコレクターのセットアップをやり直す必要はなく、混乱を招くだけです。
  5. データソースは自動検出されます。otel データベースのログ、トレース、メトリクスが自動的に検出され、Search ビューとダッシュボードビューにデータが表示されます。

直接リンクは https://console.clickhouse.cloud/services/<SERVICE_ID>/clickstack です($SERVICE_ID を置き換えてください)。

ソース検出で何も表示されない場合、データ送信からコンソールでの操作までの間にサービスがアイドル状態で一時停止した可能性が非常に高いです。ユーザーに上記の SELECT 1 起動クエリを再実行してもらい、その後、原因の分かりにくいエラーのデバッグをユーザーに任せるのではなく、検出を再実行してもらってください。


ステップ 9:要約して引き継ぐ(シークレットを繰り返さない)

おおよそ次の形式で要約を出力します。トークンは参照されるだけで、表示されません。SQL のパスワードは一切表示されず、コレクターはユーザーが停止するまで実行され続けます。「停止方法」の行は、選択したデプロイモードに合わせて調整してください。

✅ ClickStack is set up and ingesting telemetry for service <SERVICE_NAME> (<SERVICE_ID>).
   Complete onboarding in the console (Step 8) to auto-detect the sources and see your data.

Collector
  ▸ New local collector via <Docker Compose | docker run>  (or: configured your existing collector)
  ▸ Send OTLP gRPC to: localhost:4317
  ▸ Send OTLP HTTP to: localhost:4318
  ▸ Health check:      http://localhost:13133/   (local collector only)
  ▸ Required header:   authorization: <OTLP token>
       (retrieve with:  grep OTLP_AUTH_TOKEN <WORKDIR>/collector.env)

ClickHouse target
  ▸ Endpoint: <CLICKHOUSE_ENDPOINT>
  ▸ SQL user: hyperdx_ingest   (password in <WORKDIR>/collector.env, mode 0600)
  ▸ Database: otel

Finish in the ClickHouse Cloud console:
  ▸ Open the service, select ClickStack in the left menu, then Getting Started,
    and complete onboarding to auto-detect sources.
  ▸ https://console.clickhouse.cloud/services/<SERVICE_ID>/clickstack

続けて、次の内容を自分の言葉でユーザーに伝えます。

  1. すべてのシークレットは <WORKDIR>/collector.env(モード 0600)に保存されています。機密情報がこのチャットに貼り付けられたり、docker run のコマンドラインに渡されたりすることはありません。
  2. コレクターはユーザーが停止するまで実行され続けます。Compose の場合、cd <WORKDIR> && docker compose down で停止し、docker compose up -d で再起動できます。個別の Docker の場合は、docker stop clickstack-otel-collector と docker start clickstack-otel-collector を実行します。
  3. このホスト上のアプリケーション、SDK、エージェントは、env ファイルに記載された authorization ヘッダーを使って、localhost:4317(gRPC)または localhost:4318(HTTP)に OTLP を送信できるようになりました。
  4. ClickHouse Cloud サービスはアイドル状態になると一時停止します。ClickStack に最近のデータが表示されない場合、サービスがスリープ状態になっているだけの可能性があります。新しいテレメトリーを送信するか、クエリを実行するとサービスが起動します。

クリーンアップ(ユーザーが明示的に求めた場合のみ)

# Docker Compose deployment:
( cd "$WORKDIR" && docker compose down )

# Individual Docker deployment:
docker rm -f clickstack-otel-collector
docker network rm clickstack-net 2>/dev/null || true

# Either deployment, remove the ingest user:
clickhousectl cloud service query --id "$SERVICE_ID" --query "DROP USER IF EXISTS hyperdx_ingest"

# Optionally remove the local files once they are no longer needed:
# rm -f "$WORKDIR/collector.env" "$WORKDIR/svc.json" "$WORKDIR/docker-compose.yaml"

otel データベースは削除しないでください。ユーザーが保持したいテレメトリーが含まれています。

コメント