Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

elastic-apm-node

Package Overview
Dependencies
Maintainers
4
Versions
162
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

elastic-apm-node - npm Package Compare versions

Comparing version 3.27.0 to 3.28.0

1

index.d.ts

@@ -350,2 +350,3 @@ /// <reference types="node" />

childOf?: Transaction | Span | string;
exitSpan?: boolean;
}

@@ -352,0 +353,0 @@

2

lib/agent.js

@@ -174,3 +174,3 @@ 'use strict'

Agent.prototype.startSpan = function (name, type, subtype, action, { childOf } = {}) {
Agent.prototype.startSpan = function (name, type, subtype, action, { startTime, childOf, exitSpan } = {}) {
return this._instrumentation.startSpan.apply(this._instrumentation, arguments)

@@ -177,0 +177,0 @@ }

@@ -121,3 +121,3 @@ 'use strict'

const error = new CallbackCoordinationError(
'all callbacks failed',
'no response from any callback, no cloud metadata will be set (normal outside of cloud env.)',
this.errors

@@ -124,0 +124,0 @@ )

@@ -318,3 +318,4 @@ 'use strict'

} else {
// Zero-conf support: use package.json#name, else // "nodejs_service".
// Zero-conf support: use package.json#name, else
// `unknown-${service.agent.name}-service`.
try {

@@ -326,3 +327,3 @@ this.serviceName = serviceNameFromPackageJson()

if (!this.serviceName) {
this.serviceName = 'nodejs_service'
this.serviceName = 'unknown-nodejs-service'
}

@@ -530,3 +531,4 @@ }

// Disallow some weird sanitized values. For example, it is better to
// have the fallback "nodejs_service" than "_" or "____" or " ".
// have the fallback "unknown-{service.agent.name}-service" than "_" or
// "____" or " ".
const ALL_NON_ALPHANUMERIC = /^[ _-]*$/

@@ -578,3 +580,3 @@ if (ALL_NON_ALPHANUMERIC.test(serviceName)) {

//
// https://github.com/elastic/apm/blob/master/specs/agents/tracing-sampling.md
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-sampling.md
function normalizeTransactionSampleRate (opts, logger) {

@@ -848,3 +850,3 @@ if ('transactionSampleRate' in opts) {

//
// Per https://github.com/elastic/apm/blob/master/specs/agents/transport.md#user-agent
// Per https://github.com/elastic/apm/blob/main/specs/agents/transport.md#user-agent
// the pattern is roughly this:

@@ -931,5 +933,6 @@ // $repoName/$version ($serviceName $serviceVersion)

// Debugging
// Debugging/testing options
logger: clientLogger,
payloadLogFile: conf.payloadLogFile,
apmServerVersion: conf.apmServerVersion,

@@ -936,0 +939,0 @@ // Container conf

@@ -149,2 +149,3 @@ 'use strict'

error.transaction = {
name: args.trans.name,
type: args.trans.type,

@@ -151,0 +152,0 @@ sampled: args.trans.sampled

@@ -31,11 +31,4 @@ 'use strict'

// `path`, `query`, and `body` can all be null or undefined.
exports.setElasticsearchDbContext = function (span, path, query, body, isLegacy) {
exports.setElasticsearchDbContext = function (span, path, query, body) {
if (path && pathIsAQuery.test(path)) {
// From @elastic/elasticsearch: A read of Transport.js suggests query and
// body will always be serialized strings, however the documented
// `TransportRequestParams` (`ConnectionRequestParams` in version 8)
// allows for non-strings, so we will be defensive.
//
// From legacy elasticsearch: query will be an object and body will be an
// object, or an array of objects, e.g. for bulk endpoints.
const parts = []

@@ -45,3 +38,3 @@ if (query) {

parts.push(query)
} else if (isLegacy && typeof (query) === 'object') {
} else if (typeof (query) === 'object') {
const encodedQuery = querystring.encode(query)

@@ -56,8 +49,14 @@ if (encodedQuery) {

parts.push(body)
} else if (isLegacy) {
if (Array.isArray(body)) {
parts.push(body.map(JSON.stringify).join('\n')) // ndjson
} else if (typeof (body) === 'object') {
} else if (Buffer.isBuffer(body) || typeof body.pipe === 'function') {
// Never serialize a Buffer or a Readable. These guards mirror
// `shouldSerialize()` in the ES client, e.g.:
// https://github.com/elastic/elastic-transport-js/blob/069172506d1fcd544b23747d8c2d497bab053038/src/Transport.ts#L614-L618
} else if (Array.isArray(body)) {
try {
parts.push(body.map(JSON.stringify).join('\n') + '\n') // ndjson
} catch (_ignoredErr) {}
} else if (typeof (body) === 'object') {
try {
parts.push(JSON.stringify(body))
}
} catch (_ignoredErr) {}
}

@@ -64,0 +63,0 @@ }

@@ -149,8 +149,8 @@ 'use strict'

// Attempt to use the span context as a traceparent header.
// If the transaction is unsampled the span will not exist,
// however a traceparent header must still be propagated
// to indicate requested services should not be sampled.
// Use the transaction context as the parent, in this case.
var parent = span || ins.currTransaction()
// W3C trace-context propagation.
// There are a number of reasons why `span` might be null: child of an
// exit span, `transactionMaxSpans` was hit, unsampled transaction, etc.
// If so, then fallback to the current run context's span or transaction,
// if any.
var parent = span || parentRunContext.currSpan() || parentRunContext.currTransaction()
if (parent && parent._context) {

@@ -157,0 +157,0 @@ const headerValue = parent._context.toTraceParentString()

@@ -86,3 +86,3 @@ 'use strict'

}
return this._runCtxMgr.active().currTransaction() || null
return this._runCtxMgr.active().currTransaction()
}

@@ -285,2 +285,7 @@

// https://github.com/elastic/apm/blob/main/specs/agents/tracing-sampling.md#non-sampled-transactions
if (!transaction.sampled && !agent._transport.supportsKeepingUnsampledTransaction()) {
return
}
var payload = agent._transactionFilters.process(transaction._encode())

@@ -287,0 +292,0 @@ if (!payload) {

@@ -8,2 +8,23 @@ 'use strict'

// to hook into all ES server interactions.
//
// Limitations:
// - In @elastic/elasticsearch >=7.14 <8, the diagnostic events sent for ES
// spans started before the product-check is finished will have an incorrect
// `currentSpan`.
//
// An Elasticsearch (ES) request typically results in a single HTTP request to
// the server. For some of the later 7.x versions of @elastic/elasticsearch
// there is a product-check "GET /" that blocks the *first* request to the
// server. The handling of ES requests are effectively queued until that
// product-check is complete. When they *do* run, the async context is that
// of the initial ES span. This means that `apm.currentSpan` inside an ES
// client diagnostic event for these queued ES requests will be wrong.
// Currently the APM agent is not patching for this.
//
// - When using the non-default `asyncHooks=false` APM Agent option with
// @elastic/elasticsearch >=8 instrumentation, the diagnostic events do not
// have the async run context of the current span. There are two impacts:
// 1. Elasticsearch tracing spans will not have additional "http" context
// about the underlying HTTP request.
// 2. Users cannot access `apm.currentSpan` inside a diagnostic event handler.

@@ -14,3 +35,3 @@ const semver = require('semver')

const { setElasticsearchDbContext } = require('../../elasticsearch-shared')
const constants = require('../../../constants')
const shimmer = require('../../shimmer')

@@ -26,79 +47,151 @@ module.exports = function (elasticsearch, agent, { version, enabled }) {

// Before v7.7.0 the Transport#request() implementation's Promises support
// would re-call `this.request(...)` inside a Promise.
const doubleCallsRequestIfNoCb = semver.lt(version, '7.7.0')
const ins = agent._instrumentation
const isGteV8 = semver.satisfies(version, '>=8', { includePrerelease: true })
class ApmClient extends elasticsearch.Client {
constructor (...args) {
super(...args)
agent.logger.debug('shimming elasticsearch.Transport.prototype.{request,getConnection}')
shimmer.wrap(elasticsearch.Transport && elasticsearch.Transport.prototype, 'request', wrapRequest)
shimmer.wrap(elasticsearch.Transport && elasticsearch.Transport.prototype, 'getConnection', wrapGetConnection)
shimmer.wrap(elasticsearch, 'Client', wrapClient)
// The thing with the `.on()` method for getting observability events.
const diagnostic = isGteV8 ? this.diagnostic : this
// Tracking the ES client Connection object and DiagnosticResult for each
// active span. Use WeakMap to avoid a leak from possible spans that don't
// end.
const connFromSpan = new WeakMap()
const diagResultFromSpan = new WeakMap()
// Mapping an ES client event `result` to its active span.
// - Use WeakMap to avoid a leak from possible spans that don't end.
// - WeakMap allows us to key off the ES client `request` object itself,
// which means we don't need to rely on `request.id`, which might be
// unreliable because it is user-settable (see `generateRequestId` at
// https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/observability.html)
const spanFromEsResult = new WeakMap()
return elasticsearch
diagnostic.on('request', (err, result) => {
let request = null
let connection = null
if (result && result.meta) {
request = result.meta.request
connection = result.meta.connection
}
let paramMethod = null
let paramPath = null
let paramQueryString = null
let paramBody = null
if (request && request.params) {
// request.params can be null with ProductNotSupportedError and
// DeserializationError.
paramMethod = request.params.method
paramPath = request.params.path
paramQueryString = request.params.querystring
paramBody = request.params.body
}
agent.logger.debug('intercepted call to @elastic/elasticsearch "request" event %o',
{ id: request && request.id, method: paramMethod, path: paramPath })
function wrapClient (OrigClient) {
class ClientTraced extends OrigClient {
constructor (...args) {
super(...args)
const diagnostic = isGteV8 ? this.diagnostic : this
diagnostic.on('response', (_err, result) => {
if (result) {
const currSpan = ins.currSpan()
if (currSpan) {
diagResultFromSpan[currSpan] = result
}
}
})
}
}
return ClientTraced
}
let span = spanFromEsResult.get(result)
// Transport#request() calls Transport#getConnection() when it is ready to
// make the HTTP request. This returns the actual connection to be used for
// the request. This is limited, however:
// - `getConnection()` is not called if the request was aborted early.
// - If all connections are marked dead, then this returns null.
// - We are assuming this is called with the correct async context. See
// "Limitations" above.
function wrapGetConnection (origGetConnection) {
return function wrappedGetConnection (opts) {
const conn = origGetConnection.apply(this, arguments)
const currSpan = ins.currSpan()
if (conn && currSpan) {
connFromSpan[currSpan] = conn
}
return conn
}
}
if (err) {
agent.captureError(err)
if (span !== undefined) {
span.end()
spanFromEsResult.delete(result)
}
return
function wrapRequest (origRequest) {
return function wrappedRequest (params, options, cb) {
options = options || {}
if (typeof options === 'function') {
cb = options
options = {}
}
if (typeof cb !== 'function' && doubleCallsRequestIfNoCb) {
return origRequest.apply(this, arguments)
}
const method = (params && params.method) || '<UnknownMethod>'
const path = (params && params.path) || '<UnknownPath>'
agent.logger.debug({ method, path }, 'intercepted call to @elastic/elasticsearch.Transport.prototype.request')
const span = ins.createSpan(`Elasticsearch: ${method} ${path}`, 'db', 'elasticsearch', 'request', { exitSpan: true })
if (!span) {
return origRequest.apply(this, arguments)
}
const parentRunContext = ins.currRunContext()
const spanRunContext = parentRunContext.enterSpan(span)
const finish = ins.bindFunctionToRunContext(spanRunContext, (err, result) => {
// Set DB context.
// In @elastic/elasticsearch@7, `Transport#request` encodes
// `params.{querystring,body}` in-place; use it. In >=8 this encoding is
// no longer in-place. A better eventual solution would be to wrap
// `Connection.request` to capture the serialized params.
setElasticsearchDbContext(
span,
params && params.path,
params && params.querystring,
params && (params.body || params.bulkBody))
// Set destination context.
// Use the connection from wrappedGetConnection() above, if that worked.
// Otherwise, fallback to using the first connection on
// `Transport#connectionPool`, if any. (This is the best parsed
// representation of connection options passed to the Client ctor.)
let conn = connFromSpan[span]
if (conn) {
connFromSpan.delete(span)
} else if (this.connectionPool && this.connectionPool.connections) {
conn = this.connectionPool.connections[0]
}
const connUrl = conn && conn.url
span.setDestinationContext(getDBDestination(span,
connUrl && connUrl.hostname, connUrl && connUrl.port))
// With retries (see `makeRequest` in Transport.js) each attempt will
// emit this "request" event using the same `result` object. The
// intent is to have one Elasticsearch span plus an HTTP span for each
// attempt.
if (!span) {
const spanName = `Elasticsearch: ${paramMethod || '<UnknownMethod>'} ${paramPath || '<UnknownPath>'}`
span = agent.startSpan(spanName, 'db', 'elasticsearch', 'request')
if (span) {
spanFromEsResult.set(result, span)
// Gather some HTTP context from the "DiagnosticResult" object.
// We are *not* including the response headers b/c they are boring:
//
// X-elastic-product: Elasticsearch
// content-type: application/json
// content-length: ...
//
// Getting the ES client request "DiagnosticResult" object has some edge cases:
// - In v7 using a callback, we always get `result`.
// - In v7 using a Promise, if the promise is rejected, then `result` is
// not passed.
// - In v8, `result` only includes HTTP response info if `options.meta`
// is true. We use the diagnostic 'response' event instead.
// - In v7, see the limitation note above for the rare start case where
// the diagnostic 'response' event may have the wrong currentSpan.
// The result is that with Promise usage of v7, ES client requests that
// are queued behind the "product-check" and that reject, won't have a
// `diagResult`.
let diagResult = isGteV8 ? null : result
if (!diagResult) {
diagResult = diagResultFromSpan[span]
if (diagResult) {
diagResultFromSpan.delete(span)
}
}
if (!span) {
return
if (diagResult) {
const httpContext = {}
let haveHttpContext = false
if (diagResult.statusCode) {
haveHttpContext = true
httpContext.status_code = diagResult.statusCode
}
// *Not* currently adding headers because
if (diagResult.headers && 'content-length' in diagResult.headers) {
const contentLength = Number(diagResult.headers['content-length'])
if (!isNaN(contentLength)) {
haveHttpContext = true
httpContext.response = { encoded_body_size: contentLength }
}
}
if (haveHttpContext) {
span.setHttpContext(httpContext)
}
}
setElasticsearchDbContext(span, paramPath, paramQueryString, paramBody, false)
if (connection && connection.url) {
const { hostname, port } = connection.url
span.setDestinationContext(
getDBDestination(span, hostname, port))
}
})
diagnostic.on('response', (err, result) => {
const span = spanFromEsResult.get(result)
if (err) {

@@ -114,4 +207,3 @@ // Error properties are specified here:

const errOpts = {
captureAttributes: false,
skipOutcome: true
captureAttributes: false
}

@@ -130,25 +222,29 @@ if (err.name === 'ResponseError' && err.body && err.body.error) {

}
// The capture error method normally sets an outcome on the
// active span. However, the Elasticsearch client span (the span
// we're concerned with here) is no longer the active span.
// Therefore, we manully set an outcome here, and also set
// errOpts.skipOutcome above. The errOpts.skipOutcome options
// instructs captureError to _not_ set the outcome on the active span
if (span !== undefined) {
span._setOutcomeFromErrorCapture(constants.OUTCOME_FAILURE)
}
agent.captureError(err, errOpts)
}
if (span !== undefined) {
span.end()
spanFromEsResult.delete(result)
span.end()
})
if (typeof cb === 'function') {
const wrappedCb = (err, result) => {
finish(err, result)
ins.withRunContext(parentRunContext, cb, this, err, result)
}
})
return ins.withRunContext(spanRunContext, origRequest, this, params, options, wrappedCb)
} else {
const origPromise = ins.withRunContext(spanRunContext, origRequest, this, ...arguments)
origPromise.then(
function onResolve (result) {
finish(null, result)
},
function onReject (err) {
finish(err, null)
}
)
return origPromise
}
}
}
agent.logger.debug('subclassing @elastic/elasticsearch.Client')
return Object.assign(elasticsearch, { Client: ApmClient })
}

@@ -57,3 +57,3 @@ 'use strict'

const span = ins.createSpan(name, TYPE, SUBTYPE, opName)
const span = ins.createSpan(name, TYPE, SUBTYPE, opName, { exitSpan: true })
if (!span) {

@@ -73,3 +73,4 @@ return orig.apply(request, origArguments)

// 'complete'.
const region = request.httpRequest && request.httpRequest.region
const httpRequest = request.httpRequest
const region = httpRequest && httpRequest.region

@@ -79,3 +80,3 @@ // Destination context.

// the bucket is in a different region.
const endpoint = request.httpRequest && request.httpRequest.endpoint
const endpoint = httpRequest && httpRequest.endpoint
const destContext = {

@@ -100,4 +101,26 @@ service: {

if (response) {
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/HttpResponse.html
const httpResponse = response.httpResponse
let statusCode
if (httpResponse) {
statusCode = httpResponse.statusCode
// Set HTTP context. Some context not being set, though it is available:
// - method: Not that helpful.
// - url: Mostly redundant with context.destination.address.
// - response.headers: A lot of added size for uncertain utility. The
// inclusion of Amazon's request ID headers might be worth it.
const httpContext = {
status_code: statusCode
}
const encodedBodySize = Buffer.isBuffer(httpResponse.body) && httpResponse.body.byteLength
if (encodedBodySize) {
// I'm not actually sure if this might be decoded_body_size.
httpContext.response = { encoded_body_size: encodedBodySize }
}
span.setHttpContext(httpContext)
}
// Follow the spec for HTTP client span outcome.
// https://github.com/elastic/apm/blob/master/specs/agents/tracing-instrumentation-http.md#outcome
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-instrumentation-http.md#outcome
//

@@ -107,3 +130,2 @@ // For example, a S3 GetObject conditional request (e.g. using the

// statusCode=304. This is a *successful* outcome.
const statusCode = response.httpResponse && response.httpResponse.statusCode
if (statusCode) {

@@ -110,0 +132,0 @@ span._setOutcomeFromHttpStatusCode(statusCode)

@@ -15,2 +15,4 @@ 'use strict'

const ins = agent._instrumentation
if (cassandra.Client) {

@@ -35,3 +37,3 @@ if (semver.gte(version, '4.4.0')) {

return async function wrappedAsyncConnect () {
const span = agent.startSpan('Cassandra: Connect', 'db', 'cassandra', 'connect')
const span = ins.createSpan('Cassandra: Connect', 'db', 'cassandra', 'connect')
try {

@@ -47,3 +49,3 @@ return await original.apply(this, arguments)

return function wrappedConnect (callback) {
const span = agent.startSpan('Cassandra: Connect', 'db', 'cassandra', 'connect')
const span = ins.createSpan('Cassandra: Connect', 'db', 'cassandra', 'connect')
if (!span) {

@@ -86,3 +88,3 @@ return original.apply(this, arguments)

return function wrappedBatch (queries, options, callback) {
const span = agent.startSpan('Cassandra: Batch query', 'db', 'cassandra', 'query')
const span = ins.createSpan('Cassandra: Batch query', 'db', 'cassandra', 'query')
if (!span) {

@@ -131,3 +133,3 @@ return original.apply(this, arguments)

return function wrappedExecute (query, params, options, callback) {
const span = agent.startSpan(null, 'db', 'cassandra', 'query')
const span = ins.createSpan(null, 'db', 'cassandra', 'query')
if (!span) {

@@ -171,3 +173,3 @@ return original.apply(this, arguments)

return function wrappedEachRow (query, params, options, rowCallback, callback) {
const span = agent.startSpan(null, 'db', 'cassandra', 'query')
const span = ins.createSpan(null, 'db', 'cassandra', 'query')
if (!span) {

@@ -174,0 +176,0 @@ return original.apply(this, arguments)

@@ -59,2 +59,4 @@ 'use strict'

const ins = agent._instrumentation
agent.logger.debug('shimming elasticsearch.Transport.prototype.request')

@@ -67,3 +69,3 @@ shimmer.wrap(elasticsearch.Transport && elasticsearch.Transport.prototype, 'request', wrapRequest)

return function wrappedRequest (params, cb) {
var span = agent.startSpan(null, 'db', 'elasticsearch', 'request')
var span = ins.createSpan(null, 'db', 'elasticsearch', 'request', { exitSpan: true })
var id = span && span.transaction.id

@@ -79,3 +81,3 @@ var method = params && params.method

setElasticsearchDbContext(span, path, params && params.query,
params && params.body, true)
params && params.body)

@@ -91,2 +93,4 @@ // Get the remote host information from elasticsearch Transport options.

const parentRunContext = ins.currRunContext()
const spanRunContext = parentRunContext.enterSpan(span)
if (typeof cb === 'function') {

@@ -96,7 +100,7 @@ var args = Array.prototype.slice.call(arguments)

span.end()
return cb.apply(this, arguments)
ins.withRunContext(parentRunContext, cb, this, ...arguments)
}
return original.apply(this, args)
return ins.withRunContext(spanRunContext, original, this, ...args)
} else {
const originalPromise = original.apply(this, arguments)
const originalPromise = ins.withRunContext(spanRunContext, original, this, ...arguments)

@@ -103,0 +107,0 @@ const descriptors = Object.getOwnPropertyDescriptors(originalPromise)

@@ -19,2 +19,4 @@ 'use strict'

const ins = agent._instrumentation
if (mongodb.Server) {

@@ -53,5 +55,5 @@ agent.logger.debug('shimming mongodb-core.Server.prototype.command')

span = agent.startSpan(ns + '.' + type, 'db', 'mongodb', 'query')
span = ins.createSpan(ns + '.' + type, 'db', 'mongodb', 'query')
if (span) {
arguments[index] = wrappedCallback
arguments[index] = ins.bindFunctionToRunContext(ins.currRunContext(), wrappedCallback)
}

@@ -83,5 +85,5 @@ }

if (typeof cb === 'function') {
span = agent.startSpan(ns + '.' + name, 'db', 'mongodb', 'query')
span = ins.createSpan(ns + '.' + name, 'db', 'mongodb', 'query')
if (span) {
arguments[index] = wrappedCallback
arguments[index] = ins.bindFunctionToRunContext(ins.currRunContext(), wrappedCallback)
}

@@ -113,6 +115,6 @@ }

var spanName = `${this.ns}.${this.cmd.find ? 'find' : name}`
span = agent.startSpan(spanName, 'db', 'mongodb', 'query')
span = ins.createSpan(spanName, 'db', 'mongodb', 'query')
}
if (span) {
arguments[0] = wrappedCallback
arguments[0] = ins.bindFunctionToRunContext(ins.currRunContext(), wrappedCallback)
if (name === 'next') {

@@ -119,0 +121,0 @@ this[firstSpan] = true

@@ -13,2 +13,5 @@ 'use strict'

module.exports = function (mysql, agent, { version, enabled }) {
if (!enabled) {
return mysql
}
if (!semver.satisfies(version, '^2.0.0')) {

@@ -25,4 +28,2 @@ agent.logger.debug('mysql version %s not supported - aborting...', version)

if (!enabled) return mysql
agent.logger.debug('shimming mysql.createConnection')

@@ -80,3 +81,3 @@ shimmer.wrap(mysql, 'createConnection', wrapCreateConnection)

arguments[0] = agent._instrumentation.bindFunction(function wrapedCallback (err, connection) { // eslint-disable-line handle-callback-err
if (connection && enabled) wrapQueryable(connection, 'getConnection() > connection', agent)
if (connection) wrapQueryable(connection, 'getConnection() > connection', agent)
return cb.apply(this, arguments)

@@ -83,0 +84,0 @@ })

@@ -15,2 +15,5 @@ 'use strict'

module.exports = function (redis, agent, { version, enabled }) {
if (!enabled) {
return redis
}
if (!semver.satisfies(version, '>=2.0.0 <4.0.0')) {

@@ -74,3 +77,3 @@ agent.logger.debug('redis version %s not supported - aborting...', version)

agent.logger.debug({ command: command }, 'intercepted call to RedisClient.prototype.internal_send_command')
const span = enabled && ins.createSpan(command.toUpperCase(), TYPE, SUBTYPE)
const span = ins.createSpan(command.toUpperCase(), TYPE, SUBTYPE)
if (!span) {

@@ -107,3 +110,3 @@ return original.apply(this, arguments)

agent.logger.debug({ command: command }, 'intercepted call to RedisClient.prototype.send_command')
var span = enabled && ins.createSpan(command.toUpperCase(), TYPE, SUBTYPE)
var span = ins.createSpan(command.toUpperCase(), TYPE, SUBTYPE)
if (!span) {

@@ -110,0 +113,0 @@ return original.apply(this, arguments)

@@ -19,9 +19,15 @@ 'use strict'

function Span (transaction, name, ...args) {
const defaultChildOf = transaction._agent._instrumentation.currSpan() || transaction
// new Span(transaction)
// new Span(transaction, name?, opts?)
// new Span(transaction, name?, type?, opts?)
// new Span(transaction, name?, type?, subtype?, opts?)
// new Span(transaction, name?, type?, subtype?, action?, opts?)
function Span (transaction, ...args) {
const opts = typeof args[args.length - 1] === 'object'
? (args.pop() || {})
: {}
const [name, ...tsaArgs] = args // "tsa" === Type, Subtype, Action
if (!opts.childOf) {
const defaultChildOf = transaction._agent._instrumentation.currSpan() || transaction
opts.childOf = defaultChildOf

@@ -33,4 +39,7 @@ opts.timer = defaultChildOf._timer

GenericSpan.call(this, transaction._agent, ...args, opts)
this._exitSpan = !!opts.exitSpan
delete opts.exitSpan
GenericSpan.call(this, transaction._agent, ...tsaArgs, opts)
this._db = null

@@ -37,0 +46,0 @@ this._http = null

@@ -119,4 +119,4 @@ 'use strict'

// Create a span on this transaction and make it the current span.
Transaction.prototype.startSpan = function (...spanArgs) {
const span = this.createSpan(...spanArgs)
Transaction.prototype.startSpan = function (...args) {
const span = this.createSpan(...args)
if (span) {

@@ -133,3 +133,3 @@ this._agent._instrumentation.supersedeWithSpanRunContext(span)

// context of the calling code. Compare to `startSpan`.
Transaction.prototype.createSpan = function (...spanArgs) {
Transaction.prototype.createSpan = function (...args) {
if (!this.sampled) {

@@ -147,4 +147,19 @@ return null

// Exit spans must not have child spans (unless of the same type and subtype).
// https://github.com/elastic/apm/blob/master/specs/agents/tracing-spans.md#child-spans-of-exit-spans
const opts = typeof args[args.length - 1] === 'object'
? (args.pop() || {})
: {}
const [_name, type, subtype] = args // eslint-disable-line no-unused-vars
opts.childOf = opts.childOf || this._agent._instrumentation.currSpan() || this
const childOf = opts.childOf
if (childOf instanceof Span && childOf._exitSpan &&
!(childOf.type === type && childOf.subtype === subtype)) {
this._agent.logger.trace({ exitSpanId: childOf.id, newSpanArgs: args },
'createSpan: drop child span of exit span')
return null
}
this._builtSpans++
return new Span(this, ...spanArgs)
return new Span(this, ...args, opts)
}

@@ -202,3 +217,3 @@

// add sample_rate to transaction
// https://github.com/elastic/apm/blob/master/specs/agents/tracing-sampling.md
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-sampling.md
// Only set sample_rate on transaction payload if a valid trace state

@@ -205,0 +220,0 @@ // variable is set.

@@ -6,6 +6,6 @@ 'use strict'

// https://github.com/elastic/apm/blob/master/specs/agents/tracing-instrumentation-aws-lambda.md#deriving-cold-starts
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-instrumentation-aws-lambda.md#deriving-cold-starts
let isFirstRun = true
// https://github.com/elastic/apm/blob/master/specs/agents/tracing-instrumentation-aws-lambda.md#overwriting-metadata
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-instrumentation-aws-lambda.md#overwriting-metadata
function getLambdaMetadata (context) {

@@ -12,0 +12,0 @@ // E.g. 'arn:aws:lambda:us-west-2:123456789012:function:my-function:someAlias'

@@ -13,3 +13,3 @@ 'use strict'

//
// Per https://github.com/elastic/apm/blob/master/specs/agents/logging.md
// Per https://github.com/elastic/apm/blob/main/specs/agents/logging.md
// the valid log levels are:

@@ -16,0 +16,0 @@ // - trace

@@ -46,2 +46,6 @@ 'use strict'

supportsKeepingUnsampledTransaction () {
return true
}
// Inherited from Writable, called in agent.js.

@@ -48,0 +52,0 @@ destroy () {}

@@ -27,3 +27,3 @@ 'use strict'

//
// https://github.com/elastic/apm/blob/master/specs/agents/tracing-sampling.md
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-sampling.md
tracestate.setValue('s', 0)

@@ -30,0 +30,0 @@ }

{
"name": "elastic-apm-node",
"version": "3.27.0",
"version": "3.28.0",
"description": "The official Elastic APM agent for Node.js",

@@ -89,3 +89,3 @@ "main": "index.js",

"core-util-is": "^1.0.2",
"elastic-apm-http-client": "^10.3.0",
"elastic-apm-http-client": "^10.4.0",
"end-of-stream": "^1.4.4",

@@ -122,3 +122,3 @@ "error-callsites": "^2.0.4",

"@elastic/elasticsearch": "^7.15.0",
"@elastic/elasticsearch-canary": "^8.0.0-canary.37",
"@elastic/elasticsearch-canary": "^8.1.0-canary.2",
"@hapi/hapi": "^20.1.2",

@@ -125,0 +125,0 @@ "@koa/router": "^9.0.1",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc