examples/features/opentelemetry: demonstrate tracing using OpenTelemetry plugin - #8056
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #8056 +/- ##
==========================================
- Coverage 82.16% 82.10% -0.06%
==========================================
Files 410 412 +2
Lines 40248 40491 +243
==========================================
+ Hits 33068 33244 +176
- Misses 5830 5881 +51
- Partials 1350 1366 +16 🚀 New features to boost your workflow:
|
f463f2b to
58451b6
Compare
purnesh42H
left a comment
There was a problem hiding this comment.
@janardhanvissa please use any of the trace exporter from here https://opentelemetry.io/docs/languages/go/exporters/. May be otlptracehttp or stdouttrace are good candidates
Also, please refer to https://opentelemetry.io/docs/languages/go/getting-started/ for writing otel trace exporting parts in client and server. We should try to avoid as much custom code as possible here to make it easy and fast for users to pick up.
| // | ||
| // For the OpenTelemetry Collector Core distribution specifically, see | ||
| // https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol | ||
|
|
There was a problem hiding this comment.
nit: // Documentation:
// The builder manifests used for official OpenTelemetry Collector binaries
// can be found at the following repository:
// https://github.com/open-telemetry/opentelemetry-collector-releases
//
// For the OpenTelemetry Collector Core distribution specifically, refer to:
// https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol
There was a problem hiding this comment.
These docs are for the OpenTelemetry Collector, which we're not using; we're using stdouttrace instead. These things are already removed from the go.mod.
| log.Fatalf("UnaryEcho failed: %v", err) | ||
| } | ||
| fmt.Println(r) | ||
|
|
There was a problem hiding this comment.
nit: remove the extra space
|
|
||
| func main() { | ||
| flag.Parse() | ||
|
|
There was a problem hiding this comment.
nit: Remove the extra space and check the other places as well
| 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. | ||
| OpenTelemetry is configured on both the client and the server, and exports metrics to the Prometheus exporter. The exporter exposes metrics on the Prometheus ports described above. OpenTelemetry also exports traces using the stdouttrace exporter. These traces are printed as structured data to the console output of both the client and the server. |
There was a problem hiding this comment.
| OpenTelemetry is configured on both the client and the server, and exports metrics to the Prometheus exporter. The exporter exposes metrics on the Prometheus ports described above. OpenTelemetry also exports traces using the stdouttrace exporter. These traces are printed as structured data to the console output of both the client and the server. | |
| OpenTelemetry is configured on both the client and the server, and exports metrics to the Prometheus exporter. The exporter exposes metrics on the Prometheus ports 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. |
purnesh42H
left a comment
There was a problem hiding this comment.
@janardhanvissa in README.md, please all sentences to 80 cols.
|
|
||
| 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 RPC's. |
There was a problem hiding this comment.
Please restrict the sentences to 80 cols. What is the change here?
There was a problem hiding this comment.
reached 80 cols, so moved to the next line.
|
|
||
| ## Try it | ||
|
|
||
| This section shows how to configure OpenTelemetry Metrics and Traces. |
There was a problem hiding this comment.
we can remove this I think. The first sentence is enough
|
|
||
| This section shows how to configure OpenTelemetry Metrics and Traces. | ||
|
|
||
| **1. Run the gRPC Applications:** |
| go run client/main.go | ||
| ``` | ||
|
|
||
| **2. View Telemetry Data:** |
| The client continuously makes RPC's 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. | ||
| The client continuously makes RPC's 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. The client and server are also configured to output traces directly to their standard output streams using stdouttrace. |
There was a problem hiding this comment.
wrap stdouttrace within backticks
|
|
||
| func main() { | ||
| exporter, err := prometheus.New() | ||
| flag.Parse() |
There was a problem hiding this comment.
do we need this flag.Parse()? or it can be removed?
| } | ||
| provider := metric.NewMeterProvider(metric.WithReader(exporter)) | ||
| go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler()) | ||
| // Initialize MeterProvider with Prometheus exporter. |
There was a problem hiding this comment.
no need of this comment. Actually there is no change needed here. It can be reverted
| 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") | ||
| serviceName = "grpc-server" |
There was a problem hiding this comment.
same. Do we need this? or it can be removed?
There was a problem hiding this comment.
we need to set the service name as an attribute in the resource information attached to the traces for the server.
|
|
||
| func main() { | ||
| exporter, err := prometheus.New() | ||
| flag.Parse() |
There was a problem hiding this comment.
same. do we need this? or it can be removed?
| } | ||
| provider := metric.NewMeterProvider(metric.WithReader(exporter)) | ||
| go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler()) | ||
| // Initialize MeterProvider with Prometheus exporter. |
There was a problem hiding this comment.
same. No need of any change here. Let it be how it was.
| } | ||
| provider := metric.NewMeterProvider(metric.WithReader(exporter)) | ||
| go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler()) | ||
| provider := otelmetric.NewMeterProvider(otelmetric.WithReader(exporter)) |
There was a problem hiding this comment.
nit: one comment above "Configure meter provider for metrics"
| if err != nil { | ||
| log.Fatalf("Failed to create stdouttrace exporter: %v", err) | ||
| } | ||
|
|
| log.Fatalf("Failed to create stdouttrace exporter: %v", err) | ||
| } | ||
|
|
||
| // Configure the tracer provider |
|
|
||
| // Configure the tracer provider | ||
| tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(traceExporter), sdktrace.WithResource(otelresource.NewWithAttributes(semconv.SchemaURL, semconv.ServiceName(serviceName)))) | ||
| textMapPropagator := otelpropagation.TraceContext{} // Using W3C Trace Context Propagator. |
There was a problem hiding this comment.
| textMapPropagator := otelpropagation.TraceContext{} // Using W3C Trace Context Propagator. | |
| // Configure W3C Trace Context Propagator for traces | |
| textMapPropagator := otelpropagation.TraceContext{} // Using W3C Trace Context Propagator. |
|
|
||
| ctx := context.Background() | ||
| do := opentelemetry.DialOption(opentelemetry.Options{MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}}) | ||
| // Initialize stdouttrace exporter for traces |
There was a problem hiding this comment.
replace comment with "Configure exporter for traces"
| // Initialize stdouttrace exporter for traces | |
| // Configure exporter for traces |
|
@janardhanvissa could you add the screenshots of traces on clients and server please? |
Server Client |
For the future, for text output, can we please use a github gist or pastebin instead of screenshots? |
dfawley
left a comment
There was a problem hiding this comment.
LGTM except for the comments in this review. Thanks!
| This example demonstrates how to configure OpenTelemetry Tracing on a gRPC client | ||
| and server, showcasing the trace data it produces for RPC interactions. | ||
| 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. |
There was a problem hiding this comment.
| shows what type of telemetry data it can produce for certain RPC's. | |
| shows what type of telemetry data it can produce for certain RPCs. |
| * **Trace Visualization (Console):** By monitoring the collector's console | ||
| output, you can see the flow of RPC calls and analyze the performance of | ||
| your gRPC services. No newline at end of file | ||
| The client continuously makes RPC's to a server. The client and server both |
There was a problem hiding this comment.
| 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 |
| 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") | ||
| serviceName = "grpc-client" |
There was a problem hiding this comment.
I'm fine with replacing the one usage of it with a literal. Or make it a const instead of a var otherwise.
| provider := metric.NewMeterProvider(metric.WithReader(exporter)) | ||
| go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler()) | ||
| // Configure meter provider for metrics | ||
| provider := otelmetric.NewMeterProvider(otelmetric.WithReader(exporter)) |
There was a problem hiding this comment.
Now we have a meter provider and a trace provider. Let's name this meterProvider and the other one tracerProvider.
| 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") | ||
| serviceName = "grpc-server" |
| provider := metric.NewMeterProvider(metric.WithReader(exporter)) | ||
| go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler()) | ||
| // Configure meter provider for metrics | ||
| provider := otelmetric.NewMeterProvider(otelmetric.WithReader(exporter)) |
Thanks for the suggestion! We'll follow that going forward and use Gist or Pastebin for any text output. |








RELEASE NOTES: