0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Azure Cloud Shell で otelcol を動かして Application Insights に OpenTelemetry テレメトリを送ってみる

0
Posted at

目的

Azure Application Insightsにotelcol-contribを使ってOpenTelemetryでテレメトリを送ることを確かめます。

具体的にはAzure Cloud Shell 上のCurlでHTTPリクエストを発行し、Azure Cloud Shell 上のotelcol-contrib に送り、そこからexporterによりEntra ID認証をしてApplication Insightsに送り、反映されることを確認します。

アプリケーションの場合はパッケージが用意されているのでそれに従い設定すればよいですが、この確認のためにアプリを書きたくなかったので今回この手順で試してみました。

前提

  • サービスプリンシパルを使った認証で行う
  • サブスクリプションに対する所有者(共同作成者 + ユーザアクセス管理者)の権限が必要
    • リソースグループを含めたリソースの作成、role-assignmentを行うため

作業

Azure Portalを開き、Cloud Shellを起動しBashでセッションを起動して始めます。

変数を準備する

# 必要に応じて変更
LOCATION="japaneast"
PREFIX="oteltest$RANDOM"

RG_NAME="rg-${PREFIX}"
LAW_NAME="law-${PREFIX}"
APPINSIGHTS_NAME="appi-${PREFIX}"
SP_NAME="sp-${PREFIX}"

echo "RG_NAME=${RG_NAME}"
echo "LAW_NAME=${LAW_NAME}"
echo "APPINSIGHTS_NAME=${APPINSIGHTS_NAME}"
echo "SP_NAME=${SP_NAME}"
echo "LOCATION=${LOCATION}"

現在のサブスクリプション確認、設定値取得

異なる場合は az account set -s "サブスクリプション名" で変更し再実行

read SUBSCRIPTION_ID SUBSCRIPTION_NAME TENANT_ID < <(
  az account show \
    --query "{id:id,name:name,tenantId:tenantId}" \
    -o tsv
)

echo "SUBSCRIPTION_ID=${SUBSCRIPTION_ID}"
echo "SUBSCRIPTION_NAME=${SUBSCRIPTION_NAME}"
echo "TENANT_ID=${TENANT_ID}"

リソースが作成できるようproviderを登録

初回のみ、LogAnalytics WorkspaceとApplication Insightsリソースを作成するために以下のProviderを登録しておく必要がある

az provider register -n Microsoft.OperationalInsights
az provider register -n microsoft.insights

リソースグループ作成

read RG_ID < <(
  az group create \
    --name "${RG_NAME}" \
    --location "${LOCATION}" \
    --query "id" \
    -o tsv
)
echo "RG_ID=${RG_ID}"

Application Insights 用の Log Analytics Workspace 作成

read WORKSPACE_ID < <(
  az monitor log-analytics workspace create \
    --resource-group "${RG_NAME}" \
    --workspace-name "${LAW_NAME}" \
    --location "${LOCATION}" \
    --query "id" \
    -o tsv
)

echo "WORKSPACE_ID=${WORKSPACE_ID}"

Application Insights 作成

read APPINSIGHTS_ID APPINSIGHTS_CONNECTION_STRING INSTRUMENTATION_KEY < <(
  az monitor app-insights component create \
    --app "${APPINSIGHTS_NAME}" \
    --resource-group "${RG_NAME}" \
    --location "${LOCATION}" \
    --workspace "${WORKSPACE_ID}" \
    --query "{id:id,connectionString:connectionString,instrumentationKey:instrumentationKey}" \
    -o tsv
)

echo "APPINSIGHTS_ID=${APPINSIGHTS_ID}"
echo "APPINSIGHTS_CONNECTION_STRING=${APPINSIGHTS_CONNECTION_STRING}"
echo "INSTRUMENTATION_KEY=${INSTRUMENTATION_KEY}"

Application Insights のローカル認証を無効化

今回は Application Insights のローカル認証を無効化し、Entra ID 認証でテレメトリを取り込む構成を試します。InstrumentationKeyだけの認証をできないようにします。

az resource update \
  --ids "${APPINSIGHTS_ID}" \
  --set properties.DisableLocalAuth=true \
  -o none

az resource show \
  --ids "${APPINSIGHTS_ID}" \
  --query "properties" 

Service Principalを作成

今回はサービスプリンシパルで作業します。

read AZURE_CLIENT_ID AZURE_CLIENT_SECRET AZURE_TENANT_ID < <(
  az ad sp create-for-rbac \
    --name "${SP_NAME}" \
    --skip-assignment \
    --query "{appId:appId,password:password,tenant:tenant}" \
    -o tsv
)

echo "AZURE_CLIENT_ID=${AZURE_CLIENT_ID}"
echo "AZURE_TENANT_ID=${AZURE_TENANT_ID}"

Service Principalに権限を付与

ここは実務ではManaged IDに対して作業することになるはずです。

# Service PrincipalのObject ID取得

read SP_OBJECT_ID < <(
  az ad sp show \
    --id "${AZURE_CLIENT_ID}" \
    --query "id" \
    -o tsv
)

echo "SP_OBJECT_ID=${SP_OBJECT_ID}"

# Service Principalに権限を付与
# Monitoring Metrics Publisher=3913510d-42f4-4e42-8a64-420c390055eb

read ROLE_ASSIGNMENT_ID < <(
  az role assignment create \
    --assignee-object-id "${SP_OBJECT_ID}" \
    --assignee-principal-type ServicePrincipal \
    --role "Monitoring Metrics Publisher" \
    --scope "${APPINSIGHTS_ID}" \
    --query "id" \
    -o tsv
)

echo "ROLE_ASSIGNMENT_ID=${ROLE_ASSIGNMENT_ID}"

設定値の控えを取る

設定値を控えておきます。次のotelcol起動時にこの値を環境変数として設定すればそのまま使えます。

cat << __EOF__
export APPLICATIONINSIGHTS_CONNECTION_STRING="${APPINSIGHTS_CONNECTION_STRING}"
export AZURE_TENANT_ID="${AZURE_TENANT_ID}"
export AZURE_CLIENT_ID="${AZURE_CLIENT_ID}"
export AZURE_CLIENT_SECRET="${AZURE_CLIENT_SECRET}"
__EOF__

otelcol-contribの導入

Cloud Shell上に一時的にいれます。
otelcol-contrib に同梱されている Azure Monitor exporterazureauth extension を利用します。

mkdir -p ~/otelcol-ai
cd ~/otelcol-ai

# https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/latest # で、tag_name値を確認してバージョンを合わせる
OTELCOL_VERSION=v0.154.0

# Cloud Shell上のArchがx86_64なのでamd64バイナリを利用
OTEL_TGZ="otelcol-contrib_${OTELCOL_VERSION#v}_linux_amd64.tar.gz"
OTEL_URL="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/${OTELCOL_VERSION}/${OTEL_TGZ}"

echo "OTELCOL_VERSION=${OTELCOL_VERSION}"
echo "OTEL_URL=${OTEL_URL}"

curl -fL "${OTEL_URL}" -o "${OTEL_TGZ}"
tar -xzf "${OTEL_TGZ}" && rm "${OTEL_TGZ}"

# コマンド実行できることを確認
./otelcol-contrib --version

otelcolの設定ファイルを作成し検証

debugとazuremonitorを利用し手出力するようにします。ただ、デフォルトで起動してしまう prometheus exporter のポート番号を8889にずらしています。(Cloud Shell上の8888ポートがぶつかったため)

マネージドIDを扱う場合は、extensions.azure_auth.managed_identity を指定するようです。

# 先ほど採取した環境変数の値を設定(同じセッションなら流れでこのまま実行してもよい)
export APPLICATIONINSIGHTS_CONNECTION_STRING="${APPINSIGHTS_CONNECTION_STRING}"
export AZURE_TENANT_ID="${AZURE_TENANT_ID}"
export AZURE_CLIENT_ID="${AZURE_CLIENT_ID}"
export AZURE_CLIENT_SECRET="${AZURE_CLIENT_SECRET}"

cat << '__YAML__' > otelcol-azuremonitor.yaml
extensions:
  azure_auth:
    service_principal:
      tenant_id: ${env:AZURE_TENANT_ID}
      client_id: ${env:AZURE_CLIENT_ID}
      client_secret: ${env:AZURE_CLIENT_SECRET}
    scopes:
      - https://monitor.azure.com/.default

receivers:
  otlp:
    protocols:
      http:
        endpoint: 127.0.0.1:4318

processors:
  batch:
    timeout: 5s

exporters:
  debug:
    verbosity: detailed

  azuremonitor:
    connection_string: ${env:APPLICATIONINSIGHTS_CONNECTION_STRING}
    auth:
      authenticator: azure_auth
    maxbatchinterval: 5s
    sending_queue:
      enabled: true

service:
  extensions:
    - azure_auth

  telemetry:
    logs:
      level: debug
    metrics:
      readers:
        - pull:
            exporter:
              prometheus:
                host: 127.0.0.1
                port: 8889

  pipelines:
    traces:
      receivers:
        - otlp
      processors:
        - batch
      exporters:
        - debug
        - azuremonitor

    metrics:
      receivers:
        - otlp
      processors:
        - batch
      exporters:
        - debug
        - azuremonitor

    logs:
      receivers:
        - otlp
      processors:
        - batch
      exporters:
        - debug
        - azuremonitor
__YAML__

./otelcol-contrib validate --config otelcol-azuremonitor.yaml

validateコマンドの結果、何も出力されなければOK。

環境変数が未設定だとエラーが出る(Error: extensions::azure_auth::service_principal: empty "tenant_id" field など)

otelcolを起動

cd ~/otelcol-ai
./otelcol-contrib --config otelcol-azuremonitor.yaml 2>&1 | tee otelcol.log

待ち受け状態になればOK。ポート番号が使用中だったり問題があると終了するので注意。

別セッションでcurlで送る

新しいセッションを開始し、curlでotelcolに送り、Application Insightsに送られることを確認します。

もし curlで接続できない場合は、同一セッションで otelcol をバックグラウンド起動して curl してください。

# ダミーデータ作成。処理時間約1秒かかったテレメトリを送る
START_TIME=$(date -d "1 second ago" +%s%N)
END_TIME=$(date +%s%N)
TRACE_ID=$(openssl rand -hex 16)
SPAN_ID=$(openssl rand -hex 8)

# otelcolへ送信
curl -i \
  -X POST http://127.0.0.1:4318/v1/traces \
  -H "Content-Type: application/json" \
  --data-binary @- << __JSON__
{
  "resourceSpans": [
    {
      "resource": {
        "attributes": [
          {
            "key": "service.name",
            "value": {
              "stringValue": "curl-to-otelcol-to-azuremonitor"
            }
          },
          {
            "key": "deployment.environment",
            "value": {
              "stringValue": "cloudshell"
            }
          }
        ]
      },
      "scopeSpans": [
        {
          "scope": {
            "name": "manual-curl"
          },
          "spans": [
            {
              "traceId": "${TRACE_ID}",
              "spanId": "${SPAN_ID}",
              "name": "curl-generated-span",
              "kind": "SPAN_KIND_SERVER",
              "startTimeUnixNano": "${START_TIME}",
              "endTimeUnixNano": "${END_TIME}",
              "attributes": [
                {
                  "key": "http.request.method",
                  "value": {
                    "stringValue": "GET"
                  }
                },
                {
                  "key": "url.path",
                  "value": {
                    "stringValue": "/curl/test"
                  }
                },
                {
                  "key": "http.response.status_code",
                  "value": {
                    "intValue": "200"
                  }
                }
              ],
              "status": {
                "code": "STATUS_CODE_OK"
              }
            }
          ]
        }
      ]
    }
  ]
}
__JSON__

echo
echo "TRACE_ID=${TRACE_ID}"
echo "SPAN_ID=${SPAN_ID}"

curlのHTTPリクエストが200で正常終了しています。

また、otelcol側も以下のようなazuremonitorexporterのログが確認できればApplication Insights側にも送られているはずです。ここが400等の場合はリクエストデータ不備の可能性があります。

2026-06-23T00:13:02.440Z debug azuremonitorexporter@v0.154.0/factory.go:151 Response: 200 {"resource": {"service.instance.id": "12f7fa2d-fd32-4943-b9fc-cd35fd635e6a", "service.name": "otelcol-contrib", "service.version": "0.154.0"}, "otelcol.component.id": "azuremonitor", "otelcol.component.kind": "exporter", "otelcol.signal": "metrics"}

うまくいくとApplication Insights上に確認でき、取り込まれたことがわかります。

image.png

後始末

# Azure リソース削除
az group delete \
  --name "${RG_NAME}" \
  --yes \
  --no-wait

# Service Principal の削除
az ad sp delete \
  --id "${AZURE_CLIENT_ID}"
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?