@platformatic/telemetry 0.35.5 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/telemetry.js +22 -7
- package/package.json +2 -1
- package/test/client.test.js +1 -1
- package/test/telemetry.test.js +40 -0
package/lib/telemetry.js
CHANGED
|
@@ -8,6 +8,7 @@ const { Resource } = require('@opentelemetry/resources')
|
|
|
8
8
|
const { PlatformaticTracerProvider } = require('./platformatic-trace-provider')
|
|
9
9
|
const { PlatformaticContext } = require('./platformatic-context')
|
|
10
10
|
const { fastifyTextMapGetter, fastifyTextMapSetter } = require('./fastify-text-map')
|
|
11
|
+
const { formatParamUrl } = require('@fastify/swagger')
|
|
11
12
|
const fastUri = require('fast-uri')
|
|
12
13
|
|
|
13
14
|
// Platformatic telemetry plugin.
|
|
@@ -27,14 +28,27 @@ const fastUri = require('fast-uri')
|
|
|
27
28
|
|
|
28
29
|
const { name: moduleName, version: moduleVersion } = require('../package.json')
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const extractPath = (request) => {
|
|
32
|
+
// We must user RouterPath, because otherwise `/test/123` will be considered as
|
|
33
|
+
// a different operation than `/test/321`. In case is not set (this should actually happen only for HTTP/404) we fallback to the path.
|
|
34
|
+
const { routerPath, url } = request
|
|
35
|
+
let path
|
|
36
|
+
if (routerPath) {
|
|
37
|
+
path = formatParamUrl(routerPath)
|
|
38
|
+
} else {
|
|
39
|
+
path = url
|
|
40
|
+
}
|
|
41
|
+
return path
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function formatSpanName (request, path) {
|
|
45
|
+
const { method } = request
|
|
32
46
|
/* istanbul ignore next */
|
|
33
|
-
return
|
|
47
|
+
return path ? `${method} ${path}` : method
|
|
34
48
|
}
|
|
35
49
|
|
|
36
50
|
const formatSpanAttributes = {
|
|
37
|
-
request (request) {
|
|
51
|
+
request (request, path) {
|
|
38
52
|
const { hostname, method, url, protocol } = request
|
|
39
53
|
// Inspired by: https://github.com/fastify/fastify-url-data/blob/master/plugin.js#L11
|
|
40
54
|
const urlData = fastUri.parse(`${protocol}://${hostname}${url}`)
|
|
@@ -42,7 +56,7 @@ const formatSpanAttributes = {
|
|
|
42
56
|
'server.address': hostname,
|
|
43
57
|
'server.port': urlData.port,
|
|
44
58
|
'http.request.method': method,
|
|
45
|
-
'url.path':
|
|
59
|
+
'url.path': path,
|
|
46
60
|
'url.scheme': protocol
|
|
47
61
|
}
|
|
48
62
|
},
|
|
@@ -122,15 +136,16 @@ async function setupTelemetry (app, opts) {
|
|
|
122
136
|
// We populate the context with the incoming request headers
|
|
123
137
|
let context = propagator.extract(new PlatformaticContext(), request, fastifyTextMapGetter)
|
|
124
138
|
|
|
139
|
+
const path = extractPath(request)
|
|
125
140
|
const span = tracer.startSpan(
|
|
126
|
-
formatSpanName(request),
|
|
141
|
+
formatSpanName(request, path),
|
|
127
142
|
{},
|
|
128
143
|
context
|
|
129
144
|
)
|
|
130
145
|
span.kind = SpanKind.SERVER
|
|
131
146
|
// Next 2 lines are needed by W3CTraceContextPropagator
|
|
132
147
|
context = context.setSpan(span)
|
|
133
|
-
span.setAttributes(formatSpanAttributes.request(request))
|
|
148
|
+
span.setAttributes(formatSpanAttributes.request(request, path))
|
|
134
149
|
span.context = context
|
|
135
150
|
request.span = span
|
|
136
151
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/telemetry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.0",
|
|
4
4
|
"description": "OpenTelemetry integration for Platformatic",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Marco Piraccini <marco.piraccini@gmail.com>",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"tap": "^16.3.6"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
+
"@fastify/swagger": "^8.9.0",
|
|
19
20
|
"@opentelemetry/api": "^1.4.1",
|
|
20
21
|
"@opentelemetry/core": "^1.15.0",
|
|
21
22
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.41.0",
|
package/test/client.test.js
CHANGED
|
@@ -178,7 +178,7 @@ test('should trace a client request failing', async ({ equal, same, teardown })
|
|
|
178
178
|
equal(finishedSpans.length, 2)
|
|
179
179
|
// We have two one for the client and one for the server
|
|
180
180
|
const spanServer = finishedSpans[0]
|
|
181
|
-
equal(spanServer.name, 'GET')
|
|
181
|
+
equal(spanServer.name, 'GET /wrong')
|
|
182
182
|
equal(spanServer.kind, SpanKind.SERVER)
|
|
183
183
|
equal(spanServer.status.code, SpanStatusCode.ERROR)
|
|
184
184
|
equal(spanServer.attributes['http.request.method'], 'GET')
|
package/test/telemetry.test.js
CHANGED
|
@@ -9,6 +9,7 @@ async function setupApp (pluginOpts, routeHandler, teardown) {
|
|
|
9
9
|
const app = fastify()
|
|
10
10
|
await app.register(telemetryPlugin, pluginOpts)
|
|
11
11
|
app.get('/test', routeHandler)
|
|
12
|
+
app.get('/test/:id', routeHandler)
|
|
12
13
|
app.ready()
|
|
13
14
|
teardown(async () => {
|
|
14
15
|
await app.close()
|
|
@@ -278,3 +279,42 @@ test('should not trace if the operation is skipped', async ({ equal, same, teard
|
|
|
278
279
|
const finishedSpans = exporter.getFinishedSpans()
|
|
279
280
|
equal(finishedSpans.length, 0)
|
|
280
281
|
})
|
|
282
|
+
|
|
283
|
+
test('should not put the URL param in path', async ({ equal, same, teardown }) => {
|
|
284
|
+
const handler = async (request, reply) => {
|
|
285
|
+
return { foo: 'bar' }
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const injectArgs = {
|
|
289
|
+
method: 'GET',
|
|
290
|
+
url: '/test/123',
|
|
291
|
+
headers: {
|
|
292
|
+
host: 'test'
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const app = await setupApp({
|
|
297
|
+
serviceName: 'test-service',
|
|
298
|
+
version: '1.0.0',
|
|
299
|
+
exporter: {
|
|
300
|
+
type: 'memory'
|
|
301
|
+
}
|
|
302
|
+
}, handler, teardown)
|
|
303
|
+
|
|
304
|
+
await app.inject(injectArgs)
|
|
305
|
+
const { exporter } = app.openTelemetry
|
|
306
|
+
const finishedSpans = exporter.getFinishedSpans()
|
|
307
|
+
equal(finishedSpans.length, 1)
|
|
308
|
+
const span = finishedSpans[0]
|
|
309
|
+
equal(span.kind, SpanKind.SERVER)
|
|
310
|
+
equal(span.name, 'GET /test/{id}')
|
|
311
|
+
equal(span.status.code, SpanStatusCode.OK)
|
|
312
|
+
equal(span.attributes['http.request.method'], 'GET')
|
|
313
|
+
equal(span.attributes['url.path'], '/test/{id}')
|
|
314
|
+
equal(span.attributes['http.response.status_code'], 200)
|
|
315
|
+
equal(span.attributes['url.scheme'], 'http')
|
|
316
|
+
equal(span.attributes['server.address'], 'test')
|
|
317
|
+
const resource = span.resource
|
|
318
|
+
same(resource.attributes['service.name'], 'test-service')
|
|
319
|
+
same(resource.attributes['service.version'], '1.0.0')
|
|
320
|
+
})
|