Skip to content

Commit

Permalink
Merge branch 'main' into feature/add_pika_instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
owais committed Sep 29, 2021
2 parents e09dfa1 + 93e5399 commit e07c4b1
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#2147](https://github.com/open-telemetry/opentelemetry-python/pull/2147))
- Fix validity calculation for trace and span IDs
([#2145](https://github.com/open-telemetry/opentelemetry-python/pull/2145))
- Add `schema_url` to `TracerProvider.get_tracer`
([#2154](https://github.com/open-telemetry/opentelemetry-python/pull/2154))

## [1.5.0-0.24b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.5.0-0.24b0) - 2021-08-26

Expand Down
30 changes: 22 additions & 8 deletions opentelemetry-api/src/opentelemetry/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@


import os
import typing
from abc import ABC, abstractmethod
from contextlib import contextmanager
from enum import Enum
Expand Down Expand Up @@ -186,7 +187,8 @@ class TracerProvider(ABC):
def get_tracer(
self,
instrumenting_module_name: str,
instrumenting_library_version: str = "",
instrumenting_library_version: typing.Optional[str] = None,
schema_url: typing.Optional[str] = None,
) -> "Tracer":
"""Returns a `Tracer` for use by the given instrumentation library.
Expand All @@ -208,6 +210,8 @@ def get_tracer(
instrumenting_library_version: Optional. The version string of the
instrumenting library. Usually this should be the same as
``pkg_resources.get_distribution(instrumenting_library_name).version``.
schema_url: Optional. Specifies the Schema URL of the emitted telemetry.
"""


Expand All @@ -220,7 +224,8 @@ class _DefaultTracerProvider(TracerProvider):
def get_tracer(
self,
instrumenting_module_name: str,
instrumenting_library_version: str = "",
instrumenting_library_version: typing.Optional[str] = None,
schema_url: typing.Optional[str] = None,
) -> "Tracer":
# pylint:disable=no-self-use,unused-argument
return _DefaultTracer()
Expand All @@ -230,14 +235,19 @@ class ProxyTracerProvider(TracerProvider):
def get_tracer(
self,
instrumenting_module_name: str,
instrumenting_library_version: str = "",
instrumenting_library_version: typing.Optional[str] = None,
schema_url: typing.Optional[str] = None,
) -> "Tracer":
if _TRACER_PROVIDER:
return _TRACER_PROVIDER.get_tracer(
instrumenting_module_name, instrumenting_library_version
instrumenting_module_name,
instrumenting_library_version,
schema_url,
)
return ProxyTracer(
instrumenting_module_name, instrumenting_library_version
instrumenting_module_name,
instrumenting_library_version,
schema_url,
)


Expand Down Expand Up @@ -375,10 +385,12 @@ class ProxyTracer(Tracer):
def __init__(
self,
instrumenting_module_name: str,
instrumenting_library_version: str,
instrumenting_library_version: typing.Optional[str] = None,
schema_url: typing.Optional[str] = None,
):
self._instrumenting_module_name = instrumenting_module_name
self._instrumenting_library_version = instrumenting_library_version
self._schema_url = schema_url
self._real_tracer: Optional[Tracer] = None
self._noop_tracer = _DefaultTracer()

Expand All @@ -391,6 +403,7 @@ def _tracer(self) -> Tracer:
self._real_tracer = _TRACER_PROVIDER.get_tracer(
self._instrumenting_module_name,
self._instrumenting_library_version,
self._schema_url,
)
return self._real_tracer
return self._noop_tracer
Expand Down Expand Up @@ -445,8 +458,9 @@ def start_as_current_span(

def get_tracer(
instrumenting_module_name: str,
instrumenting_library_version: str = "",
instrumenting_library_version: typing.Optional[str] = None,
tracer_provider: Optional[TracerProvider] = None,
schema_url: typing.Optional[str] = None,
) -> "Tracer":
"""Returns a `Tracer` for use by the given instrumentation library.
Expand All @@ -458,7 +472,7 @@ def get_tracer(
if tracer_provider is None:
tracer_provider = get_tracer_provider()
return tracer_provider.get_tracer(
instrumenting_module_name, instrumenting_library_version
instrumenting_module_name, instrumenting_library_version, schema_url
)


Expand Down
6 changes: 4 additions & 2 deletions opentelemetry-api/tests/trace/test_globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ def tearDown(self) -> None:
def test_get_tracer(self):
"""trace.get_tracer should proxy to the global tracer provider."""
trace.get_tracer("foo", "var")
self._mock_tracer_provider.get_tracer.assert_called_with("foo", "var")
self._mock_tracer_provider.get_tracer.assert_called_with(
"foo", "var", None
)
mock_provider = unittest.mock.Mock()
trace.get_tracer("foo", "var", mock_provider)
mock_provider.get_tracer.assert_called_with("foo", "var")
mock_provider.get_tracer.assert_called_with("foo", "var", None)


class TestTracer(unittest.TestCase):
Expand Down
5 changes: 3 additions & 2 deletions opentelemetry-api/tests/trace/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

# pylint: disable=W0212,W0222,W0221

import typing
import unittest

from opentelemetry import trace
Expand All @@ -24,7 +24,8 @@ class TestProvider(trace._DefaultTracerProvider):
def get_tracer(
self,
instrumenting_module_name: str,
instrumenting_library_version: str = "",
instrumenting_library_version: typing.Optional[str] = None,
schema_url: typing.Optional[str] = None,
) -> trace.Tracer:
return TestTracer()

Expand Down
10 changes: 8 additions & 2 deletions opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import logging
import threading
import traceback
import typing
from collections import OrderedDict
from contextlib import contextmanager
from os import environ
Expand Down Expand Up @@ -1099,18 +1100,23 @@ def resource(self) -> Resource:
def get_tracer(
self,
instrumenting_module_name: str,
instrumenting_library_version: str = "",
instrumenting_library_version: typing.Optional[str] = None,
schema_url: typing.Optional[str] = None,
) -> "trace_api.Tracer":
if not instrumenting_module_name: # Reject empty strings too.
instrumenting_module_name = ""
logger.error("get_tracer called with missing module name.")
if instrumenting_library_version is None:
instrumenting_library_version = ""
return Tracer(
self.sampler,
self.resource,
self._active_span_processor,
self.id_generator,
InstrumentationInfo(
instrumenting_module_name, instrumenting_library_version
instrumenting_module_name,
instrumenting_library_version,
schema_url,
),
self._span_limits,
)
Expand Down
38 changes: 29 additions & 9 deletions opentelemetry-sdk/src/opentelemetry/sdk/util/instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import typing


class InstrumentationInfo:
Expand All @@ -20,31 +21,50 @@ class InstrumentationInfo:
properties.
"""

__slots__ = ("_name", "_version")
__slots__ = ("_name", "_version", "_schema_url")

def __init__(self, name: str, version: str):
def __init__(
self,
name: str,
version: typing.Optional[str] = None,
schema_url: typing.Optional[str] = None,
):
self._name = name
self._version = version
self._schema_url = schema_url

def __repr__(self):
return f"{type(self).__name__}({self._name}, {self._version})"
return f"{type(self).__name__}({self._name}, {self._version}, {self._schema_url})"

def __hash__(self):
return hash((self._name, self._version))
return hash((self._name, self._version, self._schema_url))

def __eq__(self, value):
return type(value) is type(self) and (self._name, self._version) == (
value._name,
value._version,
return (
type(value) is type(self)
and (
self._name,
self._version,
self._schema_url,
)
== (value._name, value._version, value._schema_url)
)

def __lt__(self, value):
if type(value) is not type(self):
return NotImplemented
return (self._name, self._version) < (value._name, value._version)
return (self._name, self._version, self._schema_url) < (
value._name,
value._version,
value._schema_url,
)

@property
def schema_url(self) -> typing.Optional[str]:
return self._schema_url

@property
def version(self) -> str:
def version(self) -> typing.Optional[str]:
return self._version

@property
Expand Down
9 changes: 7 additions & 2 deletions opentelemetry-sdk/tests/trace/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,17 +237,20 @@ def test_start_span_invalid_spancontext(self):

def test_instrumentation_info(self):
tracer_provider = trace.TracerProvider()
schema_url = "https://opentelemetry.io/schemas/1.3.0"
tracer1 = tracer_provider.get_tracer("instr1")
tracer2 = tracer_provider.get_tracer("instr2", "1.3b3")
tracer2 = tracer_provider.get_tracer("instr2", "1.3b3", schema_url)
span1 = tracer1.start_span("s1")
span2 = tracer2.start_span("s2")
self.assertEqual(
span1.instrumentation_info, InstrumentationInfo("instr1", "")
)
self.assertEqual(
span2.instrumentation_info, InstrumentationInfo("instr2", "1.3b3")
span2.instrumentation_info,
InstrumentationInfo("instr2", "1.3b3", schema_url),
)

self.assertEqual(span2.instrumentation_info.schema_url, schema_url)
self.assertEqual(span2.instrumentation_info.version, "1.3b3")
self.assertEqual(span2.instrumentation_info.name, "instr2")

Expand All @@ -267,6 +270,7 @@ def test_invalid_instrumentation_info(self):
)
span1 = tracer1.start_span("foo")
self.assertTrue(span1.is_recording())
self.assertEqual(tracer1.instrumentation_info.schema_url, None)
self.assertEqual(tracer1.instrumentation_info.version, "")
self.assertEqual(tracer1.instrumentation_info.name, "")

Expand All @@ -275,6 +279,7 @@ def test_invalid_instrumentation_info(self):
)
span2 = tracer2.start_span("bar")
self.assertTrue(span2.is_recording())
self.assertEqual(tracer2.instrumentation_info.schema_url, None)
self.assertEqual(tracer2.instrumentation_info.version, "")
self.assertEqual(tracer2.instrumentation_info.name, "")

Expand Down
17 changes: 17 additions & 0 deletions tests/util/src/opentelemetry/test/wsgitestutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io
import wsgiref.util as wsgiref_util

from opentelemetry import trace
from opentelemetry.test.spantestutil import SpanTestBase


Expand All @@ -37,3 +38,19 @@ def start_response(self, status, response_headers, exc_info=None):
self.response_headers = response_headers
self.exc_info = exc_info
return self.write

def assertTraceResponseHeaderMatchesSpan(
self, headers, span
): # pylint: disable=invalid-name
self.assertIn("traceresponse", headers)
self.assertEqual(
headers["access-control-expose-headers"],
"traceresponse",
)

trace_id = trace.format_trace_id(span.get_span_context().trace_id)
span_id = trace.format_span_id(span.get_span_context().span_id)
self.assertEqual(
f"00-{trace_id}-{span_id}-01",
headers["traceresponse"],
)

0 comments on commit e07c4b1

Please sign in to comment.