Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example for using tracing extension and messages #209

Open
liamwh opened this issue May 15, 2023 · 2 comments
Open

Example for using tracing extension and messages #209

liamwh opened this issue May 15, 2023 · 2 comments

Comments

@liamwh
Copy link

liamwh commented May 15, 2023

Is your feature request related to a problem? Please describe.

I am investigating how we could leverage CloudEvents within my org, but am uncertain how we can include tracing information in a CloudEvent so that traces can be followed across service boundaries and correlated by Jaeger / Tempo.

For example:
One service is written in Rust, and it leverages the tracing crate. The functions are leveraging the instrument macro and with tracing configured as seen here. We'd like to publish a CloudEvent externally to the application (Kafa for example), and we see that we should use this extension extension API, but there no examples how to use it.

Describe the solution you'd like

An example added to the /examples folder where an event is published that includes tracing information according to the CloudEvents distributed tracing spec whilst using the tracing crate, the most prominent tracing crate for Rust.

   let example_event = cloudevents::EventBuilderV10::new()
        .id(Ulid::new())
        .source(SOURCE_NAME)
        .ty(EXAMPLE_EVENT_TYPE)
        .time(chrono::Utc::now())
        .subject(example_object.id)
        .data(
            mime::APPLICATION_OCTET_STREAM.to_string(),
            bincode::serialize(&example_object)?,
        )
        .extension("traceparent", bincode::serialize(&WHAT_GOES_HERE)) // <-- How to get values as required by traceparent here?
        .build()?;
@liamwh
Copy link
Author

liamwh commented May 15, 2023

Found the solution. I still think adding an example is a good idea, and I'm also wondering if a builder param behind a feature flag makes sense here to automate all this boilerplate?

 let builder = cloudevents::EventBuilderV10::new()
      .id(Ulid::new())
      .source(SOURCE_NAME)
      .ty(EXAMPLE_EVENT_TYPE)
      .time(chrono::Utc::now())
      .subject(example_object.id)
      .data(
          mime::APPLICATION_OCTET_STREAM.to_string(),
          bincode::serialize(&example_object)?,
      )

  let span = tracing::Span::current();
  let otel_context = span.context();
  let span = otel_context.span();
  let span_context = span.span_context();
  if span_context.is_sampled() {
      let trace_id = span_context.trace_id().to_bytes();
      let span_id = span_context.span_id().to_bytes();
      let trace_flags = span_context.trace_flags().to_u8();
      let trace_id_hex = hex::encode(trace_id);
      let span_id_hex = hex::encode(span_id);
      let traceparent = format!("00-{}-{}-{:02x}", trace_id_hex, span_id_hex, trace_flags);
      builder = builder.extension("traceparent", traceparent);
  }
  let example_event = builder.build()?;

@Lazzaretti
Copy link
Member

That would be nice (example & feature flag)! I will happily review a PR if you have time to contribute something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants