otel-utils 0.1.16__tar.gz → 0.1.18__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: otel-utils
3
- Version: 0.1.16
3
+ Version: 0.1.18
4
4
  Summary: Utilidades simplificadas para instrumentación con OpenTelemetry
5
5
  License: Proprietary
6
6
  Author: Harold Portocarrero
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "otel-utils"
3
- version = "0.1.16"
3
+ version = "0.1.18"
4
4
  description = "Utilidades simplificadas para instrumentación con OpenTelemetry"
5
5
  authors = ["Harold Portocarrero <harold@getcometa.com>"]
6
6
  readme = "README.md"
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import logging
2
3
  import platform
3
4
  from contextlib import contextmanager
@@ -7,6 +8,25 @@ 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',
19
+ 'levelno', 'pathname', 'filename', 'module', 'stack_info',
20
+ 'lineno', 'funcName', 'created', 'msecs', 'relativeCreated',
21
+ 'name', 'thread', 'threadName', 'processName', 'process'
22
+ ):
23
+ log_data[key] = value
24
+
25
+ log_data['message'] = record.getMessage()
26
+
27
+ return json.dumps(log_data)
28
+
29
+
10
30
  class StructuredLogger:
11
31
  """
12
32
  Logger that produces structured logs with tracing context.
@@ -24,6 +44,11 @@ class StructuredLogger:
24
44
  **(default_attributes or {})
25
45
  }
26
46
 
47
+ if not self.logger.handlers or not any(isinstance(h.formatter, JsonFormatter) for h in self.logger.handlers):
48
+ handler = logging.StreamHandler()
49
+ handler.setFormatter(JsonFormatter())
50
+ self.logger.addHandler(handler)
51
+
27
52
  def _get_trace_context(self) -> Dict[str, str]:
28
53
  """
29
54
  Gets the current tracing context if it exists.
@@ -53,31 +78,24 @@ class StructuredLogger:
53
78
  "logger.name": self.logger.name
54
79
  }
55
80
 
56
- additional_info = []
57
- if kwargs.get("error_type"):
58
- additional_info.append(f"type={kwargs['error_type']}")
59
- log_attributes["error.type"] = kwargs["error_type"]
60
- if kwargs.get("error_message"):
61
- additional_info.append(f"message={kwargs['error_message']}")
62
- log_attributes["error.message"] = kwargs["error_message"]
63
- if kwargs.get("operation"):
64
- additional_info.append(f"operation={kwargs['operation']}")
65
- log_attributes["operation"] = kwargs["operation"]
66
-
67
- remaining_attrs = {
68
- k: v for k, v in kwargs.items()
69
- if k not in ["error_type", "error_message", "operation"]
70
- }
71
- if remaining_attrs:
72
- log_attributes["attributes"] = remaining_attrs
81
+ if trace_context:
82
+ log_attributes["trace_id"] = trace_context.get("trace_id")
83
+ log_attributes["span_id"] = trace_context.get("span_id")
84
+
85
+ operation = kwargs.pop("operation", None)
86
+ if operation:
87
+ log_attributes["operation"] = operation
88
+
89
+ status = kwargs.pop("status", None)
90
+ if status:
91
+ log_attributes["status"] = status
73
92
 
74
- additional_str = f" - {', '.join(additional_info)}" if additional_info else ""
75
- trace_str = f"[trace_id={trace_context.get('trace_id', '0')}]" if trace_context else ""
76
- log_message = f"{trace_str} {message}{additional_str}"
93
+ if kwargs:
94
+ log_attributes["context"] = kwargs
77
95
 
78
96
  self.logger.log(
79
97
  level,
80
- log_message,
98
+ message,
81
99
  extra={
82
100
  "structured": True,
83
101
  "otel.name": "log",
File without changes