robotframework-tracer 0.2.1__py3-none-any.whl → 0.2.2__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.
- robotframework_tracer/listener.py +43 -55
- robotframework_tracer/span_builder.py +2 -2
- robotframework_tracer/version.py +1 -1
- {robotframework_tracer-0.2.1.dist-info → robotframework_tracer-0.2.2.dist-info}/METADATA +12 -1
- robotframework_tracer-0.2.2.dist-info/RECORD +10 -0
- {robotframework_tracer-0.2.1.dist-info → robotframework_tracer-0.2.2.dist-info}/WHEEL +1 -1
- robotframework_tracer-0.2.1.dist-info/RECORD +0 -10
- {robotframework_tracer-0.2.1.dist-info → robotframework_tracer-0.2.2.dist-info}/top_level.txt +0 -0
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import platform
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
import robot
|
|
1
5
|
from opentelemetry import trace
|
|
2
6
|
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPExporter
|
|
3
|
-
from opentelemetry.
|
|
7
|
+
from opentelemetry.propagate import inject
|
|
8
|
+
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
|
4
9
|
from opentelemetry.sdk.trace import TracerProvider
|
|
5
10
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
6
|
-
from opentelemetry.sdk.trace.sampling import
|
|
11
|
+
from opentelemetry.sdk.trace.sampling import ParentBased, TraceIdRatioBased
|
|
7
12
|
from opentelemetry.semconv.resource import ResourceAttributes
|
|
8
|
-
from opentelemetry.propagate import inject
|
|
9
|
-
import platform
|
|
10
|
-
import sys
|
|
11
|
-
import robot
|
|
12
13
|
|
|
13
14
|
from .config import TracerConfig
|
|
14
15
|
from .span_builder import SpanBuilder
|
|
@@ -37,57 +38,20 @@ class TracingListener:
|
|
|
37
38
|
|
|
38
39
|
ROBOT_LISTENER_API_VERSION = 3
|
|
39
40
|
|
|
40
|
-
def __init__(
|
|
41
|
-
self,
|
|
42
|
-
endpoint=None,
|
|
43
|
-
service_name=None,
|
|
44
|
-
protocol=None,
|
|
45
|
-
capture_arguments=None,
|
|
46
|
-
max_arg_length=None,
|
|
47
|
-
capture_logs=None,
|
|
48
|
-
sample_rate=None,
|
|
49
|
-
span_prefix_style=None,
|
|
50
|
-
log_level=None,
|
|
51
|
-
max_log_length=None,
|
|
52
|
-
):
|
|
41
|
+
def __init__(self, *args, **kwargs):
|
|
53
42
|
"""Initialize the tracing listener.
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
sample_rate: Sampling rate (0.0-1.0)
|
|
63
|
-
span_prefix_style: Span prefix style (none, text, emoji)
|
|
64
|
-
log_level: Minimum log level to capture (DEBUG, INFO, WARN, ERROR)
|
|
65
|
-
max_log_length: Maximum length for log messages
|
|
44
|
+
Accepts arguments in multiple formats:
|
|
45
|
+
- Environment variables (recommended): OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME
|
|
46
|
+
- Keyword arguments: endpoint=..., service_name=...
|
|
47
|
+
- RF listener args: key=value pairs (comma-separated)
|
|
48
|
+
|
|
49
|
+
Note: Robot Framework splits listener arguments on ':' which breaks URLs.
|
|
50
|
+
This listener automatically reconstructs URLs that were split.
|
|
66
51
|
"""
|
|
67
|
-
|
|
68
|
-
kwargs
|
|
69
|
-
|
|
70
|
-
kwargs["endpoint"] = endpoint
|
|
71
|
-
if service_name is not None:
|
|
72
|
-
kwargs["service_name"] = service_name
|
|
73
|
-
if protocol is not None:
|
|
74
|
-
kwargs["protocol"] = protocol
|
|
75
|
-
if capture_arguments is not None:
|
|
76
|
-
kwargs["capture_arguments"] = capture_arguments
|
|
77
|
-
if max_arg_length is not None:
|
|
78
|
-
kwargs["max_arg_length"] = max_arg_length
|
|
79
|
-
if capture_logs is not None:
|
|
80
|
-
kwargs["capture_logs"] = capture_logs
|
|
81
|
-
if sample_rate is not None:
|
|
82
|
-
kwargs["sample_rate"] = sample_rate
|
|
83
|
-
if span_prefix_style is not None:
|
|
84
|
-
kwargs["span_prefix_style"] = span_prefix_style
|
|
85
|
-
if log_level is not None:
|
|
86
|
-
kwargs["log_level"] = log_level
|
|
87
|
-
if max_log_length is not None:
|
|
88
|
-
kwargs["max_log_length"] = max_log_length
|
|
89
|
-
|
|
90
|
-
self.config = TracerConfig(**kwargs)
|
|
52
|
+
parsed_kwargs = self._parse_listener_args(args)
|
|
53
|
+
parsed_kwargs.update(kwargs)
|
|
54
|
+
self.config = TracerConfig(**parsed_kwargs)
|
|
91
55
|
|
|
92
56
|
# Initialize OpenTelemetry with automatic resource detection
|
|
93
57
|
resource_attrs = {
|
|
@@ -130,6 +94,30 @@ class TracingListener:
|
|
|
130
94
|
self.tracer = trace.get_tracer(__name__)
|
|
131
95
|
self.span_stack = []
|
|
132
96
|
|
|
97
|
+
@staticmethod
|
|
98
|
+
def _parse_listener_args(args):
|
|
99
|
+
"""Parse Robot Framework listener arguments.
|
|
100
|
+
|
|
101
|
+
RF splits arguments on ':' which breaks URLs like http://host:port.
|
|
102
|
+
This method reconstructs the original string and parses key=value pairs.
|
|
103
|
+
"""
|
|
104
|
+
if not args:
|
|
105
|
+
return {}
|
|
106
|
+
|
|
107
|
+
import re
|
|
108
|
+
|
|
109
|
+
# Rejoin with ':' to reconstruct original (RF splits on ':')
|
|
110
|
+
rejoined = ":".join(args)
|
|
111
|
+
|
|
112
|
+
# Match: key=value where value may contain URLs (stops at comma+key= or end)
|
|
113
|
+
kwargs = {}
|
|
114
|
+
pattern = r"(\w+)=([^,]*?)(?=,\w+=|$)"
|
|
115
|
+
for match in re.finditer(pattern, rejoined):
|
|
116
|
+
key, value = match.groups()
|
|
117
|
+
kwargs[key.strip()] = value.strip()
|
|
118
|
+
|
|
119
|
+
return kwargs
|
|
120
|
+
|
|
133
121
|
def _set_trace_context_variables(self):
|
|
134
122
|
"""Set Robot Framework variables with current trace context."""
|
|
135
123
|
if not BUILTIN_AVAILABLE:
|
|
@@ -170,7 +158,7 @@ class TracingListener:
|
|
|
170
158
|
if headers.get("tracestate"):
|
|
171
159
|
builtin.set_test_variable("${TRACESTATE}", headers["tracestate"])
|
|
172
160
|
|
|
173
|
-
except Exception
|
|
161
|
+
except Exception:
|
|
174
162
|
# Silently ignore errors to avoid breaking tests
|
|
175
163
|
pass
|
|
176
164
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from opentelemetry import trace, baggage
|
|
2
|
-
from opentelemetry.trace import Status, StatusCode
|
|
3
1
|
import robot
|
|
2
|
+
from opentelemetry import baggage, trace
|
|
3
|
+
from opentelemetry.trace import Status, StatusCode
|
|
4
4
|
|
|
5
5
|
from .attributes import AttributeExtractor, RFAttributes
|
|
6
6
|
|
robotframework_tracer/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.2.
|
|
1
|
+
__version__ = "0.2.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: robotframework-tracer
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: OpenTelemetry distributed tracing for Robot Framework
|
|
5
5
|
Author: Robot Framework Tracer Contributors
|
|
6
6
|
License: Apache-2.0
|
|
@@ -108,9 +108,20 @@ docker run -d --name jaeger \
|
|
|
108
108
|
### 2. Run your tests with the listener
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
|
+
# Basic usage (uses default endpoint localhost:4318)
|
|
111
112
|
robot --listener robotframework_tracer.TracingListener tests/
|
|
113
|
+
|
|
114
|
+
# With environment variables (recommended for custom endpoints)
|
|
115
|
+
export OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318/v1/traces
|
|
116
|
+
export OTEL_SERVICE_NAME=my-tests
|
|
117
|
+
robot --listener robotframework_tracer.TracingListener tests/
|
|
118
|
+
|
|
119
|
+
# With inline options (comma-separated key=value pairs)
|
|
120
|
+
robot --listener "robotframework_tracer.TracingListener:service_name=my-tests,capture_logs=true" tests/
|
|
112
121
|
```
|
|
113
122
|
|
|
123
|
+
> **Note:** Robot Framework splits listener arguments on `:`. URLs containing `://` are automatically reconstructed by the listener.
|
|
124
|
+
|
|
114
125
|
### 3. View traces
|
|
115
126
|
|
|
116
127
|
Open http://localhost:16686 in your browser to see your test traces in Jaeger UI.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
robotframework_tracer/__init__.py,sha256=cZh3xnNaYhRisrqqWH5Gdt4zsgpbh1mUALJiUtGNG8M,204
|
|
2
|
+
robotframework_tracer/attributes.py,sha256=_pDHYBJs4QLrnR3Sms7_QyM9IGYHSjZekr-8fkAosBo,3806
|
|
3
|
+
robotframework_tracer/config.py,sha256=4Dis_UlhSaXkO4ln2VeAMIyvFBy_BD3Og9lI9MWXpnA,2530
|
|
4
|
+
robotframework_tracer/listener.py,sha256=1GzNKvzaZnkFAsXeSBR80XXYI69ApzN_A2G3Ol6r8kI,11388
|
|
5
|
+
robotframework_tracer/span_builder.py,sha256=4c3bOpUgVwSPoM3bh3Hl0Dfq2BxOWs_GQsFh9lvE7r8,4836
|
|
6
|
+
robotframework_tracer/version.py,sha256=m6kyaNpwBcP1XYcqrelX2oS3PJuOnElOcRdBa9pEb8c,22
|
|
7
|
+
robotframework_tracer-0.2.2.dist-info/METADATA,sha256=1QAHLrTVMk7Qof4FD48jfs8jYHF7CLa0R7EcYzcOCxk,9190
|
|
8
|
+
robotframework_tracer-0.2.2.dist-info/WHEEL,sha256=WnJ8fYhv8N4SYVK2lLYNI6N0kVATA7b0piVUNvqIIJE,91
|
|
9
|
+
robotframework_tracer-0.2.2.dist-info/top_level.txt,sha256=G1sMKH-8SM_CdJe0Wm6wa_rg1uo62jfhft_UfaxZ05I,22
|
|
10
|
+
robotframework_tracer-0.2.2.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
robotframework_tracer/__init__.py,sha256=cZh3xnNaYhRisrqqWH5Gdt4zsgpbh1mUALJiUtGNG8M,204
|
|
2
|
-
robotframework_tracer/attributes.py,sha256=_pDHYBJs4QLrnR3Sms7_QyM9IGYHSjZekr-8fkAosBo,3806
|
|
3
|
-
robotframework_tracer/config.py,sha256=4Dis_UlhSaXkO4ln2VeAMIyvFBy_BD3Og9lI9MWXpnA,2530
|
|
4
|
-
robotframework_tracer/listener.py,sha256=WTrK7cNa5hfrru8BpPiu8GCQVzyITtctudFyNAdoPfA,11940
|
|
5
|
-
robotframework_tracer/span_builder.py,sha256=BT6D-fnfwvjGhQihfrg0-BGcZ3EJnEN_bjaTwDHPIqg,4836
|
|
6
|
-
robotframework_tracer/version.py,sha256=HfjVOrpTnmZ-xVFCYSVmX50EXaBQeJteUHG-PD6iQs8,22
|
|
7
|
-
robotframework_tracer-0.2.1.dist-info/METADATA,sha256=_BlwNqM8YeoIGI3V_PuUImCyH3IetyndNXtSJm4yZjA,8617
|
|
8
|
-
robotframework_tracer-0.2.1.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
9
|
-
robotframework_tracer-0.2.1.dist-info/top_level.txt,sha256=G1sMKH-8SM_CdJe0Wm6wa_rg1uo62jfhft_UfaxZ05I,22
|
|
10
|
-
robotframework_tracer-0.2.1.dist-info/RECORD,,
|
{robotframework_tracer-0.2.1.dist-info → robotframework_tracer-0.2.2.dist-info}/top_level.txt
RENAMED
|
File without changes
|