diff --git a/.venv/lib/python3.11/site-packages/opencensus/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5404bf2f6fc44255e3c778f5acb2c23201d4af70 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/log/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/log/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..869c51ccfd1963b1e65a23444875a23954f0da79 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/log/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/metrics/label_value.py b/.venv/lib/python3.11/site-packages/opencensus/metrics/label_value.py new file mode 100644 index 0000000000000000000000000000000000000000..9ebe76e4de37668dcffc9bddf1354dc3d5a3eae5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/metrics/label_value.py @@ -0,0 +1,42 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +class LabelValue(object): + """The label values associated with the TimeSeries. + + :type value: str + :param value: the value for the label + """ + def __init__(self, value=None): + self._value = value + + def __repr__(self): + return ("{}({})" + .format( + type(self).__name__, + self.value, + )) + + @property + def value(self): + """the value for the label""" + return self._value + + def __eq__(self, other): + return isinstance(other, LabelValue) and \ + self.value == other.value + + def __hash__(self): + return hash(self.value) diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/__init__.py b/.venv/lib/python3.11/site-packages/opencensus/tags/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fc346ebf3671a4e6715b1442c2fc642edb0b68aa --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/tags/__init__.py @@ -0,0 +1,23 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.common.runtime_context import RuntimeContext +from opencensus.tags.tag import Tag +from opencensus.tags.tag_key import TagKey +from opencensus.tags.tag_map import TagMap +from opencensus.tags.tag_value import TagValue + +__all__ = ['Tag', 'TagContext', 'TagKey', 'TagValue', 'TagMap'] + +TagContext = RuntimeContext.register_slot('tag_context', None) diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72a16070b60ee4032fbeb026b5964fac64e72187 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6c35c1af7504daf955dc0744f3705c3d90fe1c3 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_key.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_key.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24061c974c36b1fead9d36a4c570b55a483392a2 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_key.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_map.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_map.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5c2497755a81537d259f24a0f11f72e59429c7f Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_map.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_value.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_value.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ebb7162508d9a313d3a40a4cba7dbcc127debfb3 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/tag_value.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/validation.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/validation.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3fd77ae090a42371e666b1c5cca388dd70c70aac Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/tags/__pycache__/validation.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__init__.py b/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e1eca01eaa16bb6f490081015cb2951c179fba21 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b308a6f61f29b26960c8493bbc149a9c24be9a49 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__pycache__/binary_serializer.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__pycache__/binary_serializer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a4de8103ac4609f12ead4387f64bb2d25917cf8 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/__pycache__/binary_serializer.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/binary_serializer.py b/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/binary_serializer.py new file mode 100644 index 0000000000000000000000000000000000000000..ee93d8d8dc6bb7ab735062179ad5b4b5cde7b04c --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/tags/propagation/binary_serializer.py @@ -0,0 +1,109 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# -*- coding: utf-8 -*- + +import six + +import logging + +from google.protobuf.internal.encoder import _VarintBytes + +from opencensus.tags import tag_map as tag_map_module + +# Used for decoding hex bytes to hex string. +UTF8 = 'utf-8' + +VERSION_ID = 0 +TAG_FIELD_ID = 0 +TAG_MAP_SERIALIZED_SIZE_LIMIT = 8192 + + +class BinarySerializer(object): + def from_byte_array(self, binary): + if len(binary) <= 0: + logging.warning("Input byte[] cannot be empty/") + return tag_map_module.TagMap() + else: + buffer = memoryview(binary) + version_id = buffer[0] + if six.PY2: + version_id = ord(version_id) + if version_id != VERSION_ID: + raise ValueError("Invalid version id.") + return self._parse_tags(buffer) + + def to_byte_array(self, tag_context): + encoded_bytes = b'' + encoded_bytes += _VarintBytes(VERSION_ID) + total_chars = 0 + for tag in tag_context: + tag_key, tag_value = tag + total_chars += len(tag_key) + total_chars += len(tag_value) + encoded_bytes = self._encode_tag( + tag_key, tag_value, encoded_bytes) + if total_chars <= TAG_MAP_SERIALIZED_SIZE_LIMIT: + return encoded_bytes + else: # pragma: NO COVER + logging.warning("Size of the tag context exceeds the maximum size") + + def _parse_tags(self, buffer): + tag_context = tag_map_module.TagMap() + limit = len(buffer) + total_chars = 0 + i = 1 + while i < limit: + field_id = buffer[i] if six.PY3 else ord(buffer[i]) + if field_id == TAG_FIELD_ID: + i += 1 + key = self._decode_string(buffer, i) + i += len(key) + total_chars += len(key) + i += 1 + val = self._decode_string(buffer, i) + i += len(val) + total_chars += len(val) + i += 1 + if total_chars > \ + TAG_MAP_SERIALIZED_SIZE_LIMIT: # pragma: NO COVER + logging.warning("Size of the tag context exceeds maximum") + break + else: + tag_context.insert(str(key), str(val)) + else: + break + return tag_context + + def _encode_tag(self, tag_key, tag_value, encoded_bytes): + encoded_bytes += _VarintBytes(TAG_FIELD_ID) + encoded_bytes = self._encode_string(tag_key, encoded_bytes) + encoded_bytes = self._encode_string(tag_value, encoded_bytes) + return encoded_bytes + + def _encode_string(self, input_str, encoded_bytes): + encoded_bytes += _VarintBytes(len(input_str)) + encoded_bytes += input_str.encode(UTF8) + return encoded_bytes + + def _decode_string(self, buffer, pos): + length = buffer[pos] if six.PY3 else ord(buffer[pos]) + builder = "" + i = 1 + while i <= length: + bytes_to_decode = buffer[pos + i] if six.PY3 \ + else ord(buffer[pos + i]) + builder += _VarintBytes(bytes_to_decode).decode() + i += 1 + return builder diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/tag.py b/.venv/lib/python3.11/site-packages/opencensus/tags/tag.py new file mode 100644 index 0000000000000000000000000000000000000000..717b0afdeff33d82febbf387b7a84a9c169d7834 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/tags/tag.py @@ -0,0 +1,38 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections import namedtuple + +from opencensus.tags.tag_key import TagKey +from opencensus.tags.tag_value import TagValue + +Tag_ = namedtuple('Tag', ['key', 'value']) + + +class Tag(Tag_): + """A tag, in the format [KEY]:[VALUE]. + + :type key: str + :param key: The name of the tag + + :type value: str + :param value: The value of the tag + + """ + def __new__(cls, key, value): + return super(Tag, cls).__new__( + cls, + key=TagKey(key), + value=TagValue(value), + ) diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/tag_key.py b/.venv/lib/python3.11/site-packages/opencensus/tags/tag_key.py new file mode 100644 index 0000000000000000000000000000000000000000..7399d2da01eaec8099e629bda24e1f6d1503fe50 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/tags/tag_key.py @@ -0,0 +1,35 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.tags.validation import is_valid_tag_name + +_TAG_NAME_ERROR = \ + 'tag name must not be empty,' \ + 'no longer than 255 characters and of ascii values between 32 - 126' + + +class TagKey(str): + """A tag key with a property name""" + + def __new__(cls, name): + """Create and return a new tag key + + :type name: str + :param name: The name of the key + :return: TagKey + """ + if not isinstance(name, cls): + if not is_valid_tag_name(name): + raise ValueError(_TAG_NAME_ERROR) + return super(TagKey, cls).__new__(cls, name) diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/tag_map.py b/.venv/lib/python3.11/site-packages/opencensus/tags/tag_map.py new file mode 100644 index 0000000000000000000000000000000000000000..9a818e6338b4e09875099cd2ddbdb23117cc1020 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/tags/tag_map.py @@ -0,0 +1,104 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections import OrderedDict + +from opencensus.tags.tag_key import TagKey +from opencensus.tags.tag_value import TagValue + + +class TagMap(object): + """ A tag map is a map of tags from key to value + + :type tags: list(:class: '~opencensus.tags.tag.Tag') + :param tags: a list of tags + + """ + + def __init__(self, tags=None): + self.map = OrderedDict(tags if tags else []) + + def __iter__(self): + return self.map.items().__iter__() + + def insert(self, key, value): + """Inserts a key and value in the map if the map does not already + contain the key. + + :type key: :class: '~opencensus.tags.tag_key.TagKey' + :param key: a tag key to insert into the map + + :type value: :class: '~opencensus.tags.tag_value.TagValue' + :param value: a tag value that is associated with the tag key and + the value to insert into the tag map + + """ + if key in self.map: + return + + try: + tag_key = TagKey(key) + tag_val = TagValue(value) + self.map[tag_key] = tag_val + except ValueError: + raise + + def delete(self, key): + """Deletes a tag from the map if the key is in the map + + :type key: :class: '~opencensus.tags.tag_key.TagKey' + :param key: A string representing a possible tag key + + :returns: the value of the key in the dictionary if it is in there, + or None if it is not. + """ + self.map.pop(key, None) + + def update(self, key, value): + """Updates the map by updating the value of a key + + :type key: :class: '~opencensus.tags.tag_key.TagKey' + :param key: A tag key to be updated + + :type value: :class: '~opencensus.tags.tag_value.TagValue' + :param value: The value to update the key to in the map + + """ + if key in self.map: + self.map[key] = value + + def tag_key_exists(self, key): + """Checking if the tag key exists in the map + + :type key: '~opencensus.tags.tag_key.TagKey' + :param key: A string to check to see if that is a key in the map + + :returns: True if the key is in map, False is it is not + + """ + return key in self.map + + def get_value(self, key): + """ Gets the value of the key passed in if the key exists in the map + + :type key: str + :param key: A string representing a key to get the value of in the map + + :returns: A KeyError if the value is None, else returns the value + + """ + try: + return self.map[key] + except KeyError: + raise KeyError('key is not in map') diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/tag_value.py b/.venv/lib/python3.11/site-packages/opencensus/tags/tag_value.py new file mode 100644 index 0000000000000000000000000000000000000000..d22b07e0ba7e70ef1c2d6b51d6f723a01451356b --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/tags/tag_value.py @@ -0,0 +1,35 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.tags.validation import is_valid_tag_value + +_TAG_VALUE_ERROR = \ + 'tag value must not be longer than 255 characters ' \ + 'and of ascii values between 32 - 126' + + +class TagValue(str): + """The value of a tag""" + + def __new__(cls, value): + """Create and return a new tag value + + :type value: str + :param value: A string representing the value of a key in a tag + :return: TagValue + """ + if not isinstance(value, cls): + if not is_valid_tag_value(value): + raise ValueError(_TAG_VALUE_ERROR) + return super(TagValue, cls).__new__(cls, value) diff --git a/.venv/lib/python3.11/site-packages/opencensus/tags/validation.py b/.venv/lib/python3.11/site-packages/opencensus/tags/validation.py new file mode 100644 index 0000000000000000000000000000000000000000..8d51ac86caba797b3a0b03af3044cba619e9907a --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/tags/validation.py @@ -0,0 +1,42 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def is_legal_chars(value): + return all(32 <= ord(char) <= 126 for char in value) + + +def is_valid_tag_name(name): + """Checks if the name of a tag key is valid + + :type name: str + :param name: name to check + + :rtype: bool + :returns: True if it valid, else returns False + """ + return is_legal_chars(name) if 0 < len(name) <= 255 else False + + +def is_valid_tag_value(value): + """Checks if the value is valid + + :type value: str + :param value: the value to be checked + + :rtype: bool + :returns: True if valid, if not, False. + + """ + return is_legal_chars(value) if len(value) <= 255 else False diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__init__.py b/.venv/lib/python3.11/site-packages/opencensus/trace/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..df61b27206097325403317a8b5e3dcb2e7521764 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/__init__.py @@ -0,0 +1,17 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.trace.span import Span + +__all__ = ['Span'] diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/attributes.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/attributes.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55cb102cf106850717c53e683f7f74c7fc427a65 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/attributes.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/base_exporter.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/base_exporter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4cc4116ee83f2ac879e77945fec3c87060a8d87 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/base_exporter.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/base_span.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/base_span.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cf4d8b1d752af0d7b720869416ecf8bc7046706 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/base_span.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/config_integration.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/config_integration.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..05848b9384e449244522e6f0b7988d7c37016f69 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/config_integration.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/execution_context.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/execution_context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d97e1c4f39c951c8f5dca50724fd76c2e7cada3a Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/execution_context.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/file_exporter.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/file_exporter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..517db86e22923ac30a0d9dff5efb8cb2123d00fb Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/file_exporter.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/print_exporter.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/print_exporter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb2fabbf8bda46fe105ba76b1b008571bf51020d Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/print_exporter.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/span_context.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/span_context.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..340ccb55a56d978d547ad0ed6621f409c850d194 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/span_context.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/span_data.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/span_data.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca3057f8090e54a61431b17565c874f201fd4496 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/__pycache__/span_data.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/attributes.py b/.venv/lib/python3.11/site-packages/opencensus/trace/attributes.py new file mode 100644 index 0000000000000000000000000000000000000000..99172a384a8596ed0d02ff8a93183a4e5c413dc8 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/attributes.py @@ -0,0 +1,74 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import six + +from opencensus.common import utils + + +def _format_attribute_value(value): + if isinstance(value, bool): + value_type = 'bool_value' + elif isinstance(value, int): + value_type = 'int_value' + elif isinstance(value, six.string_types): + value_type = 'string_value' + value = utils.get_truncatable_str(value) + elif isinstance(value, float): + value_type = 'double_value' + else: + return None + + return {value_type: value} + + +class Attributes(object): + """A set of attributes, each in the format [KEY]:[VALUE]. + + :type attributes: dict + :param attributes: The set of attributes. Each attribute's key can be up + to 128 bytes long. The value can be a string up to 256 + bytes, an integer, a floating-point number, or the + Boolean values true and false. + """ + def __init__(self, attributes=None): + self.attributes = attributes or {} + + def set_attribute(self, key, value): + """Set a key value pair.""" + self.attributes[key] = value + + def delete_attribute(self, key): + """Delete an attribute given a key if existed.""" + self.attributes.pop(key, None) + + def get_attribute(self, key): + """Get a attribute value.""" + return self.attributes.get(key, None) + + def format_attributes_json(self): + """Convert the Attributes object to json format.""" + attributes_json = {} + + for key, value in self.attributes.items(): + key = utils.check_str_length(key)[0] + value = _format_attribute_value(value) + + if value is not None: + attributes_json[key] = value + + result = { + 'attributeMap': attributes_json + } + + return result diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/attributes_helper.py b/.venv/lib/python3.11/site-packages/opencensus/trace/attributes_helper.py new file mode 100644 index 0000000000000000000000000000000000000000..3ebd94f100def0b67e7ce414b785752e72df3a63 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/attributes_helper.py @@ -0,0 +1,43 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +COMMON_ATTRIBUTES = { + 'AGENT': 'g.co/agent', + 'COMPONENT': 'component', + 'ERROR_MESSAGE': 'error.message', + 'ERROR_NAME': 'error.name', + 'HTTP_CLIENT_CITY': 'http.client_city', + 'HTTP_CLIENT_COUNTRY': 'http.client_country', + 'HTTP_CLIENT_PROTOCOL': 'http.client_protocol', + 'HTTP_CLIENT_REGION': 'http.client_region', + 'HTTP_HOST': 'http.host', + 'HTTP_METHOD': 'http.method', + 'HTTP_PATH': 'http.path', + 'HTTP_ROUTE': 'http.route', + 'HTTP_REDIRECTED_URL': 'http.redirected_url', + 'HTTP_REQUEST_SIZE': 'http.request_size', + 'HTTP_RESPONSE_SIZE': 'http.response_size', + 'HTTP_STATUS_CODE': 'http.status_code', + 'HTTP_URL': 'http.url', + 'HTTP_USER_AGENT': 'http.user_agent', + 'PID': 'pid', + 'STACKTRACE': 'stacktrace', + 'TID': 'tid', +} + + +GRPC_ATTRIBUTES = { + 'GRPC_HOST_PORT': 'grpc.host_port', + 'GRPC_METHOD': 'grpc.method', +} diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/base_exporter.py b/.venv/lib/python3.11/site-packages/opencensus/trace/base_exporter.py new file mode 100644 index 0000000000000000000000000000000000000000..322ace10f24990b8961f090761ba257dd6aa16a8 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/base_exporter.py @@ -0,0 +1,43 @@ +# Copyright 2016-17, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Module containing base class for exporters.""" + + +class Exporter(object): + """Base class for opencensus trace request exporters. + + Subclasses of :class:`Exporter` must override :meth:`export`. + """ + + def emit(self, span_datas): + """ + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to emit + """ + raise NotImplementedError + + def export(self, span_datas): + """Export the trace. Send trace to transport, and transport will call + exporter.emit() to actually send the trace to the specified tracing + backend. + + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to export + """ + raise NotImplementedError diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/base_span.py b/.venv/lib/python3.11/site-packages/opencensus/trace/base_span.py new file mode 100644 index 0000000000000000000000000000000000000000..459b7ec683cf14407a627e362b3ae826c9134f07 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/base_span.py @@ -0,0 +1,109 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Module containing base class for Span.""" + + +class BaseSpan(object): + """Base class for Opencensus spans. + Subclasses of :class:`BaseSpan` must implement the below methods. + """ + + @staticmethod + def on_create(callback): + raise NotImplementedError + + @property + def children(self): + """The child spans of the current span.""" + raise NotImplementedError + + def span(self, name='child_span'): + """Create a child span for the current span and append it to the child + spans list. + + :type name: str + :param name: (Optional) The name of the child span. + + :rtype: :class: `~opencensus.trace.span.Span` + :returns: A child Span to be added to the current span. + """ + raise NotImplementedError + + def add_attribute(self, attribute_key, attribute_value): + """Add attribute to span. + + :type attribute_key: str + :param attribute_key: Attribute key. + + :type attribute_value:str + :param attribute_value: Attribute value. + """ + raise NotImplementedError + + def add_annotation(self, description, **attrs): + """Add an annotation to span. + + :type description: str + :param description: A user-supplied message describing the event. + The maximum length for the description is 256 bytes. + + :type attrs: kwargs + :param attrs: keyworded arguments e.g. failed=True, name='Caching' + """ + raise NotImplementedError + + def add_message_event(self, message_event): + """Add a message event to this span. + + :type message_event: :class:`opencensus.trace.time_event.MessageEvent` + :param message_event: The message event to attach to this span. + """ + raise NotImplementedError + + def add_link(self, link): + """Add a Link. + + :type link: :class: `~opencensus.trace.link.Link` + :param link: A Link object. + """ + raise NotImplementedError + + def set_status(self, status): + """Sets span status. + + :type code: :class: `~opencensus.trace.status.Status` + :param code: A Status object. + """ + raise NotImplementedError + + def start(self): + """Set the start time for a span.""" + raise NotImplementedError + + def finish(self): + """Set the end time for a span.""" + raise NotImplementedError + + def __iter__(self): + """Iterate through the span tree.""" + raise NotImplementedError + + def __enter__(self): + """Start a span.""" + raise NotImplementedError + + def __exit__(self, exception_type, exception_value, traceback): + """Finish a span.""" + raise NotImplementedError diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/blank_span.py b/.venv/lib/python3.11/site-packages/opencensus/trace/blank_span.py new file mode 100644 index 0000000000000000000000000000000000000000..1b4c40ef4d5bbb41a26ea9e4009fdd2258b426d9 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/blank_span.py @@ -0,0 +1,165 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.trace import base_span +from opencensus.trace.span_context import generate_span_id +from opencensus.trace.tracers import base + + +class BlankSpan(base_span.BaseSpan): + """A BlankSpan is an individual timed event which forms a node of the trace + tree. All operations are no-op. + + :type name: str + :param name: The name of the span. + + :type parent_span: :class:`~opencensus.trace.blank_span.BlankSpan` + :param parent_span: (Optional) Parent span. + + :type status: :class: `~opencensus.trace.status.Status` + :param status: (Optional) An optional final status for this span. + + :type context_tracer: :class:`~opencensus.trace.tracers.noop_tracer. + NoopTracer` + :param context_tracer: The tracer that holds a stack of spans. If this is + not None, then when exiting a span, use the end_span + method in the tracer class to finish a span. If no + tracer is passed in, then just finish the span using + the finish method in the Span class. + """ + + def __init__( + self, + name=None, + parent_span=None, + attributes=None, + start_time=None, + end_time=None, + span_id=None, + stack_trace=None, + annotations=None, + message_events=None, + links=None, + status=None, + same_process_as_parent_span=None, + context_tracer=None, + span_kind=None): + self.name = name + self.parent_span = parent_span + self.start_time = start_time + self.end_time = end_time + + self.span_id = generate_span_id() + self.parent_span = base.NullContextManager() + + self.attributes = {} + self.stack_trace = stack_trace + self.annotations = annotations + self.message_events = message_events + self.links = [] + self.status = status + self.same_process_as_parent_span = same_process_as_parent_span + self._child_spans = [] + self.context_tracer = context_tracer + self.span_kind = span_kind + + @staticmethod + def on_create(callback): + pass + + @property + def children(self): + """The child spans of the current BlankSpan.""" + return list() + + def span(self, name='child_span'): + """Create a child span for the current span and append it to the child + spans list. + + :type name: str + :param name: (Optional) The name of the child span. + + :rtype: :class: `~opencensus.trace.blankspan.BlankSpan` + :returns: A child Span to be added to the current span. + """ + child_span = BlankSpan(name, parent_span=self) + self._child_spans.append(child_span) + return child_span + + def add_attribute(self, attribute_key, attribute_value): + """No-op implementation of this method. + + :type attribute_key: str + :param attribute_key: Attribute key. + + :type attribute_value:str + :param attribute_value: Attribute value. + """ + pass + + def add_annotation(self, description, **attrs): + """No-op implementation of this method. + + :type description: str + :param description: A user-supplied message describing the event. + The maximum length for the description is 256 bytes. + + :type attrs: kwargs + :param attrs: keyworded arguments e.g. failed=True, name='Caching' + """ + pass + + def add_message_event(self, message_event): + """No-op implementation of this method. + + :type message_event: :class:`opencensus.trace.time_event.MessageEvent` + :param message_event: The message event to attach to this span. + """ + pass + + def add_link(self, link): + """No-op implementation of this method. + + :type link: :class: `~opencensus.trace.link.Link` + :param link: A Link object. + """ + pass + + def set_status(self, status): + """No-op implementation of this method. + + :type code: :class: `~opencensus.trace.status.Status` + :param code: A Status object. + """ + pass + + def start(self): + """No-op implementation of this method.""" + pass + + def finish(self): + """No-op implementation of this method.""" + pass + + def __iter__(self): + """Iterate through the span tree.""" + yield self + + def __enter__(self): + """Start a span.""" + return self + + def __exit__(self, exception_type, exception_value, traceback): + """Finish a span.""" + pass diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/config_integration.py b/.venv/lib/python3.11/site-packages/opencensus/trace/config_integration.py new file mode 100644 index 0000000000000000000000000000000000000000..a0d8e5d3c146b4424f29d79fecff324c6344b651 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/config_integration.py @@ -0,0 +1,38 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import importlib +import logging + +log = logging.getLogger(__name__) + + +def trace_integrations(integrations, tracer=None): + """Enable tracing on the selected integrations. + :type integrations: list + :param integrations: The integrations to be traced. + """ + integrated = [] + + for item in integrations: + module_name = 'opencensus.ext.{}.trace'.format(item) + try: + module = importlib.import_module(module_name) + module.trace_integration(tracer=tracer) + integrated.append(item) + except Exception as e: + log.warning('Failed to integrate module: {}'.format(module_name)) + log.warning('{}'.format(e)) + + return integrated diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/exceptions_status.py b/.venv/lib/python3.11/site-packages/opencensus/trace/exceptions_status.py new file mode 100644 index 0000000000000000000000000000000000000000..8a1c0510a6b72750413b55dbb8d19ee6f5992170 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/exceptions_status.py @@ -0,0 +1,25 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from google.rpc import code_pb2 + +from opencensus.trace.status import Status + +CANCELLED = Status(code_pb2.CANCELLED) +INVALID_URL = Status(code_pb2.INVALID_ARGUMENT, message='invalid URL') +TIMEOUT = Status(code_pb2.DEADLINE_EXCEEDED, message='request timed out') + + +def unknown(exception): + return Status.from_exception(exception) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/execution_context.py b/.venv/lib/python3.11/site-packages/opencensus/trace/execution_context.py new file mode 100644 index 0000000000000000000000000000000000000000..58dd0d070999341909855b08136a224be0f99635 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/execution_context.py @@ -0,0 +1,89 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.common.runtime_context import RuntimeContext +from opencensus.trace.tracers import noop_tracer + +_attrs_slot = RuntimeContext.register_slot('attrs', lambda: {}) +_current_span_slot = RuntimeContext.register_slot('current_span', None) +_exporter_slot = RuntimeContext.register_slot('is_exporter', False) +_tracer_slot = RuntimeContext.register_slot('tracer', noop_tracer.NoopTracer()) + + +def is_exporter(): + return RuntimeContext.is_exporter + + +def set_is_exporter(is_exporter): + RuntimeContext.is_exporter = is_exporter + + +def get_opencensus_tracer(): + """Get the opencensus tracer from runtime context.""" + return RuntimeContext.tracer + + +def set_opencensus_tracer(tracer): + """Add the tracer to runtime context.""" + RuntimeContext.tracer = tracer + + +def set_opencensus_attr(attr_key, attr_value): + attrs = RuntimeContext.attrs.copy() + attrs[attr_key] = attr_value + RuntimeContext.attrs = attrs + + +def set_opencensus_attrs(attrs): + RuntimeContext.attrs = attrs + + +def get_opencensus_attr(attr_key): + return RuntimeContext.attrs.get(attr_key) + + +def get_opencensus_attrs(): + return RuntimeContext.attrs + + +def get_current_span(): + return RuntimeContext.current_span + + +def set_current_span(current_span): + RuntimeContext.current_span = current_span + + +def get_opencensus_full_context(): + attrs = RuntimeContext.attrs + current_span = RuntimeContext.current_span + tracer = RuntimeContext.tracer + return tracer, current_span, attrs + + +def set_opencensus_full_context(tracer, span, attrs): + set_opencensus_tracer(tracer) + set_current_span(span) + set_opencensus_attrs(attrs or {}) + + +def clean(): + _attrs_slot.clear() + _current_span_slot.clear() + _tracer_slot.clear() + + +def clear(): + """Clear the context, used in test.""" + clean() diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/file_exporter.py b/.venv/lib/python3.11/site-packages/opencensus/trace/file_exporter.py new file mode 100644 index 0000000000000000000000000000000000000000..86f56271f705f0226b95592bf9d234078ec9eec8 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/file_exporter.py @@ -0,0 +1,71 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Export the trace spans to a local file.""" + +import json + +from opencensus.common.transports import sync +from opencensus.trace import base_exporter, span_data + +DEFAULT_FILENAME = 'opencensus-traces.json' + + +class FileExporter(base_exporter.Exporter): + """ + :type file_name: str + :param file_name: The name of the output file. + + :type transport: :class:`type` + :param transport: Class for creating new transport objects. It should + extend from the base_exporter :class:`.Transport` type + and implement :meth:`.Transport.export`. Defaults to + :class:`.SyncTransport`. The other option is + :class:`.AsyncTransport`. + + :type file_mode: str + :param file_mode: The file mode to open the output file with. + Defaults to w+ + + """ + + def __init__(self, file_name=DEFAULT_FILENAME, + transport=sync.SyncTransport, + file_mode='w+'): + self.file_name = file_name + self.transport = transport(self) + self.file_mode = file_mode + + def emit(self, span_datas): + """ + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to emit + """ + with open(self.file_name, self.file_mode) as file: + # convert to the legacy trace json for easier refactoring + # TODO: refactor this to use the span data directly + legacy_trace_json = span_data.format_legacy_trace_json(span_datas) + trace_str = json.dumps(legacy_trace_json) + file.write(trace_str) + + def export(self, span_datas): + """ + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to export + """ + self.transport.export(span_datas) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/integrations.py b/.venv/lib/python3.11/site-packages/opencensus/trace/integrations.py new file mode 100644 index 0000000000000000000000000000000000000000..da70b27b8deddf0ea53d54b09539c8f3b9ee820d --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/integrations.py @@ -0,0 +1,52 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import threading + +_INTEGRATIONS_BIT_MASK = 0 +_INTEGRATIONS_LOCK = threading.Lock() + + +class _Integrations: + NONE = 0 + DJANGO = 1 + FLASK = 2 + GOOGLE_CLOUD = 4 + HTTP_LIB = 8 + LOGGING = 16 + MYSQL = 32 + POSTGRESQL = 64 + PYMONGO = 128 + PYMYSQL = 256 + PYRAMID = 512 + REQUESTS = 1024 + SQLALCHEMY = 2056 + HTTPX = 16777216 + FASTAPI = 4194304 + + +def get_integrations(): + return _INTEGRATIONS_BIT_MASK + + +def add_integration(integration): + with _INTEGRATIONS_LOCK: + global _INTEGRATIONS_BIT_MASK # pylint: disable=global-statement + _INTEGRATIONS_BIT_MASK |= integration + + +def remove_intregration(integration): + with _INTEGRATIONS_LOCK: + global _INTEGRATIONS_BIT_MASK # pylint: disable=global-statement + _INTEGRATIONS_BIT_MASK &= ~integration diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/link.py b/.venv/lib/python3.11/site-packages/opencensus/trace/link.py new file mode 100644 index 0000000000000000000000000000000000000000..cbd3b5d6e77a5087f085fb9436ed53635e008dd9 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/link.py @@ -0,0 +1,71 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +class Type(object): + """The relationship of the current span relative to the linked span: child, + parent, or unspecified. + + Attributes: + TYPE_UNSPECIFIED (int): The relationship of the two spans is unknown. + CHILD_LINKED_SPAN (int): The linked span is a child of the current span. + PARENT_LINKED_SPAN (int): The linked span is a parent of the current + span. + """ + TYPE_UNSPECIFIED = 0 + CHILD_LINKED_SPAN = 1 + PARENT_LINKED_SPAN = 2 + + +class Link(object): + """A pointer from the current span to another span in the same trace or in + a different trace. For example, this can be used in batching operations, + where a single batch handler processes multiple requests from different + traces or when the handler receives a request from a different project. + + :type trace_id: str + :param trace_id: The [TRACE_ID] for a trace within a project. + + :type span_id: str + :param span_id: The [SPAN_ID] for a span within a trace. + + :type type: Enum of :class:`~opencensus.trace.link.Type` + :param type: The relationship of the current span relative to the linked + span. + + :type attributes: :class:`~opencensus.trace.attributes.Attributes` + :param attributes: A set of attributes on the link. You have have up to 32 + attributes per link. + """ + def __init__(self, trace_id, span_id, type=None, attributes=None): + self.trace_id = trace_id + self.span_id = span_id + + if type is None: + type = Type.TYPE_UNSPECIFIED + + self.type = type + self.attributes = attributes + + def format_link_json(self): + """Convert a Link object to json format.""" + link_json = {} + link_json['trace_id'] = self.trace_id + link_json['span_id'] = self.span_id + link_json['type'] = self.type + + if self.attributes is not None: + link_json['attributes'] = self.attributes + + return link_json diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/logging_exporter.py b/.venv/lib/python3.11/site-packages/opencensus/trace/logging_exporter.py new file mode 100644 index 0000000000000000000000000000000000000000..5852ffc5749bc1ee05280782f1f85556cccb7982 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/logging_exporter.py @@ -0,0 +1,85 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Export the spans data to python logging.""" + +import logging + +from opencensus.common.transports import sync +from opencensus.trace import base_exporter, span_data + + +class LoggingExporter(base_exporter.Exporter): + """A exporter to export the spans data to python logging. Also can use + handlers like CloudLoggingHandler to log to Stackdriver Logging API. + + :type handler: :class:`logging.handler` + :param handler: the handler to attach to the global handler + + :type transport: :class:`type` + :param transport: Class for creating new transport objects. It should + extend from the base_exporter :class:`.Transport` type + and implement :meth:`.Transport.export`. Defaults to + :class:`.SyncTransport`. The other option is + :class:`.AsyncTransport`. + + Example: + + .. code-block:: python + + import google.cloud.logging + from google.cloud.logging.handlers import CloudLoggingHandler + from opencensus.trace import logging_exporter + + client = google.cloud.logging.Client() + cloud_handler = CloudLoggingHandler(client) + exporter = logging_exporter.LoggingExporter(handler=cloud_handler) + + exporter.export(your_spans_list) + + Or initialize a context tracer with the logging exporter, then the traces + will be exported to logging when finished. + """ + + def __init__(self, handler=None, transport=sync.SyncTransport): + self.logger = logging.getLogger() + + if handler is None: + handler = logging.StreamHandler() + + self.handler = handler + self.logger.addHandler(handler) + self.logger.setLevel(logging.INFO) + self.transport = transport(self) + + def emit(self, span_datas): + """ + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to emit + """ + # convert to the legacy trace json for easier refactoring + # TODO: refactor this to use the span data directly + legacy_trace_json = span_data.format_legacy_trace_json(span_datas) + self.logger.info(legacy_trace_json) + + def export(self, span_datas): + """ + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to export + """ + self.transport.export(span_datas) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/print_exporter.py b/.venv/lib/python3.11/site-packages/opencensus/trace/print_exporter.py new file mode 100644 index 0000000000000000000000000000000000000000..c989e0a00404964f94136c8710b95eda57bdd766 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/print_exporter.py @@ -0,0 +1,51 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Export the trace spans by printing them out.""" + +from opencensus.common.transports import sync +from opencensus.trace import base_exporter + + +class PrintExporter(base_exporter.Exporter): + """Export the spans by printing them. + + :type transport: :class:`type` + :param transport: Class for creating new transport objects. It should + extend from the base_exporter :class:`.Transport` type + and implement :meth:`.Transport.export`. Defaults to + :class:`.SyncTransport`. The other option is + :class:`.AsyncTransport`. + """ + + def __init__(self, transport=sync.SyncTransport): + self.transport = transport(self) + + def emit(self, span_datas): + """ + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to emit + """ + print(span_datas) + + def export(self, span_datas): + """ + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to export + """ + self.transport.export(span_datas) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__init__.py b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bab6aa58152f47b2217e4ce52304f2e7ce5e1c8b --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d9ecde3f5cd9f31e3d3e41b6f4937626a3fea3d Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/__init__.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/b3_format.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/b3_format.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9986b175d4552e4e94f4d8245d3c78b010df314 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/b3_format.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/binary_format.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/binary_format.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1034c1548167ae2f8418c7a1eccf31d46fa238c Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/binary_format.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/google_cloud_format.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/google_cloud_format.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c0338160dc89f41f0282dbd57e66d0cafcf328c Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/google_cloud_format.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/text_format.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/text_format.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bba14c598e732bc748131e26a17d66b3ef093368 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/text_format.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/trace_context_http_header_format.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/trace_context_http_header_format.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ba7bcfaa8bf1b2eb4ce86d68c7bd6b31727fbc3 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/trace_context_http_header_format.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/tracestate_string_format.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/tracestate_string_format.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d28a83dce01804b828cf53a84d95766f6e2d75ad Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/__pycache__/tracestate_string_format.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/b3_format.py b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/b3_format.py new file mode 100644 index 0000000000000000000000000000000000000000..d8a87021d1bc041f69d79bb4e43a41f999ae0862 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/b3_format.py @@ -0,0 +1,117 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from opencensus.trace.span_context import INVALID_SPAN_ID, SpanContext +from opencensus.trace.trace_options import TraceOptions + +_STATE_HEADER_KEY = 'b3' +_TRACE_ID_KEY = 'x-b3-traceid' +_SPAN_ID_KEY = 'x-b3-spanid' +_SAMPLED_KEY = 'x-b3-sampled' + + +class B3FormatPropagator(object): + """Propagator for the B3 HTTP header format. + + See: https://github.com/openzipkin/b3-propagation + """ + + def from_headers(self, headers): + """Generate a SpanContext object from B3 propagation headers. + + :type headers: dict + :param headers: HTTP request headers. + + :rtype: :class:`~opencensus.trace.span_context.SpanContext` + :returns: SpanContext generated from B3 propagation headers. + """ + if headers is None: + return SpanContext(from_header=False) + + trace_id, span_id, sampled = None, None, None + + state = headers.get(_STATE_HEADER_KEY) + if state: + fields = state.split('-', 4) + + if len(fields) == 1: + sampled = fields[0] + elif len(fields) == 2: + trace_id, span_id = fields + elif len(fields) == 3: + trace_id, span_id, sampled = fields + elif len(fields) == 4: + trace_id, span_id, sampled, _parent_span_id = fields + else: + return SpanContext(from_header=False) + else: + trace_id = headers.get(_TRACE_ID_KEY) + span_id = headers.get(_SPAN_ID_KEY) + sampled = headers.get(_SAMPLED_KEY) + + if sampled is not None: + # The specification encodes an enabled tracing decision as "1". + # In the wild pre-standard implementations might still send "true". + # "d" is set in the single header case when debugging is enabled. + sampled = sampled.lower() in ('1', 'd', 'true') + else: + # If there's no incoming sampling decision, it was deferred to us. + # Even though we set it to False here, we might still sample + # depending on the tracer configuration. + sampled = False + + trace_options = TraceOptions() + trace_options.set_enabled(sampled) + + # TraceId and SpanId headers both have to exist + if not trace_id or not span_id: + return SpanContext(trace_options=trace_options) + + # Convert 64-bit trace ids to 128-bit + if len(trace_id) == 16: + trace_id = '0'*16 + trace_id + + span_context = SpanContext( + trace_id=trace_id, + span_id=span_id, + trace_options=trace_options, + from_header=True + ) + + return span_context + + def to_headers(self, span_context): + """Convert a SpanContext object to B3 propagation headers. + + :type span_context: + :class:`~opencensus.trace.span_context.SpanContext` + :param span_context: SpanContext object. + + :rtype: dict + :returns: B3 propagation headers. + """ + + if not span_context.span_id: + span_id = INVALID_SPAN_ID + else: + span_id = span_context.span_id + + sampled = span_context.trace_options.enabled + + return { + _TRACE_ID_KEY: span_context.trace_id, + _SPAN_ID_KEY: span_id, + _SAMPLED_KEY: '1' if sampled else '0' + } diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/binary_format.py b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/binary_format.py new file mode 100644 index 0000000000000000000000000000000000000000..b6e5b64d0b5180017e4eb44a9009e583affdc115 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/binary_format.py @@ -0,0 +1,168 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import binascii +import collections +import logging +import struct + +from opencensus.trace import span_context as span_context_module +from opencensus.trace.trace_options import TraceOptions + +# Used for decoding hex bytes to hex string. +UTF8 = 'utf-8' + +VERSION_ID = 0 +TRACE_ID_FIELD_ID = 0 +SPAN_ID_FIELD_ID = 1 +TRACE_OPTION_FIELD_ID = 2 + +# Sizes are number of bytes. +ID_SIZE = 1 +TRACE_ID_SIZE = 16 +SPAN_ID_SIZE = 8 +TRACE_OPTION_SIZE = 1 + +FORMAT_LENGTH = 4 * ID_SIZE + TRACE_ID_SIZE + SPAN_ID_SIZE + TRACE_OPTION_SIZE + +# See: https://docs.python.org/3/library/struct.html#format-characters +BIG_ENDIAN = '>' +CHAR_ARRAY_FORMAT = 's' +UNSIGNED_CHAR = 'B' +UNSIGNED_LONG_LONG = 'Q' + +# Adding big endian indicator at the beginning to avoid auto padding. This is +# for ensuring the length of binary is not changed when propagating. +BINARY_FORMAT = '{big_endian}{version_id}' \ + '{trace_id_field_id}{trace_id}' \ + '{span_id_field_id}{span_id}' \ + '{trace_option_field_id}{trace_option}'\ + .format( + big_endian=BIG_ENDIAN, + version_id=UNSIGNED_CHAR, + trace_id_field_id=UNSIGNED_CHAR, + trace_id='{}{}'.format(TRACE_ID_SIZE, CHAR_ARRAY_FORMAT), + span_id_field_id=UNSIGNED_CHAR, + span_id='{}{}'.format(SPAN_ID_SIZE, CHAR_ARRAY_FORMAT), + trace_option_field_id=UNSIGNED_CHAR, + trace_option=UNSIGNED_CHAR) + +Header = collections.namedtuple( + 'Header', + 'version_id ' + 'trace_id_field_id ' + 'trace_id ' + 'span_id_field_id ' + 'span_id ' + 'trace_option_field_id ' + 'trace_option') + + +class BinaryFormatPropagator(object): + """This propagator contains the method for serializing and deserializing + SpanContext using a binary format. + + See: https://github.com/census-instrumentation/opencensus-specs/blob/ + master/encodings/BinaryEncoding.md + + Example: + [SpanContext] + trace_id: hex string with length 32. + e.g. 'a0b72ca15c1a4bd18962d0ac59dc90b9' + span_id: hex string with length 16. + e.g. 'a0b72ca15c1a4bd1' + enabled (trace option): bool. + e.g. True + [Binary Format] + trace_id: Bytes with length 16. + e.g. b'\xa0\xb7,\xa1\\\x1aK\xd1\x89b\xd0\xacY\xdc\x90\xb9' + span_id: Bytes with length 8. + e.g. b'\x00\xf0g\xaa\x0b\xa9\x02\xb7' + trace_option: Byte with length 1. + e.g. b'\x01' + """ + def from_header(self, binary): + """Generate a SpanContext object using the trace context header. + The value of enabled parsed from header is int. Need to convert to + bool. + + :type binary: bytes + :param binary: Trace context header which was extracted from the + request headers. + + :rtype: :class:`~opencensus.trace.span_context.SpanContext` + :returns: SpanContext generated from the trace context header. + """ + # If no binary provided, generate a new SpanContext + if binary is None: + return span_context_module.SpanContext(from_header=False) + + # If cannot parse, return a new SpanContext and ignore the context + # from binary. + try: + data = Header._make(struct.unpack(BINARY_FORMAT, binary)) + except struct.error: + logging.warning( + 'Cannot parse the incoming binary data {}, ' + 'wrong format. Total bytes length should be {}.'.format( + binary, FORMAT_LENGTH + ) + ) + return span_context_module.SpanContext(from_header=False) + + # data.trace_id is in bytes with length 16, hexlify it to hex bytes + # with length 32, then decode it to hex string using utf-8. + trace_id = str(binascii.hexlify(data.trace_id).decode(UTF8)) + span_id = str(binascii.hexlify(data.span_id).decode(UTF8)) + trace_options = TraceOptions(data.trace_option) + + span_context = span_context_module.SpanContext( + trace_id=trace_id, + span_id=span_id, + trace_options=trace_options, + from_header=True) + + return span_context + + def to_header(self, span_context): + """Convert a SpanContext object to header in binary format. + + :type span_context: + :class:`~opencensus.trace.span_context.SpanContext` + :param span_context: SpanContext object. + + :rtype: bytes + :returns: A trace context header in binary format. + """ + trace_id = span_context.trace_id + span_id = span_context.span_id + trace_options = int(span_context.trace_options.trace_options_byte) + + # If there is no span_id in this context, set it to 0, which is + # considered invalid and won't be set as the downstream parent span_id. + if span_id is None: + span_id = span_context_module.INVALID_SPAN_ID + + # Convert trace_id to bytes with length 16, treat span_id as 64 bit + # integer which is unsigned long long type and convert it to bytes with + # length 8, trace_option is integer with length 1. + return struct.pack( + BINARY_FORMAT, + VERSION_ID, + TRACE_ID_FIELD_ID, + binascii.unhexlify(trace_id), + SPAN_ID_FIELD_ID, + binascii.unhexlify(span_id), + TRACE_OPTION_FIELD_ID, + trace_options) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/google_cloud_format.py b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/google_cloud_format.py new file mode 100644 index 0000000000000000000000000000000000000000..32ac8ccbafddd363e37d00cdce6316d0f12c0db8 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/google_cloud_format.py @@ -0,0 +1,128 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import re + +from opencensus.trace.span_context import SpanContext +from opencensus.trace.trace_options import TraceOptions + +_TRACE_CONTEXT_HEADER_NAME = 'X-Cloud-Trace-Context' +_TRACE_CONTEXT_HEADER_FORMAT = r'([0-9a-f]{32})(\/([\d]{0,20}))?(;o=(\d+))?' +_TRACE_CONTEXT_HEADER_RE = re.compile(_TRACE_CONTEXT_HEADER_FORMAT) +_TRACE_ID_DELIMETER = '/' +_SPAN_ID_DELIMETER = ';' + + +class GoogleCloudFormatPropagator(object): + """This class is for converting the trace header in google cloud format + and generate a SpanContext, or converting a SpanContext to a google cloud + format header. Later we will add implementation for supporting other + format like binary format and zipkin, opencensus format. + """ + def from_header(self, header): + """Generate a SpanContext object using the trace context header. + The value of enabled parsed from header is int. Need to convert to + bool. + + :type header: str + :param header: Trace context header which was extracted from the HTTP + request headers. + + :rtype: :class:`~opencensus.trace.span_context.SpanContext` + :returns: SpanContext generated from the trace context header. + """ + if header is None: + return SpanContext() + + try: + match = re.search(_TRACE_CONTEXT_HEADER_RE, header) + except TypeError: + logging.warning( + 'Header should be str, got %s. Cannot parse the header.', + header.__class__.__name__) + raise + + if match: + trace_id = match.group(1) + span_id = match.group(3) + trace_options = match.group(5) + + if trace_options is None: + trace_options = 1 + + if span_id: + span_id = '{:016x}'.format(int(span_id)) + + span_context = SpanContext( + trace_id=trace_id, + span_id=span_id, + trace_options=TraceOptions(trace_options), + from_header=True) + return span_context + else: + logging.warning( + 'Cannot parse the header %s, generate a new context instead.', + header) + return SpanContext() + + def from_headers(self, headers): + """Generate a SpanContext object using the trace context header. + + :type headers: dict + :param headers: HTTP request headers. + + :rtype: :class:`~opencensus.trace.span_context.SpanContext` + :returns: SpanContext generated from the trace context header. + """ + if headers is None: + return SpanContext() + header = headers.get(_TRACE_CONTEXT_HEADER_NAME) + if header is None: + return SpanContext() + return self.from_header(header) + + def to_header(self, span_context): + """Convert a SpanContext object to header string. + + :type span_context: + :class:`~opencensus.trace.span_context.SpanContext` + :param span_context: SpanContext object. + + :rtype: str + :returns: A trace context header string in google cloud format. + """ + trace_id = span_context.trace_id + span_id = span_context.span_id + trace_options = span_context.trace_options.trace_options_byte + + header = '{}/{};o={}'.format( + trace_id, + int(span_id, 16), + int(trace_options)) + return header + + def to_headers(self, span_context): + """Convert a SpanContext object to HTTP request headers. + + :type span_context: + :class:`~opencensus.trace.span_context.SpanContext` + :param span_context: SpanContext object. + + :rtype: dict + :returns: Trace context headers in google cloud format. + """ + return { + _TRACE_CONTEXT_HEADER_NAME: self.to_header(span_context), + } diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/text_format.py b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/text_format.py new file mode 100644 index 0000000000000000000000000000000000000000..e0ae02f4d134d4b4e7684d70547636602496ec44 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/text_format.py @@ -0,0 +1,85 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.trace.span_context import SpanContext +from opencensus.trace.trace_options import TraceOptions + +_OPENCENSUS_TRACE_PREFIX = 'opencensus-trace' +_TRACE_ID_KEY = '{}-traceid'.format(_OPENCENSUS_TRACE_PREFIX) +_SPAN_ID_KEY = '{}-spanid'.format(_OPENCENSUS_TRACE_PREFIX) +_TRACE_OPTIONS_KEY = '{}-traceoptions'.format(_OPENCENSUS_TRACE_PREFIX) + +DEFAULT_TRACE_OPTIONS = '1' + + +class TextFormatPropagator(object): + """This class provides the basic utilities for extracting the trace + information from a carrier which is a dict to form a SpanContext. And + generating a dict using the provided SpanContext. + """ + def from_carrier(self, carrier): + """Generate a SpanContext object using the information in the carrier. + + :type carrier: dict + :param carrier: The carrier which has the trace_id, span_id, options + information for creating a SpanContext. + + :rtype: :class:`~opencensus.trace.span_context.SpanContext` + :returns: SpanContext generated from the carrier. + """ + trace_id = None + span_id = None + trace_options = None + + for key in carrier: + key = key.lower() + if key == _TRACE_ID_KEY: + trace_id = carrier[key] + if key == _SPAN_ID_KEY: + span_id = carrier[key] + if key == _TRACE_OPTIONS_KEY: + trace_options = bool(carrier[key]) + + if trace_options is None: + trace_options = DEFAULT_TRACE_OPTIONS + + return SpanContext( + trace_id=trace_id, + span_id=span_id, + trace_options=TraceOptions(trace_options), + from_header=True) + + def to_carrier(self, span_context, carrier): + """Inject the SpanContext fields to carrier dict. + + :type span_context: + :class:`~opencensus.trace.span_context.SpanContext` + :param span_context: SpanContext object. + + :type carrier: dict + :param carrier: The carrier which holds the trace_id, span_id, options + information from a SpanContext. + + :rtype: dict + :returns: The carrier which holds the span context information. + """ + carrier[_TRACE_ID_KEY] = str(span_context.trace_id) + + if span_context.span_id is not None: + carrier[_SPAN_ID_KEY] = str(span_context.span_id) + + carrier[_TRACE_OPTIONS_KEY] = str( + span_context.trace_options.trace_options_byte) + + return carrier diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/trace_context_http_header_format.py b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/trace_context_http_header_format.py new file mode 100644 index 0000000000000000000000000000000000000000..46cf61893bda4f1273d36cdc01fa92ca25d69c91 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/trace_context_http_header_format.py @@ -0,0 +1,115 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re + +from opencensus.trace.propagation.tracestate_string_format import ( + TracestateStringFormatter, +) +from opencensus.trace.span_context import SpanContext +from opencensus.trace.trace_options import TraceOptions + +_TRACEPARENT_HEADER_NAME = 'traceparent' +_TRACESTATE_HEADER_NAME = 'tracestate' +_TRACEPARENT_HEADER_FORMAT = \ + '^[ \t]*([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})' + \ + '(-.*)?[ \t]*$' +_TRACEPARENT_HEADER_FORMAT_RE = re.compile(_TRACEPARENT_HEADER_FORMAT) + + +class TraceContextPropagator(object): + """Propagator for processing the trace context HTTP header format.""" + + def from_headers(self, headers): + """Generate a SpanContext object using the W3C Distributed Tracing headers. + + :type headers: dict + :param headers: HTTP request headers. + + :rtype: :class:`~opencensus.trace.span_context.SpanContext` + :returns: SpanContext generated from the trace context header. + """ + if headers is None: + return SpanContext() + + header = headers.get(_TRACEPARENT_HEADER_NAME) + if header is None: + return SpanContext() + + match = re.search(_TRACEPARENT_HEADER_FORMAT_RE, header) + if not match: + return SpanContext() + + version = match.group(1) + trace_id = match.group(2) + span_id = match.group(3) + trace_options = match.group(4) + + if trace_id == '0' * 32 or span_id == '0' * 16: + return SpanContext() + + if version == '00': + if match.group(5): + return SpanContext() + if version == 'ff': + return SpanContext() + + span_context = SpanContext( + trace_id=trace_id, + span_id=span_id, + trace_options=TraceOptions(trace_options), + from_header=True) + + header = headers.get(_TRACESTATE_HEADER_NAME) + if header is None: + return span_context + try: + tracestate = TracestateStringFormatter().from_string(header) + if tracestate.is_valid(): + span_context.tracestate = \ + TracestateStringFormatter().from_string(header) + except ValueError: + pass + return span_context + + def to_headers(self, span_context): + """Convert a SpanContext object to W3C Distributed Tracing headers, + using version 0. + + :type span_context: + :class:`~opencensus.trace.span_context.SpanContext` + :param span_context: SpanContext object. + + :rtype: dict + :returns: W3C Distributed Tracing headers. + """ + trace_id = span_context.trace_id + span_id = span_context.span_id + trace_options = span_context.trace_options.enabled + + # Convert the trace options + trace_options = '01' if trace_options else '00' + + headers = { + _TRACEPARENT_HEADER_NAME: '00-{}-{}-{}'.format( + trace_id, + span_id, + trace_options + ), + } + tracestate = span_context.tracestate + if tracestate: + headers[_TRACESTATE_HEADER_NAME] = \ + TracestateStringFormatter().to_string(tracestate) + return headers diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/tracestate_string_format.py b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/tracestate_string_format.py new file mode 100644 index 0000000000000000000000000000000000000000..7680e8dec3f1cb9917a8208074b4f44ebe33d871 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/propagation/tracestate_string_format.py @@ -0,0 +1,43 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re + +from opencensus.trace.tracestate import _KEY_FORMAT, _VALUE_FORMAT, Tracestate + +_DELIMITER_FORMAT = '[ \t]*,[ \t]*' +_MEMBER_FORMAT = '(%s)(=)(%s)' % (_KEY_FORMAT, _VALUE_FORMAT) + +_DELIMITER_FORMAT_RE = re.compile(_DELIMITER_FORMAT) +_MEMBER_FORMAT_RE = re.compile(_MEMBER_FORMAT) + + +class TracestateStringFormatter(object): + def from_string(self, string): + tracestate = Tracestate() + for member in re.split(_DELIMITER_FORMAT_RE, string): + match = _MEMBER_FORMAT_RE.match(member) + if not match: + raise ValueError('illegal key-value format %r' % (member)) + key, eq, value = match.groups() + if key in tracestate: + raise ValueError('conflict key {!r}'.format(key)) + tracestate[key] = value + return tracestate + + def to_string(self, tracestate): + return ','.join(map( + lambda key: key + '=' + tracestate[key], + tracestate + )) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/samplers/__init__.py b/.venv/lib/python3.11/site-packages/opencensus/trace/samplers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0158abecf9bd0625f72854da9d68685697eb263d --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/samplers/__init__.py @@ -0,0 +1,94 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +DEFAULT_SAMPLING_RATE = 1e-4 + + +class Sampler(object): + """Base class for opencensus trace request samplers. + + Subclasses must override :meth:`should_sample`. + """ + + def should_sample(self, span_context): + """Whether to sample this request. + + :type span_context: :class:`opencensus.trace.span_context.SpanContext` + :param span_context: The span context. + + :rtype: bool + :returns: Whether to sample the request according to the context. + """ + raise NotImplementedError + + +class AlwaysOnSampler(Sampler): + """Sampler that samples every request, regardless of trace options.""" + + def should_sample(self, span_context): + return True + + +class AlwaysOffSampler(Sampler): + """Sampler that doesn't sample any request, regardless of trace options.""" + + def should_sample(self, span_context): + return False + + +class ProbabilitySampler(Sampler): + """Sample a request at a fixed rate. + + :type rate: float + :param rate: The rate of sampling. + """ + def __init__(self, rate=None): + if rate is None: + rate = DEFAULT_SAMPLING_RATE + + if not 0 <= rate <= 1: + raise ValueError('Rate must between 0 and 1.') + + self.rate = rate + + def should_sample(self, span_context): + """Make the sampling decision based on the lower 8 bytes of the trace + ID. If the value is less than the bound, return True, else False. + + :type span_context: :class:`opencensus.trace.span_context.SpanContext` + :param span_context: The span context. + + :rtype: bool + :returns: Whether to sample the request according to the context. + """ + if span_context.trace_options.get_enabled(): + return True + + lower_long = get_lower_long_from_trace_id(span_context.trace_id) + bound = self.rate * 0xffffffffffffffff + return lower_long <= bound + + +def get_lower_long_from_trace_id(trace_id): + """Returns the lower 8 bytes of the trace ID as a long value, assuming + little endian order. + + :rtype: long + :returns: Lower 8 bytes of trace ID + """ + lower_bytes = trace_id[16:] + lower_long = int(lower_bytes, 16) + + return lower_long diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/span.py b/.venv/lib/python3.11/site-packages/opencensus/trace/span.py new file mode 100644 index 0000000000000000000000000000000000000000..584a4bdc249a61fb21ab2ab81dee7dadcc1aa3d9 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/span.py @@ -0,0 +1,457 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +try: + from collections.abc import MutableMapping + from collections.abc import Sequence +except ImportError: + from collections import MutableMapping + from collections import Sequence + +import threading +from collections import OrderedDict, deque +from datetime import datetime +from itertools import chain + +from opencensus.common import utils +from opencensus.trace import attributes as attributes_module +from opencensus.trace import base_span +from opencensus.trace import link as link_module +from opencensus.trace import stack_trace as stack_trace_module +from opencensus.trace import status as status_module +from opencensus.trace import time_event +from opencensus.trace.span_context import generate_span_id +from opencensus.trace.tracers import base + +# https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/TraceConfig.md # noqa +MAX_NUM_ATTRIBUTES = 32 +MAX_NUM_ANNOTATIONS = 32 +MAX_NUM_MESSAGE_EVENTS = 128 +MAX_NUM_LINKS = 32 + + +class BoundedList(Sequence): + """An append only list with a fixed max size.""" + def __init__(self, maxlen): + self.dropped = 0 + self._dq = deque(maxlen=maxlen) + self._lock = threading.Lock() + + def __repr__(self): + return ("{}({}, maxlen={})" + .format( + type(self).__name__, + list(self._dq), + self._dq.maxlen + )) + + def __getitem__(self, index): + return self._dq[index] + + def __len__(self): + return len(self._dq) + + def __iter__(self): + return iter(self._dq) + + def append(self, item): + with self._lock: + if len(self._dq) == self._dq.maxlen: + self.dropped += 1 + self._dq.append(item) + + def extend(self, seq): + with self._lock: + to_drop = len(seq) + len(self._dq) - self._dq.maxlen + if to_drop > 0: + self.dropped += to_drop + self._dq.extend(seq) + + @classmethod + def from_seq(cls, maxlen, seq): + seq = tuple(seq) + if len(seq) > maxlen: + raise ValueError + bounded_list = cls(maxlen) + bounded_list._dq = deque(seq, maxlen=maxlen) + return bounded_list + + +class BoundedDict(MutableMapping): + """A dict with a fixed max capacity.""" + def __init__(self, maxlen): + self.maxlen = maxlen + self.dropped = 0 + self._dict = OrderedDict() + self._lock = threading.Lock() + + def __repr__(self): + return ("{}({}, maxlen={})" + .format( + type(self).__name__, + dict(self._dict), + self.maxlen + )) + + def __getitem__(self, key): + return self._dict[key] + + def __setitem__(self, key, value): + with self._lock: + if key in self._dict: + del self._dict[key] + elif len(self._dict) == self.maxlen: + del self._dict[next(iter(self._dict.keys()))] + self.dropped += 1 + self._dict[key] = value + + def __delitem__(self, key): + del self._dict[key] + + def __iter__(self): + return iter(self._dict) + + def __len__(self): + return len(self._dict) + + @classmethod + def from_map(cls, maxlen, mapping): + mapping = OrderedDict(mapping) + if len(mapping) > maxlen: + raise ValueError + bounded_dict = cls(maxlen) + bounded_dict._dict = mapping + return bounded_dict + + +class SpanKind(object): + UNSPECIFIED = 0 + SERVER = 1 + CLIENT = 2 + + +class Span(base_span.BaseSpan): + """A span is an individual timed event which forms a node of the trace + tree. Each span has its name, span id and parent id. The parent id + indicates the causal relationships between the individual spans in a + single distributed trace. Span that does not have a parent id is called + root span. All spans associated with a specific trace also share a common + trace id. Spans do not need to be continuous, there can be gaps between + two spans. + + :type name: str + :param name: The name of the span. + + :type parent_span: :class:`~opencensus.trace.span.Span` + :param parent_span: (Optional) Parent span. + + :type attributes: dict + :param attributes: Collection of attributes associated with the span. + Attribute keys must be less than 128 bytes. + Attribute values must be less than 16 kilobytes. + + :type start_time: str + :param start_time: (Optional) Start of the time interval (inclusive) + during which the trace data was collected from the + application. + + :type end_time: str + :param end_time: (Optional) End of the time interval (inclusive) during + which the trace data was collected from the application. + + :type span_id: int + :param span_id: Identifier for the span, unique within a trace. + + :type stack_trace: :class: `~opencensus.trace.stack_trace.StackTrace` + :param stack_trace: (Optional) A call stack appearing in a trace + + :type annotations: list(:class:`opencensus.trace.time_event.Annotation`) + :param annotations: (Optional) The list of span annotations. + + :type message_events: + list(:class:`opencensus.trace.time_event.MessageEvent`) + :param message_events: (Optional) The list of span message events. + + :type links: list + :param links: (Optional) Links associated with the span. You can have up + to 128 links per Span. + + :type status: :class: `~opencensus.trace.status.Status` + :param status: (Optional) An optional final status for this span. + + :type same_process_as_parent_span: bool + :param same_process_as_parent_span: (Optional) A highly recommended but not + required flag that identifies when a + trace crosses a process boundary. + True when the parent_span belongs to + the same process as the current span. + + :type context_tracer: :class:`~opencensus.trace.tracers.context_tracer. + ContextTracer` + :param context_tracer: The tracer that holds a stack of spans. If this is + not None, then when exiting a span, use the end_span + method in the tracer class to finish a span. If no + tracer is passed in, then just finish the span using + the finish method in the Span class. + + :type span_kind: int + :param span_kind: (Optional) Highly recommended flag that denotes the type + of span (valid values defined by :class: + `opencensus.trace.span.SpanKind`) + """ + + def __init__( + self, + name, + parent_span=None, + attributes=None, + start_time=None, + end_time=None, + span_id=None, + stack_trace=None, + annotations=None, + message_events=None, + links=None, + status=None, + same_process_as_parent_span=None, + context_tracer=None, + span_kind=SpanKind.UNSPECIFIED): + self.name = name + self.parent_span = parent_span + self.start_time = start_time + self.end_time = end_time + + if span_id is None: + span_id = generate_span_id() + + if attributes is None: + self.attributes = BoundedDict(MAX_NUM_ATTRIBUTES) + else: + self.attributes = BoundedDict.from_map( + MAX_NUM_ATTRIBUTES, attributes) + + # Do not manipulate spans directly using the methods in Span Class, + # make sure to use the Tracer. + if parent_span is None: + parent_span = base.NullContextManager() + + if annotations is None: + self.annotations = BoundedList(MAX_NUM_ANNOTATIONS) + else: + self.annotations = BoundedList.from_seq(MAX_NUM_LINKS, annotations) + + if message_events is None: + self.message_events = BoundedList(MAX_NUM_MESSAGE_EVENTS) + else: + self.message_events = BoundedList.from_seq( + MAX_NUM_LINKS, message_events) + + if links is None: + self.links = BoundedList(MAX_NUM_LINKS) + else: + self.links = BoundedList.from_seq(MAX_NUM_LINKS, links) + + if status is None: + self.status = status_module.Status.as_ok() + else: + self.status = status + + self.span_id = span_id + self.stack_trace = stack_trace + self.same_process_as_parent_span = same_process_as_parent_span + self._child_spans = [] + self.context_tracer = context_tracer + self.span_kind = span_kind + for callback in Span._on_create_callbacks: + callback(self) + + _on_create_callbacks = [] + + @staticmethod + def on_create(callback): + Span._on_create_callbacks.append(callback) + + @property + def children(self): + """The child spans of the current span.""" + return self._child_spans + + def span(self, name='child_span'): + """Create a child span for the current span and append it to the child + spans list. + + :type name: str + :param name: (Optional) The name of the child span. + + :rtype: :class: `~opencensus.trace.span.Span` + :returns: A child Span to be added to the current span. + """ + child_span = Span(name, parent_span=self) + self._child_spans.append(child_span) + return child_span + + def add_attribute(self, attribute_key, attribute_value): + """Add attribute to span. + + :type attribute_key: str + :param attribute_key: Attribute key. + + :type attribute_value:str + :param attribute_value: Attribute value. + """ + self.attributes[attribute_key] = attribute_value + + def add_annotation(self, description, **attrs): + """Add an annotation to span. + + :type description: str + :param description: A user-supplied message describing the event. + The maximum length for the description is 256 bytes. + + :type attrs: kwargs + :param attrs: keyworded arguments e.g. failed=True, name='Caching' + """ + self.annotations.append(time_event.Annotation( + datetime.utcnow(), + description, + attributes_module.Attributes(attrs) + )) + + def add_message_event(self, message_event): + """Add a message event to this span. + + :type message_event: :class:`opencensus.trace.time_event.MessageEvent` + :param message_event: The message event to attach to this span. + """ + self.message_events.append(message_event) + + def add_link(self, link): + """Add a Link. + + :type link: :class: `~opencensus.trace.link.Link` + :param link: A Link object. + """ + if isinstance(link, link_module.Link): + self.links.append(link) + else: + raise TypeError("Type Error: received {}, but requires Link.". + format(type(link).__name__)) + + def set_status(self, status): + """Sets span status. + + :type code: :class: `~opencensus.trace.status.Status` + :param code: A Status object. + """ + if isinstance(status, status_module.Status): + self.status = status + else: + raise TypeError("Type Error: received {}, but requires Status.". + format(type(status).__name__)) + + def start(self): + """Set the start time for a span.""" + self.start_time = utils.to_iso_str() + + def finish(self): + """Set the end time for a span.""" + self.end_time = utils.to_iso_str() + + def __iter__(self): + """Iterate through the span tree.""" + for span in chain.from_iterable(map(iter, self.children)): + yield span + yield self + + def __enter__(self): + """Start a span.""" + self.start() + return self + + def __exit__(self, exception_type, exception_value, traceback): + """Finish a span.""" + if traceback is not None: + self.stack_trace =\ + stack_trace_module.StackTrace.from_traceback(traceback) + if exception_value is not None: + self.status = status_module.Status.from_exception(exception_value) + if self.context_tracer is not None: + self.context_tracer.end_span() + return + + self.finish() + + +def format_span_json(span): + """Helper to format a Span in JSON format. + + :type span: :class:`~opencensus.trace.span.Span` + :param span: A Span to be transferred to JSON format. + + :rtype: dict + :returns: Formatted Span. + """ + span_json = { + 'displayName': utils.get_truncatable_str(span.name), + 'spanId': span.span_id, + 'startTime': span.start_time, + 'endTime': span.end_time, + 'childSpanCount': len(span._child_spans) + } + + parent_span_id = None + + if span.parent_span is not None: + parent_span_id = span.parent_span.span_id + + if parent_span_id is not None: + span_json['parentSpanId'] = parent_span_id + + if span.attributes: + span_json['attributes'] = attributes_module.Attributes( + span.attributes).format_attributes_json() + + if span.stack_trace is not None: + span_json['stackTrace'] = span.stack_trace.format_stack_trace_json() + + formatted_time_events = [] + if span.annotations: + formatted_time_events.extend( + {'time': aa.timestamp, + 'annotation': aa.format_annotation_json()} + for aa in span.annotations) + if span.message_events: + formatted_time_events.extend( + {'time': aa.timestamp, + 'message_event': aa.format_message_event_json()} + for aa in span.message_events) + if formatted_time_events: + span_json['timeEvents'] = { + 'timeEvent': formatted_time_events + } + + if span.links: + span_json['links'] = { + 'link': [ + link.format_link_json() for link in span.links] + } + + if span.status is not None: + span_json['status'] = span.status.format_status_json() + + if span.same_process_as_parent_span is not None: + span_json['sameProcessAsParentSpan'] = \ + span.same_process_as_parent_span + + return span_json diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/span_context.py b/.venv/lib/python3.11/site-packages/opencensus/trace/span_context.py new file mode 100644 index 0000000000000000000000000000000000000000..ed190a34508573d8a5aa035ec5858f51bde74bf3 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/span_context.py @@ -0,0 +1,168 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""SpanContext encapsulates the current context within the request's trace.""" + +import six + +import logging +import random +import re + +from opencensus.trace import trace_options as trace_options_module + +_INVALID_TRACE_ID = '0' * 32 +INVALID_SPAN_ID = '0' * 16 + +TRACE_ID_PATTERN = re.compile('[0-9a-f]{32}?') +SPAN_ID_PATTERN = re.compile('[0-9a-f]{16}?') + +# Default options, don't force sampling +DEFAULT_OPTIONS = '0' + + +class SpanContext(object): + """SpanContext includes 3 fields: traceId, spanId, and an trace_options flag + which indicates whether or not the request is being traced. It contains the + current context to be propagated to the child spans. + + :type trace_id: str + :param trace_id: (Optional) Trace_id is a 32 digits uuid for the trace. + If not given, will generate one automatically. + + :type span_id: str + :param span_id: (Optional) Identifier for the span, unique within a trace. + + :type trace_options: :class: `~opencensus.trace.trace_options.TraceOptions` + :param trace_options: (Optional) TraceOptions indicates 8 trace options. + + :type from_header: bool + :param from_header: (Optional) Indicates whether the trace context is + generated from request header. + """ + def __init__( + self, + trace_id=None, + span_id=None, + trace_options=None, + tracestate=None, + from_header=False): + if trace_id is None: + trace_id = generate_trace_id() + + if trace_options is None: + trace_options = trace_options_module.TraceOptions(DEFAULT_OPTIONS) + + self.from_header = from_header + self.trace_id = self._check_trace_id(trace_id) + self.span_id = self._check_span_id(span_id) + self.trace_options = trace_options + self.tracestate = tracestate + + def __repr__(self): + """Returns a string form of the SpanContext. + + :rtype: str + :returns: String form of the SpanContext. + """ + fmt = '{}(trace_id={}, span_id={}, trace_options={}, tracestate={})' + return fmt.format( + type(self).__name__, + self.trace_id, + self.span_id, + self.trace_options, + self.tracestate, + ) + + def _check_span_id(self, span_id): + """Check the format of the span_id to ensure it is 16-character hex + value representing a 64-bit number. If span_id is invalid, logs a + warning message and returns None + + :type span_id: str + :param span_id: Identifier for the span, unique within a span. + + :rtype: str + :returns: Span_id for the current span. + """ + if span_id is None: + return None + assert isinstance(span_id, six.string_types) + + if span_id is INVALID_SPAN_ID: + logging.warning( + 'Span_id %s is invalid (cannot be all zero)', span_id) + self.from_header = False + return None + + match = SPAN_ID_PATTERN.match(span_id) + + if match: + return span_id + else: + logging.warning( + 'Span_id %s does not the match the ' + 'required format', span_id) + self.from_header = False + return None + + def _check_trace_id(self, trace_id): + """Check the format of the trace_id to ensure it is 32-character hex + value representing a 128-bit number. If trace_id is invalid, returns a + randomly generated trace id + + :type trace_id: str + :param trace_id: + + :rtype: str + :returns: Trace_id for the current context. + """ + assert isinstance(trace_id, six.string_types) + + if trace_id is _INVALID_TRACE_ID: + logging.warning( + 'Trace_id %s is invalid (cannot be all zero), ' + 'generating a new one.', trace_id) + self.from_header = False + return generate_trace_id() + + match = TRACE_ID_PATTERN.match(trace_id) + + if match: + return trace_id + else: + logging.warning( + 'Trace_id %s does not the match the required format,' + 'generating a new one instead.', trace_id) + self.from_header = False + return generate_trace_id() + + +def generate_span_id(): + """Return the random generated span ID for a span. Must be a 16 character + hexadecimal encoded string + + :rtype: str + :returns: 16 digit randomly generated hex trace id. + """ + return '{:016x}'.format(random.getrandbits(64)) + + +def generate_trace_id(): + """Generate a random 32 char hex trace_id. + + :rtype: str + :returns: 32 digit randomly generated hex trace id. + """ + return '{:032x}'.format(random.getrandbits(128)) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/span_data.py b/.venv/lib/python3.11/site-packages/opencensus/trace/span_data.py new file mode 100644 index 0000000000000000000000000000000000000000..04daa77d4929065fb96feca952b2f6c0104e1e58 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/span_data.py @@ -0,0 +1,184 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import collections + +from opencensus.common import utils +from opencensus.trace import attributes + +_SpanData = collections.namedtuple( + '_SpanData', + ( + 'name', + 'context', + 'span_id', + 'parent_span_id', + 'attributes', + 'start_time', + 'end_time', + 'child_span_count', + 'stack_trace', + 'annotations', + 'message_events', + 'links', + 'status', + 'same_process_as_parent_span', + 'span_kind', + ), +) + + +class SpanData(_SpanData): + """Immutable representation of all data collected by a + :class: `~opencensus.trace.span.Span`. + + :type name: str + :param name: The name of the span. + + :type: context: :class: `~opencensus.trace.span_context.SpanContext` + :param context: The SpanContext of the Span + + :type span_id: int + :param span_id: Identifier for the span, unique within a trace. + + :type parent_span_id: int + :param parent_span_id: (Optional) Parent span id. + + :type attributes: dict + :param attributes: Collection of attributes associated with the span. + + :type start_time: str + :param start_time: (Optional) Start of the time interval (inclusive) + during which the trace data was collected from the + application. + + :type end_time: str + :param end_time: (Optional) End of the time interval (inclusive) during + which the trace data was collected from the application. + + :type child_span_count: int + :param child_span_count: the number of child spans that were + generated while the span was active. + + :type stack_trace: :class: `~opencensus.trace.stack_trace.StackTrace` + :param stack_trace: (Optional) A call stack appearing in a trace + + :type annotations: list(:class:`opencensus.trace.time_event.Annotation`) + :param annotations: (Optional) The list of span annotations. + + :type message_events: + list(:class:`opencensus.trace.time_event.MessageEvent`) + :param message_events: (Optional) The list of span message events. + + :type links: list + :param links: (Optional) Links associated with the span. You can have up + to 128 links per Span. + + :type status: :class: `~opencensus.trace.status.Status` + :param status: (Optional) An optional final status for this span. + + :type same_process_as_parent_span: bool + :param same_process_as_parent_span: (Optional) A highly recommended but not + required flag that identifies when a + trace crosses a process boundary. + True when the parent_span belongs to + the same process as the current span. + :type span_kind: int + :param span_kind: (Optional) Highly recommended flag that denotes the type + of span (valid values defined by :class: + `opencensus.trace.span.SpanKind`) + + """ + __slots__ = () + + +def _format_legacy_span_json(span_data): + """ + :param SpanData span_data: SpanData object to convert + :rtype: dict + :return: Dictionary representing the Span + """ + span_json = { + 'displayName': utils.get_truncatable_str(span_data.name), + 'spanId': span_data.span_id, + 'startTime': span_data.start_time, + 'endTime': span_data.end_time, + 'childSpanCount': span_data.child_span_count, + 'kind': span_data.span_kind + } + + if span_data.parent_span_id is not None: + span_json['parentSpanId'] = span_data.parent_span_id + + if span_data.attributes: + span_json['attributes'] = attributes.Attributes( + span_data.attributes).format_attributes_json() + + if span_data.stack_trace is not None: + span_json['stackTrace'] = \ + span_data.stack_trace.format_stack_trace_json() + + formatted_time_events = [] + if span_data.annotations: + formatted_time_events.extend( + {'time': aa.timestamp, + 'annotation': aa.format_annotation_json()} + for aa in span_data.annotations) + if span_data.message_events: + formatted_time_events.extend( + {'time': aa.timestamp, + 'message_event': aa.format_message_event_json()} + for aa in span_data.message_events) + if formatted_time_events: + span_json['timeEvents'] = { + 'timeEvent': formatted_time_events + } + + if span_data.links: + span_json['links'] = { + 'link': [ + link.format_link_json() for link in span_data.links] + } + + if span_data.status is not None: + span_json['status'] = span_data.status.format_status_json() + + if span_data.same_process_as_parent_span is not None: + span_json['sameProcessAsParentSpan'] = \ + span_data.same_process_as_parent_span + + return span_json + + +def format_legacy_trace_json(span_datas): + """Formats a list of SpanData tuples into the legacy 'trace' dictionary + format for backwards compatibility + :type span_datas: list of :class: + `~opencensus.trace.span_data.SpanData` + :param list of opencensus.trace.span_data.SpanData span_datas: + SpanData tuples to emit + :rtype: dict + :return: Legacy 'trace' dictionary representing given SpanData tuples + """ + if not span_datas: + return {} + top_span = span_datas[0] + assert isinstance(top_span, SpanData) + trace_id = top_span.context.trace_id if top_span.context is not None \ + else None + assert trace_id is not None + return { + 'traceId': trace_id, + 'spans': [_format_legacy_span_json(sd) for sd in span_datas], + } diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/stack_trace.py b/.venv/lib/python3.11/site-packages/opencensus/trace/stack_trace.py new file mode 100644 index 0000000000000000000000000000000000000000..2024b9fef58b743b024e3f36c2046893f0a5b008 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/stack_trace.py @@ -0,0 +1,189 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import hashlib +import os +import random +import traceback + +from opencensus.common.utils import get_truncatable_str + +MAX_FRAMES = 128 + +BUILD_ID = os.environ.get('BUILD_ID', 'unknown') +SOURCE_VERSION = os.environ.get('SOURCE_VERSION', 'unknown') + + +class StackFrame(object): + """Represents a single stack frame in a stack trace. + + :type func_name: str + :param func_name: The fully-qualified name that uniquely identifies the + function or method that is active in this frame (up to + 1024 bytes). + + :type original_func_name: str + :param original_func_name: An un-mangled function name, if functionName is + mangled. The name can be fully-qualified + (up to 1024 bytes). + + :type file_name: str + :param file_name: The name of the source file where the function call + appears (up to 256 bytes). + + :type line_num: int + :param line_num: The line number in fileName where the function call + appears. + + :type col_num: int + :param col_num: The column number where the function call appears, if + available. This is important in JavaScript because of its + anonymous functions. + + :type load_module: str + :param load_module: For example: main binary, kernel modules, and dynamic + libraries such as libc.so, sharedlib.so + (up to 256 bytes). + + :type build_id: str + :param build_id: A unique identifier for the module, usually a hash of its + contents (up to 128 bytes). + + + :type source_version: str + :param source_version: The version of the deployed source code + (up to 128 bytes). + """ + def __init__(self, + func_name, + original_func_name, + file_name, + line_num, + col_num, + load_module, + build_id, + source_version): + self.func_name = func_name + self.original_func_name = original_func_name + self.file_name = file_name + self.line_num = line_num + self.col_num = col_num + self.load_module = load_module + self.build_id = build_id + self.source_version = source_version + + def format_stack_frame_json(self): + """Convert StackFrame object to json format.""" + stack_frame_json = {} + stack_frame_json['function_name'] = get_truncatable_str( + self.func_name) + stack_frame_json['original_function_name'] = get_truncatable_str( + self.original_func_name) + stack_frame_json['file_name'] = get_truncatable_str(self.file_name) + stack_frame_json['line_number'] = self.line_num + stack_frame_json['column_number'] = self.col_num + stack_frame_json['load_module'] = { + 'module': get_truncatable_str(self.load_module), + 'build_id': get_truncatable_str(self.build_id), + } + stack_frame_json['source_version'] = get_truncatable_str( + self.source_version) + + return stack_frame_json + + +class StackTrace(object): + """A call stack appearing in a trace. + + :type stack_frames: list + :param stack_frames: Stack frames in this stack trace. A maximum of 128 + frames are allowed. + + :type stack_trace_hash_id: str + :param stack_trace_hash_id: The hash ID is used to conserve network + bandwidth for duplicate stack traces within a + single trace. + """ + def __init__(self, stack_frames=None, stack_trace_hash_id=None): + if stack_frames is None: + stack_frames = [] + if len(stack_frames) > MAX_FRAMES: + self.dropped_frames_count = len(stack_frames) - MAX_FRAMES + stack_frames = stack_frames[-MAX_FRAMES:] + else: + self.dropped_frames_count = 0 + + if stack_trace_hash_id is None: + stack_trace_hash_id = generate_hash_id() + + self.stack_frames = stack_frames + self.stack_trace_hash_id = stack_trace_hash_id + + @classmethod + def from_traceback(cls, tb): + """Initializes a StackTrace from a python traceback instance""" + stack_trace = cls( + stack_trace_hash_id=generate_hash_id_from_traceback(tb) + ) + # use the add_stack_frame so that json formatting is applied + for tb_frame_info in traceback.extract_tb(tb): + filename, line_num, fn_name, _ = tb_frame_info + stack_trace.add_stack_frame( + StackFrame( + func_name=fn_name, + original_func_name=fn_name, + file_name=filename, + line_num=line_num, + col_num=0, # I don't think this is available in python + load_module=filename, + build_id=BUILD_ID, + source_version=SOURCE_VERSION + ) + ) + return stack_trace + + def add_stack_frame(self, stack_frame): + """Add StackFrame to frames list.""" + if len(self.stack_frames) >= MAX_FRAMES: + self.dropped_frames_count += 1 + else: + self.stack_frames.append(stack_frame.format_stack_frame_json()) + + def format_stack_trace_json(self): + """Convert a StackTrace object to json format.""" + stack_trace_json = {} + + if self.stack_frames: + stack_trace_json['stack_frames'] = { + 'frame': self.stack_frames, + 'dropped_frames_count': self.dropped_frames_count + } + + stack_trace_json['stack_trace_hash_id'] = self.stack_trace_hash_id + + return stack_trace_json + + +def generate_hash_id(): + """Generate a hash id.""" + return random.getrandbits(64) + + +def generate_hash_id_from_traceback(tb): + m = hashlib.md5() # nosec + for tb_line in traceback.format_tb(tb): + m.update(tb_line.encode('utf-8')) + # truncate the hash for easier compatibility with StackDriver, + # should still be unique enough to avoid collisions + return int(m.hexdigest()[:12], 16) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/status.py b/.venv/lib/python3.11/site-packages/opencensus/trace/status.py new file mode 100644 index 0000000000000000000000000000000000000000..b0dca5061e121705488d452173354aae47a509fa --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/status.py @@ -0,0 +1,84 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from google.rpc import code_pb2 + + +class Status(object): + """The Status type defines a logical error model that is suitable for + different programming environments, including REST APIs and RPC APIs. + It is used by gRPC. + + :type code: int + :param code: An enum value of :class: `~google.rpc.Code`. + + :type message: str + :param message: A developer-facing error message, should be in English. + + :type details: list + :param details: A list of messages that carry the error details. + There is a common set of message types for APIs to use. + e.g. [ + { + "@type": string, + field1: ..., + ... + }, + ] + See: https://cloud.google.com/trace/docs/reference/v2/ + rest/v2/Status#FIELDS.details + """ + def __init__(self, code, message=None, details=None): + self.code = code + self.message = message + self.details = details + + @property + def canonical_code(self): + return self.code + + @property + def description(self): + return self.message + + @property + def is_ok(self): + return self.canonical_code == code_pb2.OK + + def format_status_json(self): + """Convert a Status object to json format.""" + status_json = {} + + status_json['code'] = self.canonical_code + + if self.description is not None: + status_json['message'] = self.description + + if self.details is not None: + status_json['details'] = self.details + + return status_json + + @classmethod + def from_exception(cls, exc): + return cls( + code=code_pb2.UNKNOWN, + message=str(exc) + ) + + @classmethod + def as_ok(cls): + return cls( + code=code_pb2.OK, + ) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/time_event.py b/.venv/lib/python3.11/site-packages/opencensus/trace/time_event.py new file mode 100644 index 0000000000000000000000000000000000000000..2f12b453b1e76fdf38ae5069a78070aa671d1072 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/time_event.py @@ -0,0 +1,117 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.common import utils + + +class Type(object): + """ + Indicates whether the message was sent or received. + + Attributes: + TYPE_UNSPECIFIED (int): Unknown event type. + SENT (int): Indicates a sent message. + RECEIVED (int): Indicates a received message. + """ + TYPE_UNSPECIFIED = 0 + SENT = 1 + RECEIVED = 2 + + +class Annotation(object): + """Text annotation with a set of attributes. + + :type timestamp: :class:`~datetime.datetime` + :param timestamp: The timestamp indicating the time the event occurred. + + :type description: str + :param description: A user-supplied message describing the event. + The maximum length for the description is 256 bytes. + + :type attributes: :class:`~opencensus.trace.attributes.Attributes` + :param attributes: A set of attributes on the annotation. + You can have up to 4 attributes per Annotation. + """ + def __init__(self, timestamp, description, attributes=None): + self.timestamp = utils.to_iso_str(timestamp) + self.description = description + self.attributes = attributes + + def format_annotation_json(self): + annotation_json = {} + annotation_json['description'] = utils.get_truncatable_str( + self.description) + + if self.attributes is not None: + annotation_json['attributes'] = self.attributes.\ + format_attributes_json() + + return annotation_json + + +class MessageEvent(object): + """An event describing a message sent/received between Spans. + + :type timestamp: :class:`~datetime.datetime` + :param timestamp: The timestamp indicating the time the event occurred. + + :type type: Enum of :class: `~opencensus.trace.time_event.Type` + :param type: Indicates whether the message was sent or received. + + :type id: str (int64 format) + :param id: An identifier for the MessageEvent's message that can be used + to match SENT and RECEIVED MessageEvents. It is recommended to + be unique within a Span. + + :type uncompressed_size_bytes: str (int64 format) + :param uncompressed_size_bytes: The number of uncompressed bytes sent or + received. + + :type compressed_size_bytes: str (int64 format) + :param compressed_size_bytes: The number of compressed bytes sent or + received. If missing assumed to be the same + size as uncompressed. + + """ + def __init__(self, timestamp, id, type=None, uncompressed_size_bytes=None, + compressed_size_bytes=None): + self.timestamp = utils.to_iso_str(timestamp) + + if type is None: + type = Type.TYPE_UNSPECIFIED + + if compressed_size_bytes is None and \ + uncompressed_size_bytes is not None: + compressed_size_bytes = uncompressed_size_bytes + + self.id = id + self.type = type + self.uncompressed_size_bytes = uncompressed_size_bytes + self.compressed_size_bytes = compressed_size_bytes + + def format_message_event_json(self): + message_event_json = {} + + message_event_json['id'] = self.id + message_event_json['type'] = self.type + + if self.uncompressed_size_bytes is not None: + message_event_json[ + 'uncompressed_size_bytes'] = self.uncompressed_size_bytes + + if self.compressed_size_bytes is not None: + message_event_json[ + 'compressed_size_bytes'] = self.compressed_size_bytes + + return message_event_json diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/trace_options.py b/.venv/lib/python3.11/site-packages/opencensus/trace/trace_options.py new file mode 100644 index 0000000000000000000000000000000000000000..cac1bf849647396d6091dabf5e5f0ec57cd2cf5b --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/trace_options.py @@ -0,0 +1,78 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +# Enabled field is the least significant bit of trace options. +_ENABLED_BITMASK = 1 << 0 + +# Default trace options +DEFAULT = '1' + + +class TraceOptions(object): + """A class that represents global trace options. + + :type trace_options_byte: str + :param trace_options_byte: 1 byte bitmap for trace options. + """ + + def __init__(self, trace_options_byte=None): + if trace_options_byte is None: + trace_options_byte = DEFAULT + + self.trace_options_byte = self.check_trace_options(trace_options_byte) + self.enabled = self.get_enabled() + + def check_trace_options(self, trace_options_byte): + trace_options_int = int(trace_options_byte) + + if trace_options_int < 0 or trace_options_int > 255: + logging.warning("Trace options invalid, should be 1 byte.") + trace_options_byte = DEFAULT + + return trace_options_byte + + def __repr__(self): + fmt = '{}(enabled={})' + return fmt.format( + type(self).__name__, + self.get_enabled(), + ) + + def get_enabled(self): + """Get the last bit from the trace options which is the enabled field. + + :type trace_options: byte + :param trace_options: 1 byte field which indicates 8 trace options, + currently only have the enabled option. 1 means + enabled, 0 means not enabled. + + :rtype: bool + :returns: Enabled tracing or not. + """ + enabled = bool(int(self.trace_options_byte) & _ENABLED_BITMASK) + + return enabled + + def set_enabled(self, enabled): + """Update the last bit of the trace options byte str. + + :type enabled: bool + :param enabled: Whether enable tracing in this span context or not. + """ + enabled_bit = '1' if enabled else '0' + self.trace_options_byte = str( + self.trace_options_byte)[:-1] + enabled_bit + self.enabled = self.get_enabled() diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracer.py b/.venv/lib/python3.11/site-packages/opencensus/trace/tracer.py new file mode 100644 index 0000000000000000000000000000000000000000..130dd9ec71c970e91fcb2ebf24da8e0bf3e9d606 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/tracer.py @@ -0,0 +1,144 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.trace import execution_context, print_exporter, samplers +from opencensus.trace.propagation import trace_context_http_header_format +from opencensus.trace.span_context import SpanContext +from opencensus.trace.tracers import context_tracer, noop_tracer + + +class Tracer(object): + """The Tracer is for tracing a request for web applications. + + :type span_context: :class:`~opencensus.trace.span_context.SpanContext` + :param span_context: SpanContext encapsulates the current context within + the request's trace. + + :type sampler: :class:`~opencensus.trace.samplers.base.Sampler` + :param sampler: Instances of Sampler objects. Defaults to + :class:`.ProbabilitySampler`. Other options include + :class:`.AlwaysOnSampler` and :class:`.AlwaysOffSampler`. + + :type exporter: :class:`~opencensus.trace.base_exporter.exporter` + :param exporter: Instances of exporter objects. Default to + :class:`.Printexporter`. The rest options are + :class:`.Fileexporter`, :class:`.Printexporter`, + :class:`.Loggingexporter`, :class:`.Zipkinexporter`, + :class:`.GoogleCloudexporter` + """ + def __init__( + self, + span_context=None, + sampler=None, + exporter=None, + propagator=None): + if span_context is None: + span_context = SpanContext() + + if sampler is None: + sampler = samplers.ProbabilitySampler() + + if exporter is None: + exporter = print_exporter.PrintExporter() + + if propagator is None: + propagator = \ + trace_context_http_header_format.TraceContextPropagator() + + self.span_context = span_context + self.sampler = sampler + self.exporter = exporter + self.propagator = propagator + self.tracer = self.get_tracer() + self.store_tracer() + + def should_sample(self): + """Determine whether to sample this request or not. + If the context enables tracing, return True. + Else follow the decision of the sampler. + + :rtype: bool + :returns: Whether to trace the request or not. + """ + return self.sampler.should_sample(self.span_context) + + def get_tracer(self): + """Return a tracer according to the sampling decision.""" + sampled = self.should_sample() + + if sampled: + self.span_context.trace_options.set_enabled(True) + return context_tracer.ContextTracer( + exporter=self.exporter, + span_context=self.span_context) + return noop_tracer.NoopTracer() + + def store_tracer(self): + """Add the current tracer to thread_local""" + execution_context.set_opencensus_tracer(self) + + def finish(self): + """End all spans.""" + self.tracer.finish() + + def span(self, name='span'): + """Create a new span with the trace using the context information. + + :type name: str + :param name: The name of the span. + + :rtype: :class:`~opencensus.trace.span.Span` + :returns: The Span object. + """ + return self.tracer.span(name) + + def start_span(self, name='span'): + return self.tracer.start_span(name) + + def end_span(self): + """End a span. Update the span_id in SpanContext to the current span's + parent span id; Update the current span; Send the span to exporter. + """ + self.tracer.end_span() + + def current_span(self): + """Return the current span.""" + return self.tracer.current_span() + + def add_attribute_to_current_span(self, attribute_key, attribute_value): + """Add attribute to current span. + + :type attribute_key: str + :param attribute_key: Attribute key. + + :type attribute_value:str + :param attribute_value: Attribute value. + """ + self.tracer.add_attribute_to_current_span( + attribute_key, attribute_value) + + def trace_decorator(self): + """Decorator to trace a function.""" + + def decorator(func): + + def wrapper(*args, **kwargs): + self.tracer.start_span(name=func.__name__) + return_value = func(*args, **kwargs) + self.tracer.end_span() + return return_value + + return wrapper + + return decorator diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__init__.py b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bab6aa58152f47b2217e4ce52304f2e7ce5e1c8b --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/base.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1429d00ed594e316b9405852adb3121adb3ffdb5 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/base.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/context_tracer.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/context_tracer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..64b102da369d7468adfef31ababb45ca239a4754 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/context_tracer.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/noop_tracer.cpython-311.pyc b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/noop_tracer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bce4d4597ba1a021d7d1de75d36d58d410826711 Binary files /dev/null and b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/__pycache__/noop_tracer.cpython-311.pyc differ diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/base.py b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/base.py new file mode 100644 index 0000000000000000000000000000000000000000..1dca5c84e12077f07c2725357e7532de6b2d1783 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/base.py @@ -0,0 +1,82 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +class Tracer(object): + """Base class for Opencensus tracers. + + Subclasses of :class:`Tracer` must implement the below methods. + """ + def finish(self): + """End the spans and send to reporters.""" + raise NotImplementedError + + def span(self, name='span'): + """Create a new span with the trace using the context information. + + :type name: str + :param name: The name of the span. + + :rtype: :class:`~opencensus.trace.span.Span` + :returns: The Span object. + """ + raise NotImplementedError + + def start_span(self, name='span'): + """Start a span. + + :type name: str + :param name: The name of the span. + + :rtype: :class:`~opencensus.trace.span.Span` + :returns: The Span object. + """ + raise NotImplementedError + + def end_span(self): + """End a span. Remove the span from the span stack, and update the + span_id in TraceContext as the current span_id which is the peek + element in the span stack. + """ + raise NotImplementedError + + def current_span(self): + """Return the current span.""" + raise NotImplementedError + + def add_attribute_to_current_span(self, attribute_key, attribute_value): + raise NotImplementedError + + def list_collected_spans(self): + """List collected spans.""" + raise NotImplementedError + + +class NullContextManager(object): + """Empty object as a helper for faking Trace and Span when tracing is + disabled. + """ + def __init__(self, span_id=None, context_tracer=None): + self.name = None + self.span_id = span_id + self.context_tracer = context_tracer + + def __enter__(self): + return self # pragma: NO COVER + + def __exit__(self, exc_type, exc_value, traceback): + pass # pragma: NO COVER + + def span(self, name='span'): + return NullContextManager(context_tracer=self.context_tracer) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/context_tracer.py b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/context_tracer.py new file mode 100644 index 0000000000000000000000000000000000000000..137e5d0fd4c250d7ca1f76baabc8eb49a51a0452 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/context_tracer.py @@ -0,0 +1,176 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import threading + +from opencensus.trace import execution_context, print_exporter +from opencensus.trace import span as trace_span +from opencensus.trace import span_data as span_data_module +from opencensus.trace.span_context import SpanContext +from opencensus.trace.tracers import base + + +class ContextTracer(base.Tracer): + """The interface for tracing a request context. + + :type span_context: :class:`~opencensus.trace.span_context.SpanContext` + :param span_context: SpanContext encapsulates the current context within + the request's trace. + """ + + def __init__(self, exporter=None, span_context=None): + if exporter is None: + exporter = print_exporter.PrintExporter() + + if span_context is None: + span_context = SpanContext() + + self.exporter = exporter + self.span_context = span_context + self.trace_id = span_context.trace_id + self.root_span_id = span_context.span_id + + self._spans_list_condition = threading.Condition() + # List of spans to report + self._spans_list = [] + + def finish(self): + """Finish all spans + + :rtype: dict + :returns: JSON format trace. + """ + while self._spans_list: + self.end_span() + + def span(self, name='span'): + """Create a new span with the trace using the context information. + + :type name: str + :param name: The name of the span. + + :rtype: :class:`~opencensus.trace.span.Span` + :returns: The Span object. + """ + span = self.start_span(name=name) + return span + + def start_span(self, name='span'): + """Start a span. + + :type name: str + :param name: The name of the span. + + :rtype: :class:`~opencensus.trace.span.Span` + :returns: The Span object. + """ + parent_span = self.current_span() + + # If a span has remote parent span, then the parent_span.span_id + # should be the span_id from the request header. + if parent_span is None: + parent_span = base.NullContextManager( + span_id=self.span_context.span_id) + + span = trace_span.Span( + name, + parent_span=parent_span, + context_tracer=self) + with self._spans_list_condition: + self._spans_list.append(span) + self.span_context.span_id = span.span_id + execution_context.set_current_span(span) + span.start() + return span + + def end_span(self, *args, **kwargs): + """End a span. Update the span_id in SpanContext to the current span's + parent span id; Update the current span. + """ + cur_span = self.current_span() + if cur_span is None and self._spans_list: + cur_span = self._spans_list[-1] + + if cur_span is None: + logging.warning('No active span, cannot do end_span.') + return + + cur_span.finish() + self.span_context.span_id = cur_span.parent_span.span_id if \ + cur_span.parent_span else None + + if isinstance(cur_span.parent_span, trace_span.Span): + execution_context.set_current_span(cur_span.parent_span) + else: + execution_context.set_current_span(None) + + with self._spans_list_condition: + if cur_span in self._spans_list: + span_datas = self.get_span_datas(cur_span) + self.exporter.export(span_datas) + self._spans_list.remove(cur_span) + + return cur_span + + def current_span(self): + """Return the current span.""" + current_span = execution_context.get_current_span() + + return current_span + + def list_collected_spans(self): + return self._spans_list + + def add_attribute_to_current_span(self, attribute_key, attribute_value): + """Add attribute to current span. + + :type attribute_key: str + :param attribute_key: Attribute key. + + :type attribute_value:str + :param attribute_value: Attribute value. + """ + current_span = self.current_span() + current_span.add_attribute(attribute_key, attribute_value) + + def get_span_datas(self, span): + """Extracts a list of SpanData tuples from a span + + :rtype: list of opencensus.trace.span_data.SpanData + :return list of SpanData tuples + """ + span_datas = [ + span_data_module.SpanData( + name=ss.name, + context=self.span_context, + span_id=ss.span_id, + parent_span_id=ss.parent_span.span_id if + ss.parent_span else None, + attributes=ss.attributes, + start_time=ss.start_time, + end_time=ss.end_time, + child_span_count=len(ss.children), + stack_trace=ss.stack_trace, + annotations=ss.annotations, + message_events=ss.message_events, + links=ss.links, + status=ss.status, + same_process_as_parent_span=ss.same_process_as_parent_span, + span_kind=ss.span_kind + ) + for ss in span + ] + + return span_datas diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/noop_tracer.py b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/noop_tracer.py new file mode 100644 index 0000000000000000000000000000000000000000..71a16eb07ae79c630ed7218a50b1e463fe950dc2 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/tracers/noop_tracer.py @@ -0,0 +1,85 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from opencensus.trace import blank_span as trace_span +from opencensus.trace import trace_options +from opencensus.trace.span_context import SpanContext +from opencensus.trace.tracers import base + + +class NoopTracer(base.Tracer): + """No-op implementation of the :class:`Tracer` interface, all methods are + no-ops. Should be used when tracing is not enabled or not sampled. + """ + + def __init__(self): + + self.span_context = SpanContext( + trace_options=trace_options.TraceOptions(0) + ) + + def finish(self): + """End spans and send to reporter.""" + return None + + def span(self, name='span'): + """Create a new span with the trace using the context information. + + :type name: str + :param name: The name of the span. + + :rtype: :class:`~opencensus.trace.trace_span.Span` + :returns: The Span object. + """ + + span = self.start_span(name=name) + return span + + def start_span(self, name='span'): + """Start a span. + + :type name: str + :param name: The name of the span. + + :rtype: :class:`~opencensus.trace.trace_span.Span` + :returns: The Span object. + """ + span = trace_span.BlankSpan(name, context_tracer=self) + return span + + def end_span(self): + """End a span. Remove the span from the span stack, and update the + span_id in TraceContext as the current span_id which is the peek + element in the span stack. + """ + pass + + def current_span(self): + """Return the current span.""" + return trace_span.BlankSpan() + + def add_attribute_to_current_span(self, attribute_key, attribute_value): + """Add attribute to current span. + + :type attribute_key: str + :param attribute_key: Attribute key. + + :type attribute_value:str + :param attribute_value: Attribute value. + """ + return + + def list_collected_spans(self): + """List collected spans.""" + return None diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/tracestate.py b/.venv/lib/python3.11/site-packages/opencensus/trace/tracestate.py new file mode 100644 index 0000000000000000000000000000000000000000..a8666e661f6120227a9b8861a0e14301e8af552a --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/tracestate.py @@ -0,0 +1,65 @@ +# Copyright 2018, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re +from collections import OrderedDict + +_KEY_WITHOUT_VENDOR_FORMAT = r'[a-z][_0-9a-z\-\*\/]{0,255}' +_KEY_WITH_VENDOR_FORMAT = \ + r'[a-z][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}' +_KEY_FORMAT = _KEY_WITHOUT_VENDOR_FORMAT + '|' + _KEY_WITH_VENDOR_FORMAT +_VALUE_FORMAT = \ + r'[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]' + +_KEY_VALIDATION_RE = re.compile('^' + _KEY_FORMAT + '$') +_VALUE_VALIDATION_RE = re.compile('^' + _VALUE_FORMAT + '$') + + +class Tracestate(OrderedDict): + def __setitem__(self, key, value): + if not isinstance(key, str): + raise ValueError('key must be an instance of str') + if not re.match(_KEY_VALIDATION_RE, key): + raise ValueError('illegal key provided') + if not isinstance(value, str): + raise ValueError('value must be an instance of str') + if not re.match(_VALUE_VALIDATION_RE, value): + raise ValueError('illegal value provided') + super(Tracestate, self).__setitem__(key, value) + + def append(self, key, value): + if self.get(key): + del self[key] + self[key] = value + + # make this an optional choice instead of enforcement during put/update + # if the tracestate value size is bigger than 512 characters, the tracer + # CAN decide to forward the tracestate + def is_valid(self): + if len(self) == 0: + return False + # there can be a maximum of 32 list-members in a list + if len(self) > 32: + return False + return True + + def prepend(self, key, value): + self[key] = value + if hasattr(self, 'move_to_end'): + self.move_to_end(key, last=False) + else: # less performant way for Python 2.x + copy = OrderedDict(self) + self.clear() + self[key] = value + self.update(copy) diff --git a/.venv/lib/python3.11/site-packages/opencensus/trace/utils.py b/.venv/lib/python3.11/site-packages/opencensus/trace/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7088aa316bf8b0345b76c4fedaf0116009f7fdad --- /dev/null +++ b/.venv/lib/python3.11/site-packages/opencensus/trace/utils.py @@ -0,0 +1,128 @@ +# Copyright 2017, OpenCensus Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re + +from google.rpc import code_pb2 + +from opencensus.trace import execution_context +from opencensus.trace.status import Status + +# By default the excludelist urls are not tracing, currently just include the +# health check url. The paths are literal string matched instead of regular +# expressions. Do not include the '/' at the beginning of the path. +DEFAULT_EXCLUDELIST_PATHS = [ + '_ah/health', +] + +# Pattern for matching the 'https://', 'http://', 'ftp://' part. +URL_PATTERN = '^(https?|ftp):\\/\\/' + + +def get_func_name(func): + """Return a name which includes the module name and function name.""" + func_name = getattr(func, '__name__', func.__class__.__name__) + module_name = func.__module__ + + if module_name is not None: + module_name = func.__module__ + return '{}.{}'.format(module_name, func_name) + + return func_name + + +def disable_tracing_url(url, excludelist_paths=None): + """Disable tracing on the provided excludelist paths, by default not tracing + the health check request. + + If the url path starts with the excludelisted path, return True. + + :type excludelist_paths: list + :param excludelist_paths: Paths that not tracing. + + :rtype: bool + :returns: True if not tracing, False if tracing. + """ + if excludelist_paths is None: + excludelist_paths = DEFAULT_EXCLUDELIST_PATHS + + # Remove the 'https?|ftp://' if exists + url = re.sub(URL_PATTERN, '', url) + + # Split the url by the first '/' and get the path part + url_path = url.split('/', 1)[1] + + for path in excludelist_paths: + if url_path.startswith(path): + return True + + return False + + +def disable_tracing_hostname(url, excludelist_hostnames=None): + """Disable tracing for the provided excludelist URLs, by default not tracing + the exporter url. + + If the url path starts with the excludelisted path, return True. + + :type excludelist_hostnames: list + :param excludelist_hostnames: URL that not tracing. + + :rtype: bool + :returns: True if not tracing, False if tracing. + """ + if excludelist_hostnames is None: + # Exporter host_name are not traced by default + _tracer = execution_context.get_opencensus_tracer() + try: + excludelist_hostnames = [ + '{}:{}'.format( + _tracer.exporter.host_name, + _tracer.exporter.port + ) + ] + except(AttributeError): + excludelist_hostnames = [] + + return url in excludelist_hostnames + + +def status_from_http_code(http_code): + """Returns equivalent status from http status code + based on OpenCensus specs. + + :type http_code: int + :param http_code: HTTP request status code. + + :rtype: int + :returns: A instance of :class: `~opencensus.trace.status.Status`. + """ + if http_code <= 199: + return Status(code_pb2.UNKNOWN) + + if http_code <= 399: + return Status(code_pb2.OK) + + grpc_code = { + 400: code_pb2.INVALID_ARGUMENT, + 401: code_pb2.UNAUTHENTICATED, + 403: code_pb2.PERMISSION_DENIED, + 404: code_pb2.NOT_FOUND, + 429: code_pb2.RESOURCE_EXHAUSTED, + 501: code_pb2.UNIMPLEMENTED, + 503: code_pb2.UNAVAILABLE, + 504: code_pb2.DEADLINE_EXCEEDED, + }.get(http_code, code_pb2.UNKNOWN) + + return Status(grpc_code) diff --git a/.venv/lib/python3.11/site-packages/proto/_package_info.py b/.venv/lib/python3.11/site-packages/proto/_package_info.py new file mode 100644 index 0000000000000000000000000000000000000000..75e89ebaac18b581197b10dc8b2e27111df621e1 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/proto/_package_info.py @@ -0,0 +1,50 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys + +from proto.marshal import Marshal + + +def compile(name, attrs): + """Return the package and marshal to use. + + Args: + name (str): The name of the new class, as sent to ``type.__new__``. + attrs (Mapping[str, Any]): The attrs for a new class, as sent + to ``type.__new__`` + + Returns: + Tuple[str, ~.Marshal]: + - The proto package, if any (empty string otherwise). + - The marshal object to use. + """ + # Pull a reference to the module where this class is being + # declared. + module = sys.modules.get(attrs.get("__module__")) + module_name = module.__name__ if hasattr(module, __name__) else "" + proto_module = getattr(module, "__protobuf__", object()) + + # A package should be present; get the marshal from there. + # TODO: Revert to empty string as a package value after protobuf fix. + # When package is empty, upb based protobuf fails with an + # "TypeError: Couldn't build proto file into descriptor pool: invalid name: empty part ()' means" + # during an attempt to add to descriptor pool. + package = getattr( + proto_module, "package", module_name if module_name else "_default_package" + ) + marshal = Marshal(name=getattr(proto_module, "marshal", package)) + + # Done; return the data. + return (package, marshal)