hexkit 6.0.0__tar.gz → 7.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hexkit-6.0.0/src/hexkit.egg-info → hexkit-7.0.0}/PKG-INFO +10 -9
- {hexkit-6.0.0 → hexkit-7.0.0}/pyproject.toml +14 -14
- hexkit-7.0.0/src/hexkit/opentelemetry.py +76 -0
- {hexkit-6.0.0 → hexkit-7.0.0/src/hexkit.egg-info}/PKG-INFO +10 -9
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit.egg-info/SOURCES.txt +0 -1
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit.egg-info/requires.txt +9 -8
- hexkit-6.0.0/src/hexkit/opentelemetry.py +0 -177
- hexkit-6.0.0/src/hexkit.egg-info/entry_points.txt +0 -2
- {hexkit-6.0.0 → hexkit-7.0.0}/LICENSE +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/MANIFEST.in +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/README.md +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/setup.cfg +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/__main__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/base.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/config.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/correlation.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/custom_types.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/log.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/dao.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/daopub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/daosub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/eventpub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/eventsub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/objstorage.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/config.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/daosub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/eventpub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/eventsub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/utils.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/testcontainer.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/testutils.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/migrations/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/migrations/_manager.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/migrations/_utils.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/migrations/helpers.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/provider.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/testutils.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/provider/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/provider/config.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/provider/daopub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/provider/persistent_pub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/testutils.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/provider.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/test_file1.yaml +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/test_file2.yaml +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/test_file3.yaml +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/test_file4.yaml +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/testutils/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/testutils/_fixtures.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/testutils/_typical_workflow.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/testutils/_utils.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/testing/__init__.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/testing/eventpub.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/py.typed +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/utils.py +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit.egg-info/dependency_links.txt +0 -0
- {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hexkit
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0
|
|
4
4
|
Summary: A Toolkit for Building Microservices using the Hexagonal Architecture
|
|
5
5
|
Author-email: "German Human Genome Phenome Archive (GHGA)" <contact@ghga.de>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -32,25 +32,26 @@ Requires-Dist: botocore<2,>=1.37; extra == "s3"
|
|
|
32
32
|
Provides-Extra: mongodb
|
|
33
33
|
Requires-Dist: pymongo<5,>=4.13; extra == "mongodb"
|
|
34
34
|
Provides-Extra: opentelemetry-base
|
|
35
|
-
Requires-Dist: opentelemetry-sdk<2,>=1.
|
|
36
|
-
Requires-Dist: opentelemetry-exporter-otlp<2,>=1.
|
|
37
|
-
Requires-Dist: opentelemetry-instrumentation>=0.
|
|
38
|
-
Requires-Dist: opentelemetry-instrumentation-httpx>=0.
|
|
35
|
+
Requires-Dist: opentelemetry-sdk<2,>=1.35.0; extra == "opentelemetry-base"
|
|
36
|
+
Requires-Dist: opentelemetry-exporter-otlp<2,>=1.35.0; extra == "opentelemetry-base"
|
|
37
|
+
Requires-Dist: opentelemetry-instrumentation>=0.56b0; extra == "opentelemetry-base"
|
|
38
|
+
Requires-Dist: opentelemetry-instrumentation-httpx>=0.56b0; extra == "opentelemetry-base"
|
|
39
|
+
Requires-Dist: opentelemetry-distro>=0.56b0; extra == "opentelemetry-base"
|
|
39
40
|
Provides-Extra: opentelemetry-akafka
|
|
40
41
|
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-akafka"
|
|
41
42
|
Requires-Dist: hexkit[akafka]; extra == "opentelemetry-akafka"
|
|
42
|
-
Requires-Dist: opentelemetry-instrumentation-aiokafka>=0.
|
|
43
|
+
Requires-Dist: opentelemetry-instrumentation-aiokafka>=0.56b0; extra == "opentelemetry-akafka"
|
|
43
44
|
Provides-Extra: opentelemetry-mongodb
|
|
44
45
|
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-mongodb"
|
|
45
46
|
Requires-Dist: hexkit[mongodb]; extra == "opentelemetry-mongodb"
|
|
46
|
-
Requires-Dist: opentelemetry-instrumentation-pymongo>=0.
|
|
47
|
+
Requires-Dist: opentelemetry-instrumentation-pymongo>=0.56b0; extra == "opentelemetry-mongodb"
|
|
47
48
|
Provides-Extra: opentelemetry-fastapi
|
|
48
49
|
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-fastapi"
|
|
49
|
-
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.
|
|
50
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.56b0; extra == "opentelemetry-fastapi"
|
|
50
51
|
Provides-Extra: opentelemetry-s3
|
|
51
52
|
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-s3"
|
|
52
53
|
Requires-Dist: hexkit[s3]; extra == "opentelemetry-s3"
|
|
53
|
-
Requires-Dist: opentelemetry-instrumentation-botocore>=0.
|
|
54
|
+
Requires-Dist: opentelemetry-instrumentation-botocore>=0.56b0; extra == "opentelemetry-s3"
|
|
54
55
|
Provides-Extra: opentelemetry
|
|
55
56
|
Requires-Dist: hexkit[opentelemetry-akafka]; extra == "opentelemetry"
|
|
56
57
|
Requires-Dist: hexkit[opentelemetry-mongodb]; extra == "opentelemetry"
|
|
@@ -24,7 +24,7 @@ classifiers = [
|
|
|
24
24
|
"Intended Audience :: Developers",
|
|
25
25
|
]
|
|
26
26
|
name = "hexkit"
|
|
27
|
-
version = "
|
|
27
|
+
version = "7.0.0"
|
|
28
28
|
description = "A Toolkit for Building Microservices using the Hexagonal Architecture"
|
|
29
29
|
dependencies = [
|
|
30
30
|
"opentelemetry-api >=1.31.1, <2",
|
|
@@ -49,29 +49,30 @@ mongodb = [
|
|
|
49
49
|
"pymongo >=4.13, <5",
|
|
50
50
|
]
|
|
51
51
|
opentelemetry-base = [
|
|
52
|
-
"opentelemetry-sdk >=1.
|
|
53
|
-
"opentelemetry-exporter-otlp >=1.
|
|
54
|
-
"opentelemetry-instrumentation >=0.
|
|
55
|
-
"opentelemetry-instrumentation-httpx >=0.
|
|
52
|
+
"opentelemetry-sdk >=1.35.0, <2",
|
|
53
|
+
"opentelemetry-exporter-otlp >=1.35.0, <2",
|
|
54
|
+
"opentelemetry-instrumentation >=0.56b0",
|
|
55
|
+
"opentelemetry-instrumentation-httpx >=0.56b0",
|
|
56
|
+
"opentelemetry-distro >=0.56b0",
|
|
56
57
|
]
|
|
57
58
|
opentelemetry-akafka = [
|
|
58
59
|
"hexkit[opentelemetry-base]",
|
|
59
60
|
"hexkit[akafka]",
|
|
60
|
-
"opentelemetry-instrumentation-aiokafka >=0.
|
|
61
|
+
"opentelemetry-instrumentation-aiokafka >=0.56b0",
|
|
61
62
|
]
|
|
62
63
|
opentelemetry-mongodb = [
|
|
63
64
|
"hexkit[opentelemetry-base]",
|
|
64
65
|
"hexkit[mongodb]",
|
|
65
|
-
"opentelemetry-instrumentation-pymongo >=0.
|
|
66
|
+
"opentelemetry-instrumentation-pymongo >=0.56b0",
|
|
66
67
|
]
|
|
67
68
|
opentelemetry-fastapi = [
|
|
68
69
|
"hexkit[opentelemetry-base]",
|
|
69
|
-
"opentelemetry-instrumentation-fastapi >=0.
|
|
70
|
+
"opentelemetry-instrumentation-fastapi >=0.56b0",
|
|
70
71
|
]
|
|
71
72
|
opentelemetry-s3 = [
|
|
72
73
|
"hexkit[opentelemetry-base]",
|
|
73
74
|
"hexkit[s3]",
|
|
74
|
-
"opentelemetry-instrumentation-botocore >=0.
|
|
75
|
+
"opentelemetry-instrumentation-botocore >=0.56b0",
|
|
75
76
|
]
|
|
76
77
|
opentelemetry = [
|
|
77
78
|
"hexkit[opentelemetry-akafka]",
|
|
@@ -102,9 +103,6 @@ all = [
|
|
|
102
103
|
[project.urls]
|
|
103
104
|
Repository = "https://github.com/ghga-de/hexkit"
|
|
104
105
|
|
|
105
|
-
[project.entry-points.opentelemetry_distro]
|
|
106
|
-
hexkit_distro = "hexkit.opentelemetry:HexkitDistro"
|
|
107
|
-
|
|
108
106
|
[tool.setuptools.packages.find]
|
|
109
107
|
where = [
|
|
110
108
|
"src",
|
|
@@ -226,7 +224,7 @@ source = [
|
|
|
226
224
|
[tool.tox]
|
|
227
225
|
legacy_tox_ini = """
|
|
228
226
|
[tox]
|
|
229
|
-
env_list = py3{9,12,13}
|
|
227
|
+
env_list = py3{9,10,11,12,13}
|
|
230
228
|
|
|
231
229
|
[gh-actions]
|
|
232
230
|
python =
|
|
@@ -242,5 +240,7 @@ legacy_tox_ini = """
|
|
|
242
240
|
DOCKER_HOST
|
|
243
241
|
deps =
|
|
244
242
|
--no-deps -r ./lock/requirements-dev.txt
|
|
245
|
-
commands =
|
|
243
|
+
commands =
|
|
244
|
+
py3{9,10}: pip install --no-deps backports.asyncio.runner==1.2.0 exceptiongroup==1.3.0 tomli==2.2.1
|
|
245
|
+
pytest {posargs}
|
|
246
246
|
"""
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Copyright 2021 - 2025 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln
|
|
2
|
+
# for the German Human Genome-Phenome Archive (GHGA)
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
"""OpenTelemetry specific configuration code. This is gated behind the opentelemetry extra."""
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
import os
|
|
19
|
+
from typing import Annotated
|
|
20
|
+
|
|
21
|
+
from opentelemetry import trace
|
|
22
|
+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
23
|
+
from opentelemetry.sdk.environment_variables import OTEL_SDK_DISABLED
|
|
24
|
+
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
|
25
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
26
|
+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
27
|
+
from opentelemetry.sdk.trace.sampling import ParentBasedTraceIdRatio
|
|
28
|
+
from pydantic import Field
|
|
29
|
+
from pydantic_settings import BaseSettings
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class OpenTelemetryConfig(BaseSettings):
|
|
35
|
+
"""OpenTelemetry specific configuration options"""
|
|
36
|
+
|
|
37
|
+
enable_opentelemetry: bool = Field(
|
|
38
|
+
default=False,
|
|
39
|
+
description="If set to true, this will run necessary setup code."
|
|
40
|
+
"If set to false, environment variables are set that should also effectively "
|
|
41
|
+
"disable autoinstrumentation.",
|
|
42
|
+
)
|
|
43
|
+
otel_trace_sampling_rate: Annotated[float, Field(strict=True, ge=0, le=1)] = Field(
|
|
44
|
+
default=1.0,
|
|
45
|
+
description="Determines which proportion of spans should be sampled. "
|
|
46
|
+
"A value of 1.0 means all and is equivalent to the previous behaviour. "
|
|
47
|
+
"Setting this to 0 will result in no spans being sampled, but this does not "
|
|
48
|
+
"automatically set `enable_opentelemetry` to False.",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def configure_opentelemetry(*, service_name: str, config: OpenTelemetryConfig):
|
|
53
|
+
"""Configure all needed parts of OpenTelemetry.
|
|
54
|
+
|
|
55
|
+
Setup of the TracerProvider is done programmatically, while disabling OpenTelemetry
|
|
56
|
+
sets the corresponding environment variable.
|
|
57
|
+
"""
|
|
58
|
+
if config.enable_opentelemetry:
|
|
59
|
+
resource = Resource(attributes={SERVICE_NAME: service_name})
|
|
60
|
+
# Replace the default static sampler with a probabilistic one that honors parent
|
|
61
|
+
# span sampling decisions
|
|
62
|
+
# This should consistently yield full traces within a service but not necessarily
|
|
63
|
+
# across service boundaries
|
|
64
|
+
# With the default sampling rate, behaviour does not change, but this allows to
|
|
65
|
+
# introduce head sampling by adjusting a config option on the service side later on
|
|
66
|
+
sampler = ParentBasedTraceIdRatio(rate=config.otel_trace_sampling_rate)
|
|
67
|
+
|
|
68
|
+
# Initialize service specific TracerProvider
|
|
69
|
+
trace_provider = TracerProvider(resource=resource, sampler=sampler)
|
|
70
|
+
processor = BatchSpanProcessor(OTLPSpanExporter())
|
|
71
|
+
trace_provider.add_span_processor(processor)
|
|
72
|
+
trace.set_tracer_provider(trace_provider)
|
|
73
|
+
else:
|
|
74
|
+
# Currently OTEL_SDK_DISABLED doesn't seem to be honored by all implementations yet
|
|
75
|
+
# It seems to be working well enough for the Python implementation.
|
|
76
|
+
os.environ[OTEL_SDK_DISABLED] = "true"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hexkit
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0
|
|
4
4
|
Summary: A Toolkit for Building Microservices using the Hexagonal Architecture
|
|
5
5
|
Author-email: "German Human Genome Phenome Archive (GHGA)" <contact@ghga.de>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -32,25 +32,26 @@ Requires-Dist: botocore<2,>=1.37; extra == "s3"
|
|
|
32
32
|
Provides-Extra: mongodb
|
|
33
33
|
Requires-Dist: pymongo<5,>=4.13; extra == "mongodb"
|
|
34
34
|
Provides-Extra: opentelemetry-base
|
|
35
|
-
Requires-Dist: opentelemetry-sdk<2,>=1.
|
|
36
|
-
Requires-Dist: opentelemetry-exporter-otlp<2,>=1.
|
|
37
|
-
Requires-Dist: opentelemetry-instrumentation>=0.
|
|
38
|
-
Requires-Dist: opentelemetry-instrumentation-httpx>=0.
|
|
35
|
+
Requires-Dist: opentelemetry-sdk<2,>=1.35.0; extra == "opentelemetry-base"
|
|
36
|
+
Requires-Dist: opentelemetry-exporter-otlp<2,>=1.35.0; extra == "opentelemetry-base"
|
|
37
|
+
Requires-Dist: opentelemetry-instrumentation>=0.56b0; extra == "opentelemetry-base"
|
|
38
|
+
Requires-Dist: opentelemetry-instrumentation-httpx>=0.56b0; extra == "opentelemetry-base"
|
|
39
|
+
Requires-Dist: opentelemetry-distro>=0.56b0; extra == "opentelemetry-base"
|
|
39
40
|
Provides-Extra: opentelemetry-akafka
|
|
40
41
|
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-akafka"
|
|
41
42
|
Requires-Dist: hexkit[akafka]; extra == "opentelemetry-akafka"
|
|
42
|
-
Requires-Dist: opentelemetry-instrumentation-aiokafka>=0.
|
|
43
|
+
Requires-Dist: opentelemetry-instrumentation-aiokafka>=0.56b0; extra == "opentelemetry-akafka"
|
|
43
44
|
Provides-Extra: opentelemetry-mongodb
|
|
44
45
|
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-mongodb"
|
|
45
46
|
Requires-Dist: hexkit[mongodb]; extra == "opentelemetry-mongodb"
|
|
46
|
-
Requires-Dist: opentelemetry-instrumentation-pymongo>=0.
|
|
47
|
+
Requires-Dist: opentelemetry-instrumentation-pymongo>=0.56b0; extra == "opentelemetry-mongodb"
|
|
47
48
|
Provides-Extra: opentelemetry-fastapi
|
|
48
49
|
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-fastapi"
|
|
49
|
-
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.
|
|
50
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.56b0; extra == "opentelemetry-fastapi"
|
|
50
51
|
Provides-Extra: opentelemetry-s3
|
|
51
52
|
Requires-Dist: hexkit[opentelemetry-base]; extra == "opentelemetry-s3"
|
|
52
53
|
Requires-Dist: hexkit[s3]; extra == "opentelemetry-s3"
|
|
53
|
-
Requires-Dist: opentelemetry-instrumentation-botocore>=0.
|
|
54
|
+
Requires-Dist: opentelemetry-instrumentation-botocore>=0.56b0; extra == "opentelemetry-s3"
|
|
54
55
|
Provides-Extra: opentelemetry
|
|
55
56
|
Requires-Dist: hexkit[opentelemetry-akafka]; extra == "opentelemetry"
|
|
56
57
|
Requires-Dist: hexkit[opentelemetry-mongodb]; extra == "opentelemetry"
|
|
@@ -15,7 +15,6 @@ src/hexkit/utils.py
|
|
|
15
15
|
src/hexkit.egg-info/PKG-INFO
|
|
16
16
|
src/hexkit.egg-info/SOURCES.txt
|
|
17
17
|
src/hexkit.egg-info/dependency_links.txt
|
|
18
|
-
src/hexkit.egg-info/entry_points.txt
|
|
19
18
|
src/hexkit.egg-info/requires.txt
|
|
20
19
|
src/hexkit.egg-info/top_level.txt
|
|
21
20
|
src/hexkit/protocols/__init__.py
|
|
@@ -23,27 +23,28 @@ hexkit[opentelemetry-s3]
|
|
|
23
23
|
[opentelemetry-akafka]
|
|
24
24
|
hexkit[opentelemetry-base]
|
|
25
25
|
hexkit[akafka]
|
|
26
|
-
opentelemetry-instrumentation-aiokafka>=0.
|
|
26
|
+
opentelemetry-instrumentation-aiokafka>=0.56b0
|
|
27
27
|
|
|
28
28
|
[opentelemetry-base]
|
|
29
|
-
opentelemetry-sdk<2,>=1.
|
|
30
|
-
opentelemetry-exporter-otlp<2,>=1.
|
|
31
|
-
opentelemetry-instrumentation>=0.
|
|
32
|
-
opentelemetry-instrumentation-httpx>=0.
|
|
29
|
+
opentelemetry-sdk<2,>=1.35.0
|
|
30
|
+
opentelemetry-exporter-otlp<2,>=1.35.0
|
|
31
|
+
opentelemetry-instrumentation>=0.56b0
|
|
32
|
+
opentelemetry-instrumentation-httpx>=0.56b0
|
|
33
|
+
opentelemetry-distro>=0.56b0
|
|
33
34
|
|
|
34
35
|
[opentelemetry-fastapi]
|
|
35
36
|
hexkit[opentelemetry-base]
|
|
36
|
-
opentelemetry-instrumentation-fastapi>=0.
|
|
37
|
+
opentelemetry-instrumentation-fastapi>=0.56b0
|
|
37
38
|
|
|
38
39
|
[opentelemetry-mongodb]
|
|
39
40
|
hexkit[opentelemetry-base]
|
|
40
41
|
hexkit[mongodb]
|
|
41
|
-
opentelemetry-instrumentation-pymongo>=0.
|
|
42
|
+
opentelemetry-instrumentation-pymongo>=0.56b0
|
|
42
43
|
|
|
43
44
|
[opentelemetry-s3]
|
|
44
45
|
hexkit[opentelemetry-base]
|
|
45
46
|
hexkit[s3]
|
|
46
|
-
opentelemetry-instrumentation-botocore>=0.
|
|
47
|
+
opentelemetry-instrumentation-botocore>=0.56b0
|
|
47
48
|
|
|
48
49
|
[s3]
|
|
49
50
|
boto3<2,>=1.37
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
# Copyright 2021 - 2025 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln
|
|
2
|
-
# for the German Human Genome-Phenome Archive (GHGA)
|
|
3
|
-
#
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
# you may not use this file except in compliance with the License.
|
|
6
|
-
# You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License.
|
|
15
|
-
"""OpenTelemetry specific configuration code. This is gated behind the opentelemetry extra."""
|
|
16
|
-
|
|
17
|
-
import logging
|
|
18
|
-
import os
|
|
19
|
-
from typing import Annotated, Callable, Literal, Optional
|
|
20
|
-
|
|
21
|
-
from opentelemetry import trace
|
|
22
|
-
from opentelemetry.environment_variables import (
|
|
23
|
-
OTEL_LOGS_EXPORTER,
|
|
24
|
-
OTEL_METRICS_EXPORTER,
|
|
25
|
-
OTEL_TRACES_EXPORTER,
|
|
26
|
-
)
|
|
27
|
-
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
28
|
-
from opentelemetry.instrumentation.distro import ( # type: ignore[attr-defined]
|
|
29
|
-
BaseDistro,
|
|
30
|
-
)
|
|
31
|
-
from opentelemetry.sdk.environment_variables import (
|
|
32
|
-
OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
33
|
-
OTEL_EXPORTER_OTLP_PROTOCOL,
|
|
34
|
-
OTEL_SDK_DISABLED,
|
|
35
|
-
)
|
|
36
|
-
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
|
37
|
-
from opentelemetry.sdk.trace import TracerProvider
|
|
38
|
-
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
39
|
-
from opentelemetry.sdk.trace.sampling import ParentBasedTraceIdRatio
|
|
40
|
-
from pydantic import AnyHttpUrl, Field
|
|
41
|
-
from pydantic_settings import BaseSettings
|
|
42
|
-
|
|
43
|
-
TRACER: Optional["SpanTracer"] = None
|
|
44
|
-
|
|
45
|
-
logger = logging.getLogger(__name__)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class SpanTracer:
|
|
49
|
-
"""Custom tracer class providing a decorator to autpopulate span names."""
|
|
50
|
-
|
|
51
|
-
def __init__(self, name):
|
|
52
|
-
self.tracer = trace.get_tracer(name)
|
|
53
|
-
|
|
54
|
-
def start_span(
|
|
55
|
-
self, *, record_exception: bool = False, set_status_on_exception: bool = False
|
|
56
|
-
):
|
|
57
|
-
"""Decorator function starting a span populated with the __qualname__ of the wrapped function"""
|
|
58
|
-
|
|
59
|
-
def outer_wrapper(function: Callable):
|
|
60
|
-
def traced_function(*args, **kwargs):
|
|
61
|
-
name = function.__qualname__
|
|
62
|
-
with self.tracer.start_as_current_span(
|
|
63
|
-
name,
|
|
64
|
-
record_exception=record_exception,
|
|
65
|
-
set_status_on_exception=set_status_on_exception,
|
|
66
|
-
):
|
|
67
|
-
return function(*args, **kwargs)
|
|
68
|
-
|
|
69
|
-
return traced_function
|
|
70
|
-
|
|
71
|
-
return outer_wrapper
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
class OpenTelemetryConfig(BaseSettings):
|
|
75
|
-
"""OpenTelemetry specific configuration options"""
|
|
76
|
-
|
|
77
|
-
enable_opentelemetry: bool = Field(
|
|
78
|
-
default=False,
|
|
79
|
-
description="If set to true, this will run necessary setup code."
|
|
80
|
-
"If set to false, environment variables are set that should also effectively "
|
|
81
|
-
"disable autoinstrumentation.",
|
|
82
|
-
)
|
|
83
|
-
otel_trace_sampling_rate: Annotated[float, Field(strict=True, ge=0, le=1)] = Field(
|
|
84
|
-
default=1.0,
|
|
85
|
-
description="Determines which proportion of spans should be sampled. "
|
|
86
|
-
"A value of 1.0 means all and is equivalent to the previous behaviour. "
|
|
87
|
-
"Setting this to 0 will result in no spans being sampled, but this does not "
|
|
88
|
-
"automatically set `enable_opentelemetry` to False.",
|
|
89
|
-
)
|
|
90
|
-
otel_exporter_protocol: Literal["grpc", "http/protobuf"] = Field(
|
|
91
|
-
default="http/protobuf",
|
|
92
|
-
description="Specifies which protocol should be used by exporters.",
|
|
93
|
-
)
|
|
94
|
-
otel_exporter_endpoint: AnyHttpUrl = Field(
|
|
95
|
-
default=...,
|
|
96
|
-
description="Base endpoint URL for the collector that receives content from the exporter.",
|
|
97
|
-
examples=["http://localhost:4318"],
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
class HexkitDistro(BaseDistro):
|
|
102
|
-
"""
|
|
103
|
-
Custom OpenTelemetry Distro configuring a default set of configuration
|
|
104
|
-
based on a config file.
|
|
105
|
-
"""
|
|
106
|
-
|
|
107
|
-
def _configure(self, **kwargs):
|
|
108
|
-
"""Custom DefaultDistro iplementation to provide autoinstrumentation entry points."""
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def configure_opentelemetry(*, service_name: str, config: OpenTelemetryConfig):
|
|
112
|
-
"""Configure all needed parts of OpenTelemetry.
|
|
113
|
-
|
|
114
|
-
Setup of the TracerProvider is done programmatically, all other configuration exports
|
|
115
|
-
OpenTelemetry specific environment variables.
|
|
116
|
-
"""
|
|
117
|
-
global TRACER
|
|
118
|
-
# opentelemetry distro sets this to grpc, but in the current context http/protobuf is preferred
|
|
119
|
-
os.environ[OTEL_EXPORTER_OTLP_PROTOCOL] = config.otel_exporter_protocol
|
|
120
|
-
os.environ[OTEL_EXPORTER_OTLP_ENDPOINT] = str(config.otel_exporter_endpoint)
|
|
121
|
-
# Disable OpenTelemetry metrics and logs explicitly as they are not processed in the backend currently
|
|
122
|
-
# This overwrites the defaults of `otlp` set in opentelemetry distro
|
|
123
|
-
os.environ[OTEL_METRICS_EXPORTER] = "none"
|
|
124
|
-
os.environ[OTEL_LOGS_EXPORTER] = "none"
|
|
125
|
-
|
|
126
|
-
if config.enable_opentelemetry:
|
|
127
|
-
if TRACER is not None:
|
|
128
|
-
logger.warning(
|
|
129
|
-
"OpenTelemetry configuration code should only be run once. "
|
|
130
|
-
"If it has been run with a different service name than %s before, "
|
|
131
|
-
"the tracer and resource name will likely be wrong in some cases.",
|
|
132
|
-
service_name,
|
|
133
|
-
)
|
|
134
|
-
resource = Resource(attributes={SERVICE_NAME: service_name})
|
|
135
|
-
# Replace the default static sampler with a probabilistic one that honors parent
|
|
136
|
-
# span sampling decisions
|
|
137
|
-
# This should consistently yield full traces within a service but not necessarily
|
|
138
|
-
# across service boundaries
|
|
139
|
-
# With the default sampling rate, behaviour does not change, but this allows to
|
|
140
|
-
# introduce head sampling by adjusting a config option on the service side later on
|
|
141
|
-
sampler = ParentBasedTraceIdRatio(rate=config.otel_trace_sampling_rate)
|
|
142
|
-
|
|
143
|
-
# Initialize service specific TracerProvider
|
|
144
|
-
trace_provider = TracerProvider(resource=resource, sampler=sampler)
|
|
145
|
-
processor = BatchSpanProcessor(OTLPSpanExporter())
|
|
146
|
-
trace_provider.add_span_processor(processor)
|
|
147
|
-
trace.set_tracer_provider(trace_provider)
|
|
148
|
-
TRACER = SpanTracer(service_name)
|
|
149
|
-
else:
|
|
150
|
-
# Currently OTEL_SDK_DISABLED doesn't seem to be honored by all implementations yet
|
|
151
|
-
# It seems to be working well enough for the Python implementation, but to be on
|
|
152
|
-
# the safe side, let's explicitly disable the trace exporter for now
|
|
153
|
-
os.environ[OTEL_TRACES_EXPORTER] = "none"
|
|
154
|
-
os.environ[OTEL_SDK_DISABLED] = "true"
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def start_span(
|
|
158
|
-
*,
|
|
159
|
-
record_exception: bool = True,
|
|
160
|
-
set_status_on_exception: bool = True,
|
|
161
|
-
) -> Callable:
|
|
162
|
-
"""Returns decorated or undecorated function depending on if TRACER is instantiated.
|
|
163
|
-
|
|
164
|
-
Should be used as a decorator.
|
|
165
|
-
"""
|
|
166
|
-
|
|
167
|
-
def wrapper(function: Callable):
|
|
168
|
-
# Caller did not have any time to populate from config yet or otel is disabled
|
|
169
|
-
if TRACER is None:
|
|
170
|
-
return function
|
|
171
|
-
# Return decorated function
|
|
172
|
-
return TRACER.start_span(
|
|
173
|
-
record_exception=record_exception,
|
|
174
|
-
set_status_on_exception=set_status_on_exception,
|
|
175
|
-
)(function)
|
|
176
|
-
|
|
177
|
-
return wrapper
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|