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.
Files changed (66) hide show
  1. {hexkit-6.0.0/src/hexkit.egg-info → hexkit-7.0.0}/PKG-INFO +10 -9
  2. {hexkit-6.0.0 → hexkit-7.0.0}/pyproject.toml +14 -14
  3. hexkit-7.0.0/src/hexkit/opentelemetry.py +76 -0
  4. {hexkit-6.0.0 → hexkit-7.0.0/src/hexkit.egg-info}/PKG-INFO +10 -9
  5. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit.egg-info/SOURCES.txt +0 -1
  6. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit.egg-info/requires.txt +9 -8
  7. hexkit-6.0.0/src/hexkit/opentelemetry.py +0 -177
  8. hexkit-6.0.0/src/hexkit.egg-info/entry_points.txt +0 -2
  9. {hexkit-6.0.0 → hexkit-7.0.0}/LICENSE +0 -0
  10. {hexkit-6.0.0 → hexkit-7.0.0}/MANIFEST.in +0 -0
  11. {hexkit-6.0.0 → hexkit-7.0.0}/README.md +0 -0
  12. {hexkit-6.0.0 → hexkit-7.0.0}/setup.cfg +0 -0
  13. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/__init__.py +0 -0
  14. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/__main__.py +0 -0
  15. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/base.py +0 -0
  16. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/config.py +0 -0
  17. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/correlation.py +0 -0
  18. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/custom_types.py +0 -0
  19. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/log.py +0 -0
  20. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/__init__.py +0 -0
  21. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/dao.py +0 -0
  22. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/daopub.py +0 -0
  23. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/daosub.py +0 -0
  24. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/eventpub.py +0 -0
  25. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/eventsub.py +0 -0
  26. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/protocols/objstorage.py +0 -0
  27. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/__init__.py +0 -0
  28. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/__init__.py +0 -0
  29. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/config.py +0 -0
  30. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/__init__.py +0 -0
  31. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/daosub.py +0 -0
  32. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/eventpub.py +0 -0
  33. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/eventsub.py +0 -0
  34. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/provider/utils.py +0 -0
  35. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/testcontainer.py +0 -0
  36. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/akafka/testutils.py +0 -0
  37. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/__init__.py +0 -0
  38. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/migrations/__init__.py +0 -0
  39. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/migrations/_manager.py +0 -0
  40. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/migrations/_utils.py +0 -0
  41. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/migrations/helpers.py +0 -0
  42. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/provider.py +0 -0
  43. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongodb/testutils.py +0 -0
  44. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/__init__.py +0 -0
  45. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/provider/__init__.py +0 -0
  46. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/provider/config.py +0 -0
  47. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/provider/daopub.py +0 -0
  48. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/provider/persistent_pub.py +0 -0
  49. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/mongokafka/testutils.py +0 -0
  50. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/__init__.py +0 -0
  51. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/provider.py +0 -0
  52. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/__init__.py +0 -0
  53. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/test_file1.yaml +0 -0
  54. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/test_file2.yaml +0 -0
  55. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/test_file3.yaml +0 -0
  56. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/test_files/test_file4.yaml +0 -0
  57. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/testutils/__init__.py +0 -0
  58. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/testutils/_fixtures.py +0 -0
  59. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/testutils/_typical_workflow.py +0 -0
  60. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/s3/testutils/_utils.py +0 -0
  61. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/testing/__init__.py +0 -0
  62. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/providers/testing/eventpub.py +0 -0
  63. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/py.typed +0 -0
  64. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit/utils.py +0 -0
  65. {hexkit-6.0.0 → hexkit-7.0.0}/src/hexkit.egg-info/dependency_links.txt +0 -0
  66. {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: 6.0.0
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.31.1; extra == "opentelemetry-base"
36
- Requires-Dist: opentelemetry-exporter-otlp<2,>=1.31.1; extra == "opentelemetry-base"
37
- Requires-Dist: opentelemetry-instrumentation>=0.52b1; extra == "opentelemetry-base"
38
- Requires-Dist: opentelemetry-instrumentation-httpx>=0.52b1; extra == "opentelemetry-base"
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.52b1; extra == "opentelemetry-akafka"
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.52b1; extra == "opentelemetry-mongodb"
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.52b1; extra == "opentelemetry-fastapi"
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.52b1; extra == "opentelemetry-s3"
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 = "6.0.0"
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.31.1, <2",
53
- "opentelemetry-exporter-otlp >=1.31.1, <2",
54
- "opentelemetry-instrumentation >=0.52b1",
55
- "opentelemetry-instrumentation-httpx >=0.52b1",
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.52b1",
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.52b1",
66
+ "opentelemetry-instrumentation-pymongo >=0.56b0",
66
67
  ]
67
68
  opentelemetry-fastapi = [
68
69
  "hexkit[opentelemetry-base]",
69
- "opentelemetry-instrumentation-fastapi >=0.52b1",
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.52b1",
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 = pytest {posargs}
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: 6.0.0
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.31.1; extra == "opentelemetry-base"
36
- Requires-Dist: opentelemetry-exporter-otlp<2,>=1.31.1; extra == "opentelemetry-base"
37
- Requires-Dist: opentelemetry-instrumentation>=0.52b1; extra == "opentelemetry-base"
38
- Requires-Dist: opentelemetry-instrumentation-httpx>=0.52b1; extra == "opentelemetry-base"
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.52b1; extra == "opentelemetry-akafka"
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.52b1; extra == "opentelemetry-mongodb"
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.52b1; extra == "opentelemetry-fastapi"
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.52b1; extra == "opentelemetry-s3"
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.52b1
26
+ opentelemetry-instrumentation-aiokafka>=0.56b0
27
27
 
28
28
  [opentelemetry-base]
29
- opentelemetry-sdk<2,>=1.31.1
30
- opentelemetry-exporter-otlp<2,>=1.31.1
31
- opentelemetry-instrumentation>=0.52b1
32
- opentelemetry-instrumentation-httpx>=0.52b1
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.52b1
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.52b1
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.52b1
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
@@ -1,2 +0,0 @@
1
- [opentelemetry_distro]
2
- hexkit_distro = hexkit.opentelemetry:HexkitDistro
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