grpcio-observability 1.71.0__cp310-cp310-musllinux_1_1_aarch64.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,171 @@
1
+ # Copyright 2023 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from typing import AnyStr, Callable, Dict, Iterable, List, Optional
16
+
17
+ # pytype: disable=pyi-error
18
+ from grpc_observability import _open_telemetry_observability
19
+ from grpc_observability._observability import OptionalLabelType
20
+ from opentelemetry.metrics import MeterProvider
21
+
22
+ GRPC_METHOD_LABEL = "grpc.method"
23
+ GRPC_TARGET_LABEL = "grpc.target"
24
+ GRPC_CLIENT_METRIC_PREFIX = "grpc.client"
25
+ GRPC_OTHER_LABEL_VALUE = "other"
26
+
27
+
28
+ class OpenTelemetryLabelInjector:
29
+ """
30
+ An interface that allows you to add additional labels on the calls traced.
31
+ """
32
+
33
+ def get_labels_for_exchange(self) -> Dict[str, AnyStr]:
34
+ """
35
+ Get labels used for metadata exchange.
36
+
37
+ Returns:
38
+ A dict of labels, with a string as key representing label name, string or bytes
39
+ as value representing label value.
40
+ """
41
+ raise NotImplementedError()
42
+
43
+ def get_additional_labels(
44
+ self, include_exchange_labels: bool
45
+ ) -> Dict[str, str]:
46
+ """
47
+ Get additional labels added by this injector.
48
+
49
+ The return value from this method will be added directly to metric data.
50
+
51
+ Args:
52
+ include_exchange_labels: Whether to add additional metadata exchange related labels.
53
+
54
+ Returns:
55
+ A dict of labels.
56
+ """
57
+ raise NotImplementedError()
58
+
59
+ # pylint: disable=no-self-use
60
+ def deserialize_labels(
61
+ self, labels: Dict[str, AnyStr]
62
+ ) -> Dict[str, AnyStr]:
63
+ """
64
+ Deserialize the labels if required.
65
+
66
+ If this injector added labels for metadata exchange, this method will be called to
67
+ deserialize the exchanged labels.
68
+
69
+ For example, if this injector added xds_peer_metadata_label for exchange:
70
+
71
+ labels: {"labelA": b"valueA", "xds_peer_metadata_label": b"exchanged_bytes"}
72
+
73
+ This method should deserialize xds_peer_metadata_label and return labels as:
74
+
75
+ labels: {"labelA": b"valueA", "xds_label_A": "xds_label_A",
76
+ "xds_label_B": "xds_label_B"}
77
+
78
+ Returns:
79
+ A dict of deserialized labels.
80
+ """
81
+ return labels
82
+
83
+
84
+ class OpenTelemetryPluginOption:
85
+ """
86
+ An interface that allows you to add additional function to OpenTelemetryPlugin.
87
+ """
88
+
89
+
90
+ # pylint: disable=no-self-use
91
+ class OpenTelemetryPlugin:
92
+ """Describes a Plugin for OpenTelemetry observability."""
93
+
94
+ plugin_options: Iterable[OpenTelemetryPluginOption]
95
+ meter_provider: Optional[MeterProvider]
96
+ target_attribute_filter: Callable[[str], bool]
97
+ generic_method_attribute_filter: Callable[[str], bool]
98
+ _plugins: List[_open_telemetry_observability._OpenTelemetryPlugin]
99
+
100
+ def __init__(
101
+ self,
102
+ *,
103
+ plugin_options: Iterable[OpenTelemetryPluginOption] = [],
104
+ meter_provider: Optional[MeterProvider] = None,
105
+ target_attribute_filter: Optional[Callable[[str], bool]] = None,
106
+ generic_method_attribute_filter: Optional[Callable[[str], bool]] = None,
107
+ ):
108
+ """
109
+ Args:
110
+ plugin_options: An Iterable of OpenTelemetryPluginOption which will be
111
+ enabled for this OpenTelemetryPlugin.
112
+ meter_provider: A MeterProvider which will be used to collect telemetry data,
113
+ or None which means no metrics will be collected.
114
+ target_attribute_filter: [DEPRECATED] This attribute is deprecated and should
115
+ not be used.
116
+ Once provided, this will be called per channel to decide whether to record the
117
+ target attribute on client or to replace it with "other".
118
+ This helps reduce the cardinality on metrics in cases where many channels
119
+ are created with different targets in the same binary (which might happen
120
+ for example, if the channel target string uses IP addresses directly).
121
+ Return True means the original target string will be used, False means target string
122
+ will be replaced with "other".
123
+ generic_method_attribute_filter: Once provided, this will be called with a generic
124
+ method type to decide whether to record the method name or to replace it with
125
+ "other". Note that pre-registered methods will always be recorded no matter what
126
+ this function returns.
127
+ Return True means the original method name will be used, False means method name will
128
+ be replaced with "other".
129
+ """
130
+ self.plugin_options = plugin_options
131
+ self.meter_provider = meter_provider
132
+ self.target_attribute_filter = target_attribute_filter or (
133
+ lambda target: True
134
+ )
135
+ self.generic_method_attribute_filter = (
136
+ generic_method_attribute_filter or (lambda target: False)
137
+ )
138
+ self._plugins = [
139
+ _open_telemetry_observability._OpenTelemetryPlugin(self)
140
+ ]
141
+
142
+ def register_global(self) -> None:
143
+ """
144
+ Registers a global plugin that acts on all channels and servers running on the process.
145
+
146
+ Raises:
147
+ RuntimeError: If a global plugin was already registered.
148
+ """
149
+ _open_telemetry_observability.start_open_telemetry_observability(
150
+ plugins=self._plugins
151
+ )
152
+
153
+ def deregister_global(self) -> None:
154
+ """
155
+ De-register the global plugin that acts on all channels and servers running on the process.
156
+
157
+ Raises:
158
+ RuntimeError: If no global plugin was registered.
159
+ """
160
+ _open_telemetry_observability.end_open_telemetry_observability()
161
+
162
+ def __enter__(self) -> None:
163
+ _open_telemetry_observability.start_open_telemetry_observability(
164
+ plugins=self._plugins
165
+ )
166
+
167
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
168
+ _open_telemetry_observability.end_open_telemetry_observability()
169
+
170
+ def _get_enabled_optional_labels(self) -> List[OptionalLabelType]:
171
+ return []
@@ -0,0 +1,287 @@
1
+ # Copyright 2023 gRPC authors.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from typing import Mapping
16
+
17
+ from grpc_observability import _measures
18
+ from grpc_observability._cyobservability import MetricsName
19
+ from opencensus.stats import aggregation
20
+ from opencensus.stats import view as view_module
21
+ from opencensus.tags.tag_key import TagKey
22
+
23
+ METRICS_NAME_TO_MEASURE = {
24
+ MetricsName.CLIENT_STARTED_RPCS: _measures.CLIENT_STARTED_RPCS_MEASURE,
25
+ MetricsName.CLIENT_ROUNDTRIP_LATENCY: _measures.CLIENT_ROUNDTRIP_LATENCY_MEASURE,
26
+ MetricsName.CLIENT_COMPLETED_RPC: _measures.CLIENT_COMPLETED_RPCS_MEASURE,
27
+ MetricsName.CLIENT_API_LATENCY: _measures.CLIENT_API_LATENCY_MEASURE,
28
+ MetricsName.CLIENT_SEND_BYTES_PER_RPC: _measures.CLIENT_SEND_BYTES_PER_RPC_MEASURE,
29
+ MetricsName.CLIENT_RECEIVED_BYTES_PER_RPC: _measures.CLIENT_RECEIVED_BYTES_PER_RPC_MEASURE,
30
+ MetricsName.SERVER_STARTED_RPCS: _measures.SERVER_STARTED_RPCS_MEASURE,
31
+ MetricsName.SERVER_SENT_BYTES_PER_RPC: _measures.SERVER_SENT_BYTES_PER_RPC_MEASURE,
32
+ MetricsName.SERVER_RECEIVED_BYTES_PER_RPC: _measures.SERVER_RECEIVED_BYTES_PER_RPC_MEASURE,
33
+ MetricsName.SERVER_SERVER_LATENCY: _measures.SERVER_SERVER_LATENCY_MEASURE,
34
+ MetricsName.SERVER_COMPLETED_RPC: _measures.SERVER_COMPLETED_RPCS_MEASURE,
35
+ }
36
+
37
+
38
+ # These measure definitions should be kept in sync across opencensus
39
+ # implementations--see
40
+ # https://github.com/census-instrumentation/opencensus-java/blob/master/contrib/grpc_metrics/src/main/java/io/opencensus/contrib/grpc/metrics/RpcMeasureConstants.java.
41
+ def client_method_tag_key():
42
+ return TagKey("grpc_client_method")
43
+
44
+
45
+ def client_status_tag_key():
46
+ return TagKey("grpc_client_status")
47
+
48
+
49
+ def server_method_tag_key():
50
+ return TagKey("grpc_server_method")
51
+
52
+
53
+ def server_status_tag_key():
54
+ return TagKey("server_status_tag_key")
55
+
56
+
57
+ def count_distribution_aggregation() -> aggregation.DistributionAggregation:
58
+ exponential_boundaries = _get_exponential_boundaries(17, 1.0, 2.0)
59
+ return aggregation.DistributionAggregation(exponential_boundaries)
60
+
61
+
62
+ def bytes_distribution_aggregation() -> aggregation.DistributionAggregation:
63
+ return aggregation.DistributionAggregation(
64
+ [
65
+ 1024,
66
+ 2048,
67
+ 4096,
68
+ 16384,
69
+ 65536,
70
+ 262144,
71
+ 1048576,
72
+ 4194304,
73
+ 16777216,
74
+ 67108864,
75
+ 268435456,
76
+ 1073741824,
77
+ 4294967296,
78
+ ]
79
+ )
80
+
81
+
82
+ def millis_distribution_aggregation() -> aggregation.DistributionAggregation:
83
+ return aggregation.DistributionAggregation(
84
+ [
85
+ 0.01,
86
+ 0.05,
87
+ 0.1,
88
+ 0.3,
89
+ 0.6,
90
+ 0.8,
91
+ 1,
92
+ 2,
93
+ 3,
94
+ 4,
95
+ 5,
96
+ 6,
97
+ 8,
98
+ 10,
99
+ 13,
100
+ 16,
101
+ 20,
102
+ 25,
103
+ 30,
104
+ 40,
105
+ 50,
106
+ 65,
107
+ 80,
108
+ 100,
109
+ 130,
110
+ 160,
111
+ 200,
112
+ 250,
113
+ 300,
114
+ 400,
115
+ 500,
116
+ 650,
117
+ 800,
118
+ 1000,
119
+ 2000,
120
+ 5000,
121
+ 10000,
122
+ 20000,
123
+ 50000,
124
+ 100000,
125
+ ]
126
+ )
127
+
128
+
129
+ # Client
130
+ def client_started_rpcs(labels: Mapping[str, str]) -> view_module.View:
131
+ view = view_module.View(
132
+ "grpc.io/client/started_rpcs",
133
+ "The count of RPCs ever received at the server, including RPCs"
134
+ + " that have not completed.",
135
+ [TagKey(key) for key in labels.keys()] + [client_method_tag_key()],
136
+ _measures.CLIENT_STARTED_RPCS_MEASURE,
137
+ aggregation.CountAggregation(),
138
+ )
139
+ return view
140
+
141
+
142
+ def client_completed_rpcs(labels: Mapping[str, str]) -> view_module.View:
143
+ view = view_module.View(
144
+ "grpc.io/client/completed_rpcs",
145
+ "The total count of RPCs completed, for example, when a response"
146
+ + " is sent by the server.",
147
+ [TagKey(key) for key in labels.keys()]
148
+ + [client_method_tag_key(), client_status_tag_key()],
149
+ _measures.CLIENT_COMPLETED_RPCS_MEASURE,
150
+ aggregation.CountAggregation(),
151
+ )
152
+ return view
153
+
154
+
155
+ def client_roundtrip_latency(labels: Mapping[str, str]) -> view_module.View:
156
+ view = view_module.View(
157
+ "grpc.io/client/roundtrip_latency",
158
+ "End-to-end time taken to complete an RPC attempt including the time"
159
+ + " it takes to pick a subchannel.",
160
+ [TagKey(key) for key in labels.keys()] + [client_method_tag_key()],
161
+ _measures.CLIENT_ROUNDTRIP_LATENCY_MEASURE,
162
+ millis_distribution_aggregation(),
163
+ )
164
+ return view
165
+
166
+
167
+ def client_api_latency(labels: Mapping[str, str]) -> view_module.View:
168
+ view = view_module.View(
169
+ "grpc.io/client/api_latency",
170
+ "The total time taken by the gRPC library to complete an RPC from"
171
+ + " the application's perspective.",
172
+ [TagKey(key) for key in labels.keys()]
173
+ + [client_method_tag_key(), client_status_tag_key()],
174
+ _measures.CLIENT_API_LATENCY_MEASURE,
175
+ millis_distribution_aggregation(),
176
+ )
177
+ return view
178
+
179
+
180
+ def client_sent_compressed_message_bytes_per_rpc(
181
+ labels: Mapping[str, str]
182
+ ) -> view_module.View:
183
+ view = view_module.View(
184
+ "grpc.io/client/sent_compressed_message_bytes_per_rpc",
185
+ "The total bytes (compressed, not encrypted) sent across all"
186
+ + " request messages per RPC attempt.",
187
+ [TagKey(key) for key in labels.keys()]
188
+ + [client_method_tag_key(), client_status_tag_key()],
189
+ _measures.CLIENT_SEND_BYTES_PER_RPC_MEASURE,
190
+ bytes_distribution_aggregation(),
191
+ )
192
+ return view
193
+
194
+
195
+ def client_received_compressed_message_bytes_per_rpc(
196
+ labels: Mapping[str, str]
197
+ ) -> view_module.View:
198
+ view = view_module.View(
199
+ "grpc.io/client/received_compressed_message_bytes_per_rpc",
200
+ "The total bytes (compressed, not encrypted) received across"
201
+ + " all response messages per RPC attempt.",
202
+ [TagKey(key) for key in labels.keys()]
203
+ + [client_method_tag_key(), client_status_tag_key()],
204
+ _measures.CLIENT_RECEIVED_BYTES_PER_RPC_MEASURE,
205
+ bytes_distribution_aggregation(),
206
+ )
207
+ return view
208
+
209
+
210
+ # Server
211
+ def server_started_rpcs(labels: Mapping[str, str]) -> view_module.View:
212
+ view = view_module.View(
213
+ "grpc.io/server/started_rpcs",
214
+ "The count of RPCs ever received at the server, including RPCs"
215
+ + " that have not completed.",
216
+ [TagKey(key) for key in labels.keys()] + [server_method_tag_key()],
217
+ _measures.SERVER_STARTED_RPCS_MEASURE,
218
+ aggregation.CountAggregation(),
219
+ )
220
+ return view
221
+
222
+
223
+ def server_completed_rpcs(labels: Mapping[str, str]) -> view_module.View:
224
+ view = view_module.View(
225
+ "grpc.io/server/completed_rpcs",
226
+ "The total count of RPCs completed, for example, when a response"
227
+ + " is sent by the server.",
228
+ [TagKey(key) for key in labels.keys()]
229
+ + [server_method_tag_key(), server_status_tag_key()],
230
+ _measures.SERVER_COMPLETED_RPCS_MEASURE,
231
+ aggregation.CountAggregation(),
232
+ )
233
+ return view
234
+
235
+
236
+ def server_sent_compressed_message_bytes_per_rpc(
237
+ labels: Mapping[str, str]
238
+ ) -> view_module.View:
239
+ view = view_module.View(
240
+ "grpc.io/server/sent_compressed_message_bytes_per_rpc",
241
+ "The total bytes (compressed not encrypted) sent across all response"
242
+ + " messages per RPC.",
243
+ [TagKey(key) for key in labels.keys()]
244
+ + [server_method_tag_key(), server_status_tag_key()],
245
+ _measures.SERVER_SENT_BYTES_PER_RPC_MEASURE,
246
+ bytes_distribution_aggregation(),
247
+ )
248
+ return view
249
+
250
+
251
+ def server_received_compressed_message_bytes_per_rpc(
252
+ labels: Mapping[str, str]
253
+ ) -> view_module.View:
254
+ view = view_module.View(
255
+ "grpc.io/server/received_compressed_message_bytes_per_rpc",
256
+ "The total bytes (compressed not encrypted) received across all"
257
+ + " request messages per RPC.",
258
+ [TagKey(key) for key in labels.keys()]
259
+ + [server_method_tag_key(), server_status_tag_key()],
260
+ _measures.SERVER_RECEIVED_BYTES_PER_RPC_MEASURE,
261
+ bytes_distribution_aggregation(),
262
+ )
263
+ return view
264
+
265
+
266
+ def server_server_latency(labels: Mapping[str, str]) -> view_module.View:
267
+ view = view_module.View(
268
+ "grpc.io/server/server_latency",
269
+ "The total time taken by an RPC from server transport's"
270
+ + " (HTTP2 / inproc / cronet) perspective.",
271
+ [TagKey(key) for key in labels.keys()]
272
+ + [server_method_tag_key(), server_status_tag_key()],
273
+ _measures.SERVER_SERVER_LATENCY_MEASURE,
274
+ millis_distribution_aggregation(),
275
+ )
276
+ return view
277
+
278
+
279
+ def _get_exponential_boundaries(
280
+ num_finite_buckets: int, scale: float, grrowth_factor: float
281
+ ) -> list:
282
+ boundaries = []
283
+ upper_bound = scale
284
+ for _ in range(num_finite_buckets):
285
+ boundaries.append(upper_bound)
286
+ upper_bound *= grrowth_factor
287
+ return boundaries