Comments (1)
Here is a repro script just using the client (instead of via the apm-agent-nodejs). "call-me-back-maybe.js"
// A script, used by test/side-effects.js, to test that the client.flush
// callback is called.
//
// We expect both `console.log`s to write their output.
//
// Two important things are required to reproduce the issue:
// 1. There cannot be other activities going on that involve active libuv
// handles. For this Client that means:
// - ensure no `_pollConfig` requests via `centralConfig: false`
// - do not provide a `cloudMetadataFetcher`
// 2. There must be a listening APM server to which to send data.
const Client = require('../../') // elastic-apm-http-client
const serverUrl = process.argv[2]
const client = new Client({
logger: require('pino')({ level: 'trace', ...require('@elastic/ecs-pino-format')() }, process.stderr), // uncomment for debugging
serverUrl: serverUrl,
serviceName: 'call-me-back-maybe',
agentName: 'my-nodejs-agent',
agentVersion: '1.2.3',
userAgent: 'my-nodejs-agent/1.2.3',
centralConfig: false // important for repro, see above
})
const e = { exception: { message: 'boom', type: 'Error' } }
client.sendError(e, function sendCb () {
console.log('sendCb called')
client.flush(function flushCb () {
console.log('flushCb called')
})
})
With that logger enabled for debugging, here is a run without a fix:
% node test/lib/call-me-back-maybe.js 2> >(ecslog -x process.pid,reqId)
[2021-04-06T21:21:10.655Z] TRACE (on pink.local): intake request start
[2021-04-06T21:21:10.658Z] TRACE (on pink.local): _write: encode object
fullTimeMs: 8.877795
numEvents: 1
numBytes: 58
[2021-04-06T21:21:10.658Z] TRACE (on pink.local): intakeReq "socket": unref it
sendCb called
[2021-04-06T21:21:10.660Z] TRACE (on pink.local): _writeFlush
active: true
[2021-04-06T21:21:10.662Z] TRACE (on pink.local): gzipStream "finish"
[2021-04-06T21:21:10.662Z] TRACE (on pink.local): start intakeResTimer
timeout: 10000
[2021-04-06T21:21:10.665Z] TRACE (on pink.local): gzipStream "end"
[2021-04-06T21:21:10.665Z] TRACE (on pink.local): completePart gzipStream
concluded: false
[2021-04-06T21:21:10.666Z] TRACE (on pink.local): intakeReq "finish"
[2021-04-06T21:21:10.666Z] TRACE (on pink.local): completePart intakeReq
concluded: false
[2021-04-06T21:21:10.666Z] TRACE (on pink.local): auto-end client beforeExit
and with the fix:
% node test/lib/call-me-back-maybe.js 2> >(ecslog -x process.pid,reqId)
[2021-04-06T21:22:40.147Z] TRACE (on pink.local): intake request start
[2021-04-06T21:22:40.149Z] TRACE (on pink.local): _write: encode object
fullTimeMs: 9.602986
numEvents: 1
numBytes: 58
[2021-04-06T21:22:40.150Z] TRACE (on pink.local): intakeReq "socket": unref it
sendCb called
[2021-04-06T21:22:40.151Z] TRACE (on pink.local): _writeFlush
active: true
[2021-04-06T21:22:40.154Z] TRACE (on pink.local): gzipStream "finish"
[2021-04-06T21:22:40.154Z] TRACE (on pink.local): start intakeResTimer
timeout: 10000
[2021-04-06T21:22:40.155Z] TRACE (on pink.local): gzipStream "end"
[2021-04-06T21:22:40.155Z] TRACE (on pink.local): completePart gzipStream
concluded: false
[2021-04-06T21:22:40.156Z] TRACE (on pink.local): intakeReq "finish"
[2021-04-06T21:22:40.156Z] TRACE (on pink.local): completePart intakeReq
concluded: false
[2021-04-06T21:22:40.157Z] TRACE (on pink.local): _gracefulExit
[2021-04-06T21:22:40.158Z] TRACE (on pink.local): intakeReq "response"
statusCode: 202
reqFinished: true
[2021-04-06T21:22:40.159Z] TRACE (on pink.local): intakeRes "end"
[2021-04-06T21:22:40.159Z] TRACE (on pink.local): completePart intakeRes
concluded: false
flushCb called
[2021-04-06T21:22:40.159Z] TRACE (on pink.local): conclude intake request: success
timeline: [
[
13.591589,
"completePart gzipStream",
null
],
[
14.249018,
"completePart intakeReq",
null
],
[
17.151894,
"completePart intakeRes",
null
]
]
bytesWritten: 326
backoffDelayMs: 0
[2021-04-06T21:22:40.160Z] TRACE (on pink.local): _final
The difference is what happens when the "beforeExit" event is sent when node is about to terminate. Before the fix, the expectation was that the "beforeExit" handler would call client.end()
, which would call client._ref()
(via Client._final
) to add a libuv reference to the socket being used to flush data to APM server. However, the bug was the expectation that client.end()
would call Client.prototype._final
. That is async and doesn't happen when node is exiting. The solution is to ensure client._ref()
gets called synchronously.
from apm-nodejs-http-client.
Related Issues (20)
- Node 11 support HOT 2
- TypeError: Cannot convert undefined or null to object HOT 2
- Cannot get this to send out spans HOT 2
- Non-standard indentation and undefined catch scope HOT 6
- Indentation with EsLint and Prettier HOT 2
- Need to increment git ignore configuration HOT 5
- test failure with node v15.5.0 HOT 1
- Kibana Instrumentation and `APM Server transport error (ECONNRESET): socket hang up` Log Messages HOT 14
- perf: Alternate Options to Initial Stream Corking
- Feature Request: Logging in the Client HOT 1
- Flush seems to complete before request is sent HOT 5
- Blocking Behavior under Benchmarking Load HOT 11
- consider changing payloadLogFile handling to *not* unzip the payload data HOT 1
- 'npm run coverage' errors; breaks checks for node v15 HOT 1
- Client Behavior in AWS Lambda Enviornment
- CI implementations (in GitHub actions and Jenkinis) duplicate the number of builds per PR HOT 2
- Audit failure due to a vulnerability in semver HOT 1
- Vulnerability in semver HOT 1
- Throws error `Cannot read property 'length' of undefined` on StreamChopper.Writable.write() HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from apm-nodejs-http-client.