rebrandly-otel 0.1.11__py3-none-any.whl → 0.1.14__py3-none-any.whl
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 rebrandly-otel might be problematic. Click here for more details.
- rebrandly_otel/__init__.py +0 -1
- rebrandly_otel/rebrandly_otel.py +73 -56
- {rebrandly_otel-0.1.11.dist-info → rebrandly_otel-0.1.14.dist-info}/METADATA +1 -1
- rebrandly_otel-0.1.14.dist-info/RECORD +11 -0
- rebrandly_otel-0.1.11.dist-info/RECORD +0 -11
- {rebrandly_otel-0.1.11.dist-info → rebrandly_otel-0.1.14.dist-info}/WHEEL +0 -0
- {rebrandly_otel-0.1.11.dist-info → rebrandly_otel-0.1.14.dist-info}/licenses/LICENSE +0 -0
- {rebrandly_otel-0.1.11.dist-info → rebrandly_otel-0.1.14.dist-info}/top_level.txt +0 -0
rebrandly_otel/__init__.py
CHANGED
rebrandly_otel/rebrandly_otel.py
CHANGED
|
@@ -101,101 +101,118 @@ class RebrandlyOTEL:
|
|
|
101
101
|
|
|
102
102
|
# Fix for the lambda_handler method in rebrandly_otel.py
|
|
103
103
|
# Replace the lambda_handler method (around line 132) with this fixed version:
|
|
104
|
-
|
|
105
104
|
def lambda_handler(self,
|
|
106
105
|
name: Optional[str] = None,
|
|
107
106
|
attributes: Optional[Dict[str, Any]] = None,
|
|
108
|
-
kind: SpanKind = SpanKind.
|
|
107
|
+
kind: SpanKind = SpanKind.SERVER,
|
|
109
108
|
auto_flush: bool = True,
|
|
110
|
-
skip_aws_link: bool =
|
|
109
|
+
skip_aws_link: bool = False):
|
|
111
110
|
"""
|
|
112
111
|
Decorator specifically for Lambda handlers with automatic flushing.
|
|
113
112
|
"""
|
|
114
113
|
def decorator(func):
|
|
115
114
|
@functools.wraps(func)
|
|
116
|
-
def wrapper(event=None,
|
|
115
|
+
def wrapper(event=None, lambda_context=None):
|
|
117
116
|
# Determine span name
|
|
118
117
|
span_name = name or f"lambda.{func.__name__}"
|
|
119
|
-
|
|
118
|
+
start_time = datetime.now()
|
|
120
119
|
|
|
121
120
|
# Build span attributes
|
|
122
121
|
span_attributes = attributes or {}
|
|
123
|
-
|
|
124
122
|
span_attributes['faas.trigger'] = self._detect_lambda_trigger(event)
|
|
125
123
|
|
|
126
124
|
# Add Lambda-specific attributes if context is available
|
|
127
|
-
if
|
|
125
|
+
if lambda_context is not None:
|
|
128
126
|
span_attributes.update({
|
|
129
|
-
"faas.execution": getattr(
|
|
130
|
-
"faas.id": getattr(
|
|
131
|
-
"
|
|
132
|
-
"
|
|
127
|
+
"faas.execution": getattr(lambda_context, 'aws_request_id', 'unknown'),
|
|
128
|
+
"faas.id": getattr(lambda_context, 'function_arn', 'unknown'),
|
|
129
|
+
"faas.name": getattr(lambda_context, 'function_name', 'unknown'),
|
|
130
|
+
"faas.version": getattr(lambda_context, 'function_version', 'unknown')
|
|
133
131
|
})
|
|
134
132
|
|
|
133
|
+
# Handle context extraction from AWS events
|
|
134
|
+
token = None
|
|
135
|
+
if not skip_aws_link and event and isinstance(event, dict) and 'Records' in event:
|
|
136
|
+
first_record = event['Records'][0] if event['Records'] else None
|
|
137
|
+
if first_record:
|
|
138
|
+
carrier = {}
|
|
139
|
+
|
|
140
|
+
# Extract from SQS
|
|
141
|
+
if 'MessageAttributes' in first_record:
|
|
142
|
+
for key, value in first_record['MessageAttributes'].items():
|
|
143
|
+
if isinstance(value, dict) and 'StringValue' in value:
|
|
144
|
+
carrier[key] = value['StringValue']
|
|
145
|
+
if ('messageAttributes' in first_record and 'traceparent' in first_record['messageAttributes']
|
|
146
|
+
and 'stringValue' in first_record['messageAttributes']['traceparent']):
|
|
147
|
+
carrier['traceparent'] = first_record['messageAttributes']['traceparent']['stringValue']
|
|
148
|
+
|
|
149
|
+
# Extract from SNS
|
|
150
|
+
elif 'Sns' in first_record and 'MessageAttributes' in first_record['Sns']:
|
|
151
|
+
for key, value in first_record['Sns']['MessageAttributes'].items():
|
|
152
|
+
if isinstance(value, dict):
|
|
153
|
+
if 'Value' in value:
|
|
154
|
+
carrier[key] = value['Value']
|
|
155
|
+
elif 'StringValue' in value:
|
|
156
|
+
carrier[key] = value['StringValue']
|
|
157
|
+
|
|
158
|
+
# Attach extracted context
|
|
159
|
+
if carrier:
|
|
160
|
+
from opentelemetry import propagate, context as otel_context
|
|
161
|
+
extracted_context = propagate.extract(carrier)
|
|
162
|
+
token = otel_context.attach(extracted_context)
|
|
163
|
+
span_attributes['message.has_trace_context'] = True
|
|
164
|
+
|
|
135
165
|
result = None
|
|
136
166
|
try:
|
|
137
|
-
# Increment
|
|
167
|
+
# Increment invocation counter
|
|
138
168
|
self.meter.GlobalMetrics.invocations.add(1, {'function': span_name})
|
|
139
169
|
|
|
140
|
-
#
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
170
|
+
# Create and execute within span
|
|
171
|
+
with self.tracer.start_span(
|
|
172
|
+
name=span_name,
|
|
173
|
+
attributes=span_attributes,
|
|
174
|
+
kind=kind
|
|
175
|
+
) as span:
|
|
176
|
+
# Add invocation start event
|
|
177
|
+
span.add_event("lambda.invocation.start", {
|
|
178
|
+
'event.type': type(event).__name__ if event else 'None'
|
|
179
|
+
})
|
|
144
180
|
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
# SNS format
|
|
151
|
-
extracted_context = self.extract_context(first_record)
|
|
152
|
-
|
|
153
|
-
# Create span - use extracted context if available
|
|
154
|
-
if extracted_context:
|
|
155
|
-
token = self.attach_context(extracted_context)
|
|
156
|
-
try:
|
|
157
|
-
with self.span(span_name, attributes=span_attributes, kind=kind) as span_context:
|
|
158
|
-
# Add event type as span event
|
|
159
|
-
if event is not None:
|
|
160
|
-
span_context.add_event("lambda.invocation.start",
|
|
161
|
-
attributes={"event.type": type(event).__name__})
|
|
162
|
-
|
|
163
|
-
result = func(event, context) if event is not None else func()
|
|
164
|
-
|
|
165
|
-
# Handle result
|
|
166
|
-
self._process_lambda_result(result, span_context, span_name)
|
|
167
|
-
finally:
|
|
168
|
-
self.detach_context(token)
|
|
169
|
-
else:
|
|
170
|
-
# No context extraction needed
|
|
171
|
-
with self.span(span_name, attributes=span_attributes, kind=kind) as span_context:
|
|
172
|
-
# Add event type as span event
|
|
173
|
-
if event is not None:
|
|
174
|
-
span_context.add_event("lambda.invocation.start",
|
|
175
|
-
attributes={"event.type": type(event).__name__})
|
|
176
|
-
|
|
177
|
-
result = func(event, context) if event is not None else func()
|
|
178
|
-
|
|
179
|
-
# Handle result
|
|
180
|
-
self._process_lambda_result(result, span_context, span_name)
|
|
181
|
+
# Execute handler
|
|
182
|
+
result = func(event, lambda_context)
|
|
183
|
+
|
|
184
|
+
# Process result
|
|
185
|
+
self._process_lambda_result(result, span, span_name)
|
|
181
186
|
|
|
182
187
|
return result
|
|
183
188
|
|
|
184
189
|
except Exception as e:
|
|
185
190
|
# Increment error counter
|
|
186
|
-
self.meter.GlobalMetrics.error_invocations.add(1, {
|
|
191
|
+
self.meter.GlobalMetrics.error_invocations.add(1, {
|
|
192
|
+
'function': span_name,
|
|
193
|
+
'error': type(e).__name__
|
|
194
|
+
})
|
|
187
195
|
|
|
188
|
-
# Log error
|
|
196
|
+
# Log error
|
|
189
197
|
self.logger.logger.error(f"Lambda execution failed: {e}", exc_info=True)
|
|
190
198
|
raise
|
|
191
199
|
|
|
192
200
|
finally:
|
|
201
|
+
# Always detach context if we attached it
|
|
202
|
+
if token is not None:
|
|
203
|
+
from opentelemetry import context as otel_context
|
|
204
|
+
otel_context.detach(token)
|
|
205
|
+
|
|
193
206
|
# Record duration
|
|
194
|
-
duration = (datetime.now() -
|
|
207
|
+
duration = (datetime.now() - start_time).total_seconds() * 1000
|
|
195
208
|
self.meter.GlobalMetrics.duration.record(duration, {'function': span_name})
|
|
196
209
|
|
|
210
|
+
# Force flush if enabled
|
|
197
211
|
if auto_flush:
|
|
198
|
-
self.
|
|
212
|
+
self.logger.logger.info(f"[OTEL] Lambda '{span_name}' completed in {duration:.2f}ms, flushing...")
|
|
213
|
+
flush_success = self.force_flush(timeout_millis=1000)
|
|
214
|
+
if not flush_success:
|
|
215
|
+
self.logger.logger.warning("[OTEL] Force flush may not have completed fully")
|
|
199
216
|
|
|
200
217
|
return wrapper
|
|
201
218
|
return decorator
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
rebrandly_otel/__init__.py,sha256=NUlroPhnHAKVC_q2BiyhtURXw23w1YY1BJd45gtc9qM,275
|
|
2
|
+
rebrandly_otel/logs.py,sha256=92jaxzI5hCHnKHu3lsSAa7K_SPHQgL46AlQUESsYNds,3724
|
|
3
|
+
rebrandly_otel/metrics.py,sha256=57jwrn8e1u66BOO7fcFrmtE3Rpt4VDixG9I78K-zrUU,8537
|
|
4
|
+
rebrandly_otel/otel_utils.py,sha256=uJmfz2NspSnTVJXGKoaLUl1CYb0ow6VHKjmg2d_rdwg,1704
|
|
5
|
+
rebrandly_otel/rebrandly_otel.py,sha256=KwUWW1kiWZrB9B2xwioBsA_c-Xm4YoH51_HyX6HBvQY,21778
|
|
6
|
+
rebrandly_otel/traces.py,sha256=v582WtJv3t4Bn92vlDyZouibHtgWNxdRo_XmQCmSOEA,7126
|
|
7
|
+
rebrandly_otel-0.1.14.dist-info/licenses/LICENSE,sha256=KMXHvTwP62S2q-SG7CFfMU_09rUwxiqlM0izaYGdcgY,1103
|
|
8
|
+
rebrandly_otel-0.1.14.dist-info/METADATA,sha256=tfOB74T9zcU5aXOj3Rw6bHChrd9-wexzkq7FqQUWptY,9628
|
|
9
|
+
rebrandly_otel-0.1.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
+
rebrandly_otel-0.1.14.dist-info/top_level.txt,sha256=26PSC1gjVUl8tTH5QfKbFevjVV4E2yojoukEfiTScvM,15
|
|
11
|
+
rebrandly_otel-0.1.14.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
rebrandly_otel/__init__.py,sha256=AHcEKWq4KRafIF_x_Y8jiIQ5crNG1nbEwdnlGaEP6js,287
|
|
2
|
-
rebrandly_otel/logs.py,sha256=92jaxzI5hCHnKHu3lsSAa7K_SPHQgL46AlQUESsYNds,3724
|
|
3
|
-
rebrandly_otel/metrics.py,sha256=57jwrn8e1u66BOO7fcFrmtE3Rpt4VDixG9I78K-zrUU,8537
|
|
4
|
-
rebrandly_otel/otel_utils.py,sha256=uJmfz2NspSnTVJXGKoaLUl1CYb0ow6VHKjmg2d_rdwg,1704
|
|
5
|
-
rebrandly_otel/rebrandly_otel.py,sha256=LwzBVY67N12X--8js8yFixusFs7T--1BVog0jOVds4k,20790
|
|
6
|
-
rebrandly_otel/traces.py,sha256=v582WtJv3t4Bn92vlDyZouibHtgWNxdRo_XmQCmSOEA,7126
|
|
7
|
-
rebrandly_otel-0.1.11.dist-info/licenses/LICENSE,sha256=KMXHvTwP62S2q-SG7CFfMU_09rUwxiqlM0izaYGdcgY,1103
|
|
8
|
-
rebrandly_otel-0.1.11.dist-info/METADATA,sha256=aRJJR4nhuJiocpBS1hpXuIWpUv-KEX0R_b3wkq7ns3g,9628
|
|
9
|
-
rebrandly_otel-0.1.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
-
rebrandly_otel-0.1.11.dist-info/top_level.txt,sha256=26PSC1gjVUl8tTH5QfKbFevjVV4E2yojoukEfiTScvM,15
|
|
11
|
-
rebrandly_otel-0.1.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|