@platformatic/telemetry 2.35.1 → 2.36.2
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.
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { pathToFileURL } = require('node:url')
|
|
4
|
+
const { createRequire } = require('node:module')
|
|
5
|
+
const { join } = require('node:path')
|
|
6
|
+
|
|
7
|
+
async function importOrLocal ({ projectDir, pkg }) {
|
|
8
|
+
try {
|
|
9
|
+
return import(pkg)
|
|
10
|
+
} catch (err) {
|
|
11
|
+
const pkgJsonPath = join(projectDir, 'package.json')
|
|
12
|
+
const _require = createRequire(pkgJsonPath)
|
|
13
|
+
const fileToImport = _require.resolve(pkg)
|
|
14
|
+
return import(pathToFileURL(fileToImport))
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = importOrLocal
|
package/lib/node-telemetry.js
CHANGED
|
@@ -12,6 +12,8 @@ const { tmpdir } = require('node:os')
|
|
|
12
12
|
const logger = require('abstract-logging')
|
|
13
13
|
const { statSync, readFileSync } = require('node:fs') // We want to have all this synch
|
|
14
14
|
const util = require('node:util')
|
|
15
|
+
const { getInstrumentations } = require('./pluggable-instrumentations')
|
|
16
|
+
|
|
15
17
|
const debuglog = util.debuglog('@platformatic/telemetry')
|
|
16
18
|
const {
|
|
17
19
|
ConsoleSpanExporter,
|
|
@@ -31,8 +33,9 @@ const {
|
|
|
31
33
|
// https://github.com/open-telemetry/opentelemetry-js/issues/5103
|
|
32
34
|
process.env.OTEL_SEMCONV_STABILITY_OPT_IN = 'http/dup'
|
|
33
35
|
|
|
34
|
-
const setupNodeHTTPTelemetry = (opts) => {
|
|
35
|
-
const { serviceName } = opts
|
|
36
|
+
const setupNodeHTTPTelemetry = async (opts, serviceDir) => {
|
|
37
|
+
const { serviceName, instrumentations = [] } = opts
|
|
38
|
+
const additionalInstrumentations = await getInstrumentations(instrumentations, serviceDir)
|
|
36
39
|
|
|
37
40
|
let exporter = opts.exporter
|
|
38
41
|
if (!exporter) {
|
|
@@ -96,6 +99,7 @@ const setupNodeHTTPTelemetry = (opts) => {
|
|
|
96
99
|
}),
|
|
97
100
|
new HttpInstrumentation(),
|
|
98
101
|
new PgInstrumentation(),
|
|
102
|
+
...additionalInstrumentations
|
|
99
103
|
],
|
|
100
104
|
resource: new Resource({
|
|
101
105
|
[ATTR_SERVICE_NAME]: serviceName
|
|
@@ -110,28 +114,37 @@ const setupNodeHTTPTelemetry = (opts) => {
|
|
|
110
114
|
})
|
|
111
115
|
}
|
|
112
116
|
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
const main = async () => {
|
|
118
|
+
let data = null
|
|
119
|
+
const useWorkerData = !!workerData
|
|
115
120
|
|
|
116
|
-
if (useWorkerData) {
|
|
117
|
-
|
|
118
|
-
} else if (process.env.PLT_MANAGER_ID) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
if (useWorkerData) {
|
|
122
|
+
data = workerData
|
|
123
|
+
} else if (process.env.PLT_MANAGER_ID) {
|
|
124
|
+
try {
|
|
125
|
+
const dataPath = resolve(tmpdir(), 'platformatic', 'runtimes', `${process.env.PLT_MANAGER_ID}.json`)
|
|
126
|
+
statSync(dataPath)
|
|
127
|
+
const jsonData = JSON.parse(readFileSync(dataPath, 'utf8'))
|
|
128
|
+
data = jsonData.data
|
|
129
|
+
debuglog(`Loaded data from ${dataPath}`)
|
|
130
|
+
} catch (e) {
|
|
131
|
+
debuglog('Error reading data from file %o', e)
|
|
132
|
+
}
|
|
127
133
|
}
|
|
128
|
-
}
|
|
129
134
|
|
|
130
|
-
if (data) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
if (data) {
|
|
136
|
+
debuglog('Setting up telemetry %o', data)
|
|
137
|
+
const serviceDir = data.serviceConfig?.path
|
|
138
|
+
const telemetryConfig = useWorkerData ? data?.serviceConfig?.telemetry : data?.telemetryConfig
|
|
139
|
+
if (telemetryConfig) {
|
|
140
|
+
debuglog('telemetryConfig %o', telemetryConfig)
|
|
141
|
+
setupNodeHTTPTelemetry(telemetryConfig, serviceDir)
|
|
142
|
+
}
|
|
136
143
|
}
|
|
137
144
|
}
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
main()
|
|
148
|
+
} catch (e) {
|
|
149
|
+
debuglog('Error in main %o', e)
|
|
150
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const importOrLocal = require('./import-or-local')
|
|
4
|
+
|
|
5
|
+
// These are already set automatically by the runtime, so we throw
|
|
6
|
+
// if set again.
|
|
7
|
+
const defaultInstrumentations = [
|
|
8
|
+
'@opentelemetry/instrumentation-pg',
|
|
9
|
+
'@opentelemetry/instrumentation-http',
|
|
10
|
+
'@opentelemetry/instrumentation-undici'
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
const getInstrumentationInstance = async (instrumentationConfig, serviceDir) => {
|
|
14
|
+
if (typeof instrumentationConfig === 'string') {
|
|
15
|
+
instrumentationConfig = { package: instrumentationConfig, exportName: 'default', options: {} }
|
|
16
|
+
}
|
|
17
|
+
const { package: packageName, exportName = 'default', options = {} } = instrumentationConfig
|
|
18
|
+
|
|
19
|
+
if (defaultInstrumentations.includes(packageName)) {
|
|
20
|
+
throw new Error(`Instrumentation package ${packageName} is already included by default, please remove it from your config.`)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let mod
|
|
24
|
+
try {
|
|
25
|
+
mod = await importOrLocal({ pkg: packageName, projectDir: serviceDir })
|
|
26
|
+
} catch (err) {
|
|
27
|
+
throw new Error(`Instrumentation package not found: ${instrumentationConfig.package}, please add it to your dependencies.`)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let Instrumenter = mod[exportName]
|
|
31
|
+
if (!Instrumenter || typeof Instrumenter !== 'function') {
|
|
32
|
+
// Check for for an export that ends with 'Instrumentation'. We need to do that because unfortunately
|
|
33
|
+
// each instrumenttions has different named export. But all of them ends with 'Instrumentation'.
|
|
34
|
+
const possibleExports = Object.keys(mod).filter((key) => key.endsWith('Instrumentation'))
|
|
35
|
+
if (possibleExports.length === 0) {
|
|
36
|
+
throw new Error(`Instrumentation export not found: ${exportName} in ${packageName}. Please specify in config`)
|
|
37
|
+
}
|
|
38
|
+
if (possibleExports.length > 1) {
|
|
39
|
+
throw new Error(`Multiple Instrumentation exports found: ${possibleExports} in ${packageName}. Please specify in config`)
|
|
40
|
+
}
|
|
41
|
+
Instrumenter = mod[possibleExports[0]]
|
|
42
|
+
}
|
|
43
|
+
const instance = new Instrumenter(options)
|
|
44
|
+
return instance
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Example of instrumentations config:
|
|
48
|
+
// "instrumentations": [
|
|
49
|
+
// "@opentelemetry/instrumentation-express",
|
|
50
|
+
// {
|
|
51
|
+
// "package": "@opentelemetry/instrumentation-redisjs",
|
|
52
|
+
// "exportName": "RedisInstrumentation",
|
|
53
|
+
// "options": { "foo": "bar" }
|
|
54
|
+
// }
|
|
55
|
+
const getInstrumentations = async (configs = [], serviceDir) => {
|
|
56
|
+
const instrumentations = []
|
|
57
|
+
for (const instrumentationConfig of configs) {
|
|
58
|
+
const instance = await getInstrumentationInstance(instrumentationConfig, serviceDir)
|
|
59
|
+
instrumentations.push(instance)
|
|
60
|
+
}
|
|
61
|
+
return instrumentations
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = {
|
|
65
|
+
getInstrumentations,
|
|
66
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/telemetry",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.36.2",
|
|
4
4
|
"description": "OpenTelemetry integration for Platformatic",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Platformatic Inc. <oss@platformatic.dev> (https://platformatic.dev)",
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
},
|
|
11
11
|
"license": "Apache-2.0",
|
|
12
12
|
"devDependencies": {
|
|
13
|
+
"@databases/pg": "^5.5.0",
|
|
14
|
+
"@opentelemetry/instrumentation-express": "^0.47.0",
|
|
13
15
|
"borp": "^0.19.0",
|
|
14
16
|
"express": "^4.19.2",
|
|
15
17
|
"fastify": "^5.0.0",
|
|
@@ -21,21 +23,23 @@
|
|
|
21
23
|
"@fastify/swagger": "^9.0.0",
|
|
22
24
|
"@opentelemetry/api": "^1.8.0",
|
|
23
25
|
"@opentelemetry/core": "^1.22.0",
|
|
24
|
-
"@opentelemetry/exporter-trace-otlp-proto": "^0.
|
|
26
|
+
"@opentelemetry/exporter-trace-otlp-proto": "^0.57.0",
|
|
25
27
|
"@opentelemetry/exporter-zipkin": "^1.22.0",
|
|
28
|
+
"@opentelemetry/instrumentation": "^0.57.0",
|
|
26
29
|
"@opentelemetry/instrumentation-http": "^0.56.0",
|
|
27
30
|
"@opentelemetry/instrumentation-pg": "^0.50.0",
|
|
28
31
|
"@opentelemetry/instrumentation-undici": "^0.10.0",
|
|
29
32
|
"@opentelemetry/resources": "^1.22.0",
|
|
30
|
-
"@opentelemetry/sdk-node": "^0.
|
|
33
|
+
"@opentelemetry/sdk-node": "^0.57.0",
|
|
31
34
|
"@opentelemetry/sdk-trace-base": "^1.22.0",
|
|
32
35
|
"@opentelemetry/semantic-conventions": "^1.27.0",
|
|
33
36
|
"abstract-logging": "^2.0.1",
|
|
34
37
|
"fast-uri": "^3.0.0",
|
|
35
|
-
"fastify-plugin": "^5.0.0"
|
|
38
|
+
"fastify-plugin": "^5.0.0",
|
|
39
|
+
"@platformatic/config": "2.36.2"
|
|
36
40
|
},
|
|
37
41
|
"scripts": {
|
|
38
|
-
"test": "npm run lint && borp --timeout=
|
|
42
|
+
"test": "npm run lint && borp --timeout=120000 --concurrency=1",
|
|
39
43
|
"lint": "eslint"
|
|
40
44
|
}
|
|
41
45
|
}
|