Agent 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])
编辑启动 Node.js 的 Elastic APM 代理并返回自身。
为了使 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 服务器的“metadata”对象 — 请改用 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
在 v3.11.0 中添加了 stringify
参数
apm.setLabel('productId', 42, false);
在当前事务上设置标签。您可以在同一事务上设置多个标签。如果在当前事务期间发生错误,它也会被标记上相同的标签。
标签是键/值对,由 Elasticsearch 索引,因此可搜索(与通过 apm.setCustomContext()
设置的数据相反)。在使用自定义标签之前,请确保您了解可用的不同类型的元数据。
避免定义过多用户指定的标签。在索引中定义过多唯一字段是一种可能导致映射爆炸的情况。
apm.addLabels({ [name]: value }[, stringify = true])
编辑添加于:v1.5.0
从 apm.addTags()
重命名为 apm.addLabels()
:v2.10.0
在 v3.11.0 中添加了 stringify
参数
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 Server 的数据中包含给定<Error>
对象的属性(作为error.exception.attributes
)。默认值:true
。 -
skipOutcome
<boolean>
是否跳过将当前跨度的结果值设置为failure
。有关更多信息,请参阅跨度结果。默认值:false
。 -
parent
事务 | 跨度 |null
- 作为此错误的父级的事务或跨度实例。如果未给定(或undefined
),则将使用当前跨度或事务。如果给定null
,则不使用跨度或事务。(在 v3.33.0 中添加。)
-
-
callback
- 在错误已发送到 APM Server 后调用。如果代理无法发送错误,则它将收到一个Error
实例,以及捕获的错误的 ID。
将错误发送到 APM Server
apm.captureError(new Error('boom!'))
消息字符串
编辑除了 Error
对象之外,您还可以记录纯文本消息
apm.captureError('Something happened!')
这也将作为错误发送到 APM Server,但不会与异常关联。
参数化消息对象
编辑除了 Error
对象或字符串之外,您还可以提供一个特殊的参数化消息对象
apm.captureError({ message: 'Could not find user %s with id %d in the database', params: ['Peter', 42] })
这使得可以更好地对包含 ID 或名称等可变数据的错误消息进行分组。
元数据
编辑为了方便调试,可以随您发送到 APM Server 的每个错误一起发送一些额外的数据。APM Server 接收 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 跟踪上下文“traceparent”字符串,通常从远程服务调用接收。 -
tracestate
<string>
W3C 跟踪上下文“tracestate”字符串。 -
links
<Array>
Span 链接。事务可以引用零个或多个其他事务或 Span(与其父级分开)。Span 链接将显示在 Kibana APM 应用跟踪视图中。links
参数是一个对象数组,其中包含一个 “context” 字段,该字段是Transaction
、Span
或 W3C 跟踪上下文 traceparent 字符串。例如:apm.startTransaction('aName', { links: [{ context: anotherSpan }] })
。
-
启动新的自定义/手动事务。有关如何使用自定义事务的详细信息,请参阅事务 API 文档。
请注意,APM 代理会自动为传入的 HTTP 请求启动事务。您只需使用此函数创建自定义事务,例如,对于定期后台例程。有一个名为 request
的特殊 type
,代理在检测到传入 HTTP 请求时自动创建的事务将使用该类型。
如果 APM 代理尚未启动,则将返回一个无操作的“no-op”事务对象。
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 跟踪上下文 traceparent 字符串。例如:apm.startSpan('aName', { links: [{ context: anotherSpan }] })
。
-
启动并返回与当前活动事务关联的新自定义 Span。这与使用 apm.currentTransaction
获取当前事务,以及如果找到事务,则在其上调用 transaction.startSpan(name, type, options)
相同。
当 Span 启动时,它将测量时间,直到调用 span.end()
为止。
有关如何使用自定义 Span 的详细信息,请参阅Span 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
,该 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')
此方法和其他与“Patch”相关的 API 方法应在启动 APM 代理之前调用。在代理启动且相关模块已被 `require` 后进行的更改可能会产生意想不到的缓存行为。
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
以及当存在当前事务或 span 时包含 transaction.id
或 span.id
的对象。当没有可用的事务或 span 时,它将返回一个空对象。这使得可以将 日志关联到带有结构化日志记录器的 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; })
apm.setTransactionOutcome(outcome)
编辑新增于: v3.12.0
-
outcome
<string>
将在当前事务上设置 outcome 属性。
有关更多信息,请参阅 事务 Outcome 文档。
apm.setSpanOutcome(outcome)
编辑新增于: v3.12.0
-
outcome
<string>
将在当前 span 上设置 outcome 属性。
有关更多信息,请参阅 Span Outcome 文档。