代理 API
编辑Agent
API编辑
Elastic APM Node.js 代理是一个单例。您可以通过引入 elastic-apm-node
或 elastic-apm-node/start
来获取代理实例。代理也会由 .start()
方法返回,该方法允许您在同一行中引入和启动代理。
const apm = require('elastic-apm-node').start(...)
如果您需要在代码库的任何部分访问 Agent
,您只需引入 elastic-apm-node
即可访问已启动的单例。因此,您无需自己管理或传递已启动的 Agent
。
apm.start([options])
编辑
启动 Elastic APM Node.js 代理并返回自身。
为了让 APM 代理自动检测 Node.js 模块,必须在加载这些模块之前启动它。有关详细信息以及编译器/转译器/打包器的可能意外情况,请参阅 启动代理。
有关可用选项,请参阅 配置文档。
apm.getServiceName()
编辑
添加于:v3.11.0
获取已配置的 serviceName
。如果未明确配置服务名称,则此值可能是自动确定的。服务名称在 agent.start()
之前无法确定,因此在此之前将为 undefined
。配置错误的代理可能具有 null
服务名称。
apm.getServiceVersion()
编辑
添加于:v4.2.0
获取已配置的 serviceVersion
。如果未明确配置服务版本,则此值可能是自动确定的。服务版本在 agent.start()
之前无法确定,因此在此之前将为 undefined
。
apm.setFramework(options)
编辑
添加于:v2.8.0
-
options
<Object>
支持以下选项-
name
<string>
框架名称。 -
version
<string>
框架版本。 -
overwrite
<boolean>
如果设置为false
,则不会覆盖作为 配置选项 提供的frameworkName
和frameworkVersion
。 默认值:true
。
-
在代理启动后设置或更改 frameworkName
或 frameworkVersion
。这些配置选项也可以作为 常规代理配置 的一部分提供。
apm.addFilter(fn)
编辑
添加于:v0.1.0
使用 addFilter()
提供过滤器函数。
在将数据发送到 APM 服务器之前,将调用每个过滤器函数。这将允许您操作正在发送的数据,例如删除敏感信息(如密码等)。(注意:通过 addFilter
添加的过滤器**不**应用于发送到 APM 服务器的“元数据”对象,请改用 addMetadataFilter
。)
将按添加顺序调用每个过滤器函数,并将接收一个 payload
对象作为唯一参数,其中包含即将发送到 APM 服务器的数据。
负载的格式取决于正在发送的事件类型。有关不同格式的详细信息,请参阅 事件接收 API 文档。
过滤器函数是同步的,应该返回已操作的负载对象。如果过滤器函数不返回任何值或返回假值,则不会调用剩余的过滤器函数,并且**不会**将负载发送到 APM 服务器。
用法示例
apm.addFilter(function redactSecretHeader(payload) { if (payload.context && payload.context.request && payload.context.request.headers && payload.context.request.headers['x-secret']) { // redact sensitive data payload.context.request.headers['x-secret'] = '[REDACTED]' } // remember to return the modified payload return payload })
尽管您也可以使用过滤器函数向 user
和 custom
属性添加新的上下文信息,但建议您使用 apm.setUserContext()
和 apm.setCustomContext()
来实现此目的。
apm.addMetadataFilter(fn)
编辑
添加于:v3.14.0
使用 addMetadataFilter(fn)
为发送到 APM 服务器的 元数据对象 提供过滤器函数。这将允许您操作正在发送的数据,例如删除可能包含敏感信息的数据。
将按添加顺序调用每个过滤器函数,并将接收一个 metadata
对象作为唯一参数。过滤器函数是同步的,必须返回已操作的对象。用法示例
apm.addMetadataFilter(function dropArgv(metadata) { if (metadata.process && metadata.process.argv) { delete metadata.process.argv } return metadata })
警告:作者有责任确保返回的对象符合 元数据架构,否则所有 APM 数据接收都将失败。破坏元数据的元数据过滤器将导致代理记录错误,类似于
ERROR (elastic-apm-node): APM Server transport error (400): Unexpected APM Server response APM Server accepted 0 events in the last request Error: validation error: 'metadata' required Document: {"metadata":null}
apm.setUserContext(context)
编辑
添加于:v0.1.0
-
context
<Object>
接受以下可选属性
调用此方法可以使用有关用户/客户端的信息来丰富收集的性能数据和错误。可以在请求/响应生命周期的任何时候(即事务处于活动状态时)调用此函数。
给定的 context
将添加到活动事务中。如果找不到活动事务,则返回 false
。否则返回 true
。
可以在同一个活动事务的范围内多次调用此函数。对于每次调用,context
参数的属性将与之前给定的上下文浅层合并。
如果捕获到错误,则活动事务中的上下文将用作捕获错误的上下文,并且作为第二个参数传递给 apm.captureError
的任何自定义上下文都将优先,并进行浅层合并。
提供的用户上下文存储在 Elasticsearch 中错误和事务的 context.user
下。
apm.setCustomContext(context)
编辑
添加于:v0.1.0
-
context
<Object>
可以包含任何可以进行 JSON 编码的属性。
调用此函数可以使用您认为有助于调试性能问题或错误的任何信息来丰富收集的错误和事务。可以在事务处于活动状态的任何时候调用此函数(例如,在传入 HTTP 请求的请求/响应生命周期期间)。
提供的自定义上下文存储在 APM Server 7.0 之前的 context.custom
下,或 APM Server 7.0+ 的 transaction.custom
和 error.custom
下。
给定的 context
将添加到活动事务中。如果找不到活动事务,则返回 false
。否则返回 true
。
可以在同一个活动事务的范围内多次调用此函数。对于每次调用,context
参数的属性将与之前给定的上下文浅层合并。
如果捕获到错误,则活动事务中的上下文将用作捕获错误的上下文,并且作为第二个参数传递给 apm.captureError
的任何自定义上下文都将优先,并进行浅层合并。
在使用自定义上下文之前,请确保您了解可用的不同类型的 元数据。
apm.setLabel(name, value[, stringify = true])
编辑
添加于:v0.1.0
从 apm.setTag()
重命名为 apm.setLabel()
:v2.10.0
添加 stringify
参数:v3.11.0
apm.setLabel('productId', 42, false);
在当前事务上设置标签。您可以在同一个事务上设置多个标签。如果在当前事务期间发生错误,则该错误也会被标记为相同的标签。
标签是由 Elasticsearch 索引的键/值对,因此是可搜索的(与通过 apm.setCustomContext()
设置的数据相反)。在使用自定义标签之前,请确保您了解可用的不同类型的 元数据。
避免定义过多的用户指定标签。在索引中定义过多的唯一字段是一种可能导致 映射爆炸 的情况。
apm.addLabels({ [name]: value }[, stringify = true])
编辑
添加于:v1.5.0
从 apm.addTags()
重命名为 apm.addLabels()
:v2.10.0
添加 stringify
参数:v3.11.0
apm.addLabels({productId: 42, productName: 'butter'}, false);
在当前事务上添加多个标签。您可以多次添加标签。如果在当前事务期间发生错误,则该错误也会被标记为相同的标签。
标签是由 Elasticsearch 索引的键/值对,因此是可搜索的(与通过 apm.setCustomContext()
设置的数据相反)。在使用自定义标签之前,请确保您了解可用的不同类型的 元数据。
避免定义过多的用户指定标签。在索引中定义过多的唯一字段是一种可能导致 映射爆炸 的情况。
apm.setGlobalLabel(name, value)
编辑
添加于:v3.47.0
扩展 globalLabels
配置。它允许设置应用于所有事务的标签。一个潜在的用例是使用应用程序的状态指定标签:'initializing' | 'available' | 'unhealthy'
。
标签是由 Elasticsearch 索引的键/值对,因此是可搜索的(与通过 apm.setCustomContext()
设置的数据相反)。在使用自定义标签之前,请确保您了解可用的不同类型的 元数据。
避免定义过多的用户指定标签。在索引中定义过多的唯一字段是一种可能导致 映射爆炸 的情况。
apm.captureError(error[, options][, callback])
编辑
添加于:v0.1.0
-
error
- 可以是<Error>
对象、消息字符串 或 特殊的参数化消息对象 -
options
<Object>
支持以下选项-
timestamp
<number>
错误发生的时间。必须是 Unix 时间戳,表示自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。可以使用小数实现亚毫秒精度。如果未提供,则将使用当前时间 -
message
- 如果error
参数是<Error>
对象,则可以使用此选项提供一个附加消息字符串,该字符串将与log.message
下的错误消息一起存储 -
user
- 有关此选项的详细信息,请参阅 元数据部分 -
custom
- 有关此选项的详细信息,请参阅 元数据部分 -
request
<http.IncomingMessage>
您可以将错误与有关传入请求的信息相关联,以获取其他上下文,例如请求 URL、标头和 Cookie。但是,在大多数情况下,代理会检测错误是否是针对 http 请求的响应,并自动为您添加请求详细信息。有关更多详细信息,请参阅 http 请求部分。 -
response
<http.ServerResponse>
您可以将错误与有关 http 响应的信息相关联,以获取其他详细信息,例如状态代码和标头。但是,在大多数情况下,代理会检测在 http 请求期间是否发生错误,并自动为您添加响应详细信息。有关更多详细信息,请参阅 http 响应部分。 -
handled
<boolean>
向异常添加其他上下文,以显示错误是已处理还是未捕获。未处理的错误会立即刷新到 APM 服务器,以防应用程序即将崩溃。 默认值:true
。 -
labels
<Object>
使用标签添加其他上下文,这些标签将与当前事务中的标签一起添加到错误中。有关格式的详细信息,请参阅apm.addLabels()
方法。 -
captureAttributes
<boolean>
是否在发送到 APM 服务器的数据中包含给定<Error>
对象的属性(作为error.exception.attributes
)。 默认值:true
。 -
skipOutcome
<boolean>
是否跳过将当前跨度的结果值设置为failure
。有关更多信息,请参阅 跨度结果。 默认值:false
。 -
parent
事务 | 跨度 |null
- 要使此错误的父级成为事务或跨度实例。如果未给出(或undefined
),则将使用当前跨度或事务。如果给出null
,则不会使用任何跨度或事务。 (添加于 v3.33.0。)
-
-
callback
- 在错误发送到 APM 服务器后将调用此函数。如果代理无法发送错误,它将接收一个Error
实例以及捕获错误的 ID。
向 APM 服务器发送错误
apm.captureError(new Error('boom!'))
消息字符串编辑
您可以记录纯文本消息,而不是 Error
对象
apm.captureError('Something happened!')
这也会作为错误发送到 APM 服务器,但不会与异常相关联。
参数化消息对象编辑
您可以提供特殊的参数化消息对象,而不是 Error
对象或字符串
apm.captureError({ message: 'Could not find user %s with id %d in the database', params: ['Peter', 42] })
这使得更好地对包含变量数据(如 ID 或名称)的错误消息进行分组成为可能。
元数据编辑
为了便于调试,您可以在发送到 APM 服务器的每个错误中添加一些额外的数据。APM 服务器接收 API 支持许多不同的元数据字段,其中大部分由 Elastic APM Node.js 代理自动管理。但如果您愿意,可以使用 user
或 custom
提供一些额外的详细信息。有关事件接收 API 接受的属性的更多详细信息,请参阅事件接收 API 文档。
要提供任何这些额外的字段,请在调用 apm.captureError()
时使用可选的 options 参数。
以下是一些示例
// Sending some extra details about the user apm.captureError(error, { user: { id: 'unique_id', username: 'foo', email: '[email protected]' } }) // Sending some arbitrary details using the `custom` field apm.captureError(error, { custom: { some_important_metric: 'foobar' } })
要将每个请求的元数据提供给在一个中心位置捕获的所有错误,请使用 apm.setUserContext()
和 apm.setCustomContext()
。
apm.middleware.connect()
编辑
添加于:v0.1.0
返回一个中间件函数,用于收集错误并将错误发送到 APM 服务器。
const apm = require('elastic-apm-node').start() const connect = require('connect') const app = connect() // your regular middleware: app.use(...) app.use(...) // your main HTTP router app.use(function (req, res, next) { throw new Error('Broke!') }) // add Elastic APM in the bottom of the middleware stack app.use(apm.middleware.connect()) app.listen(3000)
apm.middleware.connect
必须 在任何其他错误处理中间件函数之前添加到中间件堆栈中,否则错误可能永远不会到达代理。
apm.startTransaction([name][, type][, options])
编辑
添加于:v0.1.0
事务 subtype
和 action
已弃用:v3.25.0
事务 subtype
和 action
已移除:v4.0.0
-
name
<string>
事务的名称。您可以稍后通过transaction.name
或apm.setTransactionName()
设置它。 默认值:unnamed
-
type
<string>
事务的类型。您可以稍后通过transaction.type
设置它。 -
options
<Object>
支持以下选项-
startTime
<number>
事务开始的时间。必须是 Unix 时间戳,表示自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。可以使用小数实现亚毫秒精度。如果未提供,则将使用当前时间 -
childOf
<string>
W3C trace-context "traceparent" 字符串,通常从远程服务调用接收。 -
tracestate
<string>
W3C trace-context "tracestate" 字符串。 -
links
<Array>
Span 链接。一个事务可以引用零个或多个其他事务或 span(与其父级分开)。Span 链接将显示在 Kibana APM 应用程序跟踪视图中。links
参数是一个对象数组,其中包含一个 "context" 字段,该字段是Transaction
、Span
或 W3C trace-context traceparent 字符串。例如:apm.startTransaction('aName', { links: [{ context: anotherSpan }] })
。
-
启动新的自定义/手动事务。有关如何使用自定义事务的详细信息,请参阅事务 API文档。
请注意,APM 代理将自动为传入的 HTTP 请求启动一个事务。您只需要使用此函数来创建自定义事务,例如用于定期后台例程。有一个特殊的 type
称为 request
,代理在检测到传入 HTTP 请求时自动创建的事务使用该类型。
如果尚未启动 APM 代理,则将返回一个不执行任何操作的“无操作”事务对象。
apm.endTransaction([result][, endTime])
编辑
添加于:v0.1.0
结束活动事务。如果当前没有活动事务,则不会发生任何事情。
请注意,代理将自动为您完成所有常规 HTTP 事务。您只需要使用此函数来结束由 apm.startTransaction()
创建的自定义事务,或者如果您希望提前结束常规事务。
或者,您可以直接在活动事务对象上调用 end()
。
apm.setTransactionName(name)
编辑
添加于:v0.1.0
-
name
<string>
设置或覆盖当前事务的名称。
如果您使用受支持的路由器/框架,代理将自动为您设置事务名称。
如果您不使用 Express、hapi、koa-router、Restify 或 Fastify,或者代理由于某种原因无法检测到 HTTP 路由的名称,则事务名称将默认为 METHOD unknown route
(例如 POST unknown route
)。
在使用自定义 Node.js 堆栈入门文章中阅读有关手动命名路由的更多信息。
apm.startSpan([name][, type][, subtype][, action][, options])
编辑
添加于:v1.1.0
-
name
<string>
span 的名称。您也可以通过span.name
设置它。 默认值:unnamed
-
type
<string>
span 的类型。您也可以通过span.type
设置它。 -
subtype
<string>
span 的子类型。您也可以通过span.subtype
设置它。 -
action
<string>
span 的操作。您也可以通过span.action
设置它。 -
options
<Object>
支持以下选项-
startTime
<number>
span 开始的时间。必须是 Unix 时间戳,表示自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。可以使用小数实现亚毫秒精度。如果未提供,则将使用当前时间 -
exitSpan
<boolean>
创建“退出 span”。退出 span 表示传出通信。它们用于在服务地图中创建节点,并在依赖关系表中创建下游服务。提供的子类型将用作下游服务名称。 -
links
<Array>
Span 链接。一个 span 可以引用零个或多个其他事务或 span(与其父级分开)。Span 链接将显示在 Kibana APM 应用程序跟踪视图中。links
参数是一个对象数组,其中包含一个 "context" 字段,该字段是Transaction
、Span
或 W3C trace-context traceparent 字符串。例如:apm.startSpan('aName', { links: [{ context: anotherSpan }] })
。
-
启动并返回与当前活动事务关联的新自定义跨度。这与使用 apm.currentTransaction
获取当前事务,并在找到事务时对其调用 transaction.startSpan(name, type, options)
相同。
跨度启动后,它将测量调用 span.end()
之前的时间。
有关如何使用自定义跨度的详细信息,请参阅跨度 API文档。
如果没有可用的活动事务,则将返回 null
。
apm.handleUncaughtExceptions([callback])
编辑
添加于:v0.1.0
默认情况下,当检测到未捕获的异常时,代理将终止 Node.js 进程。如果需要在进程终止之前运行任何自定义代码,请使用此函数。
apm.handleUncaughtExceptions(function (err) { // Do your own stuff... and then exit: process.exit(1) })
在使用以下参数将事件发送到 APM 服务器之后,将调用回调
-
err
<Error>
捕获的异常
如果使用 captureExceptions
配置选项禁用了未捕获的异常处理程序,则此函数也将启用它。
如果不指定回调,则在捕获未捕获的异常并将其发送到 APM 服务器后,节点进程将自动终止。
建议在收到未捕获的异常后不要让进程继续运行,因此,如果使用可选的回调,请记住终止节点进程。
apm.flush([callback])
编辑
添加于:v0.12.0
// with node-style callback apm.flush(function (err) { // Flush complete }) // with promises apm.flush().then(function () { // Flush complete }).catch(function (err) { // Flush returned an error }) // inside of an async function try { await apm.flush() // Flush complete } catch (err) { // Flush returned an error }
手动结束到 APM 服务器的活动传出 HTTP 请求。否则,HTTP 请求会定期自动结束,由 apiRequestTime
和 apiRequestSize
配置选项控制。
如果将可选的 callback
作为此方法的第一个参数提供,则它将在完成后调用 callback(flushErr)
。如果没有提供 callback
,则将返回一个 Promise
,它将使用 void
解析或使用 flushErr
拒绝。
在活动 HTTP 请求结束后调用回调(或者,如果没有提供 callback
参数,则 Promise
解析)。即使当前没有活动的 HTTP 请求,也会调用回调。
apm.lambda([type, ]handler)
编辑
添加于:v1.4.0
exports.hello = apm.lambda(function (event, context, callback) { callback(null, `Hello, ${payload.name}!`) })
手动检测 AWS Lambda 函数,以便围绕每次执行形成一个事务。可以选择提供一个类型来将 lambda 分组在一起。默认情况下,“lambda”将用作类型名称。
在Lambda文章中阅读更多关于 lambda 支持的信息。
apm.addPatch(modules, handler)
编辑
添加于:v2.7.0
-
modules
<string>
|<string[]>
要将补丁应用到的模块名称(如果需要)。 -
handler
<Function>
|<string>
必须是补丁函数或导出补丁函数的模块的路径-
exports
<Object>
模块的原始导出对象 -
agent
- 在补丁函数中使用的代理实例 -
options
<Object>
支持以下选项-
version
<string>
|<undefined>
模块版本(如果适用)。 -
enabled
<boolean>
指示是否启用检测的标志。可以使用disableInstrumentations
按模块名称禁用任何模块补丁。
-
-
注册一个模块补丁,以应用于拦截的 require
调用。
一个模块可以有多个补丁,并将按照添加顺序应用。
apm.addPatch('timers', (exports, agent, { version, enabled }) => { const setTimeout = exports.setTimeout exports.setTimeout = (fn, ms) => { const span = agent.startSpan('set-timeout') return setTimeout(() => { span.end() fn() }, ms) } return exports }) // or ... apm.addPatch('timers', './timer-patch')
此方法和其他与“补丁”相关的 API 方法应在启动 APM 代理之前调用。在代理启动并`require`d 相关模块后进行更改可能会导致意外的缓存行为。
apm.removePatch(modules, handler)
编辑
添加于:v2.7.0
删除模块补丁。这通常仅在替换现有补丁时才需要。要禁用检测并保持上下文传播支持,请参阅 disableInstrumentations
。
apm.removePatch('timers', './timers-patch') // or ... apm.removePatch(['timers'], './timers-patch') // or ... apm.removePatch('timers', timerPatchFunction)
apm.clearPatches(modules)
编辑
添加于:v2.7.0
清除给定模块的所有补丁。这通常仅在替换现有补丁时才需要。要禁用检测并保持上下文传播支持,请参阅 disableInstrumentations
。
apm.clearPatches('timers') // or ... apm.clearPatches(['timers'])
apm.currentTraceIds
编辑
添加于:v2.17.0
当当前事务或跨度可用时,apm.currentTraceIds
会生成一个包含 trace.id
以及 transaction.id
或 span.id
的对象。当没有可用事务或跨度时,它将返回一个空对象。这使得可以使用结构化记录器将日志关联到 APM 跟踪。
{ "trace.id": "abc123", "transaction.id": "abc123" } // or ... { "trace.id": "abc123", "span.id": "abc123" }
apm.registerMetric(name[, labels], callback)
编辑
此功能处于技术预览阶段,可能会在未来版本中更改或删除。Elastic 将努力解决任何问题,但技术预览版中的功能不受官方 GA 功能的支持 SLA 的约束。
-
name
<string>
指标的名称。 -
labels
<Object>
包含键/值对。可选标签。可省略。 -
callback
<Function>
必须是返回当前指标值的函数。
注册指标回调。
注意不要使用内置指标的名称。
apm.registerMetric( 'ws.connections' , () => { return wss.clients.size; }) // or, to additionally label the metric with "module: 'ws'": apm.registerMetric( 'ws.connections' , {module : 'ws'}, () => { return wss.clients.size; })