KDOC 664: OpenTelemetry の3つのシグナルの出力を見る
この文書のステータス
- 作成
- 2026-10-15 貴島
- レビュー
- 2026-10-15 貴島
概要
OpenTelemetry の3つのシグナル(trace、metric、log)を、それぞれいちばん小さい例で出力して見る。どれも標準出力の exporter で JSON を書き出し、整形して出力をそのまま見る。
# 例ごとに一時ディレクトリを作り、終わったら消す
dir=$(mktemp -d)
trap 'rm -rf "$dir"' EXIT
cd "$dir"
go mod init example >/dev/null 2>&1
go get \
go.opentelemetry.io/otel@v1.47.0 \
go.opentelemetry.io/otel/sdk@v1.47.0 \
go.opentelemetry.io/otel/sdk/metric@v1.47.0 \
go.opentelemetry.io/otel/sdk/log@v1.47.0 \
go.opentelemetry.io/otel/log@v1.47.0 \
go.opentelemetry.io/otel/exporters/stdout/stdouttrace@v1.47.0 \
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric@v1.47.0 \
go.opentelemetry.io/otel/exporters/stdout/stdoutlog@v0.23.0 2>/dev/null
trace
親の span の中で子の span を作る。
<<setup>>
mkdir -p trace
cat > trace/main.go <<'GO'
package main
import (
"context"
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
func main() {
ctx := context.Background()
exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint())
tp := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exp))
defer tp.Shutdown(ctx)
tracer := tp.Tracer("example")
ctx, parent := tracer.Start(ctx, "parent")
_, child := tracer.Start(ctx, "child")
child.End()
parent.End()
}
GO
go mod tidy 2>/dev/null
go run ./trace
{
"Name": "child",
"SpanContext": {
"TraceID": "23fc88efba48028dd9d7717ccb8a1b61",
"SpanID": "af787e4c4d7bf055",
"TraceFlags": "01",
"TraceState": "",
"Remote": false
},
"Parent": {
"TraceID": "23fc88efba48028dd9d7717ccb8a1b61",
"SpanID": "d3973a5b2f677925",
"TraceFlags": "01",
"TraceState": "",
"Remote": false
},
"SpanKind": 1,
"StartTime": "2026-10-15T09:50:57.99213578+09:00",
"EndTime": "2026-10-15T09:50:57.99213599+09:00",
"Attributes": null,
"Events": null,
"Links": null,
"Status": {
"Code": "Unset",
"Description": ""
},
"DroppedAttributes": 0,
"DroppedEvents": 0,
"DroppedLinks": 0,
"ChildSpanCount": 0,
"Resource": [
{
"Key": "service.name",
"Value": {
"Type": "STRING",
"Value": "unknown_service:trace"
}
},
{
"Key": "telemetry.sdk.language",
"Value": {
"Type": "STRING",
"Value": "go"
}
},
{
"Key": "telemetry.sdk.name",
"Value": {
"Type": "STRING",
"Value": "opentelemetry"
}
},
{
"Key": "telemetry.sdk.version",
"Value": {
"Type": "STRING",
"Value": "1.47.0"
}
}
],
"InstrumentationScope": {
"Name": "example",
"Version": "",
"SchemaURL": "",
"Attributes": null
},
"InstrumentationLibrary": {
"Name": "example",
"Version": "",
"SchemaURL": "",
"Attributes": null
}
}
{
"Name": "parent",
"SpanContext": {
"TraceID": "23fc88efba48028dd9d7717ccb8a1b61",
"SpanID": "d3973a5b2f677925",
"TraceFlags": "01",
"TraceState": "",
"Remote": false
},
"Parent": {
"TraceID": "00000000000000000000000000000000",
"SpanID": "0000000000000000",
"TraceFlags": "00",
"TraceState": "",
"Remote": false
},
"SpanKind": 1,
"StartTime": "2026-10-15T09:50:57.992133605+09:00",
"EndTime": "2026-10-15T09:50:57.992240576+09:00",
"Attributes": null,
"Events": null,
"Links": null,
"Status": {
"Code": "Unset",
"Description": ""
},
"DroppedAttributes": 0,
"DroppedEvents": 0,
"DroppedLinks": 0,
"ChildSpanCount": 1,
"Resource": [
{
"Key": "service.name",
"Value": {
"Type": "STRING",
"Value": "unknown_service:trace"
}
},
{
"Key": "telemetry.sdk.language",
"Value": {
"Type": "STRING",
"Value": "go"
}
},
{
"Key": "telemetry.sdk.name",
"Value": {
"Type": "STRING",
"Value": "opentelemetry"
}
},
{
"Key": "telemetry.sdk.version",
"Value": {
"Type": "STRING",
"Value": "1.47.0"
}
}
],
"InstrumentationScope": {
"Name": "example",
"Version": "",
"SchemaURL": "",
"Attributes": null
},
"InstrumentationLibrary": {
"Name": "example",
"Version": "",
"SchemaURL": "",
"Attributes": null
}
}
- 子の Parent.SpanID が親の SpanID と同じで、TraceID も同じである。これで1つのトレースの中の親子を表現している
- 親の Parent.SpanID はすべて 0 で、根の span である
- WithSyncer を使っていて span が終わったときにすぐに書き出すので先に終わった子が先に出力される
metric
カウンタに 1、2、3 を足す。
<<setup>>
mkdir -p metric
cat > metric/main.go <<'GO'
package main
import (
"context"
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
)
func main() {
ctx := context.Background()
exp, _ := stdoutmetric.New(stdoutmetric.WithPrettyPrint())
mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exp)))
defer mp.Shutdown(ctx)
counter, _ := mp.Meter("example").Int64Counter("requests")
counter.Add(ctx, 1)
counter.Add(ctx, 2)
counter.Add(ctx, 3)
}
GO
go mod tidy 2>/dev/null
go run ./metric
{
"Resource": [
{
"Key": "service.name",
"Value": {
"Type": "STRING",
"Value": "unknown_service:metric"
}
},
{
"Key": "telemetry.sdk.language",
"Value": {
"Type": "STRING",
"Value": "go"
}
},
{
"Key": "telemetry.sdk.name",
"Value": {
"Type": "STRING",
"Value": "opentelemetry"
}
},
{
"Key": "telemetry.sdk.version",
"Value": {
"Type": "STRING",
"Value": "1.47.0"
}
}
],
"ScopeMetrics": [
{
"Scope": {
"Name": "example",
"Version": "",
"SchemaURL": "",
"Attributes": null
},
"Metrics": [
{
"Name": "requests",
"Description": "",
"Unit": "",
"Data": {
"DataPoints": [
{
"Attributes": [],
"StartTime": "2026-10-15T09:50:58.694178323+09:00",
"Time": "2026-10-15T09:50:58.69420339+09:00",
"Value": 6
}
],
"Temporality": "CumulativeTemporality",
"IsMonotonic": true
}
}
]
}
]
}
- 3回の Add が、値 6 に集計された
log
ログを1件書く。
<<setup>>
mkdir -p log
cat > log/main.go <<'GO'
package main
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/stdout/stdoutlog"
"go.opentelemetry.io/otel/log"
sdklog "go.opentelemetry.io/otel/sdk/log"
)
func main() {
ctx := context.Background()
exp, _ := stdoutlog.New(stdoutlog.WithPrettyPrint())
lp := sdklog.NewLoggerProvider(sdklog.WithProcessor(sdklog.NewSimpleProcessor(exp)))
defer lp.Shutdown(ctx)
var r log.Record
r.SetSeverity(log.SeverityInfo)
r.SetBody(attribute.StringValue("hello"))
lp.Logger("example").Emit(ctx, r)
}
GO
go mod tidy 2>/dev/null
go run ./log
{
"Timestamp": "0001-01-01T00:00:00Z",
"ObservedTimestamp": "2026-10-15T09:50:59.139404628+09:00",
"Severity": 9,
"SeverityText": "",
"Body": {
"Type": "STRING",
"Value": "hello"
},
"Attributes": [],
"TraceID": "00000000000000000000000000000000",
"SpanID": "0000000000000000",
"TraceFlags": "00",
"Resource": [
{
"Key": "service.name",
"Value": {
"Type": "STRING",
"Value": "unknown_service:log"
}
},
{
"Key": "telemetry.sdk.language",
"Value": {
"Type": "STRING",
"Value": "go"
}
},
{
"Key": "telemetry.sdk.name",
"Value": {
"Type": "STRING",
"Value": "opentelemetry"
}
},
{
"Key": "telemetry.sdk.version",
"Value": {
"Type": "STRING",
"Value": "1.47.0"
}
}
],
"Scope": {
"Name": "example",
"Version": "",
"SchemaURL": "",
"Attributes": {}
},
"DroppedAttributes": 0
}
Scopeにロガーに渡した文字列が入っている
関連
- 類似: KDOC 663: リングキューの動作を試す。ただしこの例の log は SimpleProcessor なのでキューは通らない