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

Is it possible to use opentelemetry as downstream of an old system using zipkin? #4387

Open
WilliamChen-luckbob opened this issue Jan 15, 2025 · 0 comments

Comments

@WilliamChen-luckbob
Copy link

WilliamChen-luckbob commented Jan 15, 2025

I would like to use the custom traceId received from the upstream system as the request context in my current Flask project, and pass this traceId forward in the same header.

It’s possible to instrument OpenTelemetry and log the traceId in my Flask project, but it seems difficult to analyze incoming requests and extract the traceId from the headers set by the upstream server.

I haven’t found any documentation regarding parsing the traceId from headers in upstream systems and applying it to the current request context. I’m unsure if OpenTelemetry supports such operations.

GPT provided some insights, suggesting that I might be able to perform the related operations in app.before_request and app.after_request. The example code is as follows, but I am still unable to apply the traceId from the upstream system to the current Flask project.

Here is the code which will always crash when trying to start a new span using given trace id:

def register_link_tracing(app):
    trace.set_tracer_provider(TracerProvider())
    FlaskInstrumentor().instrument_app(app)
    LoggingInstrumentor().instrument(set_logging_format=True, logging_format=app.config.get('OTEL_PYTHON_LOG_FORMAT'))

    IGNORING_URL = {'/health'}

    @app.before_request
    def before_request():
        try:
            if request.path not in IGNORING_URL:
                g.start_datetime = int(time.time() * 1000)
                trace_id = request.environ.get('X_B3_TRACEID')
                parent_span_id = request.environ.get('X_B3_SPANID')
                int_trace_id = int(trace_id, 16)
                int_parent_span_id = int(parent_span_id, 16)
                # request.headers.get('HTTP_X_B3_PARENTSPANID')
                if trace_id:
                    span_context = SpanContext(
                        trace_id=int_trace_id,
                        span_id=int_parent_span_id,
                        is_remote=True,
                        trace_flags=TraceFlags.SAMPLED
                    )
                    tracer=trace.get_tracer(__name__)
                    span =tracer.start_span(name='upstream_call', context=span_context)
                    trace.set_span_in_context(span)
                current_app.logger.info(f"{request.method} {request.base_url} requesting...")
        except Exception as e:
            current_app.logger.error(f'error! {e},traceback:{traceback.format_exc()}')

    @app.after_request
    def after_request(response):
        try:
            if request.path not in IGNORING_URL:
                start_time = g.get('start_datetime')
                end_time = int(time.time() * 1000)
                time_spend = end_time - start_time
                status = response.json.get('status', '')
                message = response.json.get('message', '')
                current_app.logger.info(f"{request.method} {request.base_url} code:{response.status_code} status:{status} message:{message} time_spend:{time_spend}ms")
        except Exception as e:
            current_app.logger.error(f'error! {e},traceback:{traceback.format_exc()}')
        return response

I think I might need to implement a custom provider to replace the default TracerProvider.

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

1 participant