opentelemetry-instrumentation 0.47b0__py3-none-any.whl → 0.49b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -252,16 +252,32 @@ def _set_http_scheme(result, scheme, sem_conv_opt_in_mode):
252
252
  set_string_attribute(result, URL_SCHEME, scheme)
253
253
 
254
254
 
255
- def _set_http_host(result, host, sem_conv_opt_in_mode):
255
+ def _set_http_flavor_version(result, version, sem_conv_opt_in_mode):
256
256
  if _report_old(sem_conv_opt_in_mode):
257
- set_string_attribute(result, SpanAttributes.HTTP_HOST, host)
257
+ set_string_attribute(result, SpanAttributes.HTTP_FLAVOR, version)
258
258
  if _report_new(sem_conv_opt_in_mode):
259
- set_string_attribute(result, SERVER_ADDRESS, host)
259
+ set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version)
260
+
261
+
262
+ def _set_http_user_agent(result, user_agent, sem_conv_opt_in_mode):
263
+ if _report_old(sem_conv_opt_in_mode):
264
+ set_string_attribute(
265
+ result, SpanAttributes.HTTP_USER_AGENT, user_agent
266
+ )
267
+ if _report_new(sem_conv_opt_in_mode):
268
+ set_string_attribute(result, USER_AGENT_ORIGINAL, user_agent)
260
269
 
261
270
 
262
271
  # Client
263
272
 
264
273
 
274
+ def _set_http_host_client(result, host, sem_conv_opt_in_mode):
275
+ if _report_old(sem_conv_opt_in_mode):
276
+ set_string_attribute(result, SpanAttributes.HTTP_HOST, host)
277
+ if _report_new(sem_conv_opt_in_mode):
278
+ set_string_attribute(result, SERVER_ADDRESS, host)
279
+
280
+
265
281
  def _set_http_net_peer_name_client(result, peer_name, sem_conv_opt_in_mode):
266
282
  if _report_old(sem_conv_opt_in_mode):
267
283
  set_string_attribute(result, SpanAttributes.NET_PEER_NAME, peer_name)
@@ -310,27 +326,32 @@ def _set_http_target(result, target, path, query, sem_conv_opt_in_mode):
310
326
  set_string_attribute(result, URL_QUERY, query)
311
327
 
312
328
 
313
- def _set_http_peer_ip(result, ip, sem_conv_opt_in_mode):
329
+ def _set_http_host_server(result, host, sem_conv_opt_in_mode):
314
330
  if _report_old(sem_conv_opt_in_mode):
315
- set_string_attribute(result, SpanAttributes.NET_PEER_IP, ip)
331
+ set_string_attribute(result, SpanAttributes.HTTP_HOST, host)
316
332
  if _report_new(sem_conv_opt_in_mode):
317
- set_string_attribute(result, CLIENT_ADDRESS, ip)
333
+ set_string_attribute(result, CLIENT_ADDRESS, host)
318
334
 
319
335
 
320
- def _set_http_peer_port_server(result, port, sem_conv_opt_in_mode):
336
+ # net.peer.ip -> net.sock.peer.addr
337
+ # https://github.com/open-telemetry/semantic-conventions/blob/40db676ca0e735aa84f242b5a0fb14e49438b69b/schemas/1.15.0#L18
338
+ # net.sock.peer.addr -> client.socket.address for server spans (TODO) AND client.address if missing
339
+ # https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/CHANGELOG.md#v1210-2023-07-13
340
+ # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md#common-attributes-across-http-client-and-server-spans
341
+ def _set_http_peer_ip_server(result, ip, sem_conv_opt_in_mode):
321
342
  if _report_old(sem_conv_opt_in_mode):
322
- set_int_attribute(result, SpanAttributes.NET_PEER_PORT, port)
343
+ set_string_attribute(result, SpanAttributes.NET_PEER_IP, ip)
323
344
  if _report_new(sem_conv_opt_in_mode):
324
- set_int_attribute(result, CLIENT_PORT, port)
345
+ # Only populate if not already populated
346
+ if not result.get(CLIENT_ADDRESS):
347
+ set_string_attribute(result, CLIENT_ADDRESS, ip)
325
348
 
326
349
 
327
- def _set_http_user_agent(result, user_agent, sem_conv_opt_in_mode):
350
+ def _set_http_peer_port_server(result, port, sem_conv_opt_in_mode):
328
351
  if _report_old(sem_conv_opt_in_mode):
329
- set_string_attribute(
330
- result, SpanAttributes.HTTP_USER_AGENT, user_agent
331
- )
352
+ set_int_attribute(result, SpanAttributes.NET_PEER_PORT, port)
332
353
  if _report_new(sem_conv_opt_in_mode):
333
- set_string_attribute(result, USER_AGENT_ORIGINAL, user_agent)
354
+ set_int_attribute(result, CLIENT_PORT, port)
334
355
 
335
356
 
336
357
  def _set_http_net_peer_name_server(result, name, sem_conv_opt_in_mode):
@@ -340,13 +361,6 @@ def _set_http_net_peer_name_server(result, name, sem_conv_opt_in_mode):
340
361
  set_string_attribute(result, CLIENT_ADDRESS, name)
341
362
 
342
363
 
343
- def _set_http_flavor_version(result, version, sem_conv_opt_in_mode):
344
- if _report_old(sem_conv_opt_in_mode):
345
- set_string_attribute(result, SpanAttributes.HTTP_FLAVOR, version)
346
- if _report_new(sem_conv_opt_in_mode):
347
- set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version)
348
-
349
-
350
364
  def _set_status(
351
365
  span,
352
366
  metrics_attributes: dict,
@@ -19,9 +19,8 @@ from os.path import abspath, dirname, pathsep
19
19
  from re import sub
20
20
  from shutil import which
21
21
 
22
- from pkg_resources import iter_entry_points
23
-
24
22
  from opentelemetry.instrumentation.version import __version__
23
+ from opentelemetry.util._importlib_metadata import entry_points
25
24
 
26
25
  _logger = getLogger(__name__)
27
26
 
@@ -48,8 +47,8 @@ def run() -> None:
48
47
 
49
48
  argument_otel_environment_variable = {}
50
49
 
51
- for entry_point in iter_entry_points(
52
- "opentelemetry_environment_variables"
50
+ for entry_point in entry_points(
51
+ group="opentelemetry_environment_variables"
53
52
  ):
54
53
  environment_variable_module = entry_point.load()
55
54
 
@@ -12,11 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from functools import cached_property
15
16
  from logging import getLogger
16
17
  from os import environ
17
18
 
18
- from pkg_resources import iter_entry_points
19
-
20
19
  from opentelemetry.instrumentation.dependencies import (
21
20
  get_dist_dependency_conflicts,
22
21
  )
@@ -27,13 +26,39 @@ from opentelemetry.instrumentation.environment_variables import (
27
26
  OTEL_PYTHON_DISTRO,
28
27
  )
29
28
  from opentelemetry.instrumentation.version import __version__
29
+ from opentelemetry.util._importlib_metadata import (
30
+ EntryPoint,
31
+ distributions,
32
+ entry_points,
33
+ )
30
34
 
31
35
  _logger = getLogger(__name__)
32
36
 
33
37
 
38
+ class _EntryPointDistFinder:
39
+ @cached_property
40
+ def _mapping(self):
41
+ return {
42
+ self._key_for(ep): dist
43
+ for dist in distributions()
44
+ for ep in dist.entry_points
45
+ }
46
+
47
+ def dist_for(self, entry_point: EntryPoint):
48
+ dist = getattr(entry_point, "dist", None)
49
+ if dist:
50
+ return dist
51
+
52
+ return self._mapping.get(self._key_for(entry_point))
53
+
54
+ @staticmethod
55
+ def _key_for(entry_point: EntryPoint):
56
+ return f"{entry_point.group}:{entry_point.name}:{entry_point.value}"
57
+
58
+
34
59
  def _load_distro() -> BaseDistro:
35
60
  distro_name = environ.get(OTEL_PYTHON_DISTRO, None)
36
- for entry_point in iter_entry_points("opentelemetry_distro"):
61
+ for entry_point in entry_points(group="opentelemetry_distro"):
37
62
  try:
38
63
  # If no distro is specified, use first to come up.
39
64
  if distro_name is None or distro_name == entry_point.name:
@@ -58,15 +83,16 @@ def _load_distro() -> BaseDistro:
58
83
 
59
84
  def _load_instrumentors(distro):
60
85
  package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, [])
86
+ entry_point_finder = _EntryPointDistFinder()
61
87
  if isinstance(package_to_exclude, str):
62
88
  package_to_exclude = package_to_exclude.split(",")
63
89
  # to handle users entering "requests , flask" or "requests, flask" with spaces
64
90
  package_to_exclude = [x.strip() for x in package_to_exclude]
65
91
 
66
- for entry_point in iter_entry_points("opentelemetry_pre_instrument"):
92
+ for entry_point in entry_points(group="opentelemetry_pre_instrument"):
67
93
  entry_point.load()()
68
94
 
69
- for entry_point in iter_entry_points("opentelemetry_instrumentor"):
95
+ for entry_point in entry_points(group="opentelemetry_instrumentor"):
70
96
  if entry_point.name in package_to_exclude:
71
97
  _logger.debug(
72
98
  "Instrumentation skipped for library %s", entry_point.name
@@ -74,7 +100,8 @@ def _load_instrumentors(distro):
74
100
  continue
75
101
 
76
102
  try:
77
- conflict = get_dist_dependency_conflicts(entry_point.dist)
103
+ entry_point_dist = entry_point_finder.dist_for(entry_point)
104
+ conflict = get_dist_dependency_conflicts(entry_point_dist)
78
105
  if conflict:
79
106
  _logger.debug(
80
107
  "Skipping instrumentation %s: %s",
@@ -86,18 +113,29 @@ def _load_instrumentors(distro):
86
113
  # tell instrumentation to not run dep checks again as we already did it above
87
114
  distro.load_instrumentor(entry_point, skip_dep_check=True)
88
115
  _logger.debug("Instrumented %s", entry_point.name)
116
+ except ImportError:
117
+ # in scenarios using the kubernetes operator to do autoinstrumentation some
118
+ # instrumentors (usually requiring binary extensions) may fail to load
119
+ # because the injected autoinstrumentation code does not match the application
120
+ # environment regarding python version, libc, etc... In this case it's better
121
+ # to skip the single instrumentation rather than failing to load everything
122
+ # so treat differently ImportError than the rest of exceptions
123
+ _logger.exception(
124
+ "Importing of %s failed, skipping it", entry_point.name
125
+ )
126
+ continue
89
127
  except Exception as exc: # pylint: disable=broad-except
90
128
  _logger.exception("Instrumenting of %s failed", entry_point.name)
91
129
  raise exc
92
130
 
93
- for entry_point in iter_entry_points("opentelemetry_post_instrument"):
131
+ for entry_point in entry_points(group="opentelemetry_post_instrument"):
94
132
  entry_point.load()()
95
133
 
96
134
 
97
135
  def _load_configurators():
98
136
  configurator_name = environ.get(OTEL_PYTHON_CONFIGURATOR, None)
99
137
  configured = None
100
- for entry_point in iter_entry_points("opentelemetry_configurator"):
138
+ for entry_point in entry_points(group="opentelemetry_configurator"):
101
139
  if configured is not None:
102
140
  _logger.warning(
103
141
  "Configuration of %s not loaded, %s already loaded",
@@ -110,7 +148,9 @@ def _load_configurators():
110
148
  configurator_name is None
111
149
  or configurator_name == entry_point.name
112
150
  ):
113
- entry_point.load()().configure(auto_instrumentation_version=__version__) # type: ignore
151
+ entry_point.load()().configure(
152
+ auto_instrumentation_version=__version__
153
+ ) # type: ignore
114
154
  configured = entry_point.name
115
155
  else:
116
156
  _logger.warning(
@@ -22,14 +22,21 @@ from subprocess import (
22
22
  SubprocessError,
23
23
  check_call,
24
24
  )
25
+ from typing import Optional
25
26
 
26
- import pkg_resources
27
+ from packaging.requirements import Requirement
27
28
 
28
29
  from opentelemetry.instrumentation.bootstrap_gen import (
29
- default_instrumentations,
30
- libraries,
30
+ default_instrumentations as gen_default_instrumentations,
31
+ )
32
+ from opentelemetry.instrumentation.bootstrap_gen import (
33
+ libraries as gen_libraries,
31
34
  )
32
35
  from opentelemetry.instrumentation.version import __version__
36
+ from opentelemetry.util._importlib_metadata import (
37
+ PackageNotFoundError,
38
+ version,
39
+ )
33
40
 
34
41
  logger = logging.getLogger(__name__)
35
42
 
@@ -71,7 +78,7 @@ def _sys_pip_install(package):
71
78
  print(error)
72
79
 
73
80
 
74
- def _pip_check():
81
+ def _pip_check(libraries):
75
82
  """Ensures none of the instrumentations have dependency conflicts.
76
83
  Clean check reported as:
77
84
  'No broken requirements found.'
@@ -91,24 +98,25 @@ def _pip_check():
91
98
 
92
99
 
93
100
  def _is_installed(req):
94
- if req in sys.modules:
95
- return True
101
+ req = Requirement(req)
96
102
 
97
103
  try:
98
- pkg_resources.get_distribution(req)
99
- except pkg_resources.DistributionNotFound:
104
+ dist_version = version(req.name)
105
+ except PackageNotFoundError:
100
106
  return False
101
- except pkg_resources.VersionConflict as exc:
107
+
108
+ if not req.specifier.filter(dist_version):
102
109
  logger.warning(
103
- "instrumentation for package %s is available but version %s is installed. Skipping.",
104
- exc.req,
105
- exc.dist.as_requirement(), # pylint: disable=no-member
110
+ "instrumentation for package %s is available"
111
+ " but version %s is installed. Skipping.",
112
+ req,
113
+ dist_version,
106
114
  )
107
115
  return False
108
116
  return True
109
117
 
110
118
 
111
- def _find_installed_libraries():
119
+ def _find_installed_libraries(default_instrumentations, libraries):
112
120
  for lib in default_instrumentations:
113
121
  yield lib
114
122
 
@@ -117,18 +125,25 @@ def _find_installed_libraries():
117
125
  yield lib["instrumentation"]
118
126
 
119
127
 
120
- def _run_requirements():
128
+ def _run_requirements(default_instrumentations, libraries):
121
129
  logger.setLevel(logging.ERROR)
122
- print("\n".join(_find_installed_libraries()), end="")
130
+ print(
131
+ "\n".join(
132
+ _find_installed_libraries(default_instrumentations, libraries)
133
+ )
134
+ )
123
135
 
124
136
 
125
- def _run_install():
126
- for lib in _find_installed_libraries():
137
+ def _run_install(default_instrumentations, libraries):
138
+ for lib in _find_installed_libraries(default_instrumentations, libraries):
127
139
  _sys_pip_install(lib)
128
- _pip_check()
140
+ _pip_check(libraries)
129
141
 
130
142
 
131
- def run() -> None:
143
+ def run(
144
+ default_instrumentations: Optional[list] = None,
145
+ libraries: Optional[list] = None,
146
+ ) -> None:
132
147
  action_install = "install"
133
148
  action_requirements = "requirements"
134
149
 
@@ -158,8 +173,14 @@ def run() -> None:
158
173
  )
159
174
  args = parser.parse_args()
160
175
 
176
+ if libraries is None:
177
+ libraries = gen_libraries
178
+
179
+ if default_instrumentations is None:
180
+ default_instrumentations = gen_default_instrumentations
181
+
161
182
  cmd = {
162
183
  action_install: _run_install,
163
184
  action_requirements: _run_requirements,
164
185
  }[args.action]
165
- cmd()
186
+ cmd(default_instrumentations, libraries)
@@ -18,180 +18,184 @@
18
18
  libraries = [
19
19
  {
20
20
  "library": "aio_pika >= 7.2.0, < 10.0.0",
21
- "instrumentation": "opentelemetry-instrumentation-aio-pika==0.47b0",
21
+ "instrumentation": "opentelemetry-instrumentation-aio-pika==0.49b0",
22
22
  },
23
23
  {
24
24
  "library": "aiohttp ~= 3.0",
25
- "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.47b0",
25
+ "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.49b0",
26
26
  },
27
27
  {
28
28
  "library": "aiohttp ~= 3.0",
29
- "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.47b0",
29
+ "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.49b0",
30
+ },
31
+ {
32
+ "library": "aiokafka >= 0.8, < 1.0",
33
+ "instrumentation": "opentelemetry-instrumentation-aiokafka==0.49b0",
30
34
  },
31
35
  {
32
36
  "library": "aiopg >= 0.13.0, < 2.0.0",
33
- "instrumentation": "opentelemetry-instrumentation-aiopg==0.47b0",
37
+ "instrumentation": "opentelemetry-instrumentation-aiopg==0.49b0",
34
38
  },
35
39
  {
36
40
  "library": "asgiref ~= 3.0",
37
- "instrumentation": "opentelemetry-instrumentation-asgi==0.47b0",
41
+ "instrumentation": "opentelemetry-instrumentation-asgi==0.49b0",
38
42
  },
39
43
  {
40
44
  "library": "asyncpg >= 0.12.0",
41
- "instrumentation": "opentelemetry-instrumentation-asyncpg==0.47b0",
45
+ "instrumentation": "opentelemetry-instrumentation-asyncpg==0.49b0",
42
46
  },
43
47
  {
44
48
  "library": "boto~=2.0",
45
- "instrumentation": "opentelemetry-instrumentation-boto==0.47b0",
49
+ "instrumentation": "opentelemetry-instrumentation-boto==0.49b0",
46
50
  },
47
51
  {
48
52
  "library": "boto3 ~= 1.0",
49
- "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.47b0",
53
+ "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.49b0",
50
54
  },
51
55
  {
52
56
  "library": "botocore ~= 1.0",
53
- "instrumentation": "opentelemetry-instrumentation-botocore==0.47b0",
57
+ "instrumentation": "opentelemetry-instrumentation-botocore==0.49b0",
54
58
  },
55
59
  {
56
60
  "library": "cassandra-driver ~= 3.25",
57
- "instrumentation": "opentelemetry-instrumentation-cassandra==0.47b0",
61
+ "instrumentation": "opentelemetry-instrumentation-cassandra==0.49b0",
58
62
  },
59
63
  {
60
64
  "library": "scylla-driver ~= 3.25",
61
- "instrumentation": "opentelemetry-instrumentation-cassandra==0.47b0",
65
+ "instrumentation": "opentelemetry-instrumentation-cassandra==0.49b0",
62
66
  },
63
67
  {
64
68
  "library": "celery >= 4.0, < 6.0",
65
- "instrumentation": "opentelemetry-instrumentation-celery==0.47b0",
69
+ "instrumentation": "opentelemetry-instrumentation-celery==0.49b0",
66
70
  },
67
71
  {
68
72
  "library": "confluent-kafka >= 1.8.2, <= 2.4.0",
69
- "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.47b0",
73
+ "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.49b0",
70
74
  },
71
75
  {
72
76
  "library": "django >= 1.10",
73
- "instrumentation": "opentelemetry-instrumentation-django==0.47b0",
77
+ "instrumentation": "opentelemetry-instrumentation-django==0.49b0",
74
78
  },
75
79
  {
76
80
  "library": "elasticsearch >= 6.0",
77
- "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.47b0",
81
+ "instrumentation": "opentelemetry-instrumentation-elasticsearch==0.49b0",
78
82
  },
79
83
  {
80
84
  "library": "falcon >= 1.4.1, < 3.1.2",
81
- "instrumentation": "opentelemetry-instrumentation-falcon==0.47b0",
85
+ "instrumentation": "opentelemetry-instrumentation-falcon==0.49b0",
82
86
  },
83
87
  {
84
88
  "library": "fastapi ~= 0.58",
85
- "instrumentation": "opentelemetry-instrumentation-fastapi==0.47b0",
86
- },
87
- {
88
- "library": "fastapi-slim ~= 0.111.0",
89
- "instrumentation": "opentelemetry-instrumentation-fastapi==0.47b0",
89
+ "instrumentation": "opentelemetry-instrumentation-fastapi==0.49b0",
90
90
  },
91
91
  {
92
92
  "library": "flask >= 1.0",
93
- "instrumentation": "opentelemetry-instrumentation-flask==0.47b0",
93
+ "instrumentation": "opentelemetry-instrumentation-flask==0.49b0",
94
94
  },
95
95
  {
96
- "library": "grpcio ~= 1.27",
97
- "instrumentation": "opentelemetry-instrumentation-grpc==0.47b0",
96
+ "library": "grpcio >= 1.42.0",
97
+ "instrumentation": "opentelemetry-instrumentation-grpc==0.49b0",
98
98
  },
99
99
  {
100
100
  "library": "httpx >= 0.18.0",
101
- "instrumentation": "opentelemetry-instrumentation-httpx==0.47b0",
101
+ "instrumentation": "opentelemetry-instrumentation-httpx==0.49b0",
102
102
  },
103
103
  {
104
104
  "library": "jinja2 >= 2.7, < 4.0",
105
- "instrumentation": "opentelemetry-instrumentation-jinja2==0.47b0",
105
+ "instrumentation": "opentelemetry-instrumentation-jinja2==0.49b0",
106
+ },
107
+ {
108
+ "library": "kafka-python >= 2.0, < 3.0",
109
+ "instrumentation": "opentelemetry-instrumentation-kafka-python==0.49b0",
106
110
  },
107
111
  {
108
- "library": "kafka-python >= 2.0",
109
- "instrumentation": "opentelemetry-instrumentation-kafka-python==0.47b0",
112
+ "library": "kafka-python-ng >= 2.0, < 3.0",
113
+ "instrumentation": "opentelemetry-instrumentation-kafka-python==0.49b0",
110
114
  },
111
115
  {
112
- "library": "mysql-connector-python ~= 8.0",
113
- "instrumentation": "opentelemetry-instrumentation-mysql==0.47b0",
116
+ "library": "mysql-connector-python >= 8.0, < 10.0",
117
+ "instrumentation": "opentelemetry-instrumentation-mysql==0.49b0",
114
118
  },
115
119
  {
116
120
  "library": "mysqlclient < 3",
117
- "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.47b0",
121
+ "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.49b0",
118
122
  },
119
123
  {
120
124
  "library": "pika >= 0.12.0",
121
- "instrumentation": "opentelemetry-instrumentation-pika==0.47b0",
125
+ "instrumentation": "opentelemetry-instrumentation-pika==0.49b0",
122
126
  },
123
127
  {
124
128
  "library": "psycopg >= 3.1.0",
125
- "instrumentation": "opentelemetry-instrumentation-psycopg==0.47b0",
129
+ "instrumentation": "opentelemetry-instrumentation-psycopg==0.49b0",
126
130
  },
127
131
  {
128
132
  "library": "psycopg2 >= 2.7.3.1",
129
- "instrumentation": "opentelemetry-instrumentation-psycopg2==0.47b0",
133
+ "instrumentation": "opentelemetry-instrumentation-psycopg2==0.49b0",
130
134
  },
131
135
  {
132
136
  "library": "pymemcache >= 1.3.5, < 5",
133
- "instrumentation": "opentelemetry-instrumentation-pymemcache==0.47b0",
137
+ "instrumentation": "opentelemetry-instrumentation-pymemcache==0.49b0",
134
138
  },
135
139
  {
136
140
  "library": "pymongo >= 3.1, < 5.0",
137
- "instrumentation": "opentelemetry-instrumentation-pymongo==0.47b0",
141
+ "instrumentation": "opentelemetry-instrumentation-pymongo==0.49b0",
138
142
  },
139
143
  {
140
144
  "library": "PyMySQL < 2",
141
- "instrumentation": "opentelemetry-instrumentation-pymysql==0.47b0",
145
+ "instrumentation": "opentelemetry-instrumentation-pymysql==0.49b0",
142
146
  },
143
147
  {
144
148
  "library": "pyramid >= 1.7",
145
- "instrumentation": "opentelemetry-instrumentation-pyramid==0.47b0",
149
+ "instrumentation": "opentelemetry-instrumentation-pyramid==0.49b0",
146
150
  },
147
151
  {
148
152
  "library": "redis >= 2.6",
149
- "instrumentation": "opentelemetry-instrumentation-redis==0.47b0",
153
+ "instrumentation": "opentelemetry-instrumentation-redis==0.49b0",
150
154
  },
151
155
  {
152
156
  "library": "remoulade >= 0.50",
153
- "instrumentation": "opentelemetry-instrumentation-remoulade==0.47b0",
157
+ "instrumentation": "opentelemetry-instrumentation-remoulade==0.49b0",
154
158
  },
155
159
  {
156
160
  "library": "requests ~= 2.0",
157
- "instrumentation": "opentelemetry-instrumentation-requests==0.47b0",
161
+ "instrumentation": "opentelemetry-instrumentation-requests==0.49b0",
158
162
  },
159
163
  {
160
164
  "library": "sqlalchemy",
161
- "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.47b0",
165
+ "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.49b0",
162
166
  },
163
167
  {
164
168
  "library": "starlette ~= 0.13.0",
165
- "instrumentation": "opentelemetry-instrumentation-starlette==0.47b0",
169
+ "instrumentation": "opentelemetry-instrumentation-starlette==0.49b0",
166
170
  },
167
171
  {
168
172
  "library": "psutil >= 5",
169
- "instrumentation": "opentelemetry-instrumentation-system-metrics==0.47b0",
173
+ "instrumentation": "opentelemetry-instrumentation-system-metrics==0.49b0",
170
174
  },
171
175
  {
172
176
  "library": "tornado >= 5.1.1",
173
- "instrumentation": "opentelemetry-instrumentation-tornado==0.47b0",
177
+ "instrumentation": "opentelemetry-instrumentation-tornado==0.49b0",
174
178
  },
175
179
  {
176
180
  "library": "tortoise-orm >= 0.17.0",
177
- "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.47b0",
181
+ "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.49b0",
178
182
  },
179
183
  {
180
184
  "library": "pydantic >= 1.10.2",
181
- "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.47b0",
185
+ "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.49b0",
182
186
  },
183
187
  {
184
188
  "library": "urllib3 >= 1.0.0, < 3.0.0",
185
- "instrumentation": "opentelemetry-instrumentation-urllib3==0.47b0",
189
+ "instrumentation": "opentelemetry-instrumentation-urllib3==0.49b0",
186
190
  },
187
191
  ]
188
192
  default_instrumentations = [
189
- "opentelemetry-instrumentation-asyncio==0.47b0",
190
- "opentelemetry-instrumentation-aws-lambda==0.47b0",
191
- "opentelemetry-instrumentation-dbapi==0.47b0",
192
- "opentelemetry-instrumentation-logging==0.47b0",
193
- "opentelemetry-instrumentation-sqlite3==0.47b0",
194
- "opentelemetry-instrumentation-threading==0.47b0",
195
- "opentelemetry-instrumentation-urllib==0.47b0",
196
- "opentelemetry-instrumentation-wsgi==0.47b0",
193
+ "opentelemetry-instrumentation-asyncio==0.49b0",
194
+ "opentelemetry-instrumentation-dbapi==0.49b0",
195
+ "opentelemetry-instrumentation-logging==0.49b0",
196
+ "opentelemetry-instrumentation-sqlite3==0.49b0",
197
+ "opentelemetry-instrumentation-test==1.0.0b.dev",
198
+ "opentelemetry-instrumentation-threading==0.49b0",
199
+ "opentelemetry-instrumentation-urllib==0.49b0",
200
+ "opentelemetry-instrumentation-wsgi==0.49b0",
197
201
  ]
@@ -1,12 +1,26 @@
1
+ # Copyright The OpenTelemetry Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
1
15
  from logging import getLogger
2
- from typing import Collection, Optional
16
+ from typing import Collection, Optional, Union
17
+
18
+ from packaging.requirements import InvalidRequirement, Requirement
3
19
 
4
- from pkg_resources import (
20
+ from opentelemetry.util._importlib_metadata import (
5
21
  Distribution,
6
- DistributionNotFound,
7
- RequirementParseError,
8
- VersionConflict,
9
- get_distribution,
22
+ PackageNotFoundError,
23
+ version,
10
24
  )
11
25
 
12
26
  logger = getLogger(__name__)
@@ -27,36 +41,43 @@ class DependencyConflict:
27
41
  def get_dist_dependency_conflicts(
28
42
  dist: Distribution,
29
43
  ) -> Optional[DependencyConflict]:
30
- main_deps = dist.requires()
31
44
  instrumentation_deps = []
32
- for dep in dist.requires(("instruments",)):
33
- if dep not in main_deps:
34
- # we set marker to none so string representation of the dependency looks like
35
- # requests ~= 1.0
36
- # instead of
37
- # requests ~= 1.0; extra = "instruments"
38
- # which does not work with `get_distribution()`
39
- dep.marker = None
40
- instrumentation_deps.append(str(dep))
45
+ extra = "extra"
46
+ instruments = "instruments"
47
+ instruments_marker = {extra: instruments}
48
+ for dep in dist.requires:
49
+ if extra not in dep or instruments not in dep:
50
+ continue
51
+
52
+ req = Requirement(dep)
53
+ if req.marker.evaluate(instruments_marker):
54
+ instrumentation_deps.append(req)
41
55
 
42
56
  return get_dependency_conflicts(instrumentation_deps)
43
57
 
44
58
 
45
59
  def get_dependency_conflicts(
46
- deps: Collection[str],
60
+ deps: Collection[Union[str, Requirement]],
47
61
  ) -> Optional[DependencyConflict]:
48
62
  for dep in deps:
63
+ if isinstance(dep, Requirement):
64
+ req = dep
65
+ else:
66
+ try:
67
+ req = Requirement(dep)
68
+ except InvalidRequirement as exc:
69
+ logger.warning(
70
+ 'error parsing dependency, reporting as a conflict: "%s" - %s',
71
+ dep,
72
+ exc,
73
+ )
74
+ return DependencyConflict(dep)
75
+
49
76
  try:
50
- get_distribution(dep)
51
- except VersionConflict as exc:
52
- return DependencyConflict(dep, exc.dist)
53
- except DistributionNotFound:
54
- return DependencyConflict(dep)
55
- except RequirementParseError as exc:
56
- logger.warning(
57
- 'error parsing dependency, reporting as a conflict: "%s" - %s',
58
- dep,
59
- exc,
60
- )
77
+ dist_version = version(req.name)
78
+ except PackageNotFoundError:
61
79
  return DependencyConflict(dep)
80
+
81
+ if not req.specifier.contains(dist_version):
82
+ return DependencyConflict(dep, f"{req.name} {dist_version}")
62
83
  return None
@@ -20,9 +20,8 @@ OpenTelemetry Base Distribution (Distro)
20
20
  from abc import ABC, abstractmethod
21
21
  from logging import getLogger
22
22
 
23
- from pkg_resources import EntryPoint
24
-
25
23
  from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
24
+ from opentelemetry.util._importlib_metadata import EntryPoint
26
25
 
27
26
  _LOG = getLogger(__name__)
28
27
 
@@ -33,7 +32,6 @@ class BaseDistro(ABC):
33
32
  _instance = None
34
33
 
35
34
  def __new__(cls, *args, **kwargs):
36
-
37
35
  if cls._instance is None:
38
36
  cls._instance = object.__new__(cls, *args, **kwargs)
39
37
 
@@ -14,8 +14,9 @@
14
14
 
15
15
  import urllib.parse
16
16
  from contextlib import contextmanager
17
+ from importlib import import_module
17
18
  from re import escape, sub
18
- from typing import Dict, Iterable, Sequence
19
+ from typing import Dict, Iterable, Sequence, Union
19
20
 
20
21
  from wrapt import ObjectProxy
21
22
 
@@ -80,13 +81,30 @@ def http_status_to_status_code(
80
81
  return StatusCode.ERROR
81
82
 
82
83
 
83
- def unwrap(obj, attr: str):
84
+ def unwrap(obj: Union[object, str], attr: str):
84
85
  """Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it
85
86
 
87
+ The object containing the function to unwrap may be passed as dotted module path string.
88
+
86
89
  Args:
87
- obj: Object that holds a reference to the wrapped function
90
+ obj: Object that holds a reference to the wrapped function or dotted import path as string
88
91
  attr (str): Name of the wrapped function
89
92
  """
93
+ if isinstance(obj, str):
94
+ try:
95
+ module_path, class_name = obj.rsplit(".", 1)
96
+ except ValueError as exc:
97
+ raise ImportError(
98
+ f"Cannot parse '{obj}' as dotted import path"
99
+ ) from exc
100
+ module = import_module(module_path)
101
+ try:
102
+ obj = getattr(module, class_name)
103
+ except AttributeError as exc:
104
+ raise ImportError(
105
+ f"Cannot import '{class_name}' from '{module}'"
106
+ ) from exc
107
+
90
108
  func = getattr(obj, attr, None)
91
109
  if func and isinstance(func, ObjectProxy) and hasattr(func, "__wrapped__"):
92
110
  setattr(obj, attr, func.__wrapped__)
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __version__ = "0.47b0"
15
+ __version__ = "0.49b0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: opentelemetry-instrumentation
3
- Version: 0.47b0
3
+ Version: 0.49b0
4
4
  Summary: Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python
5
5
  Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-instrumentation
6
6
  Author-email: OpenTelemetry Authors <cncf-opentelemetry-contributors@lists.cncf.io>
@@ -18,7 +18,8 @@ Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
19
  Requires-Python: >=3.8
20
20
  Requires-Dist: opentelemetry-api~=1.4
21
- Requires-Dist: setuptools>=16.0
21
+ Requires-Dist: opentelemetry-semantic-conventions==0.49b0
22
+ Requires-Dist: packaging>=18.0
22
23
  Requires-Dist: wrapt<2.0.0,>=1.0.0
23
24
  Description-Content-Type: text/x-rst
24
25
 
@@ -64,7 +65,7 @@ to figure out which instrumentation packages the user might want to install. By
64
65
  prints out a list of the default and detected instrumentation packages that can be added to a
65
66
  requirements.txt file. It also supports installing the packages when run with
66
67
  :code:`--action=install` or :code:`-a install` flag. All default and detectable
67
- instrumentation packages are defined `here <https://github.com/flands/opentelemetry-python-contrib/blob/main/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py>`.
68
+ instrumentation packages are defined `here <https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py>`.
68
69
 
69
70
 
70
71
  opentelemetry-instrument
@@ -0,0 +1,20 @@
1
+ opentelemetry/instrumentation/_semconv.py,sha256=eX7jtDvnLjCogil0SRZ4q_ftKWyJRNKiOkiuDRNVzgA,14582
2
+ opentelemetry/instrumentation/bootstrap.py,sha256=Q-1j1G7QKXTTvH5xGGGRX3jCpTf_NuhBoy2X_MvM9sg,5428
3
+ opentelemetry/instrumentation/bootstrap_gen.py,sha256=FXsAFLZ-XaIUiv-jFr_QvjzTE8st8DYaX6GqxXzxKP8,6865
4
+ opentelemetry/instrumentation/dependencies.py,sha256=FcrMj6pudXBE70VhytIMc-JS-dVGDbtCNE2dviT4GBg,2527
5
+ opentelemetry/instrumentation/distro.py,sha256=l7wjM9eR44X-Bk6w-b3_kW3_QgW82OiITRTOY48shZk,2168
6
+ opentelemetry/instrumentation/environment_variables.py,sha256=oRcbNSSbnqJMQ3r4gBhK6jqtuI5WizapP962Z8DrVZ8,905
7
+ opentelemetry/instrumentation/instrumentor.py,sha256=0r527qBsl-fPAVXPM3iu_k94omLN5MStOFmuAqpD_Zo,4509
8
+ opentelemetry/instrumentation/propagators.py,sha256=hBkG70KlMUiTjxPeiyOhkb_eE96DRVzRyY4fEIzMqD4,4070
9
+ opentelemetry/instrumentation/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ opentelemetry/instrumentation/sqlcommenter_utils.py,sha256=yV_-hcwy_3ckP76_FC2dOrd8IKi9z_9s980ZMuGYkrE,1960
11
+ opentelemetry/instrumentation/utils.py,sha256=4SvKC9Rg1tMcQe5SiAtbX82Xe5lXx1ltMdrCGLhmc3o,7037
12
+ opentelemetry/instrumentation/version.py,sha256=feu1cU-5Mlc3KHErNko0hTd8PObq7lIudxaIp9B3L_8,608
13
+ opentelemetry/instrumentation/auto_instrumentation/__init__.py,sha256=G3qhU-ZfdATzPdsZCvBZ2CT8kNZ1Wc8l7fETXKTPF2M,3800
14
+ opentelemetry/instrumentation/auto_instrumentation/_load.py,sha256=e3IlquYKHgLuZXZ9pjMg76yxiM0Qa_-6qxgPFL-Vmh0,6301
15
+ opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py,sha256=p3cz9NlKNlnzxc7guFSPyztx8XMUteAxkN1NFYXSH-0,1449
16
+ opentelemetry_instrumentation-0.49b0.dist-info/METADATA,sha256=cELamr_k3IkgMcm94h5mWlMiFildt8WgbxPt7waVdJk,6180
17
+ opentelemetry_instrumentation-0.49b0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
18
+ opentelemetry_instrumentation-0.49b0.dist-info/entry_points.txt,sha256=iVv3t5REB0O58tFUEQQXYLrTCa1VVOFUXfrbvUk6_aU,279
19
+ opentelemetry_instrumentation-0.49b0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
20
+ opentelemetry_instrumentation-0.49b0.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- opentelemetry/instrumentation/_semconv.py,sha256=zexTZwIY9qhUzmdMwVdvnP96B_L88CRZehl3SqbKyuc,13679
2
- opentelemetry/instrumentation/bootstrap.py,sha256=J_sUXmcnUGXXj0ySJ1KxGcr-nmfDP7-S_N3vHqjLecY,4725
3
- opentelemetry/instrumentation/bootstrap_gen.py,sha256=FFap1VKz1o1lq2SpkxPyRd8sJkXx32chqfXlVQ-L540,6704
4
- opentelemetry/instrumentation/dependencies.py,sha256=ljJ0nMK_vNZXOiCTLOT1nM3xpwmx7LVaW_S53jcRvIY,1798
5
- opentelemetry/instrumentation/distro.py,sha256=vCvt0pHLtL3OF1m7MVyPUkK4UfoZN6-Vj7JCc6XLbwc,2145
6
- opentelemetry/instrumentation/environment_variables.py,sha256=oRcbNSSbnqJMQ3r4gBhK6jqtuI5WizapP962Z8DrVZ8,905
7
- opentelemetry/instrumentation/instrumentor.py,sha256=0r527qBsl-fPAVXPM3iu_k94omLN5MStOFmuAqpD_Zo,4509
8
- opentelemetry/instrumentation/propagators.py,sha256=hBkG70KlMUiTjxPeiyOhkb_eE96DRVzRyY4fEIzMqD4,4070
9
- opentelemetry/instrumentation/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- opentelemetry/instrumentation/sqlcommenter_utils.py,sha256=yV_-hcwy_3ckP76_FC2dOrd8IKi9z_9s980ZMuGYkrE,1960
11
- opentelemetry/instrumentation/utils.py,sha256=5j6HYS00vpf5EeNHHYIpys1TZn9V-hnM6Hj2qQdPRG4,6339
12
- opentelemetry/instrumentation/version.py,sha256=6FmWdr2KRW0MGpqEO5NBzLrm6URCtz_6ixXi_ALh6JA,608
13
- opentelemetry/instrumentation/auto_instrumentation/__init__.py,sha256=en-gz8Qg6JlGR6XnFF0TYBElVUGMGNo3FtnB0GBJfA0,3780
14
- opentelemetry/instrumentation/auto_instrumentation/_load.py,sha256=RDFVxFJ2NR02i8_MFc2FJFxRQjsvjX8f1H2N7ZMF5V0,4794
15
- opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py,sha256=p3cz9NlKNlnzxc7guFSPyztx8XMUteAxkN1NFYXSH-0,1449
16
- opentelemetry_instrumentation-0.47b0.dist-info/METADATA,sha256=GuxCSAJOongEM4JWciogmZYVmD5nFh7L347AKWo7wIQ,6115
17
- opentelemetry_instrumentation-0.47b0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
18
- opentelemetry_instrumentation-0.47b0.dist-info/entry_points.txt,sha256=iVv3t5REB0O58tFUEQQXYLrTCa1VVOFUXfrbvUk6_aU,279
19
- opentelemetry_instrumentation-0.47b0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
20
- opentelemetry_instrumentation-0.47b0.dist-info/RECORD,,