11import json
22import logging
33import re
4- from typing import List , Optional , Tuple , Union , cast
4+ from typing import Any , List , Optional , Tuple , Union , cast
55
6+ from azure .monitor .opentelemetry .exporter import AzureMonitorTraceExporter
67from fastapi import Request
7- from opencensus .ext .azure .trace_exporter import AzureExporter
8- from opencensus .trace import execution_context
9- from opencensus .trace .samplers import ProbabilitySampler
10- from opencensus .trace .span import SpanKind
11- from opencensus .trace .tracer import Tracer
8+ from opentelemetry import trace
9+ from opentelemetry .sdk .trace import TracerProvider
10+ from opentelemetry .sdk .trace .export import BatchSpanProcessor
11+ from opentelemetry .trace import Span , SpanKind , Tracer
1212from starlette .datastructures import QueryParams
1313
1414from pccommon .config import get_apis_config
2626logger = logging .getLogger (__name__ )
2727
2828
29- exporter = (
30- AzureExporter (
31- connection_string = (
32- f"InstrumentationKey={ _config .app_insights_instrumentation_key } "
33- )
29+ tracer : Optional [Tracer ]
30+
31+ if _config .app_insights_instrumentation_key :
32+ tracer_provider = TracerProvider ()
33+ trace .set_tracer_provider (tracer_provider )
34+
35+ azure_exporter = AzureMonitorTraceExporter (
36+ connection_string = "InstrumentationKey="
37+ + _config .app_insights_instrumentation_key
3438 )
35- if _config .app_insights_instrumentation_key
36- else None
37- )
3839
39- is_trace_enabled = exporter is not None
40+ span_processor = BatchSpanProcessor (azure_exporter )
41+ tracer_provider .add_span_processor (span_processor )
42+
43+ tracer = trace .get_tracer (__name__ )
44+ else :
45+ tracer = None
4046
4147
4248async def trace_request (
@@ -47,57 +53,29 @@ async def trace_request(
4753 request_path = request_to_path (request ).strip ("/" )
4854
4955 if _should_trace_request (request ):
50- tracer = Tracer (
51- exporter = exporter ,
52- sampler = ProbabilitySampler (1.0 ),
53- )
54- with tracer .span ("main" ) as span :
56+ assert tracer
57+ with tracer .start_as_current_span ("main" , kind = SpanKind .SERVER ) as span :
5558 (collection_id , item_id ) = await _collection_item_from_request (
5659 service_name , request
5760 )
58- span .span_kind = SpanKind .SERVER
5961
60- # Throwing the main span into request state lets us create child spans
61- # in downstream request processing, if there are specific things that
62- # are slow.
6362 request .state .parent_span = span
6463
65- # Add request dimensions to the trace prior to calling the next middleware
66- tracer .add_attribute_to_current_span (
67- attribute_key = "ref_id" ,
68- attribute_value = request .headers .get (X_AZURE_REF ),
69- )
70- tracer .add_attribute_to_current_span (
71- attribute_key = "request_entity" ,
72- attribute_value = request .headers .get (X_REQUEST_ENTITY ),
73- )
74- tracer .add_attribute_to_current_span (
75- attribute_key = "request_ip" ,
76- attribute_value = get_request_ip (request ),
77- )
78- tracer .add_attribute_to_current_span (
79- attribute_key = HTTP_METHOD , attribute_value = str (request .method )
80- )
81- tracer .add_attribute_to_current_span (
82- attribute_key = HTTP_URL , attribute_value = str (request .url )
83- )
84- tracer .add_attribute_to_current_span (
85- attribute_key = HTTP_PATH , attribute_value = request_path
86- )
87- tracer .add_attribute_to_current_span (
88- attribute_key = "service" , attribute_value = service_name
89- )
90- tracer .add_attribute_to_current_span (
91- attribute_key = "in-server" , attribute_value = "true"
64+ span .set_attribute ("ref_id" , request .headers .get (X_AZURE_REF ) or "" )
65+ span .set_attribute (
66+ "request_entity" , request .headers .get (X_REQUEST_ENTITY ) or ""
9267 )
68+ span .set_attribute ("request_ip" , get_request_ip (request ) or "" )
69+ span .set_attribute (HTTP_METHOD , str (request .method ))
70+ span .set_attribute (HTTP_URL , str (request .url ))
71+ span .set_attribute (HTTP_PATH , request_path )
72+ span .set_attribute ("service" , service_name )
73+ span .set_attribute ("in-server" , "true" )
74+
9375 if collection_id is not None :
94- tracer .add_attribute_to_current_span (
95- attribute_key = "collection" , attribute_value = collection_id
96- )
76+ span .set_attribute ("collection" , collection_id )
9777 if item_id is not None :
98- tracer .add_attribute_to_current_span (
99- attribute_key = "item" , attribute_value = item_id
100- )
78+ span .set_attribute ("item" , item_id )
10179
10280
10381collection_id_re = re .compile (
@@ -139,7 +117,7 @@ def _should_trace_request(request: Request) -> bool:
139117 - Not a health check endpoint
140118 """
141119 return (
142- is_trace_enabled
120+ ( tracer is not None )
143121 and request .method .lower () != "head"
144122 and not request .url .path .strip ("/" ).endswith ("_mgmt/ping" )
145123 )
@@ -217,15 +195,17 @@ def add_stac_attributes_from_search(search_json: str, request: Request) -> None:
217195 collection_id , item_id = parse_collection_from_search (
218196 json .loads (search_json ), request .method , request .query_params
219197 )
220- parent_span = getattr (request .state , "parent_span" , None )
221198
222- current_span = execution_context .get_current_span () or parent_span
199+ current_span : Union [Optional [Any ], Span ]
200+ current_span = trace .get_current_span ()
201+ if not current_span .is_recording ():
202+ current_span = getattr (request .state , "parent_span" , None )
223203
224- if current_span :
204+ if current_span and current_span . is_recording () :
225205 if collection_id is not None :
226- current_span .add_attribute ("collection" , collection_id )
206+ current_span .set_attribute ("collection" , collection_id )
227207 if item_id is not None :
228- current_span .add_attribute ("item" , item_id )
208+ current_span .set_attribute ("item" , item_id )
229209 else :
230210 logger .warning ("No active or parent span available for adding attributes." )
231211
0 commit comments