@@ -41,118 +41,125 @@ class TelemetryExamples extends Plugin {
4141 }
4242
4343 private registerTelemetryExampleRoutes ( router : Router ) {
44- router . post ( "/combined" , async ( req : Request , res : Response ) => {
45- const startTime = Date . now ( ) ;
46-
47- return this . telemetry . startActiveSpan (
48- "combined-example" ,
49- {
50- attributes : {
51- "example.type" : "combined" ,
52- "example.version" : "v2" ,
44+ this . route ( router , {
45+ name : "combined" ,
46+ method : "post" ,
47+ path : "/combined" ,
48+ handler : async ( req : Request , res : Response ) => {
49+ const startTime = Date . now ( ) ;
50+
51+ return this . telemetry . startActiveSpan (
52+ "combined-example" ,
53+ {
54+ attributes : {
55+ "example.type" : "combined" ,
56+ "example.version" : "v2" ,
57+ } ,
5358 } ,
54- } ,
55- async ( span : Span ) => {
56- try {
57- const userId =
58- req . body ?. userId || req . query . userId || "demo-user-123" ;
59-
60- this . telemetry . emit ( {
61- severityNumber : SeverityNumber . INFO ,
62- severityText : "INFO" ,
63- body : "Processing telemetry example request" ,
64- attributes : {
65- "user.id" : userId ,
66- "request.type" : "combined-example" ,
67- } ,
68- } ) ;
69-
70- const result = await this . complexOperation ( userId ) ;
71-
72- const duration = Date . now ( ) - startTime ;
73- this . requestCounter . add ( 1 , { status : "success" } ) ;
74- this . durationHistogram . record ( duration ) ;
75-
76- this . telemetry . emit ( {
77- severityNumber : SeverityNumber . INFO ,
78- severityText : "INFO" ,
79- body : "Request completed successfully" ,
80- attributes : {
81- "user.id" : userId ,
82- "duration.ms" : duration ,
83- "result.fields" : Object . keys ( result ) . length ,
84- } ,
85- } ) ;
86-
87- span . setStatus ( { code : SpanStatusCode . OK } ) ;
88-
89- res . json ( {
90- success : true ,
91- result,
92- duration_ms : duration ,
93- tracing : {
94- hint : "Open Grafana at http://localhost:3000" ,
95- services : [
96- "app-template (main service)" ,
97- "user-operations (complex operation)" ,
98- "auth-validation (user validation)" ,
99- "data-access (database operations - with cache!)" ,
100- "auth-service (permissions)" ,
101- "external-api (external HTTP calls)" ,
102- "data-processing (transformation)" ,
103- ] ,
104- expectedSpans : [
105- "HTTP POST (SDK auto-instrumentation)" ,
106- "combined-example (custom tracer: custom-telemetry-example)" ,
107- " └─ complex-operation (custom tracer: user-operations)" ,
108- " ├─ validate-user (100ms, custom tracer: auth-validation)" ,
109- " ├─ fetch-user-data (200ms first call / cached on repeat, custom tracer: data-access) [parallel]" ,
110- " │ └─ cache.hit attribute set by SDK (false on first call, true on repeat)" ,
111- " ├─ fetch-external-resource (custom tracer: external-api) [parallel]" ,
112- " │ └─ HTTP GET https://example.com (SDK auto-instrumentation)" ,
113- " ├─ fetch-permissions (150ms, custom tracer: auth-service) [parallel]" ,
114- " └─ transform-data (80ms, custom tracer: data-processing)" ,
115- ] ,
116- } ,
117- metrics : {
118- recorded : [ "app.requests.total" , "app.request.duration" ] ,
119- } ,
120- logs : {
121- emitted : [
122- "Starting complex operation workflow" ,
123- "Data fetching completed successfully" ,
124- "Data transformation completed" ,
125- "Permissions retrieved" ,
126- "External API call completed" ,
127- ] ,
128- } ,
129- } ) ;
130- } catch ( error ) {
131- span . recordException ( error as Error ) ;
132- span . setStatus ( { code : SpanStatusCode . ERROR } ) ;
133- this . requestCounter . add ( 1 , { status : "error" } ) ;
134-
135- this . telemetry . emit ( {
136- severityNumber : SeverityNumber . ERROR ,
137- severityText : "ERROR" ,
138- body : error instanceof Error ? error . message : "Unknown error" ,
139- attributes : {
140- "error.type" : error instanceof Error ? error . name : "Unknown" ,
141- "error.stack" : error instanceof Error ? error . stack : undefined ,
142- "request.path" : req . path ,
143- } ,
144- } ) ;
145-
146- res . status ( 500 ) . json ( {
147- error : true ,
148- message : error instanceof Error ? error . message : "Unknown error" ,
149- } ) ;
150- } finally {
151- span . end ( ) ;
152- }
153- } ,
154- { name : "custom-telemetry-example" } ,
155- ) ;
59+ async ( span : Span ) => {
60+ try {
61+ const userId =
62+ req . body ?. userId || req . query . userId || "demo-user-123" ;
63+
64+ this . telemetry . emit ( {
65+ severityNumber : SeverityNumber . INFO ,
66+ severityText : "INFO" ,
67+ body : "Processing telemetry example request" ,
68+ attributes : {
69+ "user.id" : userId ,
70+ "request.type" : "combined-example" ,
71+ } ,
72+ } ) ;
73+
74+ const result = await this . complexOperation ( userId ) ;
75+
76+ const duration = Date . now ( ) - startTime ;
77+ this . requestCounter . add ( 1 , { status : "success" } ) ;
78+ this . durationHistogram . record ( duration ) ;
79+
80+ this . telemetry . emit ( {
81+ severityNumber : SeverityNumber . INFO ,
82+ severityText : "INFO" ,
83+ body : "Request completed successfully" ,
84+ attributes : {
85+ "user.id" : userId ,
86+ "duration.ms" : duration ,
87+ "result.fields" : Object . keys ( result ) . length ,
88+ } ,
89+ } ) ;
90+
91+ span . setStatus ( { code : SpanStatusCode . OK } ) ;
92+
93+ res . json ( {
94+ success : true ,
95+ result,
96+ duration_ms : duration ,
97+ tracing : {
98+ hint : "Open Grafana at http://localhost:3000" ,
99+ services : [
100+ "app-template (main service)" ,
101+ "user-operations (complex operation)" ,
102+ "auth-validation (user validation)" ,
103+ "data-access (database operations - with cache!)" ,
104+ "auth-service (permissions)" ,
105+ "external-api (external HTTP calls)" ,
106+ "data-processing (transformation)" ,
107+ ] ,
108+ expectedSpans : [
109+ "HTTP POST (SDK auto-instrumentation)" ,
110+ "combined-example (custom tracer: custom-telemetry-example)" ,
111+ " └─ complex-operation (custom tracer: user-operations)" ,
112+ " ├─ validate-user (100ms, custom tracer: auth-validation)" ,
113+ " ├─ fetch-user-data (200ms first call / cached on repeat, custom tracer: data-access) [parallel]" ,
114+ " │ └─ cache.hit attribute set by SDK (false on first call, true on repeat)" ,
115+ " ├─ fetch-external-resource (custom tracer: external-api) [parallel]" ,
116+ " │ └─ HTTP GET https://example.com (SDK auto-instrumentation)" ,
117+ " ├─ fetch-permissions (150ms, custom tracer: auth-service) [parallel]" ,
118+ " └─ transform-data (80ms, custom tracer: data-processing)" ,
119+ ] ,
120+ } ,
121+ metrics : {
122+ recorded : [ "app.requests.total" , "app.request.duration" ] ,
123+ } ,
124+ logs : {
125+ emitted : [
126+ "Starting complex operation workflow" ,
127+ "Data fetching completed successfully" ,
128+ "Data transformation completed" ,
129+ "Permissions retrieved" ,
130+ "External API call completed" ,
131+ ] ,
132+ } ,
133+ } ) ;
134+ } catch ( error ) {
135+ span . recordException ( error as Error ) ;
136+ span . setStatus ( { code : SpanStatusCode . ERROR } ) ;
137+ this . requestCounter . add ( 1 , { status : "error" } ) ;
138+
139+ this . telemetry . emit ( {
140+ severityNumber : SeverityNumber . ERROR ,
141+ severityText : "ERROR" ,
142+ body : error instanceof Error ? error . message : "Unknown error" ,
143+ attributes : {
144+ "error.type" : error instanceof Error ? error . name : "Unknown" ,
145+ "error.stack" :
146+ error instanceof Error ? error . stack : undefined ,
147+ "request.path" : req . path ,
148+ } ,
149+ } ) ;
150+
151+ res . status ( 500 ) . json ( {
152+ error : true ,
153+ message :
154+ error instanceof Error ? error . message : "Unknown error" ,
155+ } ) ;
156+ } finally {
157+ span . end ( ) ;
158+ }
159+ } ,
160+ { name : "custom-telemetry-example" } ,
161+ ) ;
162+ } ,
156163 } ) ;
157164 }
158165
0 commit comments