/ src / solace_agent_mesh / common / utils / log_formatters.py
log_formatters.py
 1  import logging
 2  import json
 3  import os
 4  import warnings
 5  from datetime import datetime, timezone
 6  import traceback
 7  
 8  
 9  class DatadogJsonFormatter(logging.Formatter):
10      """
11      Custom formatter to output logs in Datadog-compatible JSON format.
12      
13      . deprecated::
14          This formatter is deprecated. Please use pythonjsonlogger.json.JsonFormatter instead.
15          For details, consult https://solacelabs.github.io/solace-agent-mesh/docs/documentation/deploying/logging#structured-logging
16  
17          Example:
18              formatters:
19                jsonFormatter:
20                  "()": pythonjsonlogger.json.JsonFormatter
21                  format: "%(timestamp)s %(levelname)s %(threadName)s %(name)s %(message)s"
22      """
23  
24      def format(self, record):
25          # Emit deprecation warning once
26          if not hasattr(self.__class__, '_deprecation_warned'):
27              warnings.warn(
28                  "DatadogJsonFormatter is deprecated and will be removed in a future version. "
29                  "Please use pythonjsonlogger.json.JsonFormatter instead. For details, consult https://solacelabs.github.io/solace-agent-mesh/docs/documentation/deploying/logging#structured-logging",
30                  DeprecationWarning,
31                  stacklevel=2
32              )
33              self.__class__._deprecation_warned = True
34          log_entry = {
35              "timestamp": datetime.fromtimestamp(
36                  record.created, tz=timezone.utc
37              ).isoformat(),
38              "level": record.levelname,
39              "message": record.getMessage(),
40              "logger.name": record.name,
41              "logger.thread_name": record.threadName,
42              "service": os.getenv("SERVICE_NAME", "solace_agent_mesh"),
43              "code.filepath": record.pathname,
44              "code.lineno": record.lineno,
45              "code.module": record.module,
46              "code.funcName": record.funcName,
47          }
48  
49          dd_trace_id = getattr(record, "dd.trace_id", None)
50          if dd_trace_id:
51              log_entry["dd.trace_id"] = dd_trace_id
52  
53          dd_span_id = getattr(record, "dd.span_id", None)
54          if dd_span_id:
55              log_entry["dd.span_id"] = dd_span_id
56  
57          if record.exc_info:
58              log_entry["exception.type"] = record.exc_info[0].__name__
59              log_entry["exception.message"] = str(record.exc_info[1])
60              log_entry["exception.stacktrace"] = "".join(
61                  traceback.format_exception(*record.exc_info)
62              )
63  
64          return json.dumps(log_entry)