rebrandly-otel 0.1.10__tar.gz → 0.1.11__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 rebrandly-otel might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rebrandly_otel
3
- Version: 0.1.10
3
+ Version: 0.1.11
4
4
  Summary: Python OTEL wrapper by Rebrandly
5
5
  Home-page: https://github.com/rebrandly/rebrandly-otel-python
6
6
  Author: Antonio Romano
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rebrandly_otel
3
- Version: 0.1.10
3
+ Version: 0.1.11
4
4
  Summary: Python OTEL wrapper by Rebrandly
5
5
  Home-page: https://github.com/rebrandly/rebrandly-otel-python
6
6
  Author: Antonio Romano
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="rebrandly_otel",
8
- version="0.1.10",
8
+ version="0.1.11",
9
9
  author="Antonio Romano",
10
10
  author_email="antonio@rebrandly.com",
11
11
  description="Python OTEL wrapper by Rebrandly",
@@ -195,7 +195,6 @@ class RebrandlyOTEL:
195
195
  self.meter.GlobalMetrics.duration.record(duration, {'function': span_name})
196
196
 
197
197
  if auto_flush:
198
- self.logger.logger.info(f"[OTEL] Lambda handler '{span_name}' completed in {duration:.2f}ms, flushing telemetry...")
199
198
  self.force_flush(start_datetime=start_func)
200
199
 
201
200
  return wrapper
@@ -297,7 +296,6 @@ class RebrandlyOTEL:
297
296
 
298
297
  finally:
299
298
  if auto_flush:
300
- self.logger.logger.info(f"[OTEL] Lambda handler '{span_name}' completed, flushing telemetry...")
301
299
  self.force_flush(start_datetime=start_func)
302
300
 
303
301
  return wrapper
@@ -326,7 +324,7 @@ class RebrandlyOTEL:
326
324
  self.meter.GlobalMetrics.duration.record(duration, {'source': 'force_flush'})
327
325
  self.meter.GlobalMetrics.memory_usage_bytes.set(memory.used)
328
326
  self.meter.GlobalMetrics.cpu_usage_percentage.set(cpu_percent)
329
- self.logger.logger.info(f"[OTEL] Function duration: {duration}ms, Memory usage: {memory.percent}%, CPU usage: {cpu_percent}%")
327
+ self.logger.logger.info(f"Function duration: {duration}ms, Memory usage: {memory.percent}%, CPU usage: {cpu_percent}%")
330
328
 
331
329
  try:
332
330
  # Flush traces
@@ -364,9 +362,9 @@ class RebrandlyOTEL:
364
362
  self._meter.shutdown()
365
363
  if self._logger:
366
364
  self._logger.shutdown()
367
- self.logger.logger.info("[OTEL] Shutdown completed")
365
+ print("[OTEL] Shutdown completed")
368
366
  except Exception as e:
369
- self.logger.logger.info(f"[OTEL] Error during shutdown: {e}")
367
+ print(f"[OTEL] Error during shutdown: {e}")
370
368
 
371
369
  def _detect_lambda_trigger(self, event: Any) -> str:
372
370
  """Detect Lambda trigger type from event."""
@@ -435,43 +433,15 @@ class RebrandlyOTEL:
435
433
  message: Dict[str, Any]=None,
436
434
  attributes: Optional[Dict[str, Any]] = None,
437
435
  kind: SpanKind = SpanKind.CONSUMER):
438
- """Create span from AWS message with extracted context."""
439
- # Extract context from the message if it contains trace context
440
- token = None
441
- if message and isinstance(message, dict):
442
- carrier = {}
436
+ """Create span from AWS message - properly handling trace context."""
437
+
438
+ from opentelemetry import trace, context as otel_context
443
439
 
444
- # Check for trace context in different possible locations
445
- if 'MessageAttributes' in message:
446
- # SQS format
447
- for key, value in message.get('MessageAttributes', {}).items():
448
- if isinstance(value, dict) and 'StringValue' in value:
449
- carrier[key] = value['StringValue']
450
- elif 'Sns' in message and 'MessageAttributes' in message['Sns']:
451
- # SNS format - MessageAttributes are nested under 'Sns'
452
- for key, value in message['Sns'].get('MessageAttributes', {}).items():
453
- if isinstance(value, dict):
454
- # SNS uses 'Value' instead of 'StringValue'
455
- if 'Value' in value:
456
- carrier[key] = value['Value']
457
- elif 'StringValue' in value:
458
- carrier[key] = value['StringValue']
459
- elif 'messageAttributes' in message:
460
- # Alternative format
461
- for key, value in message.get('messageAttributes', {}).items():
462
- if isinstance(value, dict) and 'stringValue' in value:
463
- carrier[key] = value['stringValue']
464
-
465
- # If we found trace context, attach it
466
- if carrier:
467
- token = self.attach_context(carrier)
468
-
469
- # Create a span with the potentially extracted context
470
440
  combined_attributes = attributes or {}
471
441
 
472
- # Add message-specific attributes
442
+ # Extract message attributes for linking/attributes
473
443
  if message and isinstance(message, dict):
474
- # Add SNS-specific attributes
444
+ # Add message-specific attributes
475
445
  if 'Sns' in message:
476
446
  sns_msg = message['Sns']
477
447
  if 'MessageId' in sns_msg:
@@ -479,24 +449,40 @@ class RebrandlyOTEL:
479
449
  if 'TopicArn' in sns_msg:
480
450
  combined_attributes['messaging.destination'] = sns_msg['TopicArn']
481
451
  combined_attributes['messaging.system'] = 'aws_sns'
482
- # Add SQS-specific attributes
452
+
453
+ # Check for trace context in SNS
454
+ if 'MessageAttributes' in sns_msg:
455
+ for key, value in sns_msg['MessageAttributes'].items():
456
+ if key == 'traceparent' and 'Value' in value:
457
+ combined_attributes['message.traceparent'] = value['Value']
458
+ combined_attributes['message.has_trace_context'] = True
459
+
483
460
  elif 'messageId' in message:
461
+ # SQS message
484
462
  combined_attributes['messaging.message_id'] = message['messageId']
485
463
  if 'eventSource' in message:
486
464
  combined_attributes['messaging.system'] = message['eventSource']
487
465
 
488
- # Add common attributes
466
+ # Check for trace context in SQS
467
+ if 'MessageAttributes' in message or 'messageAttributes' in message:
468
+ attrs = message.get('MessageAttributes') or message.get('messageAttributes', {})
469
+ for key, value in attrs.items():
470
+ if key == 'traceparent':
471
+ tp_value = value.get('StringValue') or value.get('stringValue', '')
472
+ combined_attributes['message.traceparent'] = tp_value
473
+ combined_attributes['message.has_trace_context'] = True
474
+
489
475
  if 'awsRegion' in message:
490
476
  combined_attributes['cloud.region'] = message['awsRegion']
491
477
 
492
- try:
493
- # Use the regular span method which properly handles context
494
- with self.span(name, attributes=combined_attributes, kind=kind) as span:
495
- yield span
496
- finally:
497
- # Detach context if we attached one
498
- if token:
499
- self.detach_context(token)
478
+ # Use the tracer's start_span method directly to ensure it works
479
+ # This creates a child span of whatever is currently active
480
+ with self.tracer.start_span(
481
+ name=name,
482
+ attributes=combined_attributes,
483
+ kind=kind
484
+ ) as span:
485
+ yield span
500
486
 
501
487
 
502
488
  # Create Singleton instance
@@ -93,6 +93,7 @@ class RebrandlyTracer:
93
93
  attributes: Optional[Dict[str, Any]] = None,
94
94
  kind: trace.SpanKind = trace.SpanKind.INTERNAL) -> ContextManager[Span]:
95
95
  """Start a new span as the current span."""
96
+ # Ensure we use the tracer to create a child span of the current span
96
97
  with self.tracer.start_as_current_span(
97
98
  name,
98
99
  attributes=attributes,
File without changes