日志
Elastic Python APM 代理提供以下日志功能
- 日志关联 :自动注入关联 ID,允许在日志、跟踪和服务之间导航。
- 日志重新格式化(实验性) :自动将纯文本日志重新格式化为 ECS 日志记录 格式。
Elastic Python APM 代理不会将日志发送到 Elasticsearch。它只注入关联 ID 并重新格式化日志。您必须使用其他采集策略。我们推荐使用 Filebeat。
这些功能是 应用日志采集策略 的一部分。
ecs-logging-python
库也可以用于在不使用 APM 代理的情况下使用 ECS 日志记录 格式。与 Python APM 代理一起部署时,代理将提供 日志关联 ID。
日志关联 允许您导航到属于特定跟踪的所有日志,反之亦然:对于特定日志,查看它是在什么上下文中记录的,以及用户提供了哪些参数。
代理提供了与默认 Python 日志记录库以及 structlog
的集成。
我们使用 logging.setLogRecordFactory()
来装饰默认的 LogRecordFactory,以自动向每个 LogRecord 对象添加新属性
elasticapm_transaction_id
elasticapm_trace_id
elasticapm_span_id
此工厂还会将这些字段添加到字典属性 elasticapm_labels
中,使用官方 ECS 跟踪字段。
您可以通过在配置中使用 disable_log_record_factory
设置来禁用此自动行为。
我们为 structlog
提供了一个 处理器,它将向任何已处理事件的 event_dict 添加三个新键
transaction.id
trace.id
span.id
from structlog import PrintLogger, wrap_logger
from structlog.processors import JSONRenderer
from elasticapm.handlers.structlog import structlog_processor
wrapped_logger = PrintLogger()
logger = wrap_logger(wrapped_logger, processors=[structlog_processor, JSONRenderer()])
log = logger.new()
log.msg("some_event")
Elastic APM Python 代理使用 logging 来记录内部事件和问题。默认情况下,它将使用一个 logging
记录器。如果您的项目使用 structlog,可以通过将环境变量 ELASTIC_APM_USE_STRUCTLOG
设置为 true
来告诉代理使用 structlog 记录器。
为了将您的应用程序日志与 Elastic APM Python 代理捕获的事务关联起来,您的日志必须包含以下一个或多个标识符
transaction.id
trace.id
span.id
如果您使用结构化日志记录,无论是 使用自定义解决方案 还是 structlog(推荐),这都相当容易。使用 JSONRenderer,并使用 Filebeat 将这些日志拉入 Elasticsearch。
如果没有结构化日志记录,任务会稍微棘手一些。这里我们建议首先确保您的 LogRecord 对象具有 elasticapm 属性(参见 logging
),然后您需要将特定的格式与 Grok 模式结合使用,可以在 Elasticsearch 中使用 grok 处理器,或者在 logstash 中使用插件。
假设您有一个 Formatter 看起来像这样
import logging
fh = logging.FileHandler('spam.log')
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh.setFormatter(formatter)
您只需将 Formatter
对象替换为我们提供的对象,即可添加 APM 标识符
import logging
from elasticapm.handlers.logging import Formatter
fh = logging.FileHandler('spam.log')
formatter = Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh.setFormatter(formatter)
这将自动将 apm 特定的字段附加到您的格式字符串中
formatstring = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
formatstring = formatstring + " | elasticapm " \
"transaction.id=%(elasticapm_transaction_id)s " \
"trace.id=%(elasticapm_trace_id)s " \
"span.id=%(elasticapm_span_id)s"
然后,您可以使用这样的 grok 模式(用于 Elasticsearch Grok 处理器)
{
"description" : "...",
"processors": [
{
"grok": {
"field": "message",
"patterns": ["%{GREEDYDATA:msg} | elasticapm transaction.id=%{DATA:transaction.id} trace.id=%{DATA:trace.id} span.id=%{DATA:span.id}"]
}
}
]
}
从 6.16.0 版本开始,代理可以自动将应用程序日志重新格式化为 ECS 格式,无需更改依赖项。早期版本必须安装 ecs_logging
依赖项。
日志重新格式化由 log_ecs_reformatting
配置选项控制,默认禁用。
重新格式化的日志将包括 跟踪和服务的关联 ID。