📉

Cloud RunスケールアウトでPoints must be written in orderが出てメトリクス欠落した話

に公開

想定読者

  • Cloud Run + OpenTelemetry Collector + Cloud Monitoringを触っている人
  • 「負荷はかかってるのにメトリクスが来ない」系の障害に遭遇した人

何が起きたか(症状)

Cloud Runのマルチコンテナ構成(アプリ + OTel Collector sidecar)を動かしていたところ、負荷をかけているはずなのにCloud Monitoringのメトリクスが「増えない/見えない」状態になりました。

え?なにそれ?と思いCloud Runのログを見てみると、ログには次のメッセージが出ていました。

Exporting failed. Dropping data.

write for resource failed: Points must be written in order.
One or more of the points specified had an older start time 
than the most recent point.

え〜意味合いとしては「メトリクスの書き込みにおいて、最新のポイントより古い時間のメトリクスが指定されていたため書き込みに失敗したよ」ってことに読み取れました。

は?なんじゃそれ?どういうこっちゃ?というわけで頑張って調べてみることにしました。

システム構成

前提条件となる情報を整理します。

今回は、以下のようにCloud RunのアプリからsidecarのOTel Collectorを経由して、Cloud Monitoringにメトリクスを送るという構成をとっていました。

障害発生の状況

  • Cloud Runに対して、約5rps相当の負荷でリクエストを送っていた
  • 負荷をかけていた時間帯にインスタンスサイズが2にスケールアウトしていた
  • Points must be written in orderが発生していたインスタンスは1つのinstanceIdに集中していた
  • Cloud Monitoringで表示してみたメトリクス数が、与えていた負荷より明らかに少なかった

インスタンス数の増減の確認(run.googleapis.com/container/instance_count
cloud run scaleout

実際のログ(一部データはマスキングしてます)

{
  "insertId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "labels": {
    "container_name": "otel-collector",
    "instanceId": "60af...[TRUNCATED]...8b2e"
  },
  "logName": "projects/my-sample-project/logs/run.googleapis.com%2Fstderr",
  "receiveTimestamp": "2026-01-18T19:21:28.078674280Z",
  "resource": {
    "labels": {
      "configuration_name": "sample-api-service",
      "location": "asia-northeast1",
      "project_id": "my-sample-project",
      "revision_name": "sample-api-service-00001-abc",
      "service_name": "sample-api-service"
    },
    "type": "cloud_run_revision"
  },
  "textPayload": "2026-01-18T19:21:27.929Z\terror\tinternal/queue_sender.go:49\tExporting failed. Dropping data.\t{\"resource\": {\"service.instance.id\": \"00000000-0000-0000-0000-000000000000\", \"service.name\": \"my-app-service\", \"service.version\": \"1.0.0\"}, \"otelcol.component.id\": \"googlecloud\", \"otelcol.component.kind\": \"exporter\", \"otelcol.signal\": \"metrics\", \"error\": \"failed to export metrics to projects/my-sample-project: rpc error: code = InvalidArgument desc = One or more TimeSeries could not be written: timeSeries[0,1] (example metric.type=\\\"workload.googleapis.com/http.server.requests\\\", metric.labels={\\\"http_route\\\": \\\"/api/v1/resource/{id}\\\", \\\"instrumentation_source\\\": \\\"otel-sdk\\\", \\\"http_request_method\\\": \\\"GET\\\", \\\"http_response_status_code\\\": \\\"200\\\", \\\"service_name\\\": \\\"my-app-service\\\", \\\"url_scheme\\\": \\\"https\\\"}, resource.type=\\\"generic_node\\\", resource.labels={\\\"location\\\": \\\"global\\\", \\\"node_id\\\": \\\"\\\", \\\"namespace\\\": \\\"\\\"}): write for resource failed: Points must be written in order. One or more of the points specified had an older start time than the most recent point.\\nerror details: name = Unknown  desc = total_point_count:2 errors:{status:{code:3} point_count:2}\", \"dropped_items\": 2}",
  "timestamp": "2026-01-18T19:21:27.928656Z"
}

何が原因だったか

上記の状況を踏まえて設定ファイル周りを見て試した結果、原因の特定に成功しました。

resourcedetection(gcp)の設定漏れ

え〜、Cloud Runに限らずですが、sidecarでOTelを入れる際にはResource Detection Processorを使ってホストの情報をメトリクスに付与してあげる必要があります。

これを忘れると、メトリクスにホストの情報が付与されず意図しない動作をする可能性があります。

今回でいえば、設定不足によりホストの情報がメトリクスに付与されなかった結果、複数インスタンスが違うホストであることがメトリクスで識別できない状態になり、同じメトリクスとして扱われ、結果時系列のズレによるポイント登録のエラーが発生したのだと考えられます。

具体的にどのような情報がメトリクスに付与されるのかはこちらを参照。

ぶっちゃけ、該当のどの情報の不足によって今回の事態が起きたのかは正確には把握できてませんが、とりあえず基本的な設定をうっかり忘れていたというオチだったという感じです。

設定ファイルはこちら

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

processors:
  ###################################
  # これが抜けてた〜〜〜〜〜〜〜〜!!!!
  ###################################
  resourcedetection:
    detectors: [gcp]
    timeout: 2s
    override: true
  batch: {}

exporters:
  debug:
    verbosity: detailed
  googlecloud:
    project: "my-sample-project"

service:
  extensions: [health_check]
  pipelines:
    traces:
      receivers: [otlp]
      # ここも修正
      processors: [resourcedetection, batch]
      exporters: [debug, googlecloud]
    metrics:
      receivers: [otlp]
      # ここも修正
      processors: [resourcedetection, batch]
      exporters: [debug, googlecloud]

extensions:
  health_check:
    endpoint: 0.0.0.0:13133
    check_collector_pipeline:
      enabled: true
      interval: 10s
      exporter_failure_threshold: 2

どう直したか(解決策)

設定追加して動作確認したら直ってました。あ〜。

実は原因はさまざま

自分の場合は単なる設定漏れでしたが、世界には同じような問題で原因がなかなか掴めず苦戦している人たちがちょいちょいいらっしゃいます。時系列エラーが何によって起きているのかを正確に捉えるのは難しいんだなと思う今日この頃です。いや〜単純なミスでよかったホント。

さいごに

パッとググった時に全然情報が出てこなかったので、自分で記事にしてみました。どなたかの助けになれば幸いです。

Discussion