Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion elasticapm/handlers/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class LoggingFilter(logging.Filter):
* elasticapm_transaction_id
* elasticapm_trace_id
* elasticapm_span_id
* elasticapm_service_name

These attributes can then be incorporated into your handlers and formatters,
so that you can tie log messages to transactions in elasticsearch.
Expand Down Expand Up @@ -226,7 +227,15 @@ def _add_attributes_to_log_record(record):
span_id = span.id if span else None
record.elasticapm_span_id = span_id

record.elasticapm_labels = {"transaction.id": transaction_id, "trace.id": trace_id, "span.id": span_id}
service_name = transaction.tracer.config.service_name if transaction else None
record.elasticapm_service_name = service_name

record.elasticapm_labels = {
"transaction.id": transaction_id,
"trace.id": trace_id,
"span.id": span_id,
"service.name": service_name,
}

return record

Expand Down Expand Up @@ -264,11 +273,13 @@ def format(self, record):
record.elasticapm_transaction_id = None
record.elasticapm_trace_id = None
record.elasticapm_span_id = None
record.elasticapm_service_name = None
return super(Formatter, self).format(record=record)

def formatTime(self, record, datefmt=None):
if not hasattr(record, "elasticapm_transaction_id"):
record.elasticapm_transaction_id = None
record.elasticapm_trace_id = None
record.elasticapm_span_id = None
record.elasticapm_service_name = None
return super(Formatter, self).formatTime(record=record, datefmt=datefmt)
1 change: 1 addition & 0 deletions elasticapm/handlers/structlog.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def structlog_processor(logger, method_name, event_dict):
transaction = execution_context.get_transaction()
if transaction:
event_dict["transaction.id"] = transaction.id
event_dict["service.name"] = transaction.tracer.config.service_name
if transaction and transaction.trace_parent:
event_dict["trace.id"] = transaction.trace_parent.trace_id
span = execution_context.get_span()
Expand Down
8 changes: 8 additions & 0 deletions tests/handlers/logging/logging_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ def test_logging_filter_no_span(elasticapm_client):
record = logging.LogRecord(__name__, logging.DEBUG, __file__, 252, "dummy_msg", [], None)
f.filter(record)
assert record.elasticapm_transaction_id == transaction.id
assert record.elasticapm_service_name == transaction.tracer.config.service_name
assert record.elasticapm_trace_id == transaction.trace_parent.trace_id
assert record.elasticapm_span_id is None
assert record.elasticapm_labels
Expand All @@ -277,6 +278,7 @@ def test_logging_filter_span(elasticapm_client):
record = logging.LogRecord(__name__, logging.DEBUG, __file__, 252, "dummy_msg", [], None)
f.filter(record)
assert record.elasticapm_transaction_id == transaction.id
assert record.elasticapm_service_name == transaction.tracer.config.service_name
assert record.elasticapm_trace_id == transaction.trace_parent.trace_id
assert record.elasticapm_span_id == span.id
assert record.elasticapm_labels
Expand All @@ -291,6 +293,7 @@ def test_logging_filter_span(elasticapm_client):
record = logging.LogRecord(__name__, logging.DEBUG, __file__, 252, "dummy_msg2", [], None)
f.filter(record)
assert record.elasticapm_transaction_id == transaction.id
assert record.elasticapm_service_name == transaction.tracer.config.service_name
assert record.elasticapm_trace_id == transaction.trace_parent.trace_id
assert record.elasticapm_span_id is None
assert record.elasticapm_labels
Expand All @@ -303,6 +306,7 @@ def test_structlog_processor_span(elasticapm_client):
event_dict = {}
new_dict = structlog_processor(None, None, event_dict)
assert new_dict["transaction.id"] == transaction.id
assert new_dict["service.name"] == transaction.tracer.config.service_name
assert new_dict["trace.id"] == transaction.trace_parent.trace_id
assert new_dict["span.id"] == span.id

Expand All @@ -316,6 +320,7 @@ def test_structlog_processor_span(elasticapm_client):
event_dict = {}
new_dict = structlog_processor(None, None, event_dict)
assert new_dict["transaction.id"] == transaction.id
assert new_dict["service.name"] == transaction.tracer.config.service_name
assert new_dict["trace.id"] == transaction.trace_parent.trace_id
assert "span.id" not in new_dict

Expand All @@ -331,6 +336,7 @@ def test_automatic_log_record_factory_install(elasticapm_client):
record_factory = logging.getLogRecordFactory()
record = record_factory(__name__, logging.DEBUG, __file__, 252, "dummy_msg", [], None)
assert record.elasticapm_transaction_id == transaction.id
assert record.elasticapm_service_name == transaction.tracer.config.service_name
assert record.elasticapm_trace_id == transaction.trace_parent.trace_id
assert record.elasticapm_span_id == span.id
assert record.elasticapm_labels
Expand All @@ -342,10 +348,12 @@ def test_formatter():
formatted_record = formatter.format(record)
assert "| elasticapm" in formatted_record
assert hasattr(record, "elasticapm_transaction_id")
assert hasattr(record, "elasticapm_service_name")
record = logging.LogRecord(__name__, logging.DEBUG, __file__, 252, "dummy_msg", [], None)
formatted_time = formatter.formatTime(record)
assert formatted_time
assert hasattr(record, "elasticapm_transaction_id")
assert hasattr(record, "elasticapm_service_name")


def test_logging_handler_no_client(recwarn):
Expand Down