funccomputeSubrequests(r*http.Request,subRequestsint)error{// Add custom span representing the work done for the subrequestsctx,span:=tracer.Start(r.Context(),"subrequests")deferspan.End()// Make specified number of http requests to the /single endpoint.fori:=0;i < subRequests;i++{iferr:=callSingle(ctx);err!=nil{returnerr}}// record number of sub-requests madesubRequestsHistogram.Record(ctx,int64(subRequests))returnnil}
meter インスタンスを使用して、指標を記録できる計測を作成します。たとえば、次のコードでは、meter を使用して OpenTelemetry ヒストグラムを作成しています。
sleepHistogram,err=meter.Float64Histogram("example.sleep.duration",metric.WithDescription("Sample histogram to measure time spent in sleeping"),metric.WithExplicitBucketBoundaries(0.05,0.075,0.1,0.125,0.150,0.2),metric.WithUnit("s"))iferr!=nil{panic(err)}
funcrandomSleep(r*http.Request)time.Duration{// simulate the work by sleeping 100 to 200 mssleepTime:=time.Duration(100+rand.Intn(100))*time.Millisecondtime.Sleep(sleepTime)hostValue:=attribute.String("host.value",r.Host)// custom histogram metric to record time slept in secondssleepHistogram.Record(r.Context(),sleepTime.Seconds(),metric.WithAttributes(hostValue))returnsleepTime}
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["わかりにくい","hardToUnderstand","thumb-down"],["情報またはサンプルコードが不正確","incorrectInformationOrSampleCode","thumb-down"],["必要な情報 / サンプルがない","missingTheInformationSamplesINeed","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-07-10 UTC。"],[],[],null,["# Add custom traces and metrics to your app\n\nThis document describes how to add observability code to your application by\nusing [OpenTelemetry](https://opentelemetry.io/docs/what-is-opentelemetry/). OpenTelemetry provides instrumentation libraries that\ngenerate telemetry for popular frameworks. You can augment the library-generated\ntelemetry by adding custom instrumentation that measures your\napplication-specific behavior.\n\nThe principles and concepts described in this document can be applied to apps\nwritten in all languages supported by OpenTelemetry.\nTo learn more about instrumentation, see the following documents:\n\n- [Instrumentation and observability](/stackdriver/docs/instrumentation/overview).\n- [Choose an instrumentation approach](/stackdriver/docs/instrumentation/choose-approach).\n\nThe sample code, which is the same Go app that is described in\n[Go instrumentation sample](/stackdriver/docs/instrumentation/setup/go),\nis available in GitHub. To view the full sample, click *more_vert* **More** ,\nand then select **View on GitHub**.\n\nBefore you begin\n----------------\n\n\nEnable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs.\n\n\n[Enable the APIs](https://console.cloud.google.com/flows/enableapi?apiid=logging.googleapis.com,\nmonitoring.googleapis.com,cloudtrace.googleapis.com)\n\nCreate custom traces\n--------------------\n\nTo generate custom [traces](https://opentelemetry.io/docs/concepts/signals/traces/) from your application, you add\ninstrumentation code that creates [OpenTelemetry spans](https://opentelemetry.io/docs/concepts/signals/traces/#spans). In OpenTelemetry,\nspans are the building blocks for traces.\n\nTo create a span, do the following:\n\n1. Modify your app to acquire an OpenTelemetry [`Tracer`](https://opentelemetry.io/docs/concepts/signals/traces/#tracer). In OpenTelemetry,\n a tracer is a creator of spans. You can acquire a tracer as demonstrated in\n the following code:\n\n const scopeName = \"github.com/GoogleCloudPlatform/golang-samples/opentelemetry/instrumentation/app/work\"\n\n var (\n \tmeter = otel.Meter(scopeName)\n \ttracer = otel.Tracer(scopeName)\n \tsleepHistogram metric.Float64Histogram\n \tsubRequestsHistogram metric.Int64Histogram\n )\n\n The tracer name, which is represented by `scopeName`, identifies the\n [instrumentation scope](https://opentelemetry.io/docs/concepts/instrumentation-scope/) of the generated traces.\n2. Use the `tracer` instance to create spans. In the following code sample, the\n `computeSubrequests` function generates a span whenever it is called:\n\n func computeSubrequests(r *http.Request, subRequests int) error {\n \t// Add custom span representing the work done for the subrequests\n \tctx, span := tracer.Start(r.Context(), \"subrequests\")\n \tdefer span.End()\n\n \t// Make specified number of http requests to the /single endpoint.\n \tfor i := 0; i \u003c subRequests; i++ {\n \t\tif err := callSingle(ctx); err != nil {\n \t\t\treturn err\n \t\t}\n \t}\n \t// record number of sub-requests made\n \tsubRequestsHistogram.Record(ctx, int64(subRequests))\n \treturn nil\n }\n\n In the previous code sample, the span generated from the\n `computeSubrequests` function represents the work done by the entire\n function. This is because the first step of the function is to start a new\n span using `tracer.Start` and the `defer` keyword before the `span.End()`\n ensures that the span is ended right before the function exits.\n | **Note:** You must call `End()` to complete the span. OpenTelemetry only exports completed spans.\n\nCreate custom metrics\n---------------------\n\nTo generate [metrics](https://opentelemetry.io/docs/concepts/signals/metrics/) from your application, you add\ninstrumentation code that records measurements taken during your app's\nexecution.\n\nTo create metrics, do the following:\n\n1. Modify your app to acquire an OpenTelemetry [`Meter`](https://opentelemetry.io/docs/specs/otel/metrics/api/#meter). In OpenTelemetry, a\n meter provides access to [metric instruments](https://opentelemetry.io/docs/concepts/signals/metrics/#metric-instruments) for\n recording metrics. You can acquire a meter as demonstrated in the following\n code:\n\n const scopeName = \"github.com/GoogleCloudPlatform/golang-samples/opentelemetry/instrumentation/app/work\"\n\n var (\n \tmeter = otel.Meter(scopeName)\n \ttracer = otel.Tracer(scopeName)\n \tsleepHistogram metric.Float64Histogram\n \tsubRequestsHistogram metric.Int64Histogram\n )\n\n The meter name, which is represented by `scopeName`, identifies the\n [instrumentation scope](https://opentelemetry.io/docs/concepts/instrumentation-scope/) of the generated\n metrics.\n2. Use the `meter` instance to create instruments which can record metrics. For\n example, in the following code, we use the `meter` to create an [OpenTelemetry\n Histogram](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#histogram):\n\n sleepHistogram, err = meter.Float64Histogram(\"example.sleep.duration\",\n \tmetric.WithDescription(\"Sample histogram to measure time spent in sleeping\"),\n \tmetric.WithExplicitBucketBoundaries(0.05, 0.075, 0.1, 0.125, 0.150, 0.2),\n \tmetric.WithUnit(\"s\"))\n if err != nil {\n \tpanic(err)\n }\n\n This previous code generates a histogram named `sleepHistogram`.\n3. Use the `sleepHistogram` instance to record the sleep time, which is\n determined when the function `randomSleep` is invoked:\n\n func randomSleep(r *http.Request) time.Duration {\n \t// simulate the work by sleeping 100 to 200 ms\n \tsleepTime := time.Duration(100+rand.Intn(100)) * time.Millisecond\n \ttime.Sleep(sleepTime)\n\n \thostValue := attribute.String(\"host.value\", r.Host)\n \t// custom histogram metric to record time slept in seconds\n \tsleepHistogram.Record(r.Context(), sleepTime.Seconds(), metric.WithAttributes(hostValue))\n \treturn sleepTime\n }\n\n The recorded metrics from these instruments are exported from your\n application based on your OpenTelemetry exporter configuration.\n\nWhat's next\n-----------\n\n- [Correlate metrics and traces by using exemplars](/stackdriver/docs/instrumentation/advanced-topics/exemplars)\n- [OpenTelemetry](https://opentelemetry.io/docs/what-is-opentelemetry/)\n- [OpenTelemetry Instrumentation](https://opentelemetry.io/docs/concepts/instrumentation/)\n- [OpenTelemetry Metrics Data Model](https://opentelemetry.io/docs/specs/otel/metrics/data-model/)"]]