examples/features/opentelemetry: demonstrate tracing using OpenTelemetry plugin (#8056)

This commit is contained in:
janardhanvissa 2025-04-17 10:42:51 +05:30 committed by GitHub
parent 8b2dbbbb83
commit eb4b687764
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 68 additions and 26 deletions

View File

@ -1,7 +1,7 @@
# OpenTelemetry
This example shows how to configure OpenTelemetry on a client and server, and shows
what type of telemetry data it can produce for certain RPC's.
This example shows how to configure OpenTelemetry on a client and server, and
shows what type of telemetry data it can produce for certain RPCs.
## Try it
@ -20,13 +20,18 @@ curl localhost:9465/metrics
## Explanation
The client continuously makes RPC's to a server. The client and server both
The client continuously makes RPCs to a server. The client and server both
expose a prometheus exporter to listen and provide metrics. This defaults to
:9464 for the server and :9465 for the client.
:9464 for the server and :9465 for the client. The client and server are also
configured to output traces directly to their standard output streams using
`stdouttrace`.
OpenTelemetry is configured on both the client and the server, and exports to
the Prometheus exporter. The exporter exposes metrics on the Prometheus ports
described above.
described above. OpenTelemetry exports traces using the `stdouttrace` exporter,
which prints structured trace data to the console output of both the client and
server. Each RPC call produces trace information that captures the execution
flow and timing of operations.
Curling to the exposed Prometheus ports outputs the metrics recorded on the
client and server.

View File

@ -27,19 +27,24 @@ import (
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/otel/exporters/prometheus"
otelstdouttrace "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
otelpropagation "go.opentelemetry.io/otel/propagation"
otelmetric "go.opentelemetry.io/otel/sdk/metric"
otelresource "go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/examples/features/proto/echo"
oteltracing "google.golang.org/grpc/experimental/opentelemetry"
"google.golang.org/grpc/stats/opentelemetry"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/sdk/metric"
)
var (
addr = flag.String("addr", ":50051", "the server address to connect to")
prometheusEndpoint = flag.String("prometheus_endpoint", ":9465", "the Prometheus exporter endpoint")
prometheusEndpoint = flag.String("prometheus_endpoint", ":9465", "the Prometheus exporter endpoint for metrics")
)
func main() {
@ -47,18 +52,30 @@ func main() {
if err != nil {
log.Fatalf("Failed to start prometheus exporter: %v", err)
}
provider := metric.NewMeterProvider(metric.WithReader(exporter))
go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler())
// Configure meter provider for metrics
meterProvider := otelmetric.NewMeterProvider(otelmetric.WithReader(exporter))
// Configure exporter for traces
traceExporter, err := otelstdouttrace.New(otelstdouttrace.WithPrettyPrint())
if err != nil {
log.Fatalf("Failed to create stdouttrace exporter: %v", err)
}
traceProvider := sdktrace.NewTracerProvider(sdktrace.WithBatcher(traceExporter), sdktrace.WithResource(otelresource.NewWithAttributes(semconv.SchemaURL, semconv.ServiceName("grpc-client"))))
// Configure W3C Trace Context Propagator for traces
textMapPropagator := otelpropagation.TraceContext{}
do := opentelemetry.DialOption(opentelemetry.Options{
MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: meterProvider},
TraceOptions: oteltracing.TraceOptions{TracerProvider: traceProvider, TextMapPropagator: textMapPropagator},
})
ctx := context.Background()
do := opentelemetry.DialOption(opentelemetry.Options{MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}})
go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler())
cc, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()), do)
if err != nil {
log.Fatalf("Failed to start NewClient: %v", err)
log.Fatalf("grpc.NewClient() failed: %v", err)
}
defer cc.Close()
c := echo.NewEchoClient(cc)
ctx := context.Background()
// Make an RPC every second. This should trigger telemetry to be emitted from
// the client and the server.

View File

@ -27,18 +27,23 @@ import (
"net"
"net/http"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/features/proto/echo"
"google.golang.org/grpc/stats/opentelemetry"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.opentelemetry.io/otel/exporters/prometheus"
"go.opentelemetry.io/otel/sdk/metric"
otelstdouttrace "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
otelpropagation "go.opentelemetry.io/otel/propagation"
otelmetric "go.opentelemetry.io/otel/sdk/metric"
otelresource "go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/features/proto/echo"
oteltracing "google.golang.org/grpc/experimental/opentelemetry"
"google.golang.org/grpc/stats/opentelemetry"
)
var (
addr = flag.String("addr", ":50051", "the server address to connect to")
prometheusEndpoint = flag.String("prometheus_endpoint", ":9464", "the Prometheus exporter endpoint")
prometheusEndpoint = flag.String("prometheus_endpoint", ":9464", "the Prometheus exporter endpoint for metrics")
)
type echoServer struct {
@ -55,10 +60,21 @@ func main() {
if err != nil {
log.Fatalf("Failed to start prometheus exporter: %v", err)
}
provider := metric.NewMeterProvider(metric.WithReader(exporter))
go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler())
// Configure meter provider for metrics
meterProvider := otelmetric.NewMeterProvider(otelmetric.WithReader(exporter))
// Configure exporter for traces
traceExporter, err := otelstdouttrace.New(otelstdouttrace.WithPrettyPrint())
if err != nil {
log.Fatalf("Failed to create stdouttrace exporter: %v", err)
}
traceProvider := sdktrace.NewTracerProvider(sdktrace.WithBatcher(traceExporter), sdktrace.WithResource(otelresource.NewWithAttributes(semconv.SchemaURL, semconv.ServiceName("grpc-server"))))
// Configure W3C Trace Context Propagator for traces
textMapPropagator := otelpropagation.TraceContext{}
so := opentelemetry.ServerOption(opentelemetry.Options{
MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: meterProvider},
TraceOptions: oteltracing.TraceOptions{TracerProvider: traceProvider, TextMapPropagator: textMapPropagator}})
so := opentelemetry.ServerOption(opentelemetry.Options{MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}})
go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler())
lis, err := net.Listen("tcp", *addr)
if err != nil {

View File

@ -5,7 +5,10 @@ go 1.23.0
require (
github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f
github.com/prometheus/client_golang v1.21.1
go.opentelemetry.io/otel v1.35.0
go.opentelemetry.io/otel/exporters/prometheus v0.57.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0
go.opentelemetry.io/otel/sdk v1.35.0
go.opentelemetry.io/otel/sdk/metric v1.35.0
golang.org/x/oauth2 v0.28.0
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463
@ -68,9 +71,7 @@ require (
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/net v0.38.0 // indirect

View File

@ -1151,6 +1151,8 @@ go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 h1:AHh/lAP1BHrY5gBwk8ncc25FXWm/gmmY3BX258z5nuk=
go.opentelemetry.io/otel/exporters/prometheus v0.57.0/go.mod h1:QpFWz1QxqevfjwzYdbMb4Y1NnlJvqSGwyuU0B4iuc9c=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 h1:T0Ec2E+3YZf5bgTNQVet8iTDW7oIk03tXHq+wkwIDnE=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0/go.mod h1:30v2gqH+vYGJsesLWFov8u47EpYTcIQcBjKpI6pJThg=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
@ -1165,6 +1167,7 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=