API 文档
编辑API 文档编辑
本节介绍 API 中最常用的部分。
Go Agent 使用标准 godoc 进行文档化。有关完整文档,请参阅 pkg.go.dev/go.elastic.co/apm/v2 上的文档,或使用“godoc”工具。
Tracer API编辑
您的应用程序与 Go Agent 的第一个接触点是 apm.Tracer
类型,它提供用于报告事务和错误的方法。
为了简化检测,Go Agent 提供了一个初始化函数 apm.DefaultTracer()
。此 Tracer 在第一次调用 apm.DefaultTracer()
时初始化,并在后续调用中返回。此函数返回的 Tracer 可以使用 apm.SetDefaultTracer(tracer)
进行修改。调用此函数将关闭之前的默认 Tracer(如果存在)。此 Tracer 使用环境变量进行配置;有关详细信息,请参阅 配置。
import ( "go.elastic.co/apm/v2" ) func main() { tracer := apm.DefaultTracer() ... }
事务编辑
func (*Tracer) StartTransaction(name, type string) *Transaction
编辑
StartTransaction 返回一个新的 Transaction,它具有指定的名称和类型,并且开始时间设置为当前时间。如果您需要设置时间戳或父 跟踪上下文,请使用 Tracer.StartTransactionOptions。
此方法应在事务开始时调用,例如 Web 或 RPC 请求。例如:
transaction := apm.DefaultTracer().StartTransaction("GET /", "request")
事务将在 Elastic APM 应用程序中按类型和名称分组。
启动事务后,您可以记录结果并添加上下文以进一步描述事务。
transaction.Result = "Success" transaction.Context.SetLabel("region", "us-east-1")
有关设置事务上下文的更多详细信息,请参阅 上下文。
func (*Tracer) StartTransactionOptions(name, type string, opts TransactionOptions) *Transaction
编辑
StartTransactionOptions 本质上与 StartTransaction 相同,但它还接受一个选项结构体。此结构体允许您指定父 跟踪上下文 和/或事务的开始时间。
opts := apm.TransactionOptions{ Start: time.Now(), TraceContext: parentTraceContext, } transaction := apm.DefaultTracer().StartTransactionOptions("GET /", "request", opts)
func (*Transaction) End()
编辑
End 将事务排队以发送到 Elastic APM 服务器。事务在调用此方法后不得修改,但仍可用于启动跨度。
事务的持续时间计算为事务开始到调用此方法之间经过的时间。要覆盖此行为,可以在调用 End 之前设置事务的 Duration
字段。
transaction.End()
func (*Transaction) TraceContext() TraceContext
编辑
TraceContext 返回事务的 跟踪上下文。
func (*Transaction) EnsureParent() SpanID
编辑
EnsureParent 返回事务的父跨度 ID,如果事务之前没有父跨度,则生成并记录一个父跨度 ID。
EnsureParent 使得与 JavaScript 真实用户监控 (RUM) 代理为初始页面加载创建的跨度相关联。如果您的后端服务动态生成 HTML 页面,则可以将跟踪和父跨度 ID 注入页面以初始化 JavaScript RUM 代理,以便 Web 浏览器的页面加载显示为跟踪的根。
var initialPageTemplate = template.Must(template.New("").Parse(` <html> <head> <script src="elastic-apm-js-base/dist/bundles/elastic-apm-js-base.umd.min.js"></script> <script> elasticApm.init({ serviceName: '', serverUrl: 'https://127.0.0.1:8200', pageLoadTraceId: {{.TraceContext.Trace}}, pageLoadSpanId: {{.EnsureParent}}, pageLoadSampled: {{.Sampled}}, }) </script> </head> <body>...</body> </html> `)) func initialPageHandler(w http.ResponseWriter, req *http.Request) { err := initialPageTemplate.Execute(w, apm.TransactionFromContext(req.Context())) if err != nil { ... } }
有关更多信息,请参阅 JavaScript RUM 代理文档。
func (*Transaction) ParentID() SpanID
编辑
ParentID 返回事务父级的 ID,如果事务没有父级,则返回零(无效)SpanID。
func ContextWithTransaction(context.Context, *Transaction) context.Context
编辑
ContextWithTransaction 将事务添加到上下文中,并返回结果上下文。
可以使用 apm.TransactionFromContext 检索事务。上下文也可以传递到 apm.StartSpan 中,该方法在内部使用 TransactionFromContext 来创建作为事务子级的跨度。
func TransactionFromContext(context.Context) *Transaction
编辑
TransactionFromContext 返回先前使用 apm.ContextWithTransaction 存储在上下文中的事务,如果上下文不包含事务,则返回 nil。
func DetachedContext(context.Context) context.Context
编辑
DetachedContext 返回一个新的上下文,该上下文与输入的生存期分离,但仍返回与输入相同的 value。
DetachedContext 可用于维护关联事件所需的跟踪上下文,但操作是“即发即弃”的,不应受周围上下文的截止时间或取消的影响。
func TraceFormatter(context.Context) fmt.Formatter
编辑
TraceFormatter 返回 fmt.Formatter 的实现,可用于格式化提供上下文中存储的事务和跨度的 ID。
格式化程序理解以下格式
- %v: 跟踪 ID、事务 ID 和(如果在跨度上下文中)跨度 ID,以空格分隔
- %t: 仅跟踪 ID
- %x: 仅事务 ID
- %s: 仅跨度 ID
“+”选项可用于以“key=value”样式格式化 value,字段名称为 trace.id
、transaction.id
和 span.id
。例如,使用 "%+v" 作为格式将产生 "trace.id=… transaction.id=… span.id=…"。
有关更深入的示例,请参阅 手动日志关联(非结构化)。
跨度编辑
为了描述事务中的活动,我们创建跨度。Go Agent 内置支持为某些活动生成跨度,例如数据库查询。您可以使用 API 报告特定于应用程序的跨度。
func (*Transaction) StartSpan(name, spanType string, parent *Span) *Span
编辑
StartSpan 在事务中启动并返回一个新的跨度,它具有指定的名称、类型和可选的父跨度,并且开始时间设置为当前时间。如果您需要设置时间戳或父 跟踪上下文,请使用 Transaction.StartSpanOptions。
如果跨度类型包含两个点,则假定它们用于分隔跨度类型、子类型和操作;一个点用于分隔跨度类型和子类型,并且不会设置操作。
如果事务被采样,则跨度的 ID 将被设置,并且如果 Tracer 进行了相应的配置,则其堆栈跟踪将被设置。如果事务未被采样,则返回的跨度将在调用其 End 方法时被静默丢弃。为了避免对这些被丢弃的跨度进行任何不必要的计算,请调用 Dropped 方法。
为了方便起见,在 nil Transaction 上创建跨度是有效的;生成的跨度将是非空的,可以安全使用,但不会报告给 APM 服务器。
span := tx.StartSpan("SELECT FROM foo", "db.mysql.query", nil)
func (*Transaction) StartSpanOptions(name, spanType string, opts SpanOptions) *Span
编辑
StartSpanOptions 本质上与 StartSpan 相同,但它还接受一个选项结构体。此结构体允许您指定父 跟踪上下文 和/或跨度的开始时间。如果选项中未指定父跟踪上下文,则跨度将是事务的直接子级。否则,父跟踪上下文应属于从事务派生的某个跨度。
opts := apm.SpanOptions{ Start: time.Now(), Parent: parentSpan.TraceContext(), } span := tx.StartSpanOptions("SELECT FROM foo", "db.mysql.query", opts)
func StartSpan(ctx context.Context, name, spanType string) (*Span, context.Context)
edit
StartSpan 在上下文中启动并返回一个新的跨度,该跨度位于采样事务和父跨度内(如果有)。如果跨度未被丢弃,它将包含在生成的上下文中。
span, ctx := apm.StartSpan(ctx, "SELECT FROM foo", "db.mysql.query")
func (*Span) End()
edit
End 将跨度标记为已完成。在此之后,不得修改跨度,但仍可将其用作跨度的父级。
跨度的持续时间将计算为从跨度启动到调用此方法所经过的时间。要覆盖此行为,可以在调用 End 之前设置跨度的 Duration 字段。
func (*Span) Dropped() bool
edit
Dropped 指示跨度是否被丢弃,这意味着它不会被报告给 APM 服务器。当使用 nil 或未采样事务创建跨度时,或者当已达到其最大跨度限制时,跨度会被丢弃。
func (*Span) TraceContext() TraceContext
edit
TraceContext 返回跨度的 跟踪上下文。
func ContextWithSpan(context.Context, *Span) context.Context
edit
ContextWithSpan 将跨度添加到上下文中并返回生成的上下文。
可以使用 apm.SpanFromContext 检索跨度。上下文也可以传递给 apm.StartSpan,它在内部使用 SpanFromContext 来创建另一个跨度作为该跨度的子级。
func SpanFromContext(context.Context) *Span
edit
SpanFromContext 返回之前使用 apm.ContextWithSpan 存储在上下文中的跨度,如果上下文不包含跨度,则返回 nil。
func (*Span) ParentID() SpanID
edit
ParentID 返回跨度父级的 ID。
上下文edit
在报告事务和错误时,您可以提供上下文来描述这些事件。内置的检测通常会提供一些上下文,例如 HTTP 请求的 URL 和远程地址。您也可以提供自定义上下文和标签。
func (*Context) SetLabel(key string, value interface{})
edit
SetLabel 使用给定的键和值标记事务或错误。如果键包含任何特殊字符(.
、*
、"
),它们将被替换为下划线。
如果值是数字或布尔值,则它将作为 JSON 数字或布尔值发送到服务器;否则,它将被转换为字符串,如果需要,将使用 fmt.Sprint
。从版本 6.7 开始,服务器支持数字和布尔值。
超过 1024 个字符的字符串值将被截断。标签在 Elasticsearch 中被索引为关键字字段。
在使用标签之前,请确保您了解可用的不同类型的 元数据。
避免定义太多用户指定的标签。在索引中定义太多唯一字段会导致 映射爆炸。
func (*Context) SetCustom(key string, value interface{})
edit
SetCustom 用于向事务或错误添加自定义的、非索引的上下文信息。如果键包含任何特殊字符(.
、*
、"
),它们将被替换为下划线。
非索引意味着数据在 Elasticsearch 中不可搜索或聚合,您无法在数据之上构建仪表板。但是,非索引信息对于其他原因很有用,例如提供上下文信息以帮助您快速调试性能问题或错误。
该值可以是任何可以使用 encoding/json
编码的类型。
在使用自定义上下文之前,请确保您了解可用的不同类型的 元数据。
func (*Context) SetUsername(username string)
edit
SetUsername 记录与事务关联的用户的用户名。
func (*Context) SetUserID(id string)
edit
SetUserID 记录与事务关联的用户的 ID。
func (*Context) SetUserEmail(email string)
edit
SetUserEmail 记录与事务关联的用户的电子邮件地址。
错误edit
Elastic APM 提供两种捕获错误事件的方法:报告错误日志记录和报告“异常”(在 Go 中,无论是 panic 还是错误)。
func (*Tracer) NewError(error) *Error
edit
NewError 返回一个新的 Error,其中包含从 err 中获取的详细信息。
异常消息将设置为 err.Error()
。异常模块和类型将分别设置为错误原因的包和类型名称,其中原因与 github.com/pkg/errors 中给出的定义相同。
e := apm.DefaultTracer().NewError(err) ... e.Send()
提供的错误可以实现多个接口中的任何一个以提供其他信息
// Errors implementing ErrorsStacktracer will have their stacktrace // set based on the result of the StackTrace method. type ErrorsStacktracer interface { StackTrace() github.com/pkg/errors.StackTrace } // Errors implementing Stacktracer will have their stacktrace // set based on the result of the StackTrace method. type Stacktracer interface { StackTrace() []go.elastic.co/apm/v2/stacktrace.Frame } // Errors implementing Typer will have a "type" field set to the // result of the Type method. type Typer interface { Type() string } // Errors implementing StringCoder will have a "code" field set to the // result of the Code method. type StringCoder interface { Code() string } // Errors implementing NumberCoder will have a "code" field set to the // result of the Code method. type NumberCoder interface { Code() float64 }
使用 NewError 创建的错误将使用唯一 ID 填充其 ID 字段。这可以在您的应用程序中用于关联。
func (*Tracer) NewErrorLog(ErrorLogRecord) *Error
edit
NewErrorLog 为给定的 ErrorLogRecord 返回一个新的 Error
type ErrorLogRecord struct { // Message holds the message for the log record, // e.g. "failed to connect to %s". // // If this is empty, "[EMPTY]" will be used. Message string // MessageFormat holds the non-interpolated format // of the log record, e.g. "failed to connect to %s". // // This is optional. MessageFormat string // Level holds the severity level of the log record. // // This is optional. Level string // LoggerName holds the name of the logger used. // // This is optional. LoggerName string // Error is an error associated with the log record. // // This is optional. Error error }
生成的 Error 的日志堆栈跟踪将不会被设置。调用 SetStacktrace 方法来设置它。
e := apm.DefaultTracer().NewErrorLog(apm.ErrorLogRecord{ Message: "Somebody set up us the bomb.", }) ... e.Send()
func (*Error) SetTransaction(*Transaction)
edit
SetTransaction 将错误与给定的事务关联起来。
func (*Error) SetSpan(*Span)
edit
SetSpan 将错误与给定的跨度及其跨度的交易关联起来。调用 SetSpan 时,无需再调用 SetTransaction。
func (*Error) Send()
edit
Send 将错误排队以发送到 Elastic APM 服务器。
func (*Tracer) Recovered(interface{}) *Error
edit
Recovered 从恢复的值返回一个 Error,可以选择将其与事务关联起来。错误不会被发送;调用者有责任设置错误的上下文,然后调用其 Send
方法。
tx := apm.DefaultTracer().StartTransaction(...) defer tx.End() defer func() { if v := recover(); v != nil { e := apm.DefaultTracer().Recovered(v) e.SetTransaction(tx) e.Send() } }()
func CaptureError(context.Context, error) *Error
edit
CaptureError 返回一个与上下文中存在的采样事务和跨度相关的错误(如果有),并使用给定的错误设置其异常详细信息。Error.Handled 字段将设置为 true,并将设置堆栈跟踪。
如果上下文中没有事务,或者它没有被采样,CaptureError 将返回 nil。为了方便起见,如果提供的错误为 nil,则 CaptureError 也将返回 nil。
if err != nil { e := apm.CaptureError(ctx, err) e.Send() }
跟踪上下文edit
跟踪上下文包含事务或跨度的 ID、事务或跨度所属的端到端跟踪的 ID,以及跟踪选项,例如与采样相关的标志。跟踪上下文在进程之间传播,例如在 HTTP 标头中,以便关联来自相关服务的事件。
Elastic APM 的跟踪上下文基于 W3C 跟踪上下文 草案。
错误上下文edit
错误可以像事务一样与上下文关联。有关详细信息,请参阅 上下文。此外,错误可以使用 SetTransaction 或 SetSpan 分别与活动事务或跨度关联。
tx := apm.DefaultTracer().StartTransaction("GET /foo", "request") defer tx.End() e := apm.DefaultTracer().NewError(err) e.SetTransaction(tx) e.Send()
跟踪器配置edit
许多配置属性可以通过 apm.Tracer
方法调用动态更新。有关详细信息,请参阅 pkg.go.dev/go.elastic.co/apm/v2#Tracer 中的文档。配置方法主要以 Set
为前缀,例如 apm#Tracer.SetLogger。