@platformatic/telemetry 0.34.0 → 0.34.1

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 CHANGED
@@ -1,13 +1,14 @@
1
1
  'use strict'
2
2
 
3
3
  const fp = require('fastify-plugin')
4
- const { SpanStatusCode } = require('@opentelemetry/api')
4
+ const { SpanStatusCode, SpanKind } = require('@opentelemetry/api')
5
5
  const { ConsoleSpanExporter, BatchSpanProcessor, SimpleSpanProcessor, InMemorySpanExporter } = require('@opentelemetry/sdk-trace-base')
6
6
  const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions')
7
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 fastUri = require('fast-uri')
11
12
 
12
13
  // Platformatic telemetry plugin.
13
14
  // Supported Exporters:
@@ -34,14 +35,19 @@ function formatSpanName (request) {
34
35
 
35
36
  const defaultFormatSpanAttributes = {
36
37
  request (request) {
38
+ const { hostname, method, url, protocol } = request
39
+ const urlData = fastUri.parse(`${protocol}://${hostname})`)
37
40
  return {
38
- 'req.method': request.raw.method,
39
- 'req.url': request.raw.url
41
+ 'server.address': hostname,
42
+ 'server.port': urlData.port,
43
+ 'http.request.method': method,
44
+ 'url.path': url,
45
+ 'url.scheme': protocol
40
46
  }
41
47
  },
42
48
  reply (reply) {
43
49
  return {
44
- 'reply.statusCode': reply.statusCode
50
+ 'http.response.status_code': reply.statusCode
45
51
  }
46
52
  },
47
53
  error (error) {
@@ -60,7 +66,7 @@ const setupProvider = (app, opts) => {
60
66
  app.log.warn('No exporter configured, defaulting to console.')
61
67
  exporter = { type: 'console' }
62
68
  }
63
- app.log.info(`Setting up telemetry for service: ${serviceName} version: ${version} and exporter of type ${exporter.type}`)
69
+ app.log.info(`Setting up telemetry for service: ${serviceName}${version ? ' version: ' + version : ''} with exporter of type ${exporter.type}`)
64
70
  const provider = new PlatformaticTracerProvider({
65
71
  resource: new Resource({
66
72
  [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
@@ -119,6 +125,7 @@ async function setupTelemetry (app, opts) {
119
125
  {},
120
126
  context
121
127
  )
128
+ span.kind = SpanKind.SERVER
122
129
  // Next 2 lines are needed by W3CTraceContextPropagator
123
130
  context = context.setSpan(span)
124
131
  span.setAttributes(formatSpanAttributes.request(request))
@@ -177,8 +184,19 @@ async function setupTelemetry (app, opts) {
177
184
  /* istanbul ignore next */
178
185
  method = method || ''
179
186
  const span = tracer.startSpan(`${method} ${url}`, {}, context)
187
+ span.kind = SpanKind.CLIENT
188
+
189
+ const urlObj = fastUri.parse(url)
180
190
  /* istanbul ignore next */
181
- const attributes = url ? { 'server.url': url } : {}
191
+ const attributes = url
192
+ ? {
193
+ 'server.address': urlObj.host,
194
+ 'server.port': urlObj.port,
195
+ 'http.request.method': method,
196
+ 'url.full': url,
197
+ 'url.path': urlObj.path
198
+ }
199
+ : {}
182
200
  span.setAttributes(attributes)
183
201
 
184
202
  // Next 2 lines are needed by W3CTraceContextPropagator
@@ -200,7 +218,7 @@ async function setupTelemetry (app, opts) {
200
218
  spanStatus.code = SpanStatusCode.ERROR
201
219
  }
202
220
  span.setAttributes({
203
- 'response.statusCode': response.statusCode
221
+ 'http.response.status_code': response.statusCode
204
222
  })
205
223
  span.setStatus(spanStatus)
206
224
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/telemetry",
3
- "version": "0.34.0",
3
+ "version": "0.34.1",
4
4
  "description": "OpenTelemetry integration for Platformatic",
5
5
  "main": "index.js",
6
6
  "author": "Marco Piraccini <marco.piraccini@gmail.com>",
@@ -23,6 +23,7 @@
23
23
  "@opentelemetry/resources": "^1.15.0",
24
24
  "@opentelemetry/sdk-trace-base": "^1.15.0",
25
25
  "@opentelemetry/semantic-conventions": "^1.15.0",
26
+ "fast-uri": "^2.2.0",
26
27
  "fastify-plugin": "^4.5.0"
27
28
  },
28
29
  "scripts": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { test } = require('tap')
4
4
  const fastify = require('fastify')
5
- const { SpanStatusCode } = require('@opentelemetry/api')
5
+ const { SpanStatusCode, SpanKind } = require('@opentelemetry/api')
6
6
  const telemetryPlugin = require('../lib/telemetry')
7
7
  const { PlatformaticContext } = require('../lib/platformatic-context')
8
8
  const { fastifyTextMapGetter } = require('../lib/fastify-text-map')
@@ -29,7 +29,6 @@ test('should add the propagation headers correctly, new propagation started', as
29
29
 
30
30
  const app = await setupApp({
31
31
  serviceName: 'test-service',
32
- version: '1.0.0',
33
32
  exporter: {
34
33
  type: 'memory'
35
34
  }
@@ -126,16 +125,21 @@ test('should trace a client request', async ({ equal, same, teardown }) => {
126
125
  // We have two one for the client and one for the server
127
126
  const spanServer = finishedSpans[0]
128
127
  equal(spanServer.name, 'GET /test')
128
+ equal(spanServer.kind, SpanKind.SERVER)
129
129
  equal(spanServer.status.code, SpanStatusCode.OK)
130
- equal(spanServer.attributes['req.method'], 'GET')
131
- equal(spanServer.attributes['req.url'], '/test')
132
- equal(spanServer.attributes['reply.statusCode'], 200)
130
+ equal(spanServer.attributes['http.request.method'], 'GET')
131
+ equal(spanServer.attributes['url.path'], '/test')
132
+ equal(spanServer.attributes['http.response.status_code'], 200)
133
133
 
134
134
  const spanClient = finishedSpans[1]
135
135
  equal(spanClient.name, 'GET http://localhost:3000/test')
136
+ equal(spanClient.kind, SpanKind.CLIENT)
136
137
  equal(spanClient.status.code, SpanStatusCode.OK)
137
- equal(spanClient.attributes['server.url'], 'http://localhost:3000/test')
138
- equal(spanClient.attributes['response.statusCode'], 200)
138
+ equal(spanClient.attributes['url.full'], 'http://localhost:3000/test')
139
+ equal(spanClient.attributes['http.response.status_code'], 200)
140
+ equal(spanClient.attributes['server.port'], 3000)
141
+ equal(spanClient.attributes['server.address'], 'localhost')
142
+ equal(spanClient.attributes['url.path'], '/test')
139
143
 
140
144
  // The traceparent header is added to the request and propagated to the server
141
145
  equal(receivedHeaders.traceparent, telemetryHeaders.traceparent)
@@ -175,16 +179,18 @@ test('should trace a client request failing', async ({ equal, same, teardown })
175
179
  // We have two one for the client and one for the server
176
180
  const spanServer = finishedSpans[0]
177
181
  equal(spanServer.name, 'GET')
182
+ equal(spanServer.kind, SpanKind.SERVER)
178
183
  equal(spanServer.status.code, SpanStatusCode.ERROR)
179
- equal(spanServer.attributes['req.method'], 'GET')
180
- equal(spanServer.attributes['req.url'], '/wrong')
181
- equal(spanServer.attributes['reply.statusCode'], 404)
184
+ equal(spanServer.attributes['http.request.method'], 'GET')
185
+ equal(spanServer.attributes['url.path'], '/wrong')
186
+ equal(spanServer.attributes['http.response.status_code'], 404)
182
187
 
183
188
  const spanClient = finishedSpans[1]
184
189
  equal(spanClient.name, 'GET http://localhost:3000/test')
190
+ equal(spanClient.kind, SpanKind.CLIENT)
185
191
  equal(spanClient.status.code, SpanStatusCode.ERROR)
186
- equal(spanClient.attributes['server.url'], 'http://localhost:3000/test')
187
- equal(spanClient.attributes['response.statusCode'], 404)
192
+ equal(spanClient.attributes['url.full'], 'http://localhost:3000/test')
193
+ equal(spanClient.attributes['http.response.status_code'], 404)
188
194
  })
189
195
 
190
196
  test('should trace a client request failing (no HTTP error)', async ({ equal, same, teardown }) => {
@@ -219,7 +225,7 @@ test('should trace a client request failing (no HTTP error)', async ({ equal, sa
219
225
  const spanClient = finishedSpans[0]
220
226
  equal(spanClient.name, 'GET http://localhost:3000/test')
221
227
  equal(spanClient.status.code, SpanStatusCode.ERROR)
222
- equal(spanClient.attributes['server.url'], 'http://localhost:3000/test')
228
+ equal(spanClient.attributes['url.full'], 'http://localhost:3000/test')
223
229
  equal(spanClient.attributes['error.name'], 'Error')
224
230
  equal(spanClient.attributes['error.message'], 'KABOOM!!!')
225
231
  equal(spanClient.attributes['error.stack'].includes('Error: KABOOM!!!'), true)
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { test } = require('tap')
4
4
  const fastify = require('fastify')
5
- const { SpanStatusCode } = require('@opentelemetry/api')
5
+ const { SpanStatusCode, SpanKind } = require('@opentelemetry/api')
6
6
  const telemetryPlugin = require('../lib/telemetry')
7
7
 
8
8
  async function setupApp (pluginOpts, routeHandler, teardown) {
@@ -46,11 +46,14 @@ test('should trace a request not failing', async ({ equal, same, teardown }) =>
46
46
  const finishedSpans = exporter.getFinishedSpans()
47
47
  equal(finishedSpans.length, 1)
48
48
  const span = finishedSpans[0]
49
+ equal(span.kind, SpanKind.SERVER)
49
50
  equal(span.name, 'GET /test')
50
51
  equal(span.status.code, SpanStatusCode.OK)
51
- equal(span.attributes['req.method'], 'GET')
52
- equal(span.attributes['req.url'], '/test')
53
- equal(span.attributes['reply.statusCode'], 200)
52
+ equal(span.attributes['http.request.method'], 'GET')
53
+ equal(span.attributes['url.path'], '/test')
54
+ equal(span.attributes['http.response.status_code'], 200)
55
+ equal(span.attributes['url.scheme'], 'http')
56
+ equal(span.attributes['server.address'], 'test')
54
57
  const resource = span.resource
55
58
  same(resource.attributes['service.name'], 'test-service')
56
59
  same(resource.attributes['service.version'], '1.0.0')
@@ -77,9 +80,9 @@ test('request should add attribute to a span', async ({ equal, same, teardown })
77
80
  const span = finishedSpans[0]
78
81
  equal(span.name, 'GET /test')
79
82
  equal(span.status.code, SpanStatusCode.OK)
80
- equal(span.attributes['req.method'], 'GET')
81
- equal(span.attributes['req.url'], '/test')
82
- equal(span.attributes['reply.statusCode'], 200)
83
+ equal(span.attributes['http.request.method'], 'GET')
84
+ equal(span.attributes['url.path'], '/test')
85
+ equal(span.attributes['http.response.status_code'], 200)
83
86
  // This is the attribute we added
84
87
  equal(span.attributes.foo, 'bar')
85
88
  const resource = span.resource
@@ -127,9 +130,9 @@ test('should trace a request that fails', async ({ equal, same, teardown }) => {
127
130
  const span = finishedSpans[0]
128
131
  equal(span.name, 'GET /test')
129
132
  equal(span.status.code, SpanStatusCode.ERROR)
130
- equal(span.attributes['req.method'], 'GET')
131
- equal(span.attributes['req.url'], '/test')
132
- equal(span.attributes['reply.statusCode'], 500)
133
+ equal(span.attributes['http.request.method'], 'GET')
134
+ equal(span.attributes['url.path'], '/test')
135
+ equal(span.attributes['http.response.status_code'], 500)
133
136
  equal(span.attributes['error.message'], 'booooom!!!')
134
137
  const resource = span.resource
135
138
  same(resource.attributes['service.name'], 'test-service')