otlp-test-data 0.9.4__py3-none-any.whl → 0.10.0__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.
@@ -0,0 +1,192 @@
1
+ from __future__ import annotations
2
+
3
+ import base64
4
+ import dataclasses
5
+ import json
6
+ import random
7
+ from typing import Sequence, TYPE_CHECKING
8
+ from typing_extensions import reveal_type as reveal_type # temp
9
+
10
+ import freezegun
11
+ import opentelemetry.trace
12
+ from google.protobuf.json_format import MessageToDict
13
+ from opentelemetry.exporter.otlp.proto.common._internal import trace_encoder
14
+ from opentelemetry.sdk.trace import TracerProvider
15
+ from opentelemetry.sdk.trace.export import SimpleSpanProcessor
16
+ from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
17
+ from opentelemetry.sdk.resources import Resource
18
+ from opentelemetry.trace import set_tracer_provider, get_tracer_provider
19
+
20
+ if TYPE_CHECKING:
21
+ from google.protobuf.message import Message
22
+ from opentelemetry.sdk.trace import ReadableSpan
23
+ from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (
24
+ ExportTraceServiceRequest,
25
+ )
26
+
27
+
28
+ tracer = opentelemetry.trace.get_tracer(__name__)
29
+ provider = TracerProvider()
30
+ exporter = InMemorySpanExporter()
31
+ provider.add_span_processor(SimpleSpanProcessor(exporter))
32
+ set_tracer_provider(provider)
33
+
34
+
35
+ @dataclasses.dataclass
36
+ class Config:
37
+ start_time: str = "2020-01-01 00:00:00Z"
38
+ random_seed: int = 42
39
+
40
+
41
+ time: freezegun.api.FrozenDateTimeFactory = None # type: ignore
42
+
43
+
44
+ def sample_proto(config: Config | None = None) -> bytes:
45
+ return _proto_to_bytes(_spans_to_proto_object(sample_spans(config)))
46
+
47
+
48
+ def sample_json(config: Config | None = None) -> bytes:
49
+ return _proto_to_json(_spans_to_proto_object(sample_spans(config)))
50
+
51
+
52
+ def sample_spans(config: Config | None = None) -> Sequence[ReadableSpan]:
53
+ """Creates and finishes two spans, then returns them as a list."""
54
+ global time
55
+ config = config or Config()
56
+ resource = Resource.create(
57
+ attributes={
58
+ "service.namespace": "1234-1234", # a unique id
59
+ "service.name": "my-service",
60
+ "service.instance.id": "123",
61
+ "int": 42,
62
+ "float": 3.14,
63
+ "bool": False,
64
+ "str": "sss",
65
+ "ints": [42, 0],
66
+ "floats": [3.14, 2.72],
67
+ "strs": ["sss", "shh"],
68
+ }
69
+ )
70
+ del exporter._finished_spans[:]
71
+ get_tracer_provider()._resource = resource # type: ignore
72
+
73
+ random.seed(config.random_seed)
74
+
75
+ with freezegun.freeze_time(config.start_time) as time: # type: ignore
76
+ workload()
77
+
78
+ return exporter.get_finished_spans()
79
+
80
+
81
+ def _spans_to_proto_object(spans: Sequence[ReadableSpan]) -> ExportTraceServiceRequest:
82
+ return trace_encoder.encode_spans(spans)
83
+
84
+
85
+ def _proto_to_bytes(data: Message) -> bytes:
86
+ return data.SerializePartialToString()
87
+
88
+
89
+ # FIXME: there are probably 3 different enumerated types in the API
90
+ def _proto_to_json(data: Message) -> bytes:
91
+ dic = MessageToDict(data)
92
+
93
+ for rs in dic["resourceSpans"]:
94
+ for ss in rs["scopeSpans"]:
95
+ for sp in ss["spans"]:
96
+ for k in "parentSpanId spanId traceId".split():
97
+ if k in sp:
98
+ sp[k] = base64.b64decode(sp[k]).hex()
99
+ sp["kind"] = {
100
+ "SPAN_KIND_UNSPECIFIED": 0,
101
+ "SPAN_KIND_INTERNAL": 1,
102
+ "SPAN_KIND_SERVER": 2,
103
+ "SPAN_KIND_CLIENT": 3,
104
+ "SPAN_KIND_PRODUCER": 4,
105
+ "SPAN_KIND_CONSUMER": 5,
106
+ }[sp["kind"]]
107
+
108
+ return json.dumps(dic).encode("utf-8")
109
+
110
+
111
+ def workload():
112
+ series_of_spans()
113
+ # nested_spans()
114
+ # attribute_types()
115
+ # repeated_attributes()
116
+ # events()
117
+
118
+
119
+ def series_of_spans():
120
+ with tracer.start_as_current_span("span-one") as one:
121
+ one.set_attribute("count", "one")
122
+ time.tick()
123
+
124
+ with tracer.start_as_current_span("span-two") as two:
125
+ two.set_attribute("count", "two")
126
+ time.tick()
127
+
128
+
129
+ def nested_spans():
130
+ outer()
131
+
132
+
133
+ @tracer.start_as_current_span("outer")
134
+ def outer():
135
+ time.tick()
136
+ inner()
137
+ time.tick()
138
+
139
+
140
+ @tracer.start_as_current_span("inner")
141
+ def inner():
142
+ opentelemetry.trace.get_current_span().set_attribute("an-attribute", 42)
143
+ time.tick()
144
+
145
+
146
+ def attribute_types():
147
+ with tracer.start_as_current_span("attribute-types") as span:
148
+ span.set_attributes(
149
+ {"int": 42, "bool": False, "float": 3.14, "str": "string-cheese"}
150
+ )
151
+ span.set_attributes(
152
+ {
153
+ "ints": [1, 42],
154
+ "bools": [True, False],
155
+ "floats": [2.72, 3.14],
156
+ "strs": ["string-cheese", "strung-cheese"],
157
+ }
158
+ )
159
+
160
+
161
+ def repeated_attributes():
162
+ with tracer.start_as_current_span("attribute-types") as span:
163
+ span.set_attribute("int", 42)
164
+ span.set_attribute("int", 99)
165
+
166
+ with tracer.start_as_current_span("attribute-types") as span:
167
+ span.set_attributes({"int": 42})
168
+ span.set_attributes({"int": 99})
169
+
170
+
171
+ def events():
172
+ with tracer.start_as_current_span("attribute-types") as span:
173
+ span.add_event("first event")
174
+ time.tick()
175
+
176
+ span.add_event("second event")
177
+ time.tick()
178
+
179
+ span.add_event(
180
+ "event with attributes",
181
+ attributes={
182
+ "int": 42,
183
+ "bool": False,
184
+ "float": 3.14,
185
+ "str": "string-cheese",
186
+ "ints": [1, 42],
187
+ "bools": [True, False],
188
+ "floats": [2.72, 3.14],
189
+ "strs": ["string-cheese", "strung-cheese"],
190
+ },
191
+ )
192
+ time.tick()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otlp-test-data
3
- Version: 0.9.4
3
+ Version: 0.10.0
4
4
  Summary: Produces OTLP data using OTEL instrumentation
5
5
  Classifier: Development Status :: 3 - Alpha
6
6
  Classifier: Framework :: OpenTelemetry
@@ -37,9 +37,10 @@ Produces OTLP data using OTEL instrumentation.
37
37
 
38
38
  ### Features
39
39
 
40
- - fixed, configurable timestamps
40
+ - Fixed, configurable timestamps
41
41
  - aims to cover as much of OTEL API as possible
42
- - aims to cover all valid data types
42
+ - Cover all valid data types
43
+ - Events
43
44
 
44
45
  ### Limitations
45
46
 
@@ -48,7 +49,8 @@ Produces OTLP data using OTEL instrumentation.
48
49
 
49
50
  ### TODO
50
51
 
51
- - Events
52
52
  - Links
53
53
  - Baggage
54
54
  - Schemata, when https://github.com/open-telemetry/opentelemetry-python/pull/4359 lands
55
+ - Attribute value type coercion, e.g. `class Str(str): ...` and objects with `__str__(self)`.
56
+ - Exceptions
@@ -0,0 +1,4 @@
1
+ otlp_test_data/__init__.py,sha256=7GjDanu2fUzjJDGcwmc9c3sk30HagEcwKChAdWdP42o,5551
2
+ otlp_test_data-0.10.0.dist-info/METADATA,sha256=zOkJOyrE3uWsBPC_HMZ5RVJ4lN0V1W-MTrfIVY88HFk,2112
3
+ otlp_test_data-0.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
4
+ otlp_test_data-0.10.0.dist-info/RECORD,,
@@ -1,4 +0,0 @@
1
- otlp_test_data.py,sha256=AddLeT3jimGkpm9ejMpk64VpP1GzBh5JS9gOlPAa-G0,3091
2
- otlp_test_data-0.9.4.dist-info/METADATA,sha256=MBAd2l_5Si7lmLjz8fy9LYaUhGDnfnF7FRn0TEHUPmA,2012
3
- otlp_test_data-0.9.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
4
- otlp_test_data-0.9.4.dist-info/RECORD,,
otlp_test_data.py DELETED
@@ -1,95 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import base64
4
- import dataclasses
5
- import json
6
- import random
7
- from typing import Sequence, TYPE_CHECKING
8
- from typing_extensions import reveal_type as reveal_type # temp
9
-
10
- import freezegun
11
- from google.protobuf.json_format import MessageToDict
12
- from opentelemetry.exporter.otlp.proto.common._internal import trace_encoder
13
- from opentelemetry.sdk.trace import TracerProvider
14
- from opentelemetry.sdk.trace.export import SimpleSpanProcessor
15
- from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
16
-
17
- if TYPE_CHECKING:
18
- from google.protobuf.message import Message
19
- from opentelemetry.sdk.trace import ReadableSpan
20
- from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (
21
- ExportTraceServiceRequest,
22
- )
23
-
24
-
25
- @dataclasses.dataclass
26
- class Config:
27
- start_time: str = "2020-01-01 00:00:00Z"
28
- random_seed: int = 42
29
-
30
-
31
- time = None
32
-
33
-
34
- def sample_proto(config: Config | None = None) -> bytes:
35
- return _proto_to_bytes(_spans_to_proto_object(sample_spans(config)))
36
-
37
-
38
- def sample_json(config: Config | None = None) -> bytes:
39
- return _proto_to_json(_spans_to_proto_object(sample_spans(config)))
40
-
41
-
42
- def sample_spans(config: Config | None = None) -> Sequence[ReadableSpan]:
43
- """Creates and finishes two spans, then returns them as a list."""
44
- global time
45
- config = config or Config()
46
- tracer_provider = TracerProvider()
47
- exporter = InMemorySpanExporter()
48
- tracer_provider.add_span_processor(SimpleSpanProcessor(exporter))
49
- tracer = tracer_provider.get_tracer(__name__)
50
-
51
- with freezegun.freeze_time(config.start_time) as time:
52
- random.seed(config.random_seed)
53
-
54
- # FIXME the workload section is expected to grow a lot
55
- # TODO: attributes
56
- # bool, int, float, str
57
- # list[bool], ...
58
- # tuple[bool], ...
59
- # Sequence[bool], ... (maybe)
60
- with tracer.start_as_current_span("span-one"):
61
- time.tick()
62
- with tracer.start_as_current_span("span-two"):
63
- time.tick()
64
-
65
- return exporter.get_finished_spans()
66
-
67
-
68
- def _spans_to_proto_object(spans: Sequence[ReadableSpan]) -> ExportTraceServiceRequest:
69
- return trace_encoder.encode_spans(spans)
70
-
71
-
72
- def _proto_to_bytes(data: Message) -> bytes:
73
- return data.SerializePartialToString()
74
-
75
-
76
- # FIXME: there are probably 3 different enumerated types in the API
77
- def _proto_to_json(data: Message) -> bytes:
78
- dic = MessageToDict(data)
79
-
80
- for rs in dic["resourceSpans"]:
81
- for ss in rs["scopeSpans"]:
82
- for sp in ss["spans"]:
83
- for k in "parentSpanId spanId traceId".split():
84
- if k in sp:
85
- sp[k] = base64.b64decode(sp[k]).hex()
86
- sp["kind"] = {
87
- "SPAN_KIND_UNSPECIFIED": 0,
88
- "SPAN_KIND_INTERNAL": 1,
89
- "SPAN_KIND_SERVER": 2,
90
- "SPAN_KIND_CLIENT": 3,
91
- "SPAN_KIND_PRODUCER": 4,
92
- "SPAN_KIND_CONSUMER": 5,
93
- }[sp["kind"]]
94
-
95
- return json.dumps(dic).encode("utf-8")