[{"data":1,"prerenderedAt":1759},["ShallowReactive",2],{"blog-ja-opentelemetry-distributed-tracing":3,"blog-ja-opentelemetry-distributed-tracing-alt":527},{"id":4,"title":5,"author":6,"body":7,"date":1743,"description":1744,"extension":1745,"image":91,"locale":1746,"meta":1747,"navigation":527,"path":1748,"seo":1749,"stem":1750,"tags":1751,"__hash__":1758},"blog\u002Fblog\u002Fja\u002Fopentelemetry-distributed-tracing.md","OpenTelemetry で分散トレーシングを実装する: 入門から実践まで","Kubo Team",{"type":8,"value":9,"toc":1716},"minimark",[10,28,32,36,44,48,55,78,81,92,112,120,124,139,143,149,153,421,425,731,737,740,744,750,755,789,882,887,930,934,942,1028,1032,1141,1147,1151,1155,1169,1270,1274,1282,1403,1406,1417,1423,1426,1429,1432,1441,1615,1618,1644,1652,1655,1658,1689,1699,1712],[11,12,13,14,21,22,27],"p",{},"マイクロサービスアーキテクチャでは、1 つのリクエストが複数のサービスを横断して処理されます。問題が発生した際に「どのサービスの、どの処理で遅延が発生しているのか」を特定するのは容易ではありません。CNCF Graduated プロジェクトである ",[15,16,20],"a",{"href":17,"rel":18},"https:\u002F\u002Fopentelemetry.io\u002F",[19],"nofollow","OpenTelemetry"," は、分散トレーシングを標準化し、この課題を解決するオブザーバビリティフレームワークです。",[15,23,26],{"href":24,"rel":25},"https:\u002F\u002Fkubo.hexabase.io\u002F",[19],"Kubo"," のような K3s ベースの Kubernetes 環境でも、OpenTelemetry を導入することでサービス間のリクエストフローを完全に可視化できます。",[29,30,31],"h2",{"id":31},"分散トレーシングの基本概念",[33,34,35],"h3",{"id":35},"なぜ分散トレーシングが必要なのか",[11,37,38,43],{},[15,39,42],{"href":40,"rel":41},"https:\u002F\u002Fthenewstack.io\u002Fhow-opentelemetry-works-tracing-metrics-and-logs-on-kubernetes\u002F",[19],"The New Stack の解説","が指摘するように、Kubernetes 上のマイクロサービス環境では、メトリクスとログだけでは不十分です。あるリクエストが Pod 間、ノード間、Namespace 間を横断する際の全体像を把握するには、分散トレーシングが不可欠です。",[33,45,47],{"id":46},"opentelemetry-のテレメトリシグナル","OpenTelemetry のテレメトリシグナル",[11,49,50,54],{},[15,51,20],{"href":52,"rel":53},"https:\u002F\u002Fopentelemetry.io\u002Fdocs\u002F",[19]," はベンダーニュートラルなオブザーバビリティフレームワークで、3 つのテレメトリシグナルを統合的に扱います：",[56,57,58,66,72],"ul",{},[59,60,61,65],"li",{},[62,63,64],"strong",{},"トレース（Traces）",": リクエストのエンドツーエンドのフローを追跡。Span の親子関係でサービス間の呼び出しチェーンを表現",[59,67,68,71],{},[62,69,70],{},"メトリクス（Metrics）",": 定量的な測定値。リクエスト数、レイテンシ、エラー率など",[59,73,74,77],{},[62,75,76],{},"ログ（Logs）",": イベントの記録。トレース ID と相関付けることで、特定のリクエストに関連するログを特定",[33,79,80],{"id":80},"トレーシングの構成要素",[82,83,88],"pre",{"className":84,"code":86,"language":87},[85],"language-text","Trace\n├── Span A (API Gateway, 150ms)\n│   ├── Span B (Auth Service, 20ms)\n│   └── Span C (Product Service, 100ms)\n│       ├── Span D (Database Query, 40ms)\n│       └── Span E (Cache Lookup, 5ms)\n","text",[89,90,86],"code",{"__ignoreMap":91},"",[56,93,94,100,106],{},[59,95,96,99],{},[62,97,98],{},"Trace",": 1 つのリクエストの全体的な処理フロー",[59,101,102,105],{},[62,103,104],{},"Span",": Trace 内の個々の操作単位。開始時刻、終了時刻、属性、イベントを持つ",[59,107,108,111],{},[62,109,110],{},"Context",": Trace ID と Span ID を含む情報。サービス間で伝播される",[11,113,114,119],{},[15,115,118],{"href":116,"rel":117},"https:\u002F\u002Fwww.hexabase.com\u002Fproduct\u002Fcaptain-ai\u002F",[19],"Captain.AI"," はトレーシングデータを AI で分析し、パフォーマンスボトルネックの自動検出と最適化の提案を行います。",[29,121,123],{"id":122},"opentelemetry-collector-の構成","OpenTelemetry Collector の構成",[11,125,126,127,132,133,138],{},"OpenTelemetry Collector は、テレメトリデータの受信、処理、エクスポートを担うベンダー非依存のコンポーネントです。",[15,128,131],{"href":129,"rel":130},"https:\u002F\u002Fuptrace.dev\u002Fopentelemetry\u002Fdistributed-tracing",[19],"Uptrace の解説","と ",[15,134,137],{"href":135,"rel":136},"https:\u002F\u002Flogit.io\u002Fblog\u002Fpost\u002Fopentelemetry-distributed-tracing-implementation\u002F",[19],"Logit.io の実装ガイド","を参考に構成を解説します。",[33,140,142],{"id":141},"collector-のアーキテクチャ","Collector のアーキテクチャ",[82,144,147],{"className":145,"code":146,"language":87},[85],"Receivers → Processors → Exporters\n  (OTLP)     (batch)      (Jaeger)\n  (Zipkin)   (filter)     (Tempo)\n  (Jaeger)   (sampling)   (OTLP)\n",[89,148,146],{"__ignoreMap":91},[33,150,152],{"id":151},"kubernetes-へのデプロイdaemonset-方式","Kubernetes へのデプロイ（DaemonSet 方式）",[82,154,158],{"className":155,"code":156,"language":157,"meta":91,"style":91},"language-yaml shiki shiki-themes tokyo-night","apiVersion: apps\u002Fv1\nkind: DaemonSet\nmetadata:\n  name: otel-collector\n  namespace: observability\nspec:\n  selector:\n    matchLabels:\n      app: otel-collector\n  template:\n    metadata:\n      labels:\n        app: otel-collector\n    spec:\n      containers:\n      - name: collector\n        image: otel\u002Fopentelemetry-collector-contrib:0.98.0\n        args: [\"--config=\u002Fconf\u002Fotel-collector-config.yaml\"]\n        volumeMounts:\n        - name: config\n          mountPath: \u002Fconf\n      volumes:\n      - name: config\n        configMap:\n          name: otel-collector-config\n","yaml",[89,159,160,177,188,197,208,219,227,235,243,253,261,269,277,287,295,303,318,329,351,359,372,383,391,402,410],{"__ignoreMap":91},[161,162,165,169,173],"span",{"class":163,"line":164},"line",1,[161,166,168],{"class":167},"s0U2E","apiVersion",[161,170,172],{"class":171},"sAklC",":",[161,174,176],{"class":175},"sPY7s"," apps\u002Fv1\n",[161,178,180,183,185],{"class":163,"line":179},2,[161,181,182],{"class":167},"kind",[161,184,172],{"class":171},[161,186,187],{"class":175}," DaemonSet\n",[161,189,191,194],{"class":163,"line":190},3,[161,192,193],{"class":167},"metadata",[161,195,196],{"class":171},":\n",[161,198,200,203,205],{"class":163,"line":199},4,[161,201,202],{"class":167},"  name",[161,204,172],{"class":171},[161,206,207],{"class":175}," otel-collector\n",[161,209,211,214,216],{"class":163,"line":210},5,[161,212,213],{"class":167},"  namespace",[161,215,172],{"class":171},[161,217,218],{"class":175}," observability\n",[161,220,222,225],{"class":163,"line":221},6,[161,223,224],{"class":167},"spec",[161,226,196],{"class":171},[161,228,230,233],{"class":163,"line":229},7,[161,231,232],{"class":167},"  selector",[161,234,196],{"class":171},[161,236,238,241],{"class":163,"line":237},8,[161,239,240],{"class":167},"    matchLabels",[161,242,196],{"class":171},[161,244,246,249,251],{"class":163,"line":245},9,[161,247,248],{"class":167},"      app",[161,250,172],{"class":171},[161,252,207],{"class":175},[161,254,256,259],{"class":163,"line":255},10,[161,257,258],{"class":167},"  template",[161,260,196],{"class":171},[161,262,264,267],{"class":163,"line":263},11,[161,265,266],{"class":167},"    metadata",[161,268,196],{"class":171},[161,270,272,275],{"class":163,"line":271},12,[161,273,274],{"class":167},"      labels",[161,276,196],{"class":171},[161,278,280,283,285],{"class":163,"line":279},13,[161,281,282],{"class":167},"        app",[161,284,172],{"class":171},[161,286,207],{"class":175},[161,288,290,293],{"class":163,"line":289},14,[161,291,292],{"class":167},"    spec",[161,294,196],{"class":171},[161,296,298,301],{"class":163,"line":297},15,[161,299,300],{"class":167},"      containers",[161,302,196],{"class":171},[161,304,306,310,313,315],{"class":163,"line":305},16,[161,307,309],{"class":308},"sgJMe","      -",[161,311,312],{"class":167}," name",[161,314,172],{"class":171},[161,316,317],{"class":175}," collector\n",[161,319,321,324,326],{"class":163,"line":320},17,[161,322,323],{"class":167},"        image",[161,325,172],{"class":171},[161,327,328],{"class":175}," otel\u002Fopentelemetry-collector-contrib:0.98.0\n",[161,330,332,335,337,340,343,346,348],{"class":163,"line":331},18,[161,333,334],{"class":167},"        args",[161,336,172],{"class":171},[161,338,339],{"class":171}," [",[161,341,342],{"class":171},"\"",[161,344,345],{"class":175},"--config=\u002Fconf\u002Fotel-collector-config.yaml",[161,347,342],{"class":171},[161,349,350],{"class":171},"]\n",[161,352,354,357],{"class":163,"line":353},19,[161,355,356],{"class":167},"        volumeMounts",[161,358,196],{"class":171},[161,360,362,365,367,369],{"class":163,"line":361},20,[161,363,364],{"class":308},"        -",[161,366,312],{"class":167},[161,368,172],{"class":171},[161,370,371],{"class":175}," config\n",[161,373,375,378,380],{"class":163,"line":374},21,[161,376,377],{"class":167},"          mountPath",[161,379,172],{"class":171},[161,381,382],{"class":175}," \u002Fconf\n",[161,384,386,389],{"class":163,"line":385},22,[161,387,388],{"class":167},"      volumes",[161,390,196],{"class":171},[161,392,394,396,398,400],{"class":163,"line":393},23,[161,395,309],{"class":308},[161,397,312],{"class":167},[161,399,172],{"class":171},[161,401,371],{"class":175},[161,403,405,408],{"class":163,"line":404},24,[161,406,407],{"class":167},"        configMap",[161,409,196],{"class":171},[161,411,413,416,418],{"class":163,"line":412},25,[161,414,415],{"class":167},"          name",[161,417,172],{"class":171},[161,419,420],{"class":175}," otel-collector-config\n",[33,422,424],{"id":423},"collector-の設定例","Collector の設定例",[82,426,428],{"className":155,"code":427,"language":157,"meta":91,"style":91},"apiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: otel-collector-config\n  namespace: observability\ndata:\n  otel-collector-config.yaml: |\n    receivers:\n      otlp:\n        protocols:\n          grpc:\n            endpoint: 0.0.0.0:4317\n          http:\n            endpoint: 0.0.0.0:4318\n\n    processors:\n      batch:\n        timeout: 5s\n        send_batch_size: 1024\n      memory_limiter:\n        check_interval: 1s\n        limit_mib: 512\n      tail_sampling:\n        decision_wait: 10s\n        policies:\n        - name: errors-policy\n          type: status_code\n          status_code: {status_codes: [ERROR]}\n        - name: slow-traces\n          type: latency\n          latency: {threshold_ms: 1000}\n        - name: probabilistic\n          type: probabilistic\n          probabilistic: {sampling_percentage: 10}\n\n    exporters:\n      otlp\u002Ftempo:\n        endpoint: tempo:4317\n        tls:\n          insecure: true\n      otlp\u002Fjaeger:\n        endpoint: jaeger-collector:4317\n        tls:\n          insecure: true\n\n    service:\n      pipelines:\n        traces:\n          receivers: [otlp]\n          processors: [memory_limiter, tail_sampling, batch]\n          exporters: [otlp\u002Ftempo]\n",[89,429,430,439,448,454,462,470,477,488,493,498,503,508,513,518,523,529,534,539,544,549,554,559,564,569,574,579,585,591,597,603,609,615,621,627,633,638,644,650,656,662,668,674,680,685,690,695,701,707,713,719,725],{"__ignoreMap":91},[161,431,432,434,436],{"class":163,"line":164},[161,433,168],{"class":167},[161,435,172],{"class":171},[161,437,438],{"class":175}," v1\n",[161,440,441,443,445],{"class":163,"line":179},[161,442,182],{"class":167},[161,444,172],{"class":171},[161,446,447],{"class":175}," ConfigMap\n",[161,449,450,452],{"class":163,"line":190},[161,451,193],{"class":167},[161,453,196],{"class":171},[161,455,456,458,460],{"class":163,"line":199},[161,457,202],{"class":167},[161,459,172],{"class":171},[161,461,420],{"class":175},[161,463,464,466,468],{"class":163,"line":210},[161,465,213],{"class":167},[161,467,172],{"class":171},[161,469,218],{"class":175},[161,471,472,475],{"class":163,"line":221},[161,473,474],{"class":167},"data",[161,476,196],{"class":171},[161,478,479,482,484],{"class":163,"line":229},[161,480,481],{"class":167},"  otel-collector-config.yaml",[161,483,172],{"class":171},[161,485,487],{"class":486},"sd1Qi"," |\n",[161,489,490],{"class":163,"line":237},[161,491,492],{"class":175},"    receivers:\n",[161,494,495],{"class":163,"line":245},[161,496,497],{"class":175},"      otlp:\n",[161,499,500],{"class":163,"line":255},[161,501,502],{"class":175},"        protocols:\n",[161,504,505],{"class":163,"line":263},[161,506,507],{"class":175},"          grpc:\n",[161,509,510],{"class":163,"line":271},[161,511,512],{"class":175},"            endpoint: 0.0.0.0:4317\n",[161,514,515],{"class":163,"line":279},[161,516,517],{"class":175},"          http:\n",[161,519,520],{"class":163,"line":289},[161,521,522],{"class":175},"            endpoint: 0.0.0.0:4318\n",[161,524,525],{"class":163,"line":297},[161,526,528],{"emptyLinePlaceholder":527},true,"\n",[161,530,531],{"class":163,"line":305},[161,532,533],{"class":175},"    processors:\n",[161,535,536],{"class":163,"line":320},[161,537,538],{"class":175},"      batch:\n",[161,540,541],{"class":163,"line":331},[161,542,543],{"class":175},"        timeout: 5s\n",[161,545,546],{"class":163,"line":353},[161,547,548],{"class":175},"        send_batch_size: 1024\n",[161,550,551],{"class":163,"line":361},[161,552,553],{"class":175},"      memory_limiter:\n",[161,555,556],{"class":163,"line":374},[161,557,558],{"class":175},"        check_interval: 1s\n",[161,560,561],{"class":163,"line":385},[161,562,563],{"class":175},"        limit_mib: 512\n",[161,565,566],{"class":163,"line":393},[161,567,568],{"class":175},"      tail_sampling:\n",[161,570,571],{"class":163,"line":404},[161,572,573],{"class":175},"        decision_wait: 10s\n",[161,575,576],{"class":163,"line":412},[161,577,578],{"class":175},"        policies:\n",[161,580,582],{"class":163,"line":581},26,[161,583,584],{"class":175},"        - name: errors-policy\n",[161,586,588],{"class":163,"line":587},27,[161,589,590],{"class":175},"          type: status_code\n",[161,592,594],{"class":163,"line":593},28,[161,595,596],{"class":175},"          status_code: {status_codes: [ERROR]}\n",[161,598,600],{"class":163,"line":599},29,[161,601,602],{"class":175},"        - name: slow-traces\n",[161,604,606],{"class":163,"line":605},30,[161,607,608],{"class":175},"          type: latency\n",[161,610,612],{"class":163,"line":611},31,[161,613,614],{"class":175},"          latency: {threshold_ms: 1000}\n",[161,616,618],{"class":163,"line":617},32,[161,619,620],{"class":175},"        - name: probabilistic\n",[161,622,624],{"class":163,"line":623},33,[161,625,626],{"class":175},"          type: probabilistic\n",[161,628,630],{"class":163,"line":629},34,[161,631,632],{"class":175},"          probabilistic: {sampling_percentage: 10}\n",[161,634,636],{"class":163,"line":635},35,[161,637,528],{"emptyLinePlaceholder":527},[161,639,641],{"class":163,"line":640},36,[161,642,643],{"class":175},"    exporters:\n",[161,645,647],{"class":163,"line":646},37,[161,648,649],{"class":175},"      otlp\u002Ftempo:\n",[161,651,653],{"class":163,"line":652},38,[161,654,655],{"class":175},"        endpoint: tempo:4317\n",[161,657,659],{"class":163,"line":658},39,[161,660,661],{"class":175},"        tls:\n",[161,663,665],{"class":163,"line":664},40,[161,666,667],{"class":175},"          insecure: true\n",[161,669,671],{"class":163,"line":670},41,[161,672,673],{"class":175},"      otlp\u002Fjaeger:\n",[161,675,677],{"class":163,"line":676},42,[161,678,679],{"class":175},"        endpoint: jaeger-collector:4317\n",[161,681,683],{"class":163,"line":682},43,[161,684,661],{"class":175},[161,686,688],{"class":163,"line":687},44,[161,689,667],{"class":175},[161,691,693],{"class":163,"line":692},45,[161,694,528],{"emptyLinePlaceholder":527},[161,696,698],{"class":163,"line":697},46,[161,699,700],{"class":175},"    service:\n",[161,702,704],{"class":163,"line":703},47,[161,705,706],{"class":175},"      pipelines:\n",[161,708,710],{"class":163,"line":709},48,[161,711,712],{"class":175},"        traces:\n",[161,714,716],{"class":163,"line":715},49,[161,717,718],{"class":175},"          receivers: [otlp]\n",[161,720,722],{"class":163,"line":721},50,[161,723,724],{"class":175},"          processors: [memory_limiter, tail_sampling, batch]\n",[161,726,728],{"class":163,"line":727},51,[161,729,730],{"class":175},"          exporters: [otlp\u002Ftempo]\n",[11,732,733,736],{},[15,734,26],{"href":24,"rel":735},[19]," で運用する K3s クラスタでは、DaemonSet 方式が推奨されます。ノードごとに 1 つの Collector を配置し、リソース効率を最大化します。",[29,738,739],{"id":739},"アプリケーションの計装",[33,741,743],{"id":742},"自動計装zero-code-instrumentation","自動計装（Zero-Code Instrumentation）",[11,745,746,749],{},[15,747,20],{"href":52,"rel":748},[19]," の自動計装を使えば、コードを変更せずにトレーシングを導入できます。",[11,751,752],{},[62,753,754],{},"Python の例:",[82,756,760],{"className":757,"code":758,"language":759,"meta":91,"style":91},"language-bash shiki shiki-themes tokyo-night","pip install opentelemetry-distro opentelemetry-exporter-otlp\nopentelemetry-bootstrap -a install\n","bash",[89,761,762,777],{"__ignoreMap":91},[161,763,764,768,771,774],{"class":163,"line":164},[161,765,767],{"class":766},"sE3pS","pip",[161,769,770],{"class":175}," install",[161,772,773],{"class":175}," opentelemetry-distro",[161,775,776],{"class":175}," opentelemetry-exporter-otlp\n",[161,778,779,782,786],{"class":163,"line":179},[161,780,781],{"class":766},"opentelemetry-bootstrap",[161,783,785],{"class":784},"sT800"," -a",[161,787,788],{"class":175}," install\n",[82,790,792],{"className":757,"code":791,"language":759,"meta":91,"style":91},"# 環境変数での設定\nexport OTEL_SERVICE_NAME=my-python-service\nexport OTEL_EXPORTER_OTLP_ENDPOINT=http:\u002F\u002Fotel-collector:4317\nexport OTEL_TRACES_EXPORTER=otlp\nexport OTEL_METRICS_EXPORTER=otlp\n\n# 自動計装で起動\nopentelemetry-instrument python app.py\n",[89,793,794,800,815,839,851,862,866,871],{"__ignoreMap":91},[161,795,796],{"class":163,"line":164},[161,797,799],{"class":798},"sbD-w","# 環境変数での設定\n",[161,801,802,806,809,812],{"class":163,"line":179},[161,803,805],{"class":804},"sN7LL","export",[161,807,808],{"class":766}," OTEL_SERVICE_NAME",[161,810,811],{"class":171},"=",[161,813,814],{"class":766},"my-python-service\n",[161,816,817,819,822,824,827,831,834,836],{"class":163,"line":190},[161,818,805],{"class":804},[161,820,821],{"class":766}," OTEL_EXPORTER_OTLP_ENDPOINT",[161,823,811],{"class":171},[161,825,826],{"class":766},"http",[161,828,830],{"class":829},"sGX4V",":\u002F\u002F",[161,832,833],{"class":766},"otel-collector",[161,835,172],{"class":829},[161,837,838],{"class":766},"4317\n",[161,840,841,843,846,848],{"class":163,"line":199},[161,842,805],{"class":804},[161,844,845],{"class":766}," OTEL_TRACES_EXPORTER",[161,847,811],{"class":171},[161,849,850],{"class":766},"otlp\n",[161,852,853,855,858,860],{"class":163,"line":210},[161,854,805],{"class":804},[161,856,857],{"class":766}," OTEL_METRICS_EXPORTER",[161,859,811],{"class":171},[161,861,850],{"class":766},[161,863,864],{"class":163,"line":221},[161,865,528],{"emptyLinePlaceholder":527},[161,867,868],{"class":163,"line":229},[161,869,870],{"class":798},"# 自動計装で起動\n",[161,872,873,876,879],{"class":163,"line":237},[161,874,875],{"class":766},"opentelemetry-instrument",[161,877,878],{"class":175}," python",[161,880,881],{"class":175}," app.py\n",[11,883,884],{},[62,885,886],{},"Java の例:",[82,888,890],{"className":757,"code":889,"language":759,"meta":91,"style":91},"# Java Agent を使った自動計装\njava -javaagent:opentelemetry-javaagent.jar \\\n  -Dotel.service.name=my-java-service \\\n  -Dotel.exporter.otlp.endpoint=http:\u002F\u002Fotel-collector:4317 \\\n  -jar my-app.jar\n",[89,891,892,897,908,915,922],{"__ignoreMap":91},[161,893,894],{"class":163,"line":164},[161,895,896],{"class":798},"# Java Agent を使った自動計装\n",[161,898,899,902,905],{"class":163,"line":179},[161,900,901],{"class":766},"java",[161,903,904],{"class":784}," -javaagent:opentelemetry-javaagent.jar",[161,906,907],{"class":171}," \\\n",[161,909,910,913],{"class":163,"line":190},[161,911,912],{"class":784},"  -Dotel.service.name=my-java-service",[161,914,907],{"class":171},[161,916,917,920],{"class":163,"line":199},[161,918,919],{"class":784},"  -Dotel.exporter.otlp.endpoint=http:\u002F\u002Fotel-collector:4317",[161,921,907],{"class":171},[161,923,924,927],{"class":163,"line":210},[161,925,926],{"class":784},"  -jar",[161,928,929],{"class":175}," my-app.jar\n",[33,931,933],{"id":932},"kubernetes-operator-による自動注入","Kubernetes Operator による自動注入",[11,935,936,941],{},[15,937,940],{"href":938,"rel":939},"https:\u002F\u002Fmedium.com\u002F@serverwalainfra\u002Fimplementing-end-to-end-tracing-with-opentelemetry-in-kubernetes-workloads-e9ffbf5dc002",[19],"Medium の実装記事","が解説するように、OpenTelemetry Operator を使えば Pod のアノテーションで自動計装を注入できます：",[82,943,945],{"className":155,"code":944,"language":157,"meta":91,"style":91},"apiVersion: v1\nkind: Pod\nmetadata:\n  annotations:\n    instrumentation.opentelemetry.io\u002Finject-python: \"true\"\nspec:\n  containers:\n  - name: my-app\n    image: my-python-app:latest\n",[89,946,947,955,964,970,977,993,999,1006,1018],{"__ignoreMap":91},[161,948,949,951,953],{"class":163,"line":164},[161,950,168],{"class":167},[161,952,172],{"class":171},[161,954,438],{"class":175},[161,956,957,959,961],{"class":163,"line":179},[161,958,182],{"class":167},[161,960,172],{"class":171},[161,962,963],{"class":175}," Pod\n",[161,965,966,968],{"class":163,"line":190},[161,967,193],{"class":167},[161,969,196],{"class":171},[161,971,972,975],{"class":163,"line":199},[161,973,974],{"class":167},"  annotations",[161,976,196],{"class":171},[161,978,979,982,984,987,990],{"class":163,"line":210},[161,980,981],{"class":167},"    instrumentation.opentelemetry.io\u002Finject-python",[161,983,172],{"class":171},[161,985,986],{"class":171}," \"",[161,988,989],{"class":175},"true",[161,991,992],{"class":171},"\"\n",[161,994,995,997],{"class":163,"line":221},[161,996,224],{"class":167},[161,998,196],{"class":171},[161,1000,1001,1004],{"class":163,"line":229},[161,1002,1003],{"class":167},"  containers",[161,1005,196],{"class":171},[161,1007,1008,1011,1013,1015],{"class":163,"line":237},[161,1009,1010],{"class":308},"  -",[161,1012,312],{"class":167},[161,1014,172],{"class":171},[161,1016,1017],{"class":175}," my-app\n",[161,1019,1020,1023,1025],{"class":163,"line":245},[161,1021,1022],{"class":167},"    image",[161,1024,172],{"class":171},[161,1026,1027],{"class":175}," my-python-app:latest\n",[33,1029,1031],{"id":1030},"手動計装の例go","手動計装の例（Go）",[82,1033,1037],{"className":1034,"code":1035,"language":1036,"meta":91,"style":91},"language-go shiki shiki-themes tokyo-night","import (\n    \"go.opentelemetry.io\u002Fotel\"\n    \"go.opentelemetry.io\u002Fotel\u002Ftrace\"\n)\n\nfunc handleRequest(ctx context.Context) {\n    tracer := otel.Tracer(\"my-service\")\n    ctx, span := tracer.Start(ctx, \"handleRequest\")\n    defer span.End()\n\n    \u002F\u002F カスタム属性の追加\n    span.SetAttributes(\n        attribute.String(\"user.id\", userID),\n        attribute.Int(\"http.status_code\", 200),\n    )\n\n    \u002F\u002F 子 Span の作成\n    ctx, childSpan := tracer.Start(ctx, \"database-query\")\n    result := queryDatabase(ctx)\n    childSpan.End()\n}\n","go",[89,1038,1039,1044,1049,1054,1059,1063,1068,1073,1078,1083,1087,1092,1097,1102,1107,1112,1116,1121,1126,1131,1136],{"__ignoreMap":91},[161,1040,1041],{"class":163,"line":164},[161,1042,1043],{},"import (\n",[161,1045,1046],{"class":163,"line":179},[161,1047,1048],{},"    \"go.opentelemetry.io\u002Fotel\"\n",[161,1050,1051],{"class":163,"line":190},[161,1052,1053],{},"    \"go.opentelemetry.io\u002Fotel\u002Ftrace\"\n",[161,1055,1056],{"class":163,"line":199},[161,1057,1058],{},")\n",[161,1060,1061],{"class":163,"line":210},[161,1062,528],{"emptyLinePlaceholder":527},[161,1064,1065],{"class":163,"line":221},[161,1066,1067],{},"func handleRequest(ctx context.Context) {\n",[161,1069,1070],{"class":163,"line":229},[161,1071,1072],{},"    tracer := otel.Tracer(\"my-service\")\n",[161,1074,1075],{"class":163,"line":237},[161,1076,1077],{},"    ctx, span := tracer.Start(ctx, \"handleRequest\")\n",[161,1079,1080],{"class":163,"line":245},[161,1081,1082],{},"    defer span.End()\n",[161,1084,1085],{"class":163,"line":255},[161,1086,528],{"emptyLinePlaceholder":527},[161,1088,1089],{"class":163,"line":263},[161,1090,1091],{},"    \u002F\u002F カスタム属性の追加\n",[161,1093,1094],{"class":163,"line":271},[161,1095,1096],{},"    span.SetAttributes(\n",[161,1098,1099],{"class":163,"line":279},[161,1100,1101],{},"        attribute.String(\"user.id\", userID),\n",[161,1103,1104],{"class":163,"line":289},[161,1105,1106],{},"        attribute.Int(\"http.status_code\", 200),\n",[161,1108,1109],{"class":163,"line":297},[161,1110,1111],{},"    )\n",[161,1113,1114],{"class":163,"line":305},[161,1115,528],{"emptyLinePlaceholder":527},[161,1117,1118],{"class":163,"line":320},[161,1119,1120],{},"    \u002F\u002F 子 Span の作成\n",[161,1122,1123],{"class":163,"line":331},[161,1124,1125],{},"    ctx, childSpan := tracer.Start(ctx, \"database-query\")\n",[161,1127,1128],{"class":163,"line":353},[161,1129,1130],{},"    result := queryDatabase(ctx)\n",[161,1132,1133],{"class":163,"line":361},[161,1134,1135],{},"    childSpan.End()\n",[161,1137,1138],{"class":163,"line":374},[161,1139,1140],{},"}\n",[11,1142,1143,1146],{},[15,1144,118],{"href":116,"rel":1145},[19]," と OpenTelemetry を組み合わせることで、AI がトレースデータからサービス間のボトルネックを自動的に特定し、改善提案を生成することが可能です。",[29,1148,1150],{"id":1149},"バックエンド連携jaeger-と-grafana-tempo","バックエンド連携：Jaeger と Grafana Tempo",[33,1152,1154],{"id":1153},"jaeger-との連携","Jaeger との連携",[11,1156,1157,1162,1163,1168],{},[15,1158,1161],{"href":1159,"rel":1160},"https:\u002F\u002Fwww.jaegertracing.io\u002F",[19],"Jaeger"," は CNCF Graduated の分散トレーシングバックエンドです。",[15,1164,1167],{"href":1165,"rel":1166},"https:\u002F\u002Fmedium.com\u002Fobservability-101\u002Fdistributed-tracing-in-kubernetes-using-opentelemetry-jaegar-a-step-by-step-guide-a48899c2b27a",[19],"Medium のステップバイステップガイド","を参考に：",[82,1170,1172],{"className":155,"code":1171,"language":157,"meta":91,"style":91},"# Jaeger Operator によるデプロイ\napiVersion: jaegertracing.io\u002Fv1\nkind: Jaeger\nmetadata:\n  name: jaeger\n  namespace: observability\nspec:\n  strategy: production\n  storage:\n    type: elasticsearch\n    options:\n      es.server-urls: http:\u002F\u002Felasticsearch:9200\n",[89,1173,1174,1179,1188,1197,1203,1212,1220,1226,1236,1243,1253,1260],{"__ignoreMap":91},[161,1175,1176],{"class":163,"line":164},[161,1177,1178],{"class":798},"# Jaeger Operator によるデプロイ\n",[161,1180,1181,1183,1185],{"class":163,"line":179},[161,1182,168],{"class":167},[161,1184,172],{"class":171},[161,1186,1187],{"class":175}," jaegertracing.io\u002Fv1\n",[161,1189,1190,1192,1194],{"class":163,"line":190},[161,1191,182],{"class":167},[161,1193,172],{"class":171},[161,1195,1196],{"class":175}," Jaeger\n",[161,1198,1199,1201],{"class":163,"line":199},[161,1200,193],{"class":167},[161,1202,196],{"class":171},[161,1204,1205,1207,1209],{"class":163,"line":210},[161,1206,202],{"class":167},[161,1208,172],{"class":171},[161,1210,1211],{"class":175}," jaeger\n",[161,1213,1214,1216,1218],{"class":163,"line":221},[161,1215,213],{"class":167},[161,1217,172],{"class":171},[161,1219,218],{"class":175},[161,1221,1222,1224],{"class":163,"line":229},[161,1223,224],{"class":167},[161,1225,196],{"class":171},[161,1227,1228,1231,1233],{"class":163,"line":237},[161,1229,1230],{"class":167},"  strategy",[161,1232,172],{"class":171},[161,1234,1235],{"class":175}," production\n",[161,1237,1238,1241],{"class":163,"line":245},[161,1239,1240],{"class":167},"  storage",[161,1242,196],{"class":171},[161,1244,1245,1248,1250],{"class":163,"line":255},[161,1246,1247],{"class":167},"    type",[161,1249,172],{"class":171},[161,1251,1252],{"class":175}," elasticsearch\n",[161,1254,1255,1258],{"class":163,"line":263},[161,1256,1257],{"class":167},"    options",[161,1259,196],{"class":171},[161,1261,1262,1265,1267],{"class":163,"line":271},[161,1263,1264],{"class":167},"      es.server-urls",[161,1266,172],{"class":171},[161,1268,1269],{"class":175}," http:\u002F\u002Felasticsearch:9200\n",[33,1271,1273],{"id":1272},"grafana-tempo-との連携","Grafana Tempo との連携",[11,1275,1276,1281],{},[15,1277,1280],{"href":1278,"rel":1279},"https:\u002F\u002Fwww.civo.com\u002Flearn\u002Fdistributed-tracing-kubernetes-grafana-tempo-opentelemetry",[19],"Civo の実践ガイド","が詳しく解説するように、Grafana Tempo は大規模なトレースデータの保存に最適化されたバックエンドです：",[82,1283,1285],{"className":155,"code":1284,"language":157,"meta":91,"style":91},"# Tempo の設定例\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: tempo-config\ndata:\n  tempo.yaml: |\n    server:\n      http_listen_port: 3200\n    distributor:\n      receivers:\n        otlp:\n          protocols:\n            grpc:\n    storage:\n      trace:\n        backend: s3\n        s3:\n          bucket: tempo-traces\n          endpoint: minio:9000\n",[89,1286,1287,1292,1300,1308,1314,1323,1329,1338,1343,1348,1353,1358,1363,1368,1373,1378,1383,1388,1393,1398],{"__ignoreMap":91},[161,1288,1289],{"class":163,"line":164},[161,1290,1291],{"class":798},"# Tempo の設定例\n",[161,1293,1294,1296,1298],{"class":163,"line":179},[161,1295,168],{"class":167},[161,1297,172],{"class":171},[161,1299,438],{"class":175},[161,1301,1302,1304,1306],{"class":163,"line":190},[161,1303,182],{"class":167},[161,1305,172],{"class":171},[161,1307,447],{"class":175},[161,1309,1310,1312],{"class":163,"line":199},[161,1311,193],{"class":167},[161,1313,196],{"class":171},[161,1315,1316,1318,1320],{"class":163,"line":210},[161,1317,202],{"class":167},[161,1319,172],{"class":171},[161,1321,1322],{"class":175}," tempo-config\n",[161,1324,1325,1327],{"class":163,"line":221},[161,1326,474],{"class":167},[161,1328,196],{"class":171},[161,1330,1331,1334,1336],{"class":163,"line":229},[161,1332,1333],{"class":167},"  tempo.yaml",[161,1335,172],{"class":171},[161,1337,487],{"class":486},[161,1339,1340],{"class":163,"line":237},[161,1341,1342],{"class":175},"    server:\n",[161,1344,1345],{"class":163,"line":245},[161,1346,1347],{"class":175},"      http_listen_port: 3200\n",[161,1349,1350],{"class":163,"line":255},[161,1351,1352],{"class":175},"    distributor:\n",[161,1354,1355],{"class":163,"line":263},[161,1356,1357],{"class":175},"      receivers:\n",[161,1359,1360],{"class":163,"line":271},[161,1361,1362],{"class":175},"        otlp:\n",[161,1364,1365],{"class":163,"line":279},[161,1366,1367],{"class":175},"          protocols:\n",[161,1369,1370],{"class":163,"line":289},[161,1371,1372],{"class":175},"            grpc:\n",[161,1374,1375],{"class":163,"line":297},[161,1376,1377],{"class":175},"    storage:\n",[161,1379,1380],{"class":163,"line":305},[161,1381,1382],{"class":175},"      trace:\n",[161,1384,1385],{"class":163,"line":320},[161,1386,1387],{"class":175},"        backend: s3\n",[161,1389,1390],{"class":163,"line":331},[161,1391,1392],{"class":175},"        s3:\n",[161,1394,1395],{"class":163,"line":353},[161,1396,1397],{"class":175},"          bucket: tempo-traces\n",[161,1399,1400],{"class":163,"line":361},[161,1401,1402],{"class":175},"          endpoint: minio:9000\n",[33,1404,1405],{"id":1405},"コンテキスト伝播",[11,1407,1408,1413,1414,1416],{},[15,1409,1412],{"href":1410,"rel":1411},"https:\u002F\u002Fdasroot.net\u002Fposts\u002F2026\u002F03\u002Fopentelemetry-distributed-tracing-kubernetes-istio\u002F",[19],"dasroot.net の解説","が強調するように、分散トレーシングで最も重要なのが ",[62,1415,1405],{}," です。W3C Trace Context 標準に基づくヘッダーを使用します：",[82,1418,1421],{"className":1419,"code":1420,"language":87},[85],"traceparent: 00-{trace-id}-{span-id}-{flags}\ntracestate: vendor-specific-data\n",[89,1422,1420],{"__ignoreMap":91},[11,1424,1425],{},"すべてのサービスがこのヘッダーを伝播することで、エンドツーエンドのトレースが完成します。",[29,1427,1428],{"id":1428},"サンプリング戦略とパフォーマンス最適化",[33,1430,1431],{"id":1431},"テールサンプリング",[11,1433,1434,1435,1440],{},"すべてのトレースを保存するとストレージコストが爆発的に増加します。",[15,1436,1439],{"href":1437,"rel":1438},"https:\u002F\u002Fmarkaicode.com\u002Fopentelemetry-distributed-tracing-implementation-guide\u002F",[19],"markaicode の実装ガイド","が推奨するテールサンプリング戦略：",[82,1442,1444],{"className":155,"code":1443,"language":157,"meta":91,"style":91},"processors:\n  tail_sampling:\n    decision_wait: 10s\n    policies:\n    # エラーを含むトレースは 100% 保存\n    - name: errors\n      type: status_code\n      status_code: {status_codes: [ERROR]}\n    # 1秒以上かかったトレースは 100% 保存\n    - name: slow-traces\n      type: latency\n      latency: {threshold_ms: 1000}\n    # その他は 10% サンプリング\n    - name: probabilistic\n      type: probabilistic\n      probabilistic: {sampling_percentage: 10}\n",[89,1445,1446,1453,1460,1470,1477,1482,1494,1504,1527,1532,1543,1552,1572,1577,1588,1596],{"__ignoreMap":91},[161,1447,1448,1451],{"class":163,"line":164},[161,1449,1450],{"class":167},"processors",[161,1452,196],{"class":171},[161,1454,1455,1458],{"class":163,"line":179},[161,1456,1457],{"class":167},"  tail_sampling",[161,1459,196],{"class":171},[161,1461,1462,1465,1467],{"class":163,"line":190},[161,1463,1464],{"class":167},"    decision_wait",[161,1466,172],{"class":171},[161,1468,1469],{"class":175}," 10s\n",[161,1471,1472,1475],{"class":163,"line":199},[161,1473,1474],{"class":167},"    policies",[161,1476,196],{"class":171},[161,1478,1479],{"class":163,"line":210},[161,1480,1481],{"class":798},"    # エラーを含むトレースは 100% 保存\n",[161,1483,1484,1487,1489,1491],{"class":163,"line":221},[161,1485,1486],{"class":308},"    -",[161,1488,312],{"class":167},[161,1490,172],{"class":171},[161,1492,1493],{"class":175}," errors\n",[161,1495,1496,1499,1501],{"class":163,"line":229},[161,1497,1498],{"class":167},"      type",[161,1500,172],{"class":171},[161,1502,1503],{"class":175}," status_code\n",[161,1505,1506,1509,1511,1514,1517,1519,1521,1524],{"class":163,"line":237},[161,1507,1508],{"class":167},"      status_code",[161,1510,172],{"class":171},[161,1512,1513],{"class":171}," {",[161,1515,1516],{"class":167},"status_codes",[161,1518,172],{"class":171},[161,1520,339],{"class":171},[161,1522,1523],{"class":175},"ERROR",[161,1525,1526],{"class":171},"]}\n",[161,1528,1529],{"class":163,"line":245},[161,1530,1531],{"class":798},"    # 1秒以上かかったトレースは 100% 保存\n",[161,1533,1534,1536,1538,1540],{"class":163,"line":255},[161,1535,1486],{"class":308},[161,1537,312],{"class":167},[161,1539,172],{"class":171},[161,1541,1542],{"class":175}," slow-traces\n",[161,1544,1545,1547,1549],{"class":163,"line":263},[161,1546,1498],{"class":167},[161,1548,172],{"class":171},[161,1550,1551],{"class":175}," latency\n",[161,1553,1554,1557,1559,1561,1564,1566,1570],{"class":163,"line":271},[161,1555,1556],{"class":167},"      latency",[161,1558,172],{"class":171},[161,1560,1513],{"class":171},[161,1562,1563],{"class":167},"threshold_ms",[161,1565,172],{"class":171},[161,1567,1569],{"class":1568},"sOJ5S"," 1000",[161,1571,1140],{"class":171},[161,1573,1574],{"class":163,"line":279},[161,1575,1576],{"class":798},"    # その他は 10% サンプリング\n",[161,1578,1579,1581,1583,1585],{"class":163,"line":289},[161,1580,1486],{"class":308},[161,1582,312],{"class":167},[161,1584,172],{"class":171},[161,1586,1587],{"class":175}," probabilistic\n",[161,1589,1590,1592,1594],{"class":163,"line":297},[161,1591,1498],{"class":167},[161,1593,172],{"class":171},[161,1595,1587],{"class":175},[161,1597,1598,1601,1603,1605,1608,1610,1613],{"class":163,"line":305},[161,1599,1600],{"class":167},"      probabilistic",[161,1602,172],{"class":171},[161,1604,1513],{"class":171},[161,1606,1607],{"class":167},"sampling_percentage",[161,1609,172],{"class":171},[161,1611,1612],{"class":1568}," 10",[161,1614,1140],{"class":171},[33,1616,1617],{"id":1617},"パフォーマンス最適化のポイント",[56,1619,1620,1626,1632,1638],{},[59,1621,1622,1625],{},[62,1623,1624],{},"バッチ処理",": Collector でバッチサイズとタイムアウトを適切に設定",[59,1627,1628,1631],{},[62,1629,1630],{},"メモリリミッター",": OOM を防止するためのメモリ制限設定",[59,1633,1634,1637],{},[62,1635,1636],{},"DaemonSet デプロイ",": サイドカーよりリソース効率が高い",[59,1639,1640,1643],{},[62,1641,1642],{},"属性の最適化",": 不要な属性を削除し、ペイロードサイズを削減",[11,1645,1646,1651],{},[15,1647,1650],{"href":1648,"rel":1649},"https:\u002F\u002Fandrewodendaal.com\u002Fdistributed-tracing-opentelemetry-complete-guide\u002F",[19],"Andrew Odendaal のガイド","によると、適切なサンプリング戦略により、トレースデータ量を 90% 削減しつつ、重要なトレースは 100% 保持できます。",[29,1653,1654],{"id":1654},"まとめ",[11,1656,1657],{},"OpenTelemetry による分散トレーシングは、マイクロサービス環境のオブザーバビリティを根本的に改善します。本記事のポイントをまとめると：",[1659,1660,1661,1666,1672,1678,1684],"ol",{},[59,1662,1663,1665],{},[62,1664,20],{}," はトレース・メトリクス・ログを統合するベンダーニュートラルなフレームワーク",[59,1667,1668,1671],{},[62,1669,1670],{},"Collector"," による柔軟なテレメトリパイプラインの構築",[59,1673,1674,1677],{},[62,1675,1676],{},"自動計装"," でコード変更なしにトレーシングを導入可能",[59,1679,1680,1683],{},[62,1681,1682],{},"Jaeger \u002F Grafana Tempo"," との連携でトレースの保存・可視化",[59,1685,1686,1688],{},[62,1687,1431],{}," でコストを抑えつつ重要なトレースを保持",[11,1690,1691,1694,1695,1698],{},[15,1692,26],{"href":24,"rel":1693},[19]," は K3s ベースで CNCF エコシステムとの高い親和性を持ち、OpenTelemetry の導入によりマイクロサービス環境の可視性を飛躍的に向上させることができます。分散システムのオブザーバビリティに取り組む方は、ぜひ ",[15,1696,26],{"href":24,"rel":1697},[19]," をご検討ください。",[11,1700,1701,1702,1705,1706,1711],{},"AI によるトレースデータの自動分析に興味がある方は、",[15,1703,118],{"href":116,"rel":1704},[19]," の詳細をご確認ください。導入のご相談は",[15,1707,1710],{"href":1708,"rel":1709},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[19],"お問い合わせ","からお気軽にどうぞ。",[1713,1714,1715],"style",{},"html pre.shiki code .s0U2E, html code.shiki .s0U2E{--shiki-default:#F7768E}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sPY7s, html code.shiki .sPY7s{--shiki-default:#9ECE6A}html pre.shiki code .sgJMe, html code.shiki .sgJMe{--shiki-default:#9ABDF5}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sd1Qi, html code.shiki .sd1Qi{--shiki-default:#BB9AF7}html pre.shiki code .sE3pS, html code.shiki .sE3pS{--shiki-default:#C0CAF5}html pre.shiki code .sT800, html code.shiki .sT800{--shiki-default:#E0AF68}html pre.shiki code .sbD-w, html code.shiki .sbD-w{--shiki-default:#51597D;--shiki-default-font-style:italic}html pre.shiki code .sN7LL, html code.shiki .sN7LL{--shiki-default:#9D7CD8;--shiki-default-font-style:italic}html pre.shiki code .sGX4V, html code.shiki .sGX4V{--shiki-default:#A9B1D6}html pre.shiki code .sOJ5S, html code.shiki .sOJ5S{--shiki-default:#FF9E64}",{"title":91,"searchDepth":179,"depth":179,"links":1717},[1718,1723,1728,1733,1738,1742],{"id":31,"depth":179,"text":31,"children":1719},[1720,1721,1722],{"id":35,"depth":190,"text":35},{"id":46,"depth":190,"text":47},{"id":80,"depth":190,"text":80},{"id":122,"depth":179,"text":123,"children":1724},[1725,1726,1727],{"id":141,"depth":190,"text":142},{"id":151,"depth":190,"text":152},{"id":423,"depth":190,"text":424},{"id":739,"depth":179,"text":739,"children":1729},[1730,1731,1732],{"id":742,"depth":190,"text":743},{"id":932,"depth":190,"text":933},{"id":1030,"depth":190,"text":1031},{"id":1149,"depth":179,"text":1150,"children":1734},[1735,1736,1737],{"id":1153,"depth":190,"text":1154},{"id":1272,"depth":190,"text":1273},{"id":1405,"depth":190,"text":1405},{"id":1428,"depth":179,"text":1428,"children":1739},[1740,1741],{"id":1431,"depth":190,"text":1431},{"id":1617,"depth":190,"text":1617},{"id":1654,"depth":179,"text":1654},"2026-05-27","OpenTelemetry を使った分散トレーシングの実装方法を解説。Collector の構成、自動計装、Jaeger\u002FTempo との連携、Kubernetes 環境でのベストプラクティス。","md","ja",{},"\u002Fblog\u002Fja\u002Fopentelemetry-distributed-tracing",{"title":5,"description":1744},"blog\u002Fja\u002Fopentelemetry-distributed-tracing",[20,1752,1753,1754,1755,1161,1756,1757],"分散トレーシング","Kubernetes","CNCF","Observability","Tempo","マイクロサービス","eFKUHf-JU2bpbriYcuFUEj5cJrAc6TGCm4ZLgp-S42o",1779964617053]