atatus-nodejs
Version:
Atatus APM agent for Node.js
139 lines (115 loc) • 4.14 kB
JavaScript
const zlib = require('zlib')
const axios = require('axios')
const https = require('https')
var AtatusHTTPClient = module.exports = function (name, agent, notifyHost, isAnalytics) {
this.name = name
this.agent = agent
this.serverUrl = notifyHost // Optional: Only passed when it is different from common URL. Applicable to analytics payload
this.isAnalytics = isAnalytics
}
AtatusHTTPClient.prototype.getCommonInfo = function () {
let conf = this.agent._conf
let info = {
appName: conf.appName,
licenseKey: conf.licenseKey,
apiKey: conf.apiKey,
uniqueHostname: (conf.hostDetails && conf.hostDetails.bootId) || conf.hostname,
hostname: conf.hostname,
containerId: conf.containerId,
version: conf.appVersion,
releaseStage: conf.environment,
agent: {
name: conf.loggingPreambleData && conf.loggingPreambleData.agentName,
version: conf.loggingPreambleData && conf.loggingPreambleData.agentVersion
},
tags: conf.tags,
customData: conf.customData
}
return info
}
AtatusHTTPClient.prototype.compressPayload = function (payload, cb) {
zlib.gzip(payload, function (err, buffer) {
if (err) {
this.agent.logger.debug('Payload compression failure: ', err);
return cb(null, { data: payload })
} else {
return cb(null, { data: buffer, compressed: true })
}
})
}
AtatusHTTPClient.prototype.request = function (body, cb) {
let url = (this.serverUrl || this.agent._conf.serverUrl) + this.name
let isAnalytics = this.isAnalytics
let agent = this.agent
agent._conf.backendConfig = agent._conf.backendConfig || {}
let payload = Object.assign(
body,
this.getCommonInfo()
)
agent.logger.debug('Sending to Atatus: ', url, JSON.stringify(payload, null, 4));
this.compressPayload(JSON.stringify(payload), function (err, result) {
let options = {
method: 'post',
url: url,
headers: {
'User-Agent': agent._conf.userAgent,
'Content-Type': 'application/json'
},
httpsAgent: new https.Agent({ keepAlive: true }), // , maxSockets: 50
// timeout: 60000, // 60 seconds
data: result.data
}
if (result.compressed) {
options.headers['Content-Encoding'] = 'gzip'
}
if (agent._conf.proxy) {
try {
let { protocol, port, hostname, username, password } = new URL(agent._conf.proxy)
options.proxy = {
protocol: protocol.replace(':', ''),
port: port,
host: hostname,
username: username || '',
password: password || '',
}
} catch (e) {
// silently ignore
}
}
agent.logger.debug('Compress and proxy options: ', result.compressed, options.proxy);
// console.log('Compress and proxy options: ', result.compressed, options.proxy)
axios(options)
.then(response => {
let body = response.data
let statusCode = response.statusCode || response.status
if (statusCode >= 200 && statusCode < 300) {
// If all API passed except analytics, then reset the blocked
// Keep in mind that blocked is only applicable to APM.
if (!isAnalytics) {
agent._conf.blocked = false
}
return cb(null, body);
}
return cb(null, body);
})
.catch(error => {
let response = error.response || {}
let body = response.data || {}
let statusCode = response.statusCode || response.status
var dontShowErrorMessage = false
// Uncomment and customize the following code as needed
if (statusCode === 400) {
if (typeof body.analytics !== 'undefined') {
agent._conf.backendConfig.analytics = body.analytics
}
if (body.blocked) {
agent._conf.blocked = true
dontShowErrorMessage = (agent._conf.analytics && agent._conf.backendConfig.analytics) // Don't print message if analytics is enabled.
}
}
const err = new Error(body.errorMessage || body.error || 'Request Failed!')
err.dontShowErrorMessage = dontShowErrorMessage
return cb(err)
})
})
}