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 propagation context for custom libraries #1782

Open
sinoohe opened this issue Dec 24, 2020 · 2 comments
Open

Example for propagation context for custom libraries #1782

sinoohe opened this issue Dec 24, 2020 · 2 comments

Comments

@sinoohe
Copy link

sinoohe commented Dec 24, 2020

  • [] This only affects the JavaScript OpenTelemetry library

Currently, there is no documentation/example(at least I couldn't find) about how I as a user of this library can inject the current context to a carrier, send it (by my own protocol) to the consumer, and in consumer extract the carrier and link the consumer to the producer.
I would like to add an example to the open telemetry examples folder. Is that okay? do you have any ideas?

I did this scenario once but it was super painful as there was no documentation about it. I had to call getParentSpanContext on the context extracted and pass it to the links param when creating a span in the consumer.

@dyladan
Copy link
Member

dyladan commented Dec 24, 2020

Of course that would be a very welcome addition! To me this is a failure of documentation. One point I want to make is that in the basic use case, links is not the correct way to join a parent and child span.

Here is a very quick and dirty example (I typed this directly in GitHub so it's very possible I've made some typos.

// Client
const tracer = api.trace.getTracer('client', '1.0.0');

const span = clientTracer.startSpan('send');

const response = await api.context.with(api.setSpan(api.context.active(), span), () => {
	const carrier: Record<string, string> = {};
	api.propagation.inject(api.context.active(), carrier);
	return sendRequestToServer({
		headers: carrier,
		body: {},
	});
});

span.setStatus({ code: api.SpanStatus.OK });
span.end();
// Server
const tracer = api.trace.getTracer('server', '1.0.0');

server.onRequest(async (request) => {
	// This context call sets an active context
	const response = await api.context.with(
		// This propagation call creates a new context with the extracted parent SpanContext
		api.propagation.extract(
			api.Context.ROOT_CONTEXT,
			request.headers,
		),
		async () => {
			// this span will automatically find the parent span in the context
			const span = tracer.startSpan('receive');

			const response = await doSomeProcessing();

			span.setStatus({ code: api.SpanStatus.OK })
			span.end()
			
			// This will be returned back to the caller of context.with
			return response;
		},
	);

	request.respond(response.body);
});

@sinoohe
Copy link
Author

sinoohe commented Dec 25, 2020

@dyladan in your example you are setting the trace as a parent in the receiver, but there are some cases where it's not a good idea to set the parent trace, it's better to set the links(to link consumer to producer).for example in a domain driven environment it's better to link consumer to the producer.
I'll try to create a PR for this example.
But also I could not find any documentation about this code:

const context = propagation.extract(carrier, {
  get(carrier, key) {
    return carrier[key];
  }
}, ROOT_CONTEXT);
linkContext = getParentSpanContext(context);
tracer.startSpan(spanName, {
  root: true,
  links: [{context: linkContext}]
});

do you think where is it better to add documentation for it?

pichlermarc pushed a commit to dynatrace-oss-contrib/opentelemetry-js that referenced this issue Dec 15, 2023
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