[中文版](/docs/docs-08-tracing.md) ## 08 - Report Tracing to OpenTelemetry **SRPC** supports generating and reporting tracing and spans, which can be reported in multiple ways, including exporting data locally or to [OpenTelemetry](https://opentelemetry.io). Since **SRPC** follows the [data specification](https://github.com/open-telemetry/opentelemetry-specification) of **OpenTelemetry** and the specification of [w3c trace context](https://www.w3.org/TR/trace-context/), now we can use **RPCTraceOpenTelemetry** as the reporting plugin. The report conforms to the **Workflow** style, which is pure asynchronous task and therefore has no performance impact on the RPC requests and services. ### 1. Usage After the plugin `RPCTraceOpenTelemetry` is constructed, we can use `add_filter()` to add it into **server** or **client**. For [tutorial-02-srpc_pb_client.cc](https://github.com/sogou/srpc/blob/master/tutorial/tutorial-02-srpc_pb_client.cc), add 2 lines like the following : ```cpp int main() { Example::SRPCClient client("127.0.0.1", 1412); RPCTraceOpenTelemetry span_otel("http://127.0.0.1:4318"); client.add_filter(&span_otel); ... } ``` For [tutorial-01-srpc_pb_server.cc](https://github.com/sogou/srpc/blob/master/tutorial/tutorial-01-srpc_pb_server.cc), add the similar 2 lines. We also add the local plugin to print the reported data on the screen : ```cpp int main() { SRPCServer server; RPCTraceOpenTelemetry span_otel("http://127.0.0.1:4318"); server.add_filter(&span_otel); RPCTraceDefault span_log; // this plugin will print the tracing info on the screen server.add_filter(&span_log); ... } ``` make the tutorial and run both server and client, we can see some tracing information on the screen. image We can find the span_id: **04d070f537f17d00** in client become parent_span_id: **04d070f537f17d00** in server: image ### 2. Traces on Jaeger Open the show page of Jaeger, we can find our service name **Example** and method name **Echo**. Here are two span nodes, which were reported by server and client respectively. image As what we saw on the screen, the client reported span_id: **04d070f537f17d00** and server reported span_id: **00202cf737f17d00**, these span and the correlated tracing information can be found on Jaeger, too. image ### 3. About Parameters How long to collect a trace, and the number of reported retries and other parameters can be specified through the constructor parameters of `RPCTraceOpenTelemetry`. Code reference: [src/module/rpc_trace_filter.h](https://github.com/sogou/srpc/blob/master/src/module/rpc_trace_filter.h#L238) The default value is to collect up to 1000 trace information per second, and features such as transferring tracing information through the srpc framework transparently have also been implemented, which also conform to the specifications. ### 4. Attributes We can also use `add_attributes()` to add some other informations as OTEL_RESOURCE_ATTRIBUTES. Please notice that our service name "Example" is set also thought this attributes, the key of which is `service.name`. If `service.name` is also provided in OTEL_RESOURCE_ATTRIBUTES by users, then srpc service name takes precedence. Refers to : [OpenTelemetry#resource](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry#resource) ### 5. Log and Baggage SRPC provides `log()` and `baggage()` to carry some user data through span. API : ```cpp void log(const RPCLogVector& fields); void baggage(const std::string& key, const std::string& value); ``` As a server, we can use `RPCContext` to add log annotation: ```cpp class ExampleServiceImpl : public Example::Service { public: void Echo(EchoRequest *req, EchoResponse *resp, RPCContext *ctx) override { resp->set_message("Hi back"); ctx->log({{"event", "info"}, {"message", "rpc server echo() end."}}); } }; ``` As a client, we can use `RPCClientTask` to add log on span: ```cpp srpc::SRPCClientTask *task = client.create_Echo_task(...); task->log({{"event", "info"}, {"message", "log by rpc client echo()."}}); ```