From ab5f6a07d331aa5877ab3fb75ce584b3ec2627c8 Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Wed, 16 Nov 2022 10:28:47 +0530 Subject: [PATCH 01/10] Adds environment variables for log exporter --- .../otlp/proto/grpc/_log_exporter/__init__.py | 38 +++++++++++++ .../otlp/proto/http/_log_exporter/__init__.py | 34 +++++++++--- .../sdk/environment_variables.py | 54 +++++++++++++++++++ 3 files changed, 119 insertions(+), 7 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py index 489cf35c372..9226292c08e 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py @@ -11,12 +11,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +from os import environ from typing import Optional, Sequence from grpc import ChannelCredentials, Compression from opentelemetry.exporter.otlp.proto.grpc.exporter import ( OTLPExporterMixin, get_resource_data, + _get_credentials, _translate_value, + environ_to_compression, ) from opentelemetry.proto.collector.logs.v1.logs_service_pb2 import ( ExportLogsServiceRequest, @@ -34,6 +37,14 @@ from opentelemetry.sdk._logs import LogData from opentelemetry.sdk._logs.export import LogExporter, LogExportResult +from opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, + OTEL_EXPORTER_OTLP_LOGS_HEADERS, + OTEL_EXPORTER_OTLP_LOGS_INSECURE, + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, +) class OTLPLogExporter( LogExporter, @@ -52,6 +63,33 @@ def __init__( timeout: Optional[int] = None, compression: Optional[Compression] = None, ): + if insecure is None: + insecure = environ.get(OTEL_EXPORTER_OTLP_LOGS_INSECURE) + if insecure is not None: + insecure = insecure.lower() == "true" + + if ( + not insecure + and environ.get(OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE) is not None + ): + credentials = _get_credentials( + credentials, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE + ) + + environ_timeout = environ.get(OTEL_EXPORTER_OTLP_LOGS_TIMEOUT) + environ_timeout = ( + int(environ_timeout) if environ_timeout is not None else None + ) + + compression = ( + environ_to_compression(OTEL_EXPORTER_OTLP_LOGS_COMPRESSION) + if compression is None + else compression + ) + endpoint=endpoint or environ.get(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT), + + headers=headers or environ.get(OTEL_EXPORTER_OTLP_LOGS_HEADERS), + super().__init__( **{ "endpoint": endpoint, diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py index 49daa29e8ab..f89ecfe8a46 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py @@ -29,6 +29,11 @@ OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT, + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_HEADERS, + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, ) from opentelemetry.sdk._logs import LogData from opentelemetry.sdk._logs.export import ( @@ -79,16 +84,26 @@ def __init__( compression: Optional[Compression] = None, session: Optional[requests.Session] = None, ): - self._endpoint = endpoint or _append_logs_path( - environ.get(OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_ENDPOINT) + self._endpoint = endpoint or environ.get( + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, + _append_logs_path( + environ.get(OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_ENDPOINT) + ), ) self._certificate_file = certificate_file or environ.get( - OTEL_EXPORTER_OTLP_CERTIFICATE, True + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE, True), ) - headers_string = environ.get(OTEL_EXPORTER_OTLP_HEADERS, "") - self._headers = headers or parse_env_headers(headers_string) + headers_string = environ.get( + OTEL_EXPORTER_OTLP_LOGS_HEADERS, + environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), + ) + self._headers = headers or parse_env_headers(headers_string) self._timeout = timeout or int( - environ.get(OTEL_EXPORTER_OTLP_TIMEOUT, DEFAULT_TIMEOUT) + environ.get( + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, + environ.get(OTEL_EXPORTER_OTLP_TIMEOUT, DEFAULT_TIMEOUT), + ) ) self._compression = compression or _compression_from_env() self._session = session or requests.Session() @@ -170,7 +185,12 @@ def shutdown(self): def _compression_from_env() -> Compression: compression = ( - environ.get(OTEL_EXPORTER_OTLP_COMPRESSION, "none").lower().strip() + environ.get( + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, + environ.get(OTEL_EXPORTER_OTLP_COMPRESSION, "none"), + ) + .lower() + .strip() ) return Compression(compression) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py b/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py index 562863156fc..6a0f6499ed4 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py @@ -344,6 +344,15 @@ A scheme of https indicates a secure connection and takes precedence over this configuration setting. """ +OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` target to which the log exporter is going to send logs. +The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. +A scheme of https indicates a secure connection and takes precedence over this configuration setting. +""" + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE" """ .. envvar:: OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE @@ -378,6 +387,14 @@ associated with gRPC or HTTP requests. """ +OTEL_EXPORTER_OTLP_LOGS_HEADERS = "OTEL_EXPORTER_OTLP_LOGS_HEADERS" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_HEADERS + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_HEADERS` contains the key-value pairs to be used as headers for logs +associated with gRPC or HTTP requests. +""" + OTEL_EXPORTER_OTLP_TRACES_COMPRESSION = "OTEL_EXPORTER_OTLP_TRACES_COMPRESSION" """ .. envvar:: OTEL_EXPORTER_OTLP_TRACES_COMPRESSION @@ -396,6 +413,16 @@ exporter. If both are present, this takes higher precedence. """ +OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = ( + "OTEL_EXPORTER_OTLP_LOGS_COMPRESSION" +) +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_COMPRESSION + +Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the log +exporter. If both are present, this takes higher precedence. +""" + OTEL_EXPORTER_OTLP_TRACES_TIMEOUT = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT" """ .. envvar:: OTEL_EXPORTER_OTLP_TRACES_TIMEOUT @@ -421,6 +448,15 @@ Default: False """ +OTEL_EXPORTER_OTLP_LOGS_INSECURE = "OTEL_EXPORTER_OTLP_LOGS_INSECURE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_INSECURE + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_INSECURE` represents whether to enable client transport security +for gRPC requests for metrics. A scheme of https takes precedence over the this configuration setting. +Default: False +""" + OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT" """ .. envvar:: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT @@ -440,6 +476,16 @@ TLS credentials of gRPC client for traces. Should only be used for a secure connection for tracing. """ +OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = ( + "OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE" +) +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE` stores the path to the certificate file for +TLS credentials of gRPC client for traces. Should only be used for a secure connection for tracing. +""" + OTEL_EXPORTER_OTLP_METRICS_HEADERS = "OTEL_EXPORTER_OTLP_METRICS_HEADERS" """ .. envvar:: OTEL_EXPORTER_OTLP_METRICS_HEADERS @@ -456,6 +502,14 @@ wait for each batch export for metrics. """ +OTEL_EXPORTER_OTLP_LOGS_TIMEOUT = "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` is the maximum time the OTLP exporter will +wait for each batch export for logs. +""" + OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = ( "OTEL_EXPORTER_OTLP_METRICS_COMPRESSION" ) From 3ddc60d541da98b6cdfe8b99934a4609f0f015fa Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Thu, 17 Nov 2022 21:54:00 +0530 Subject: [PATCH 02/10] Add tests for env variables introduced in logger. --- .../tests/logs/test_otlp_logs_exporter.py | 41 ++++++++++++++++++- .../tests/test_proto_log_exporter.py | 37 +++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 0861d06d654..0092bd1dd77 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -14,12 +14,13 @@ import time from concurrent.futures import ThreadPoolExecutor +from os.path import dirname from unittest import TestCase from unittest.mock import patch from google.protobuf.duration_pb2 import Duration from google.rpc.error_details_pb2 import RetryInfo -from grpc import StatusCode, server +from grpc import ChannelCredentials, Compression, StatusCode, server from opentelemetry._logs import SeverityNumber from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( @@ -45,12 +46,23 @@ from opentelemetry.proto.resource.v1.resource_pb2 import ( Resource as OTLPResource, ) +from opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_COMPRESSION, + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, + OTEL_EXPORTER_OTLP_LOGS_HEADERS, + OTEL_EXPORTER_OTLP_LOGS_INSECURE, + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, +) from opentelemetry.sdk._logs import LogData, LogRecord from opentelemetry.sdk._logs.export import LogExportResult from opentelemetry.sdk.resources import Resource as SDKResource from opentelemetry.sdk.util.instrumentation import InstrumentationScope from opentelemetry.trace import TraceFlags +THIS_DIR = dirname(__file__) + class LogsServiceServicerUNAVAILABLEDelay(LogsServiceServicer): # pylint: disable=invalid-name,unused-argument,no-self-use @@ -164,6 +176,33 @@ def test_exporting(self): # pylint: disable=protected-access self.assertEqual(self.exporter._exporting, "logs") + @patch.dict( + "os.environ", + { + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR + + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = value=2", + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", + }, + ) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" + ) + def test_env_variables(self, mock_exporter_mixin): + OTLPLogExporter() + + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) + _, kwargs = mock_exporter_mixin.call_args_list[0] + + self.assertEqual(kwargs["endpoint"], "log:4317") + self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") + self.assertEqual(kwargs["timeout"], 10) + self.assertEqual(kwargs["compression"], Compression.Gzip) + self.assertIsNotNone(kwargs["credentials"]) + self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py index 7dcb82030d4..e492a0e334e 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py @@ -61,6 +61,11 @@ OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT, + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, + OTEL_EXPORTER_OTLP_LOGS_HEADERS, + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, ) from opentelemetry.sdk.resources import Resource as SDKResource from opentelemetry.sdk.util.instrumentation import InstrumentationScope @@ -91,6 +96,38 @@ def test_constructor_default(self): "application/x-protobuf", ) + @patch.dict( + "os.environ", + { + OTEL_EXPORTER_OTLP_CERTIFICATE: ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, + OTEL_EXPORTER_OTLP_ENDPOINT: ENV_ENDPOINT, + OTEL_EXPORTER_OTLP_HEADERS: ENV_HEADERS, + OTEL_EXPORTER_OTLP_TIMEOUT: ENV_TIMEOUT, + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: "logs/certificate.env", + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: Compression.Deflate.value, + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "https://logs.endpoint.env", + OTEL_EXPORTER_OTLP_LOGS_HEADERS: "metricsEnv1=val1,metricsEnv2=val2,metricEnv3===val3==", + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "40", + }, + ) + def test_exporter_metrics_env_take_priority(self): + exporter = OTLPLogExporter() + + self.assertEqual(exporter._endpoint, "https://metrics.endpoint.env") + self.assertEqual(exporter._certificate_file, "metrics/certificate.env") + self.assertEqual(exporter._timeout, 40) + self.assertIs(exporter._compression, Compression.Deflate) + self.assertEqual( + exporter._headers, + { + "metricsenv1": "val1", + "metricsenv2": "val2", + "metricenv3": "==val3==", + }, + ) + self.assertIsInstance(exporter._session, requests.Session) + @patch.dict( "os.environ", { From fccf547f39bdb61cfa228491d0fd64bf1fc8b264 Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Thu, 8 Dec 2022 11:41:50 +0530 Subject: [PATCH 03/10] Debugging tests --- .../exporter/otlp/proto/grpc/_log_exporter/__init__.py | 4 ++-- .../tests/logs/test_otlp_logs_exporter.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py index 9226292c08e..9ca2c5f52b9 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py @@ -86,9 +86,9 @@ def __init__( if compression is None else compression ) - endpoint=endpoint or environ.get(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT), + endpoint=endpoint or environ.get(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) - headers=headers or environ.get(OTEL_EXPORTER_OTLP_LOGS_HEADERS), + headers=headers or environ.get(OTEL_EXPORTER_OTLP_LOGS_HEADERS) super().__init__( **{ diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 0092bd1dd77..fa2ea55cdea 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -191,8 +191,8 @@ def test_exporting(self): "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) def test_env_variables(self, mock_exporter_mixin): - OTLPLogExporter() - + print("*************************") + print(mock_exporter_mixin.call_args_list) self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) _, kwargs = mock_exporter_mixin.call_args_list[0] From b17d41f416536c2b2ceea082c979d941d413ed30 Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Mon, 12 Dec 2022 15:25:45 +0530 Subject: [PATCH 04/10] Tried to fix tests --- .../tests/logs/test_otlp_logs_exporter.py | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index fa2ea55cdea..2b1e8f83970 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -111,8 +111,8 @@ def Export(self, request, context): class TestOTLPLogExporter(TestCase): - def setUp(self): + def setUp(self): self.exporter = OTLPLogExporter() self.server = server(ThreadPoolExecutor(max_workers=10)) @@ -182,26 +182,26 @@ def test_exporting(self): OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR + "/fixtures/test.cert", - OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = value=2", + OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2", OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", }, ) - @patch( - "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" - ) - def test_env_variables(self, mock_exporter_mixin): - print("*************************") - print(mock_exporter_mixin.call_args_list) - self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) - _, kwargs = mock_exporter_mixin.call_args_list[0] - - self.assertEqual(kwargs["endpoint"], "log:4317") - self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") - self.assertEqual(kwargs["timeout"], 10) - self.assertEqual(kwargs["compression"], Compression.Gzip) - self.assertIsNotNone(kwargs["credentials"]) - self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + def test_env_variables(self): + exporter = OTLPLogExporter() + self.assertEqual(exporter._endpoint, "logs:4317") + self.assertEqual(exporter._timeout, 10) + self.assertEqual(exporter._compression, Compression.Gzip) + self.assertIsNotNone(exporter._credentials) + self.assertIsInstance(exporter._credentials, ChannelCredentials) + self.assertEqual( + exporter._headers, + ( + ("key1", "value1"), + ("key2", "VALUE=2"), + ("user-agent", "OTel OTLP Exporter Python/" + __version__), + ), + ) @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" From 9447d0e67bb22709cad2fbecd3c877db1600a9c0 Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Mon, 12 Dec 2022 16:33:36 +0530 Subject: [PATCH 05/10] Finding out properties of log exporter --- .../tests/logs/test_otlp_logs_exporter.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 2b1e8f83970..f867afbb3f8 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -189,11 +189,17 @@ def test_exporting(self): ) def test_env_variables(self): exporter = OTLPLogExporter() + print("**************") + print(exporter._headers) + print("*******endpoint*******") + print(exporter.__dict__) + + # print(exporter.) self.assertEqual(exporter._endpoint, "logs:4317") - self.assertEqual(exporter._timeout, 10) - self.assertEqual(exporter._compression, Compression.Gzip) - self.assertIsNotNone(exporter._credentials) - self.assertIsInstance(exporter._credentials, ChannelCredentials) + # self.assertEqual(exporter._timeout, 10) + # self.assertEqual(exporter._compression, Compression.Gzip) + # self.assertIsNotNone(exporter._credentials) + # self.assertIsInstance(exporter._credentials, ChannelCredentials) self.assertEqual( exporter._headers, ( From e10fed671a05d7e08c090881194494bfc58a0754 Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Thu, 15 Dec 2022 14:02:02 +0530 Subject: [PATCH 06/10] Fixed the logger tests finally --- .../otlp/proto/grpc/_log_exporter/__init__.py | 2 +- .../tests/logs/test_otlp_logs_exporter.py | 39 ++++++++----------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py index 9ca2c5f52b9..52cac56185a 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py @@ -96,7 +96,7 @@ def __init__( "insecure": insecure, "credentials": credentials, "headers": headers, - "timeout": timeout, + "timeout": timeout or environ_timeout, "compression": compression, } ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index f867afbb3f8..fbbc118471e 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -47,7 +47,6 @@ Resource as OTLPResource, ) from opentelemetry.sdk.environment_variables import ( - OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, @@ -181,33 +180,27 @@ def test_exporting(self): { OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR - + "/fixtures/test.cert", + + "/../fixtures/test.cert", OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2", OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", }, ) - def test_env_variables(self): - exporter = OTLPLogExporter() - print("**************") - print(exporter._headers) - print("*******endpoint*******") - print(exporter.__dict__) - - # print(exporter.) - self.assertEqual(exporter._endpoint, "logs:4317") - # self.assertEqual(exporter._timeout, 10) - # self.assertEqual(exporter._compression, Compression.Gzip) - # self.assertIsNotNone(exporter._credentials) - # self.assertIsInstance(exporter._credentials, ChannelCredentials) - self.assertEqual( - exporter._headers, - ( - ("key1", "value1"), - ("key2", "VALUE=2"), - ("user-agent", "OTel OTLP Exporter Python/" + __version__), - ), - ) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" + ) + def test_env_variables(self, mock_exporter_mixin): + OTLPLogExporter() + + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) + _, kwargs = mock_exporter_mixin.call_args_list[0] + self.assertEqual(kwargs["endpoint"], "logs:4317") + self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = VALUE=2") + self.assertEqual(kwargs["timeout"], 10) + self.assertEqual(kwargs["compression"], Compression.Gzip) + self.assertIsNotNone(kwargs["credentials"]) + self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" From 730711735fa013454cf85054e86c4ea827a7dc80 Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Thu, 15 Dec 2022 15:16:39 +0530 Subject: [PATCH 07/10] Fixes lint --- .../exporter/otlp/proto/grpc/_log_exporter/__init__.py | 5 +++-- .../tests/logs/test_otlp_logs_exporter.py | 7 ++----- .../exporter/otlp/proto/http/_log_exporter/__init__.py | 4 ++-- .../tests/test_proto_log_exporter.py | 2 +- .../src/opentelemetry/sdk/environment_variables.py | 8 ++------ 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py index 52cac56185a..f7cbadfec8b 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py @@ -46,6 +46,7 @@ OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, ) + class OTLPLogExporter( LogExporter, OTLPExporterMixin[SDKLogRecord, ExportLogsServiceRequest, LogExportResult], @@ -86,9 +87,9 @@ def __init__( if compression is None else compression ) - endpoint=endpoint or environ.get(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) + endpoint = endpoint or environ.get(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) - headers=headers or environ.get(OTEL_EXPORTER_OTLP_LOGS_HEADERS) + headers = headers or environ.get(OTEL_EXPORTER_OTLP_LOGS_HEADERS) super().__init__( **{ diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index fbbc118471e..c7996b9bf9e 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -46,16 +46,15 @@ from opentelemetry.proto.resource.v1.resource_pb2 import ( Resource as OTLPResource, ) +from opentelemetry.sdk._logs import LogData, LogRecord +from opentelemetry.sdk._logs.export import LogExportResult from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_HEADERS, - OTEL_EXPORTER_OTLP_LOGS_INSECURE, OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, ) -from opentelemetry.sdk._logs import LogData, LogRecord -from opentelemetry.sdk._logs.export import LogExportResult from opentelemetry.sdk.resources import Resource as SDKResource from opentelemetry.sdk.util.instrumentation import InstrumentationScope from opentelemetry.trace import TraceFlags @@ -110,7 +109,6 @@ def Export(self, request, context): class TestOTLPLogExporter(TestCase): - def setUp(self): self.exporter = OTLPLogExporter() @@ -201,7 +199,6 @@ def test_env_variables(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) - @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py index f89ecfe8a46..dfd70180e06 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py @@ -98,7 +98,7 @@ def __init__( OTEL_EXPORTER_OTLP_LOGS_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), ) - self._headers = headers or parse_env_headers(headers_string) + self._headers = headers or parse_env_headers(headers_string) self._timeout = timeout or int( environ.get( OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, @@ -187,7 +187,7 @@ def _compression_from_env() -> Compression: compression = ( environ.get( OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, - environ.get(OTEL_EXPORTER_OTLP_COMPRESSION, "none"), + environ.get(OTEL_EXPORTER_OTLP_COMPRESSION, "none"), ) .lower() .strip() diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py index e492a0e334e..9d6e2016ac4 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py @@ -60,12 +60,12 @@ OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, - OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_HEADERS, OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, + OTEL_EXPORTER_OTLP_TIMEOUT, ) from opentelemetry.sdk.resources import Resource as SDKResource from opentelemetry.sdk.util.instrumentation import InstrumentationScope diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py b/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py index 6a0f6499ed4..376fb187dc1 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py @@ -413,9 +413,7 @@ exporter. If both are present, this takes higher precedence. """ -OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = ( - "OTEL_EXPORTER_OTLP_LOGS_COMPRESSION" -) +OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = "OTEL_EXPORTER_OTLP_LOGS_COMPRESSION" """ .. envvar:: OTEL_EXPORTER_OTLP_LOGS_COMPRESSION @@ -476,9 +474,7 @@ TLS credentials of gRPC client for traces. Should only be used for a secure connection for tracing. """ -OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = ( - "OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE" -) +OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = "OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE" """ .. envvar:: OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE From 66a07872a0d50a4759e00f779ce3d9292387d7e8 Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Thu, 15 Dec 2022 15:19:48 +0530 Subject: [PATCH 08/10] Update ChangeLog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0f43a10da0..460c439e73a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased +- Adds environment variables for log exporter + ([#3037](https://github.com/open-telemetry/opentelemetry-python/pull/3037)) ## Version 1.15.0/0.36b0 (2022-12-09) From dbfa4c237a55d0e08a899f14ad7707be3ec25ffc Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Thu, 15 Dec 2022 15:30:02 +0530 Subject: [PATCH 09/10] Updated http log env tests --- .../tests/test_proto_log_exporter.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py index 9d6e2016ac4..a3a53a5407c 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py @@ -107,23 +107,23 @@ def test_constructor_default(self): OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: "logs/certificate.env", OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: Compression.Deflate.value, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "https://logs.endpoint.env", - OTEL_EXPORTER_OTLP_LOGS_HEADERS: "metricsEnv1=val1,metricsEnv2=val2,metricEnv3===val3==", + OTEL_EXPORTER_OTLP_LOGS_HEADERS: "logsEnv1=val1,logsEnv2=val2,logsEnv3===val3==", OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "40", }, ) def test_exporter_metrics_env_take_priority(self): exporter = OTLPLogExporter() - self.assertEqual(exporter._endpoint, "https://metrics.endpoint.env") - self.assertEqual(exporter._certificate_file, "metrics/certificate.env") + self.assertEqual(exporter._endpoint, "https://logs.endpoint.env") + self.assertEqual(exporter._certificate_file, "logs/certificate.env") self.assertEqual(exporter._timeout, 40) self.assertIs(exporter._compression, Compression.Deflate) self.assertEqual( exporter._headers, { - "metricsenv1": "val1", - "metricsenv2": "val2", - "metricenv3": "==val3==", + "logsenv1": "val1", + "logsenv2": "val2", + "logsenv3": "==val3==", }, ) self.assertIsInstance(exporter._session, requests.Session) From d8f2405f70b4bf14399124ce8815a75181dea642 Mon Sep 17 00:00:00 2001 From: PridhiArora Date: Wed, 11 Jan 2023 20:56:39 +0530 Subject: [PATCH 10/10] Updated opetelemetry sdk version Signed-off-by: PridhiArora --- exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml | 2 +- exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml b/exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml index 1daa2744236..8a07a45bb60 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml @@ -31,7 +31,7 @@ dependencies = [ "grpcio >= 1.0.0, < 2.0.0", "opentelemetry-api ~= 1.12", "opentelemetry-proto == 1.16.0.dev", - "opentelemetry-sdk ~= 1.12", + "opentelemetry-sdk ~= 1.16.0.dev", ] [project.optional-dependencies] diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml b/exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml index 680fb8b76d3..aec6afe1fce 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml +++ b/exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ "googleapis-common-protos ~= 1.52", "opentelemetry-api ~= 1.12", "opentelemetry-proto == 1.16.0.dev", - "opentelemetry-sdk ~= 1.12", + "opentelemetry-sdk ~= 1.16.0.dev", "requests ~= 2.7", ]