Gracefull shutdown doesn't work with GRPC Exporter
krim opened this issue · comments
What happened?
Steps to Reproduce
app.js
const tracingSDK = require('./tracing')
const express = require('express')
const http = require('http')
const server = http.createServer(app)
const port = 8888
server.listen(port)
console.log('Start listening on port ' + port)
function shutdown (signal) {
const second = 1000
const shutdownDelay = 15 * second
console.log(`Receive signal ${signal} wait ${shutdownDelay}ms`)
setTimeout(gracefulShutdown, shutdownDelay)
}
process.on('SIGTERM', shutdown)
process.on('SIGINT', shutdown)
function gracefulShutdown () {
console.log('HTTP server close start')
server.close((err) => {
if (err) {
console.log(err)
} else {
console.log('HTTP server close success')
}
tracingSDK.shutdown()
.then(() => console.log('Tracing terminated'))
.catch((error) => console.log(error))
.finally(() => process.exit(0))
})
})
}
Start an app:
npm run start
Expected Result
When you stop an app you expect to get Tracing terminated
Actual Result
TypeError: _a.shutdown is not a function
File "TypeError: _a.shutdown is not a function"
File " at GrpcExporterTransport.shutdown (/usr/src/app/node_modules/@opentelemetry/otlp-grpc-exporter-base/build/src/grpc-exporter-transport.js", line 55, in 69)
File " at OTLPTraceExporter.onShutdown (/usr/src/app/node_modules/@opentelemetry/otlp-grpc-exporter-base/build/src/OTLPGRPCExporterNodeBase.js", line 75, in 25)
File " at OTLPTraceExporter._shutdown (/usr/src/app/node_modules/@opentelemetry/otlp-exporter-base/build/src/OTLPExporterBase.js", line 103, in 14)
File " at BindOnceFuture.call (/usr/src/app/node_modules/@opentelemetry/core/build/src/utils/callback.js", line 40, in 48)
File " at OTLPTraceExporter.shutdown (/usr/src/app/node_modules/@opentelemetry/otlp-exporter-base/build/src/OTLPExporterBase.js", line 88, in 35)
File " at SimpleSpanProcessor._shutdown (/usr/src/app/node_modules/@opentelemetry/sdk-trace-base/build/src/export/SimpleSpanProcessor.js", line 81, in 31)
File " at BindOnceFuture.call (/usr/src/app/node_modules/@opentelemetry/core/build/src/utils/callback.js", line 40, in 48)
File " at SimpleSpanProcessor.shutdown (/usr/src/app/node_modules/@opentelemetry/sdk-trace-base/build/src/export/SimpleSpanProcessor.js", line 78, in 35)
File " at MultiSpanProcessor.shutdown (/usr/src/app/node_modules/@opentelemetry/sdk-trace-base/build/src/MultiSpanProcessor.js", line 57, in 41)
File " at NodeTracerProvider.shutdown (/usr/src/app/node_modules/@opentelemetry/sdk-trace-base/build/src/BasicTracerProvider.js", line 143, in 41)
OpenTelemetry Setup Code
const sdkNode = require('@opentelemetry/sdk-node')
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')
const { SimpleSpanProcessor, ConsoleSpanExporter, AlwaysOnSampler } = require('@opentelemetry/sdk-trace-base')
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc')
const traceExporter = new OTLPTraceExporter({
url: process.env.OTEL_COLLECTOR_URL,
})
let spanProcessors = [
new SimpleSpanProcessor(traceExporter),
]
if (process.env.DEBUG_TELEMETRY) {
spanProcessors = [...spanProcessors, new SimpleSpanProcessor(new ConsoleSpanExporter())]
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api')
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG)
}
// configure the SDK to export telemetry data to the console
// enable all auto-instrumentations from the meta package
const sdk = new sdkNode.NodeSDK({
traceExporter,
spanProcessors,
instrumentations: [
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-fs': {
enabled: false,
},
'@opentelemetry/instrumentation-mongodb': {
enabled: false,
},
'@opentelemetry/instrumentation-http': {
ignoreIncomingRequestHook (req) {
// Ignore OPTIONS requests
return req.method === 'OPTIONS'
},
},
}),
],
sampler: new AlwaysOnSampler(),
})
// initialize the SDK and register with the OpenTelemetry API
// this enables the API to record telemetry
sdk.start()
module.exports = sdk
package.json
{
"name": "test-app",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "node app"
},
"dependencies": {
"@opentelemetry/api": "1.8.0",
"@opentelemetry/auto-instrumentations-node": "0.44.0",
"@opentelemetry/exporter-trace-otlp-grpc": "0.50.0",
"@opentelemetry/sdk-node": "0.50.0",
"@opentelemetry/sdk-trace-base": "1.23.0",
"express": "^4.15.2",
}
}
Relevant log output
No response
I'm looking into this.
That's my fault. The transport should call close()
instead of shutdown()
on the _client
. The test I wrote for this case was entirely ineffective as I also managed to mock the wrong thing. 😞
Sorry about that. I'll open a PR momentarily.
Thanks a lot!