From 7a8ef3633dd84f2ceae220c6ea9086cc16f71541 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Mon, 29 Nov 2021 10:27:56 -0800 Subject: [PATCH 1/4] opentelemetry-api: update OTEL_METRICS_EXPORTER variable (#2303) * opentelemetry-api: update OTEL_METRICS_EXPORTER variable Fixes #2302 * Update CHANGELOG.md * fix lint --- CHANGELOG.md | 2 ++ .../src/opentelemetry/environment_variables.py | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7e3c2fce16..36772a49eb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Adds Aggregation and instruments as part of Metrics SDK ([#2234](https://github.com/open-telemetry/opentelemetry-python/pull/2234)) +- Update visibility of OTEL_METRICS_EXPORTER environment variable + ([#2303](https://github.com/open-telemetry/opentelemetry-python/pull/2303)) ## [1.7.1-0.26b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.7.0-0.26b0) - 2021-11-11 diff --git a/opentelemetry-api/src/opentelemetry/environment_variables.py b/opentelemetry-api/src/opentelemetry/environment_variables.py index de11e42390e..af2319453cd 100644 --- a/opentelemetry-api/src/opentelemetry/environment_variables.py +++ b/opentelemetry-api/src/opentelemetry/environment_variables.py @@ -12,6 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +OTEL_METRICS_EXPORTER = "OTEL_METRICS_EXPORTER" +""" +.. envvar:: OTEL_METRICS_EXPORTER + +""" + OTEL_PROPAGATORS = "OTEL_PROPAGATORS" """ .. envvar:: OTEL_PROPAGATORS @@ -41,9 +47,3 @@ """ .. envvar:: OTEL_PYTHON_METER_PROVIDER """ - -_OTEL_METRICS_EXPORTER = "OTEL_METRICS_EXPORTER" -""" -.. envvar:: OTEL_METRICS_EXPORTER - -""" From 5added0261a8a55f13f1f803ca051845a51f6b2c Mon Sep 17 00:00:00 2001 From: Morgan McLean Date: Mon, 29 Nov 2021 16:05:16 -0600 Subject: [PATCH 2/4] Remove hardcoded Zoom link (#2287) --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 9c6e9745b14..63ae6859a95 100644 --- a/README.md +++ b/README.md @@ -122,9 +122,7 @@ https://opentelemetry-python.readthedocs.io/en/latest/. For information about contributing to OpenTelemetry Python, see [CONTRIBUTING.md](CONTRIBUTING.md). -We meet weekly on Thursdays at 9AM PST. The meeting is subject to change depending on contributors' availability. Check the [OpenTelemetry community calendar](https://calendar.google.com/calendar/embed?src=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com) for specific dates. - -Meetings take place via [Zoom video conference](https://zoom.us/j/8287234601?pwd=YjN2MURycXc4cEZlYTRtYjJaM0grZz09). The passcode is _77777_. +We meet weekly on Thursdays at 9AM PST. The meeting is subject to change depending on contributors' availability. Check the [OpenTelemetry community calendar](https://calendar.google.com/calendar/embed?src=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com) for specific dates and Zoom meeting links. Meeting notes are available as a public [Google doc](https://docs.google.com/document/d/1CIMGoIOZ-c3-igzbd6_Pnxx1SjAkjwqoYSUWxPY8XIs/edit). For edit access, get in touch on [GitHub Discussions](https://github.com/open-telemetry/opentelemetry-python/discussions). From 46f77d0dee69dd9781fd9fae9280a12317b51606 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 2 Dec 2021 11:51:00 -0800 Subject: [PATCH 3/4] Adding support for entrypoint loading of log exporters (#2253) --- CHANGELOG.md | 2 + .../setup.cfg | 2 + opentelemetry-sdk/setup.cfg | 2 + .../sdk/_configuration/__init__.py | 84 +++++++++++++------ opentelemetry-sdk/tests/test_configurator.py | 44 ++++++---- 5 files changed, 92 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36772a49eb2..9f0cf21c606 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2234](https://github.com/open-telemetry/opentelemetry-python/pull/2234)) - Update visibility of OTEL_METRICS_EXPORTER environment variable ([#2303](https://github.com/open-telemetry/opentelemetry-python/pull/2303)) +- Adding entrypoints for log emitter provider and console, otlp log exporters + ([#2253](https://github.com/open-telemetry/opentelemetry-python/pull/2253)) ## [1.7.1-0.26b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.7.0-0.26b0) - 2021-11-11 diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/setup.cfg b/exporter/opentelemetry-exporter-otlp-proto-grpc/setup.cfg index 016fabcd36d..fb5cfe0dc2f 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/setup.cfg +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/setup.cfg @@ -57,3 +57,5 @@ where = src [options.entry_points] opentelemetry_traces_exporter = otlp_proto_grpc = opentelemetry.exporter.otlp.proto.grpc.trace_exporter:OTLPSpanExporter +opentelemetry_logs_exporter = + otlp_proto_grpc = opentelemetry.exporter.otlp.proto.grpc._log_exporter:OTLPLogExporter diff --git a/opentelemetry-sdk/setup.cfg b/opentelemetry-sdk/setup.cfg index 92c3ddbcef5..a8025965004 100644 --- a/opentelemetry-sdk/setup.cfg +++ b/opentelemetry-sdk/setup.cfg @@ -56,6 +56,8 @@ opentelemetry_traces_exporter = console = opentelemetry.sdk.trace.export:ConsoleSpanExporter opentelemetry_log_emitter_provider = sdk_log_emitter_provider = opentelemetry.sdk._logs:LogEmitterProvider +opentelemetry_logs_exporter = + console = opentelemetry.sdk._logs.export:ConsoleExporter opentelemetry_id_generator = random = opentelemetry.sdk.trace.id_generator:RandomIdGenerator opentelemetry_environment_variables = diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py index cb4aed53b53..377b21c8282 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_configuration/__init__.py @@ -28,6 +28,11 @@ OTEL_PYTHON_ID_GENERATOR, OTEL_TRACES_EXPORTER, ) +from opentelemetry.sdk._logs import ( + LogEmitterProvider, + set_log_emitter_provider, +) +from opentelemetry.sdk._logs.export import BatchLogProcessor, LogExporter from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanExporter @@ -35,32 +40,28 @@ from opentelemetry.semconv.resource import ResourceAttributes _EXPORTER_OTLP = "otlp" -_EXPORTER_OTLP_SPAN = "otlp_proto_grpc" +_EXPORTER_OTLP_PROTO_GRPC = "otlp_proto_grpc" _RANDOM_ID_GENERATOR = "random" _DEFAULT_ID_GENERATOR = _RANDOM_ID_GENERATOR +# TODO: add log exporter env variable +_OTEL_LOGS_EXPORTER = "OTEL_LOGS_EXPORTER" + def _get_id_generator() -> str: return environ.get(OTEL_PYTHON_ID_GENERATOR, _DEFAULT_ID_GENERATOR) -def _get_exporter_names() -> Sequence[str]: - trace_exporters = environ.get(OTEL_TRACES_EXPORTER) - +def _get_exporter_names(names: str) -> Sequence[str]: exporters = set() - if trace_exporters and trace_exporters.lower().strip() != "none": - exporters.update( - { - trace_exporter.strip() - for trace_exporter in trace_exporters.split(",") - } - ) + if names and names.lower().strip() != "none": + exporters.update({_exporter.strip() for _exporter in names.split(",")}) if _EXPORTER_OTLP in exporters: exporters.remove(_EXPORTER_OTLP) - exporters.add(_EXPORTER_OTLP_SPAN) + exporters.add(_EXPORTER_OTLP_PROTO_GRPC) return list(exporters) @@ -91,7 +92,29 @@ def _init_tracing( ) -def _import_tracer_provider_config_components( +def _init_logging( + exporters: Dict[str, Sequence[LogExporter]], + auto_instrumentation_version: Optional[str] = None, +): + # if env var OTEL_RESOURCE_ATTRIBUTES is given, it will read the service_name + # from the env variable else defaults to "unknown_service" + auto_resource = {} + # populate version if using auto-instrumentation + if auto_instrumentation_version: + auto_resource[ + ResourceAttributes.TELEMETRY_AUTO_VERSION + ] = auto_instrumentation_version + provider = LogEmitterProvider(resource=Resource.create(auto_resource)) + set_log_emitter_provider(provider) + + for _, exporter_class in exporters.items(): + exporter_args = {} + provider.add_log_processor( + BatchLogProcessor(exporter_class(**exporter_args)) + ) + + +def _import_config_components( selected_components, entry_point_name ) -> Sequence[Tuple[str, object]]: component_entry_points = { @@ -112,28 +135,34 @@ def _import_tracer_provider_config_components( def _import_exporters( - exporter_names: Sequence[str], -) -> Dict[str, Type[SpanExporter]]: + trace_exporter_names: Sequence[str], + log_exporter_names: Sequence[str], +) -> Tuple[Dict[str, Type[SpanExporter]], Dict[str, Type[LogExporter]]]: trace_exporters = {} + log_exporters = {} - for ( - exporter_name, - exporter_impl, - ) in _import_tracer_provider_config_components( - exporter_names, "opentelemetry_traces_exporter" + for (exporter_name, exporter_impl,) in _import_config_components( + trace_exporter_names, "opentelemetry_traces_exporter" ): if issubclass(exporter_impl, SpanExporter): trace_exporters[exporter_name] = exporter_impl else: raise RuntimeError(f"{exporter_name} is not a trace exporter") - return trace_exporters + + for (exporter_name, exporter_impl,) in _import_config_components( + log_exporter_names, "opentelemetry_logs_exporter" + ): + if issubclass(exporter_impl, LogExporter): + log_exporters[exporter_name] = exporter_impl + else: + raise RuntimeError(f"{exporter_name} is not a log exporter") + + return trace_exporters, log_exporters def _import_id_generator(id_generator_name: str) -> IdGenerator: # pylint: disable=unbalanced-tuple-unpacking - [ - (id_generator_name, id_generator_impl) - ] = _import_tracer_provider_config_components( + [(id_generator_name, id_generator_impl)] = _import_config_components( [id_generator_name.strip()], "opentelemetry_id_generator" ) @@ -144,11 +173,14 @@ def _import_id_generator(id_generator_name: str) -> IdGenerator: def _initialize_components(auto_instrumentation_version): - exporter_names = _get_exporter_names() - trace_exporters = _import_exporters(exporter_names) + trace_exporters, log_exporters = _import_exporters( + _get_exporter_names(environ.get(OTEL_TRACES_EXPORTER)), + _get_exporter_names(environ.get(_OTEL_LOGS_EXPORTER)), + ) id_generator_name = _get_id_generator() id_generator = _import_id_generator(id_generator_name) _init_tracing(trace_exporters, id_generator, auto_instrumentation_version) + _init_logging(log_exporters, auto_instrumentation_version) class _BaseConfigurator(ABC): diff --git a/opentelemetry-sdk/tests/test_configurator.py b/opentelemetry-sdk/tests/test_configurator.py index 9243b80c675..8a4aadd4790 100644 --- a/opentelemetry-sdk/tests/test_configurator.py +++ b/opentelemetry-sdk/tests/test_configurator.py @@ -18,19 +18,19 @@ from unittest.mock import patch from opentelemetry import trace -from opentelemetry.environment_variables import ( - OTEL_PYTHON_ID_GENERATOR, - OTEL_TRACES_EXPORTER, -) +from opentelemetry.environment_variables import OTEL_PYTHON_ID_GENERATOR from opentelemetry.sdk._configuration import ( _EXPORTER_OTLP, - _EXPORTER_OTLP_SPAN, + _EXPORTER_OTLP_PROTO_GRPC, _get_exporter_names, _get_id_generator, + _import_exporters, _import_id_generator, _init_tracing, ) +from opentelemetry.sdk._logs.export import ConsoleExporter from opentelemetry.sdk.resources import SERVICE_NAME, Resource +from opentelemetry.sdk.trace.export import ConsoleSpanExporter from opentelemetry.sdk.trace.id_generator import IdGenerator, RandomIdGenerator @@ -164,22 +164,34 @@ def test_trace_init_custom_id_generator(self, mock_iter_entry_points): class TestExporterNames(TestCase): def test_otlp_exporter_overwrite(self): - for exporter in [_EXPORTER_OTLP, _EXPORTER_OTLP_SPAN]: - with patch.dict(environ, {OTEL_TRACES_EXPORTER: exporter}): - self.assertEqual(_get_exporter_names(), [_EXPORTER_OTLP_SPAN]) + for exporter in [_EXPORTER_OTLP, _EXPORTER_OTLP_PROTO_GRPC]: + self.assertEqual( + _get_exporter_names(exporter), [_EXPORTER_OTLP_PROTO_GRPC] + ) - @patch.dict(environ, {OTEL_TRACES_EXPORTER: "jaeger,zipkin"}) def test_multiple_exporters(self): - self.assertEqual(sorted(_get_exporter_names()), ["jaeger", "zipkin"]) + self.assertEqual( + sorted(_get_exporter_names("jaeger,zipkin")), ["jaeger", "zipkin"] + ) - @patch.dict(environ, {OTEL_TRACES_EXPORTER: "none"}) def test_none_exporters(self): - self.assertEqual(sorted(_get_exporter_names()), []) + self.assertEqual(sorted(_get_exporter_names("none")), []) - @patch.dict(environ, {}, clear=True) def test_no_exporters(self): - self.assertEqual(sorted(_get_exporter_names()), []) + self.assertEqual(sorted(_get_exporter_names(None)), []) - @patch.dict(environ, {OTEL_TRACES_EXPORTER: ""}) def test_empty_exporters(self): - self.assertEqual(sorted(_get_exporter_names()), []) + self.assertEqual(sorted(_get_exporter_names("")), []) + + +class TestImportExporters(TestCase): + def test_console_exporters(self): + trace_exporters, logs_exporters = _import_exporters( + ["console"], ["console"] + ) + self.assertEqual( + trace_exporters["console"].__class__, ConsoleSpanExporter.__class__ + ) + self.assertEqual( + logs_exporters["console"].__class__, ConsoleExporter.__class__ + ) From 8bbaf76e59d6d0ac816109b6ba3378714c8b2333 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Fri, 3 Dec 2021 14:51:59 -0800 Subject: [PATCH 4/4] rename ConsoleExporter to ConsoleLogExporter (#2307) * rename ConsoleExporter to ConsoleLogExporter * update changelog --- CHANGELOG.md | 2 ++ opentelemetry-sdk/setup.cfg | 2 +- .../src/opentelemetry/sdk/_logs/export/__init__.py | 2 +- opentelemetry-sdk/tests/logs/test_export.py | 8 ++++---- opentelemetry-sdk/tests/test_configurator.py | 4 ++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f0cf21c606..cd154b753cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2303](https://github.com/open-telemetry/opentelemetry-python/pull/2303)) - Adding entrypoints for log emitter provider and console, otlp log exporters ([#2253](https://github.com/open-telemetry/opentelemetry-python/pull/2253)) +- Rename ConsoleExporter to ConsoleLogExporter + ([#2307](https://github.com/open-telemetry/opentelemetry-python/pull/2307)) ## [1.7.1-0.26b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.7.0-0.26b0) - 2021-11-11 diff --git a/opentelemetry-sdk/setup.cfg b/opentelemetry-sdk/setup.cfg index a8025965004..e78448dd820 100644 --- a/opentelemetry-sdk/setup.cfg +++ b/opentelemetry-sdk/setup.cfg @@ -57,7 +57,7 @@ opentelemetry_traces_exporter = opentelemetry_log_emitter_provider = sdk_log_emitter_provider = opentelemetry.sdk._logs:LogEmitterProvider opentelemetry_logs_exporter = - console = opentelemetry.sdk._logs.export:ConsoleExporter + console = opentelemetry.sdk._logs.export:ConsoleLogExporter opentelemetry_id_generator = random = opentelemetry.sdk.trace.id_generator:RandomIdGenerator opentelemetry_environment_variables = diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/export/__init__.py index c705c2b2497..87ac308317d 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/export/__init__.py @@ -63,7 +63,7 @@ def shutdown(self): """ -class ConsoleExporter(LogExporter): +class ConsoleLogExporter(LogExporter): """Implementation of :class:`LogExporter` that prints log records to the console. diff --git a/opentelemetry-sdk/tests/logs/test_export.py b/opentelemetry-sdk/tests/logs/test_export.py index 45b83358f93..502c68ed759 100644 --- a/opentelemetry-sdk/tests/logs/test_export.py +++ b/opentelemetry-sdk/tests/logs/test_export.py @@ -31,7 +31,7 @@ ) from opentelemetry.sdk._logs.export import ( BatchLogProcessor, - ConsoleExporter, + ConsoleLogExporter, SimpleLogProcessor, ) from opentelemetry.sdk._logs.export.in_memory_log_exporter import ( @@ -321,7 +321,7 @@ def _target(): log_processor.shutdown() -class TestConsoleExporter(unittest.TestCase): +class TestConsoleLogExporter(unittest.TestCase): def test_export(self): # pylint: disable=no-self-use """Check that the console exporter prints log records.""" log_data = LogData( @@ -341,7 +341,7 @@ def test_export(self): # pylint: disable=no-self-use "first_name", "first_version" ), ) - exporter = ConsoleExporter() + exporter = ConsoleLogExporter() # Mocking stdout interferes with debugging and test reporting, mock on # the exporter instance instead. @@ -362,7 +362,7 @@ def formatter(record): # pylint: disable=unused-argument return mock_record_str mock_stdout = Mock() - exporter = ConsoleExporter(out=mock_stdout, formatter=formatter) + exporter = ConsoleLogExporter(out=mock_stdout, formatter=formatter) log_data = LogData( log_record=LogRecord(), instrumentation_info=InstrumentationInfo( diff --git a/opentelemetry-sdk/tests/test_configurator.py b/opentelemetry-sdk/tests/test_configurator.py index 8a4aadd4790..ca755544b76 100644 --- a/opentelemetry-sdk/tests/test_configurator.py +++ b/opentelemetry-sdk/tests/test_configurator.py @@ -28,7 +28,7 @@ _import_id_generator, _init_tracing, ) -from opentelemetry.sdk._logs.export import ConsoleExporter +from opentelemetry.sdk._logs.export import ConsoleLogExporter from opentelemetry.sdk.resources import SERVICE_NAME, Resource from opentelemetry.sdk.trace.export import ConsoleSpanExporter from opentelemetry.sdk.trace.id_generator import IdGenerator, RandomIdGenerator @@ -193,5 +193,5 @@ def test_console_exporters(self): trace_exporters["console"].__class__, ConsoleSpanExporter.__class__ ) self.assertEqual( - logs_exporters["console"].__class__, ConsoleExporter.__class__ + logs_exporters["console"].__class__, ConsoleLogExporter.__class__ )