otel-utils 0.1.15__tar.gz → 0.1.17__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of otel-utils might be problematic. Click here for more details.
- {otel_utils-0.1.15 → otel_utils-0.1.17}/PKG-INFO +1 -1
- {otel_utils-0.1.15 → otel_utils-0.1.17}/pyproject.toml +1 -1
- {otel_utils-0.1.15 → otel_utils-0.1.17}/src/otel_utils/logging.py +35 -26
- {otel_utils-0.1.15 → otel_utils-0.1.17}/README.md +0 -0
- {otel_utils-0.1.15 → otel_utils-0.1.17}/src/otel_utils/__init__.py +0 -0
- {otel_utils-0.1.15 → otel_utils-0.1.17}/src/otel_utils/configurator.py +0 -0
- {otel_utils-0.1.15 → otel_utils-0.1.17}/src/otel_utils/metrics.py +0 -0
- {otel_utils-0.1.15 → otel_utils-0.1.17}/src/otel_utils/tracing.py +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import logging
|
|
2
3
|
import platform
|
|
3
4
|
from contextlib import contextmanager
|
|
@@ -7,6 +8,30 @@ from typing import Any, Dict, Optional
|
|
|
7
8
|
from opentelemetry import trace
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
class JsonFormatter(logging.Formatter):
|
|
12
|
+
def format(self, record):
|
|
13
|
+
log_data = {}
|
|
14
|
+
|
|
15
|
+
if hasattr(record, 'structured') and record.structured:
|
|
16
|
+
for key, value in record.__dict__.items():
|
|
17
|
+
if key not in (
|
|
18
|
+
'args', 'exc_info', 'exc_text', 'msg', 'message', 'levelname', 'levelno', 'pathname',
|
|
19
|
+
'filename',
|
|
20
|
+
'module', 'stack_info', 'lineno', 'funcName', 'created', 'msecs', 'relativeCreated', 'name',
|
|
21
|
+
'thread',
|
|
22
|
+
'threadName', 'processName', 'process'):
|
|
23
|
+
log_data[key] = value
|
|
24
|
+
|
|
25
|
+
if 'attributes' in log_data:
|
|
26
|
+
for key, value in log_data['attributes'].items():
|
|
27
|
+
log_data[key] = value
|
|
28
|
+
del log_data['attributes']
|
|
29
|
+
|
|
30
|
+
log_data['message'] = record.getMessage()
|
|
31
|
+
|
|
32
|
+
return json.dumps(log_data)
|
|
33
|
+
|
|
34
|
+
|
|
10
35
|
class StructuredLogger:
|
|
11
36
|
"""
|
|
12
37
|
Logger that produces structured logs with tracing context.
|
|
@@ -24,6 +49,11 @@ class StructuredLogger:
|
|
|
24
49
|
**(default_attributes or {})
|
|
25
50
|
}
|
|
26
51
|
|
|
52
|
+
if not self.logger.handlers or not any(isinstance(h.formatter, JsonFormatter) for h in self.logger.handlers):
|
|
53
|
+
handler = logging.StreamHandler()
|
|
54
|
+
handler.setFormatter(JsonFormatter())
|
|
55
|
+
self.logger.addHandler(handler)
|
|
56
|
+
|
|
27
57
|
def _get_trace_context(self) -> Dict[str, str]:
|
|
28
58
|
"""
|
|
29
59
|
Gets the current tracing context if it exists.
|
|
@@ -48,43 +78,22 @@ class StructuredLogger:
|
|
|
48
78
|
|
|
49
79
|
log_attributes = {
|
|
50
80
|
**self.default_attributes,
|
|
81
|
+
**trace_context,
|
|
51
82
|
"timestamp": datetime.utcnow().isoformat(),
|
|
52
83
|
"severity": logging.getLevelName(level),
|
|
53
|
-
"logger.name": self.logger.name
|
|
54
|
-
**trace_context
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
additional_info = []
|
|
58
|
-
if kwargs.get("error_type"):
|
|
59
|
-
additional_info.append(f"type={kwargs['error_type']}")
|
|
60
|
-
log_attributes["error.type"] = kwargs["error_type"]
|
|
61
|
-
if kwargs.get("error_message"):
|
|
62
|
-
additional_info.append(f"message={kwargs['error_message']}")
|
|
63
|
-
log_attributes["error.message"] = kwargs["error_message"]
|
|
64
|
-
if kwargs.get("operation"):
|
|
65
|
-
additional_info.append(f"operation={kwargs['operation']}")
|
|
66
|
-
log_attributes["operation"] = kwargs["operation"]
|
|
67
|
-
|
|
68
|
-
remaining_attrs = {
|
|
69
|
-
k: v for k, v in kwargs.items()
|
|
70
|
-
if k not in ["error_type", "error_message", "operation"]
|
|
84
|
+
"logger.name": self.logger.name
|
|
71
85
|
}
|
|
72
|
-
if remaining_attrs:
|
|
73
|
-
log_attributes["attributes"] = remaining_attrs
|
|
74
86
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
log_message = f"{trace_str} {message}{additional_str}"
|
|
87
|
+
for key, value in kwargs.items():
|
|
88
|
+
log_attributes[key] = value
|
|
78
89
|
|
|
79
90
|
self.logger.log(
|
|
80
91
|
level,
|
|
81
|
-
|
|
92
|
+
message,
|
|
82
93
|
extra={
|
|
83
94
|
"structured": True,
|
|
84
95
|
"otel.name": "log",
|
|
85
96
|
"otel.kind": "event",
|
|
86
|
-
"otelTraceID": trace_context.get("trace_id", ""),
|
|
87
|
-
"otelSpanID": trace_context.get("span_id", ""),
|
|
88
97
|
**log_attributes
|
|
89
98
|
}
|
|
90
99
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|