in lib/apm-client/http-apm-client/index.js [1483:1581]
Client.prototype._fetchApmServerVersion = function () {
const setVerUnknownAndNotify = (errmsg) => {
this._apmServerVersion = null; // means "unknown version"
this._resetEncodedMetadata();
if (isLambdaExecutionEnvironment) {
// In a Lambda environment, where the process can be frozen, it is not
// unusual for this request to hit an error. As long as APM Server version
// fetching is not critical to tracing of Lambda invocations, then it is
// preferable to not add an error message to the users log.
this._log.debug('verfetch: ' + errmsg);
} else {
this.emit('request-error', new Error(errmsg));
}
};
const headers = getHeaders(this._conf);
// Explicitly do *not* pass in `this._agent` -- the keep-alive http.Agent
// used for intake requests -- because the socket.ref() handling in
// `Client#_ref()` conflicts with the socket.unref() below.
const reqOpts = getBasicRequestOptions('GET', '/', headers, this._conf);
reqOpts.timeout = 30000;
const req = this._transportGet(reqOpts, (res) => {
res.on('error', (err) => {
// Not sure this event can ever be emitted, but just in case
res.destroy(err);
});
if (res.statusCode !== 200) {
res.resume();
setVerUnknownAndNotify(
`unexpected status from APM Server information endpoint: ${res.statusCode}`,
);
return;
}
const chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
res.on('end', () => {
if (chunks.length === 0) {
setVerUnknownAndNotify(
'APM Server information endpoint returned no body, often this indicates authentication ("apiKey" or "secretToken") is incorrect',
);
return;
}
let serverInfo;
try {
serverInfo = JSON.parse(Buffer.concat(chunks));
} catch (parseErr) {
setVerUnknownAndNotify(
`could not parse APM Server information endpoint body: ${parseErr.message}`,
);
return;
}
if (serverInfo) {
// APM Server 7.0.0 dropped the "ok"-level in the info endpoint body.
const verStr = serverInfo.ok
? serverInfo.ok.version
: serverInfo.version;
try {
this._apmServerVersion = new semver.SemVer(verStr);
} catch (verErr) {
setVerUnknownAndNotify(
`could not parse APM Server version "${verStr}": ${verErr.message}`,
);
return;
}
this._resetEncodedMetadata();
this._log.debug(
{ apmServerVersion: verStr },
'fetched APM Server version',
);
} else {
setVerUnknownAndNotify(
`could not determine APM Server version from information endpoint body: ${JSON.stringify(
serverInfo,
)}`,
);
}
});
});
req.on('socket', (socket) => {
// Unref our socket to ensure this request does not keep the process alive.
socket.unref();
});
req.on('timeout', () => {
this._log.trace('_fetchApmServerVersion timeout');
req.destroy(
new Error(`timeout (${reqOpts.timeout}ms) fetching APM Server version`),
);
});
req.on('error', (err) => {
setVerUnknownAndNotify(`error fetching APM Server version: ${err.message}`);
});
};