elastic-apm-node
Advanced tools
Comparing version 2.11.6 to 2.12.0
@@ -0,1 +1,5 @@ | ||
# 2.12.0 - 2019/8/2 | ||
* feat(metrics): add runtime metrics ([#1021](https://github.com/elastic/apm-agent-nodejs/pull/1021)) | ||
* feat(config): add environment option ([#1106](https://github.com/elastic/apm-agent-nodejs/pull/1106)) | ||
# 2.11.6 - 2019/6/11 | ||
@@ -2,0 +6,0 @@ * fix(express): don't swallow error handling middleware ([#1111](https://github.com/elastic/apm-agent-nodejs/pull/1111)) |
@@ -116,2 +116,3 @@ /// <reference types="node" /> | ||
active?: boolean; | ||
addPatch?: KeyValueConfig; | ||
apiRequestSize?: string; // Also support `number`, but as we're removing this functionality soon, there's no need to advertise it | ||
@@ -127,2 +128,3 @@ apiRequestTime?: string; // Also support `number`, but as we're removing this functionality soon, there's no need to advertise it | ||
disableInstrumentations?: string | string[]; | ||
environment?: string; | ||
errorMessageMaxLength?: string; // Also support `number`, but as we're removing this functionality soon, there's no need to advertise it | ||
@@ -133,2 +135,3 @@ errorOnAbortedRequests?: boolean; | ||
frameworkVersion?: string; | ||
globalLabels?: KeyValueConfig; | ||
hostname?: string; | ||
@@ -158,2 +161,3 @@ ignoreUrls?: Array<string | RegExp>; | ||
transactionSampleRate?: number; | ||
usePathAsTransactionName?: boolean; | ||
verifyServerCert?: boolean; | ||
@@ -221,2 +225,3 @@ } | ||
type LabelValue = string | number | boolean | null | undefined; | ||
type KeyValueConfig = string | Labels | Array<Array<LabelValue>> | ||
@@ -223,0 +228,0 @@ type Payload = { [propName: string]: any } |
@@ -38,17 +38,28 @@ 'use strict' | ||
var DEFAULTS = { | ||
verifyServerCert: true, | ||
abortedErrorThreshold: '25s', | ||
active: true, | ||
logLevel: 'info', | ||
addPatch: undefined, | ||
apiRequestSize: '768kb', | ||
apiRequestTime: '10s', | ||
stackTraceLimit: 50, | ||
asyncHooks: true, | ||
captureBody: 'off', | ||
captureErrorLogStackTraces: config.CAPTURE_ERROR_LOG_STACK_TRACES_MESSAGES, | ||
captureExceptions: true, | ||
filterHttpHeaders: true, | ||
captureErrorLogStackTraces: config.CAPTURE_ERROR_LOG_STACK_TRACES_MESSAGES, | ||
captureHeaders: true, | ||
captureSpanStackTraces: true, | ||
captureBody: 'off', | ||
containerId: undefined, | ||
disableInstrumentations: [], | ||
environment: process.env.NODE_ENV || 'development', | ||
errorMessageMaxLength: '2kb', | ||
errorOnAbortedRequests: false, | ||
abortedErrorThreshold: '25s', | ||
filterHttpHeaders: true, | ||
globalLabels: undefined, | ||
instrument: true, | ||
asyncHooks: true, | ||
kubernetesNamespace: undefined, | ||
kubernetesNodeName: undefined, | ||
kubernetesPodName: undefined, | ||
kubernetesPodUID: undefined, | ||
logLevel: 'info', | ||
metricsInterval: '30s', | ||
serverTimeout: '30s', | ||
sourceLinesErrorAppFrames: 5, | ||
@@ -58,42 +69,44 @@ sourceLinesErrorLibraryFrames: 5, | ||
sourceLinesSpanLibraryFrames: 0, | ||
errorMessageMaxLength: '2kb', | ||
stackTraceLimit: 50, | ||
transactionMaxSpans: 500, | ||
transactionSampleRate: 1.0, | ||
serverTimeout: '30s', | ||
disableInstrumentations: [], | ||
containerId: undefined, | ||
kubernetesNodeName: undefined, | ||
kubernetesNamespace: undefined, | ||
kubernetesPodName: undefined, | ||
kubernetesPodUID: undefined, | ||
captureHeaders: true, | ||
metricsInterval: '30s', | ||
usePathAsTransactionName: false, | ||
addPatch: undefined, | ||
globalLabels: undefined | ||
verifyServerCert: true | ||
} | ||
var ENV_TABLE = { | ||
serviceName: 'ELASTIC_APM_SERVICE_NAME', | ||
secretToken: 'ELASTIC_APM_SECRET_TOKEN', | ||
serverUrl: 'ELASTIC_APM_SERVER_URL', | ||
verifyServerCert: 'ELASTIC_APM_VERIFY_SERVER_CERT', | ||
serviceVersion: 'ELASTIC_APM_SERVICE_VERSION', | ||
abortedErrorThreshold: 'ELASTIC_APM_ABORTED_ERROR_THRESHOLD', | ||
active: 'ELASTIC_APM_ACTIVE', | ||
logLevel: 'ELASTIC_APM_LOG_LEVEL', | ||
hostname: 'ELASTIC_APM_HOSTNAME', | ||
addPatch: 'ELASTIC_APM_ADD_PATCH', | ||
apiRequestSize: 'ELASTIC_APM_API_REQUEST_SIZE', | ||
apiRequestTime: 'ELASTIC_APM_API_REQUEST_TIME', | ||
frameworkName: 'ELASTIC_APM_FRAMEWORK_NAME', | ||
frameworkVersion: 'ELASTIC_APM_FRAMEWORK_VERSION', | ||
stackTraceLimit: 'ELASTIC_APM_STACK_TRACE_LIMIT', | ||
asyncHooks: 'ELASTIC_APM_ASYNC_HOOKS', | ||
captureBody: 'ELASTIC_APM_CAPTURE_BODY', | ||
captureErrorLogStackTraces: 'ELASTIC_APM_CAPTURE_ERROR_LOG_STACK_TRACES', | ||
captureExceptions: 'ELASTIC_APM_CAPTURE_EXCEPTIONS', | ||
filterHttpHeaders: 'ELASTIC_APM_FILTER_HTTP_HEADERS', | ||
captureErrorLogStackTraces: 'ELASTIC_APM_CAPTURE_ERROR_LOG_STACK_TRACES', | ||
captureHeaders: 'ELASTIC_APM_CAPTURE_HEADERS', | ||
captureSpanStackTraces: 'ELASTIC_APM_CAPTURE_SPAN_STACK_TRACES', | ||
captureBody: 'ELASTIC_APM_CAPTURE_BODY', | ||
containerId: 'ELASTIC_APM_CONTAINER_ID', | ||
disableInstrumentations: 'ELASTIC_APM_DISABLE_INSTRUMENTATIONS', | ||
environment: 'ELASTIC_APM_ENVIRONMENT', | ||
errorMessageMaxLength: 'ELASTIC_APM_ERROR_MESSAGE_MAX_LENGTH', | ||
errorOnAbortedRequests: 'ELASTIC_APM_ERROR_ON_ABORTED_REQUESTS', | ||
abortedErrorThreshold: 'ELASTIC_APM_ABORTED_ERROR_THRESHOLD', | ||
filterHttpHeaders: 'ELASTIC_APM_FILTER_HTTP_HEADERS', | ||
frameworkName: 'ELASTIC_APM_FRAMEWORK_NAME', | ||
frameworkVersion: 'ELASTIC_APM_FRAMEWORK_VERSION', | ||
globalLabels: 'ELASTIC_APM_GLOBAL_LABELS', | ||
hostname: 'ELASTIC_APM_HOSTNAME', | ||
instrument: 'ELASTIC_APM_INSTRUMENT', | ||
asyncHooks: 'ELASTIC_APM_ASYNC_HOOKS', | ||
kubernetesNamespace: ['ELASTIC_APM_KUBERNETES_NAMESPACE', 'KUBERNETES_NAMESPACE'], | ||
kubernetesNodeName: ['ELASTIC_APM_KUBERNETES_NODE_NAME', 'KUBERNETES_NODE_NAME'], | ||
kubernetesPodName: ['ELASTIC_APM_KUBERNETES_POD_NAME', 'KUBERNETES_POD_NAME'], | ||
kubernetesPodUID: ['ELASTIC_APM_KUBERNETES_POD_UID', 'KUBERNETES_POD_UID'], | ||
logLevel: 'ELASTIC_APM_LOG_LEVEL', | ||
metricsInterval: 'ELASTIC_APM_METRICS_INTERVAL', | ||
payloadLogFile: 'ELASTIC_APM_PAYLOAD_LOG_FILE', | ||
secretToken: 'ELASTIC_APM_SECRET_TOKEN', | ||
serverTimeout: 'ELASTIC_APM_SERVER_TIMEOUT', | ||
serverUrl: 'ELASTIC_APM_SERVER_URL', | ||
serviceName: 'ELASTIC_APM_SERVICE_NAME', | ||
serviceVersion: 'ELASTIC_APM_SERVICE_VERSION', | ||
sourceLinesErrorAppFrames: 'ELASTIC_APM_SOURCE_LINES_ERROR_APP_FRAMES', | ||
@@ -103,35 +116,23 @@ sourceLinesErrorLibraryFrames: 'ELASTIC_APM_SOURCE_LINES_ERROR_LIBRARY_FRAMES', | ||
sourceLinesSpanLibraryFrames: 'ELASTIC_APM_SOURCE_LINES_SPAN_LIBRARY_FRAMES', | ||
errorMessageMaxLength: 'ELASTIC_APM_ERROR_MESSAGE_MAX_LENGTH', | ||
stackTraceLimit: 'ELASTIC_APM_STACK_TRACE_LIMIT', | ||
transactionMaxSpans: 'ELASTIC_APM_TRANSACTION_MAX_SPANS', | ||
transactionSampleRate: 'ELASTIC_APM_TRANSACTION_SAMPLE_RATE', | ||
serverTimeout: 'ELASTIC_APM_SERVER_TIMEOUT', | ||
disableInstrumentations: 'ELASTIC_APM_DISABLE_INSTRUMENTATIONS', | ||
payloadLogFile: 'ELASTIC_APM_PAYLOAD_LOG_FILE', | ||
containerId: 'ELASTIC_APM_CONTAINER_ID', | ||
kubernetesNodeName: [ 'ELASTIC_APM_KUBERNETES_NODE_NAME', 'KUBERNETES_NODE_NAME' ], | ||
kubernetesNamespace: [ 'ELASTIC_APM_KUBERNETES_NAMESPACE', 'KUBERNETES_NAMESPACE' ], | ||
kubernetesPodName: [ 'ELASTIC_APM_KUBERNETES_POD_NAME', 'KUBERNETES_POD_NAME' ], | ||
kubernetesPodUID: [ 'ELASTIC_APM_KUBERNETES_POD_UID', 'KUBERNETES_POD_UID' ], | ||
captureHeaders: 'ELASTIC_APM_CAPTURE_HEADERS', | ||
metricsInterval: 'ELASTIC_APM_METRICS_INTERVAL', | ||
usePathAsTransactionName: 'ELASTIC_APM_USE_PATH_AS_TRANSACTION_NAME', | ||
addPatch: 'ELASTIC_APM_ADD_PATCH', | ||
globalLabels: 'ELASTIC_APM_GLOBAL_LABELS' | ||
verifyServerCert: 'ELASTIC_APM_VERIFY_SERVER_CERT' | ||
} | ||
var BOOL_OPTS = [ | ||
'verifyServerCert', | ||
'active', | ||
'asyncHooks', | ||
'captureExceptions', | ||
'filterHttpHeaders', | ||
'captureHeaders', | ||
'captureSpanStackTraces', | ||
'errorOnAbortedRequests', | ||
'filterHttpHeaders', | ||
'instrument', | ||
'asyncHooks', | ||
'captureHeaders', | ||
'usePathAsTransactionName' | ||
'usePathAsTransactionName', | ||
'verifyServerCert' | ||
] | ||
var NUM_OPTS = [ | ||
'stackTraceLimit', | ||
'sourceLinesErrorAppFrames', | ||
@@ -141,2 +142,3 @@ 'sourceLinesErrorLibraryFrames', | ||
'sourceLinesSpanLibraryFrames', | ||
'stackTraceLimit', | ||
'transactionMaxSpans', | ||
@@ -147,6 +149,6 @@ 'transactionSampleRate' | ||
var TIME_OPTS = [ | ||
'abortedErrorThreshold', | ||
'apiRequestTime', | ||
'abortedErrorThreshold', | ||
'serverTimeout', | ||
'metricsInterval' | ||
'metricsInterval', | ||
'serverTimeout' | ||
] | ||
@@ -213,2 +215,3 @@ | ||
hostname: conf.hostname, | ||
environment: conf.environment, | ||
@@ -215,0 +218,0 @@ // Sanitize conf |
@@ -25,3 +25,3 @@ 'use strict' | ||
const metricsInterval = this[agentSymbol]._conf.metricsInterval | ||
this[registrySymbol] = new MetricsRegistry(this[agentSymbol]._transport, { | ||
this[registrySymbol] = new MetricsRegistry(this[agentSymbol], { | ||
reporterOptions: { | ||
@@ -28,0 +28,0 @@ defaultReportingIntervalInSeconds: metricsInterval, |
@@ -7,2 +7,4 @@ 'use strict' | ||
const Stats = require('./stats') | ||
module.exports = function createSystemMetrics (registry) { | ||
@@ -26,6 +28,14 @@ // Base system metrics | ||
if (semver.satisfies(process.versions.node, '>=6.1')) { | ||
registry.getOrCreateGauge( | ||
const stats = new Stats() | ||
registry.registerCollector(stats) | ||
const metrics = [ | ||
'system.process.cpu.total.norm.pct', | ||
require('./process-cpu') | ||
) | ||
'system.process.cpu.system.norm.pct', | ||
'system.process.cpu.user.norm.pct' | ||
] | ||
for (let metric of metrics) { | ||
registry.getOrCreateGauge(metric, () => stats.toJSON()[metric]) | ||
} | ||
} | ||
@@ -32,0 +42,0 @@ registry.getOrCreateGauge( |
@@ -10,3 +10,8 @@ 'use strict' | ||
module.exports = function processCPUUsage () { | ||
return processTop.cpu().percent / cpus.length | ||
const cpu = processTop.cpu() | ||
return { | ||
total: cpu.percent / cpus.length, | ||
user: (cpu.user / cpu.time) / cpus.length, | ||
system: (cpu.system / cpu.time) / cpus.length | ||
} | ||
} |
@@ -35,3 +35,3 @@ 'use strict' | ||
const total = next.total - last.total | ||
return 1 - idle / total | ||
return 1 - idle / total || 0 | ||
} | ||
@@ -38,0 +38,0 @@ |
@@ -5,20 +5,10 @@ 'use strict' | ||
module.exports = function createSystemMetrics (registry, reportingIntervalInSeconds) { | ||
module.exports = function createSystemMetrics (registry) { | ||
const stats = new Stats() | ||
stats.start(reportingIntervalInSeconds) | ||
const metrics = [ | ||
'system.cpu.total.norm.pct', | ||
'system.memory.total', | ||
'system.memory.actual.free', | ||
'system.process.cpu.total.norm.pct', | ||
'system.process.memory.size', | ||
'system.process.memory.rss.bytes' | ||
] | ||
registry.registerCollector(stats) | ||
for (let metric of metrics) { | ||
for (let metric of Object.keys(stats.toJSON())) { | ||
registry.getOrCreateGauge(metric, () => stats.toJSON()[metric]) | ||
} | ||
registry.collector = stats | ||
} |
@@ -5,2 +5,6 @@ 'use strict' | ||
const afterAll = require('after-all-results') | ||
const whitespace = /\s+/ | ||
class Stats { | ||
@@ -23,3 +27,2 @@ constructor (opts) { | ||
stime: 0, | ||
procTotalTime: 0, | ||
vsize: 0, | ||
@@ -34,2 +37,4 @@ rss: 0 | ||
'system.process.cpu.total.norm.pct': 0, | ||
'system.process.cpu.system.norm.pct': 0, | ||
'system.process.cpu.user.norm.pct': 0, | ||
'system.process.memory.size': 0, | ||
@@ -60,5 +65,10 @@ 'system.process.memory.rss.bytes': 0 | ||
reload () { | ||
if (this.inProgress) return | ||
collect (cb) { | ||
if (this.inProgress) { | ||
if (cb) process.nextTick(cb) | ||
return | ||
} | ||
this.inProgress = true | ||
const files = [ | ||
@@ -70,74 +80,71 @@ this.files.processFile, | ||
this.inProgress = true | ||
const next = afterAll((err, files) => { | ||
if (!err) this.update(files) | ||
if (cb) cb() | ||
}) | ||
return Promise.all(files.map(readFile)) | ||
.then(files => this.update(files)) | ||
.catch(() => {}) | ||
files.forEach(function (file) { | ||
fs.readFile(file, next()) | ||
}) | ||
} | ||
readStats (files) { | ||
const processFile = files[0] | ||
const memoryFile = files[1] | ||
const cpuFile = files[2] | ||
readStats ([processFile, memoryFile, cpuFile]) { | ||
// CPU data | ||
// | ||
// Example of line we're trying to parse: | ||
// cpu 13978 30 2511 9257 2248 0 102 0 0 0 | ||
// CPU data | ||
const cpuLine = firstLineOfBufferAsString(cpuFile) | ||
const cpuTimes = cpuLine.split(whitespace) | ||
let cpuTotal = 0 | ||
let cpuUsage = 0 | ||
let cpuLine | ||
for (let line of String(cpuFile).split('\n')) { | ||
if (/^cpu /.test(line)) { | ||
cpuLine = line | ||
break | ||
} | ||
for (let i = 1; i < cpuTimes.length; i++) { | ||
cpuTotal += Number(cpuTimes[i]) | ||
} | ||
if (cpuLine) { | ||
const columns = cpuLine.split(/\s+/).slice(1).map(Number) | ||
// We're off-by-one in relation to the expected index, because we include | ||
// the `cpu` label at the beginning of the line | ||
const idle = Number(cpuTimes[4]) | ||
const iowait = Number(cpuTimes[5]) | ||
const cpuUsage = cpuTotal - idle - iowait | ||
const user = columns[0] | ||
const nice = columns[1] | ||
const system = columns[2] | ||
const idle = columns[3] | ||
const iowait = columns[4] | ||
const irq = columns[5] | ||
const softirq = columns[6] | ||
const steal = columns[7] | ||
cpuTotal = user + nice + system + idle + iowait + irq + softirq + steal | ||
cpuUsage = cpuTotal - (idle + iowait) | ||
} | ||
// Memory data | ||
// const memTotal = os.totalmem() | ||
// const memAvailable = os.freemem() | ||
// TODO: Figure out why os.freemem() is different... | ||
let memAvailable = 0 | ||
let memTotal = 0 | ||
for (let line of String(memoryFile).split('\n')) { | ||
let matches = 0 | ||
for (let line of memoryFile.toString().split('\n')) { | ||
if (/^MemAvailable:/.test(line)) { | ||
memAvailable = parseInt(line.split(/\s+/)[1], 10) * 1024 | ||
memAvailable = parseInt(line.split(whitespace)[1], 10) * 1024 | ||
matches++ | ||
} else if (/^MemTotal:/.test(line)) { | ||
memTotal = parseInt(line.split(/\s+/)[1], 10) * 1024 | ||
memTotal = parseInt(line.split(whitespace)[1], 10) * 1024 | ||
matches++ | ||
} | ||
if (matches === 2) break | ||
} | ||
// Process data | ||
let utime = 0 | ||
let stime = 0 | ||
let procTotalTime = 0 | ||
let vsize = 0 | ||
let rss = process.memoryUsage().rss | ||
// | ||
// Example of line we're trying to parse: | ||
// | ||
// 44 (node /app/node_) R 1 44 44 0 -1 4210688 7948 0 0 0 109 21 0 0 20 0 10 0 133652 954462208 12906 18446744073709551615 4194304 32940036 140735797366336 0 0 0 0 4096 16898 0 0 0 17 0 0 0 0 0 0 35037200 35143856 41115648 140735797369050 140735797369131 140735797369131 140735797370852 0 | ||
// | ||
// We can't just split on whitespace as the 2nd field might contain | ||
// whitespace. However, the parentheses will always be there, so we can | ||
// ignore everything from before the `)` to get rid of the whitespace | ||
// problem. | ||
// | ||
// For details about each field, see: | ||
// http://man7.org/linux/man-pages/man5/proc.5.html | ||
const processLine = String(processFile).split('\n')[0] | ||
if (processLine) { | ||
const processData = processLine.split(/\s+/) | ||
const processLine = firstLineOfBufferAsString(processFile) | ||
const processData = processLine.slice(processLine.lastIndexOf(')')).split(whitespace) | ||
utime = parseInt(processData[13], 10) | ||
stime = parseInt(processData[14], 10) | ||
procTotalTime = utime + stime | ||
vsize = parseInt(processData[22], 10) | ||
} | ||
// all fields are referenced by their index, but are off by one because | ||
// we're dropping the first field from the line due to the whitespace | ||
// problem described above | ||
const utime = parseInt(processData[12], 10) // position in file: 14 | ||
const stime = parseInt(processData[13], 10) // position in file: 15 | ||
const vsize = parseInt(processData[21], 10) // position in file: 23 | ||
@@ -151,5 +158,4 @@ return { | ||
stime, | ||
procTotalTime, | ||
vsize, | ||
rss | ||
rss: process.memoryUsage().rss // TODO: Calculate using field 24 (rss) * PAGE_SIZE | ||
} | ||
@@ -163,14 +169,27 @@ } | ||
const delta = { | ||
cpuTotal: next.cpuTotal - prev.cpuTotal, | ||
cpuUsage: next.cpuUsage - prev.cpuUsage, | ||
procTotalTime: next.procTotalTime - prev.procTotalTime | ||
} | ||
stats['system.cpu.total.norm.pct'] = delta.cpuUsage / delta.cpuTotal || 0 | ||
const cpuTotal = next.cpuTotal - prev.cpuTotal | ||
const cpuUsage = next.cpuUsage - prev.cpuUsage | ||
const utime = next.utime - prev.utime | ||
const stime = next.stime - prev.stime | ||
stats['system.cpu.total.norm.pct'] = cpuUsage / cpuTotal || 0 | ||
stats['system.memory.actual.free'] = next.memAvailable | ||
stats['system.memory.total'] = next.memTotal | ||
const cpuProcessPercent = delta.procTotalTime / delta.cpuTotal || 0 | ||
// We use Math.min to guard against an edge case where /proc/self/stat | ||
// reported more clock ticks than /proc/stat, in which case it looks like | ||
// the process spent more CPU time than was used by the system. In that | ||
// case we just assume it was a 100% CPU. | ||
// | ||
// This might happen because we don't read the process file at the same | ||
// time as the system file. In between the two reads, the process will | ||
// spend some time on the CPU and hence the two reads are not 100% synced | ||
// up. | ||
const cpuProcessPercent = Math.min((utime + stime) / cpuTotal || 0, 1) | ||
const cpuProcessUserPercent = Math.min(utime / cpuTotal || 0, 1) | ||
const cpuProcessSystemPercent = Math.min(stime / cpuTotal || 0, 1) | ||
stats['system.process.cpu.total.norm.pct'] = cpuProcessPercent | ||
stats['system.process.cpu.user.norm.pct'] = cpuProcessUserPercent | ||
stats['system.process.cpu.system.norm.pct'] = cpuProcessSystemPercent | ||
stats['system.process.memory.size'] = next.vsize | ||
@@ -182,27 +201,7 @@ stats['system.process.memory.rss.bytes'] = next.rss | ||
} | ||
start (reportingIntervalInSeconds, cb) { | ||
if (this.timer) this.stop() | ||
const timer = setInterval(() => { | ||
if (cb) cb(this.toJSON()) | ||
this.reload() | ||
}, reportingIntervalInSeconds * 1000) | ||
this.timer = timer | ||
timer.unref() | ||
} | ||
stop () { | ||
clearInterval(this.timer) | ||
this.timer = null | ||
} | ||
} | ||
function readFile (file) { | ||
return new Promise((resolve, reject) => { | ||
fs.readFile(file, (err, res) => { | ||
err ? reject(err) : resolve(res) | ||
}) | ||
}) | ||
function firstLineOfBufferAsString (buff) { | ||
const newline = buff.indexOf('\n') | ||
return buff.toString('utf8', 0, newline === -1 ? buff.length : newline) | ||
} | ||
@@ -209,0 +208,0 @@ |
@@ -8,2 +8,3 @@ 'use strict' | ||
const MetricsReporter = require('./reporter') | ||
const createRuntimeMetrics = require('./runtime') | ||
const createSystemMetrics = process.platform === 'linux' | ||
@@ -13,23 +14,23 @@ ? require('./platforms/linux') | ||
const defaultReporterOptions = { | ||
defaultDimensions: { | ||
hostname: os.hostname(), | ||
env: process.env.NODE_ENV || 'development' // TODO: Use environment config option once it lands | ||
} | ||
} | ||
class MetricsRegistry extends SelfReportingMetricsRegistry { | ||
constructor (agent, { reporterOptions, registryOptions } = {}) { | ||
const defaultReporterOptions = { | ||
defaultDimensions: { | ||
hostname: agent._conf.hostname || os.hostname(), | ||
env: agent._conf.environment || '' | ||
} | ||
} | ||
class MetricsRegistry extends SelfReportingMetricsRegistry { | ||
constructor (transport, { reporterOptions, registryOptions } = {}) { | ||
const options = Object.assign({}, defaultReporterOptions, reporterOptions) | ||
const reporter = new MetricsReporter(transport, options) | ||
const reporter = new MetricsReporter(agent._transport, options) | ||
super(reporter, registryOptions) | ||
if (options.enabled) createSystemMetrics(this, options.defaultReportingIntervalInSeconds) | ||
this._registry.collectors = [] | ||
createSystemMetrics(this) | ||
createRuntimeMetrics(this) | ||
} | ||
shutdown () { | ||
if (this.collector) { | ||
this.collector.stop() | ||
} | ||
return super.shutdown() | ||
registerCollector (collector) { | ||
this._registry.collectors.push(collector) | ||
} | ||
@@ -36,0 +37,0 @@ } |
'use strict' | ||
const { Reporter } = require('measured-reporting') | ||
const afterAll = require('after-all-results') | ||
@@ -23,11 +24,17 @@ class MetricsReporter extends Reporter { | ||
metrics.forEach(metric => { | ||
data.samples[metric.name] = { | ||
value: metric.metricImpl.toJSON() | ||
const next = afterAll(() => { | ||
metrics.forEach(metric => { | ||
data.samples[metric.name] = { | ||
value: metric.metricImpl.toJSON() | ||
} | ||
}) | ||
if (this.enabled) { | ||
this.transport.sendMetricSet(data) | ||
} | ||
}) | ||
if (this.enabled) { | ||
this.transport.sendMetricSet(data) | ||
} | ||
this._registry.collectors.forEach(function (collector) { | ||
collector.collect(next()) | ||
}) | ||
} | ||
@@ -34,0 +41,0 @@ } |
{ | ||
"name": "elastic-apm-node", | ||
"version": "2.11.6", | ||
"version": "2.12.0", | ||
"description": "The official Elastic APM agent for Node.js", | ||
@@ -18,3 +18,3 @@ "main": "index.js", | ||
"test:cli": "node test/script/cli.js", | ||
"test:deps": "dependency-check . -i async_hooks -i parseurl && dependency-check . --unused --no-dev --entry lib/instrumentation/modules/*", | ||
"test:deps": "dependency-check . -i async_hooks -i parseurl -i perf_hooks && dependency-check . --unused --no-dev --entry lib/instrumentation/modules/*", | ||
"test:tav": "tav --quiet", | ||
@@ -82,3 +82,3 @@ "test:docs": "./test/script/docker/run_docs.sh", | ||
"core-util-is": "^1.0.2", | ||
"elastic-apm-http-client": "^7.3.0", | ||
"elastic-apm-http-client": "^8.0.0", | ||
"end-of-stream": "^1.4.1", | ||
@@ -88,3 +88,4 @@ "fast-safe-stringify": "^2.0.6", | ||
"is-native": "^1.0.1", | ||
"measured-reporting": "^1.41.0", | ||
"measured-reporting": "^1.49.0", | ||
"monitor-event-loop-delay": "^1.0.0", | ||
"object-filter-sequence": "^1.0.0", | ||
@@ -98,3 +99,3 @@ "object.entries": "^1.1.0", | ||
"require-in-the-middle": "^4.0.0", | ||
"semver": "^6.0.0", | ||
"semver": "^6.1.1", | ||
"set-cookie-serde": "^1.0.0", | ||
@@ -108,26 +109,26 @@ "sql-summary": "^1.0.1", | ||
"@babel/cli": "^7.2.3", | ||
"@babel/core": "^7.4.0", | ||
"@babel/preset-env": "^7.4.2", | ||
"@babel/core": "^7.4.5", | ||
"@babel/preset-env": "^7.4.5", | ||
"@commitlint/cli": "^8.0.0", | ||
"@commitlint/config-conventional": "^8.0.0", | ||
"@commitlint/travis-cli": "^8.0.0", | ||
"@types/node": "^12.0.0", | ||
"apollo-server-express": "^2.1.0", | ||
"aws-sdk": "^2.463.0", | ||
"@types/node": "^12.0.8", | ||
"apollo-server-express": "^2.6.3", | ||
"aws-sdk": "^2.477.0", | ||
"bluebird": "^3.5.2", | ||
"cassandra-driver": "^4.0.0", | ||
"commitlint-config-squash-pr": "^1.0.0", | ||
"connect": "^3.6.6", | ||
"connect": "^3.7.0", | ||
"container-info": "^1.0.1", | ||
"dependency-check": "^3.2.1", | ||
"elasticsearch": "^16.0.0", | ||
"elasticsearch": "^16.1.1", | ||
"express": "^4.16.4", | ||
"express-graphql": "^0.8.0", | ||
"express-queue": "^0.0.12", | ||
"fastify": "^2.0.1", | ||
"finalhandler": "^1.1.1", | ||
"fastify": "^2.5.0", | ||
"finalhandler": "^1.1.2", | ||
"generic-pool": "^3.4.2", | ||
"get-port": "^4.0.0", | ||
"got": "^9.2.2", | ||
"graphql": "^14.1.1", | ||
"graphql": "^14.3.1", | ||
"handlebars": "^4.0.12", | ||
@@ -137,7 +138,7 @@ "hapi": "^18.1.0", | ||
"inquirer": "^0.12.0", | ||
"ioredis": "^4.3.0", | ||
"ioredis": "^4.10.0", | ||
"is-my-json-valid": "^2.19.0", | ||
"jade": "^1.11.0", | ||
"json-schema-ref-parser": "^6.0.1", | ||
"knex": "^0.17.3", | ||
"knex": "^0.17.6", | ||
"koa": "^2.5.3", | ||
@@ -148,15 +149,15 @@ "koa-router": "^7.4.0", | ||
"mkdirp": "^0.5.1", | ||
"mongodb-core": "^3.1.10", | ||
"mongodb-core": "^3.2.7", | ||
"mysql": "^2.16.0", | ||
"mysql2": "^1.6.3", | ||
"ndjson": "^1.5.0", | ||
"nyc": "^14.0.0", | ||
"nyc": "^14.1.1", | ||
"once": "^1.4.0", | ||
"p-finally": "^1.0.0", | ||
"pg": "^7.5.0", | ||
"pg": "^7.11.0", | ||
"pug": "^2.0.3", | ||
"redis": "^2.8.0", | ||
"request": "^2.88.0", | ||
"restify": "^8.3.1", | ||
"restify-clients": "^2.6.2", | ||
"restify": "^8.3.3", | ||
"restify-clients": "^2.6.6", | ||
"rimraf": "^2.6.2", | ||
@@ -166,10 +167,10 @@ "send": "^0.17.0", | ||
"tape": "^4.10.2", | ||
"tedious": "^6.1.1", | ||
"test-all-versions": "^4.0.0", | ||
"tedious": "^6.2.0", | ||
"test-all-versions": "^4.1.1", | ||
"thunky": "^1.0.3", | ||
"typescript": "^3.3.4000", | ||
"typescript": "^3.5.2", | ||
"untildify": "^4.0.0", | ||
"util.promisify": "^1.0.0", | ||
"wait-on": "^3.1.0", | ||
"ws": "^7.0.0" | ||
"ws": "^7.0.1" | ||
}, | ||
@@ -193,5 +194,5 @@ "greenkeeper": { | ||
"coordinates": [ | ||
55.77826, | ||
12.593255 | ||
55.778263, | ||
12.593183 | ||
] | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
236129
71
5460
27
17
+ Addedelastic-apm-http-client@8.2.1(transitive)
+ Addedmonitor-event-loop-delay@1.0.0(transitive)
- Removedelastic-apm-http-client@7.3.0(transitive)
Updatedmeasured-reporting@^1.49.0
Updatedsemver@^6.1.1