自定义代码的监控
编辑自定义代码的监控编辑
在事务中创建额外的跨度编辑
Elastic APM 默认监控许多库,但有时您需要了解特定函数的执行时间或调用频率。
假设您使用的是我们 支持的框架 之一,您可以应用 @elasticapm.capture_span()
装饰器来实现这一点。如果您没有使用支持的框架,请参阅 创建新事务。
elasticapm.capture_span
可以用作装饰器或上下文管理器。以下示例以两种方式使用它
import elasticapm @elasticapm.capture_span() def coffee_maker(strength): fetch_water() with elasticapm.capture_span('near-to-machine'): insert_filter() for i in range(strength): pour_coffee() start_drip() fresh_pots()
类似地,您可以使用 elasticapm.async_capture_span
来监控 async
工作负载
import elasticapm @elasticapm.async_capture_span() async def coffee_maker(strength): await fetch_water() async with elasticapm.async_capture_span('near-to-machine'): await insert_filter() async for i in range(strength): await pour_coffee() start_drip() fresh_pots()
asyncio
支持仅在 Python 3.7+ 中可用。
有关 capture_span
的更多信息,请参阅 API 文档。
创建新事务编辑
需要注意的是,elasticapm.capture_span
仅在存在现有事务时才有效。如果您没有使用我们 支持的框架 之一,您需要创建一个 Client
对象并自行开始和结束事务。您甚至可以使用代理的 自动监控!
要收集支持库生成的跨度,您需要调用 elasticapm.instrument()
(仅在应用程序的初始化阶段调用一次)并至少创建一个事务。由您决定在应用程序中什么是事务——它可以是脚本的整个执行过程或其中的一部分。
以下示例将整个执行过程视为一个包含两个 HTTP 请求跨度的事务。elasticapm.Client
的配置可以通过编程方式传递,它也会自动利用任何可用的配置环境变量。
import requests import time import elasticapm def main(): sess = requests.Session() for url in [ 'https://elastic.ac.cn', 'https://benchmarks.elastic.co' ]: resp = sess.get(url) time.sleep(1) if __name__ == '__main__': client = elasticapm.Client(service_name="foo", server_url="https://example.com:8200") elasticapm.instrument() # Only call this once, as early as possible. client.begin_transaction(transaction_type="script") main() client.end_transaction(name=__name__, result="success")
请注意,您无需执行任何操作来发送数据——Client
对象会在脚本退出之前处理此操作。此外,Client
对象应被视为单例——您应该只创建一个实例并存储/传递该实例以进行所有事务处理。
分布式追踪编辑
在跨多个服务监控自定义代码时,您应该尽可能传播 TraceParent。这使 Elastic APM 能够将各种事务捆绑到一个分布式跟踪中。Python Agent 会自动将 TraceParent 信息添加到传出的 HTTP 请求的标头中,然后可以在接收端使用这些信息将 TraceParent 信息添加到新创建的手动事务中。
此外,Python Agent 提供了用于以字符串格式传播 TraceParent 的实用程序。
import elasticapm client = elasticapm.Client(service_name="foo", server_url="https://example.com:8200") # Retrieve the current TraceParent as a string, requires active transaction traceparent_string = elasticapm.get_trace_parent_header() # Create a TraceParent object from a string and use it for a new transaction parent = elasticapm.trace_parent_from_string(traceparent_string) client.begin_transaction(transaction_type="script", trace_parent=parent) # Do some work client.end_transaction(name=__name__, result="success") # Create a TraceParent object from a dictionary of headers, provided # automatically by the sending service if it is using an Elastic APM Agent. parent = elasticapm.trace_parent_from_headers(headers_dict) client.begin_transaction(transaction_type="script", trace_parent=parent) # Do some work client.end_transaction(name=__name__, result="success")