Skip to content

Commit 665bd48

Browse files
authored
Adds environment variables for log exporter (#3037)
1 parent 2fa6210 commit 665bd48

File tree

8 files changed

+194
-11
lines changed

8 files changed

+194
-11
lines changed

Diff for: CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## Unreleased
9+
- Adds environment variables for log exporter
10+
([#3037](https://github.com/open-telemetry/opentelemetry-python/pull/3037))
911

1012
## Version 1.15.0/0.36b0 (2022-12-09)
1113

Diff for: exporter/opentelemetry-exporter-otlp-proto-grpc/pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ dependencies = [
3131
"grpcio >= 1.0.0, < 2.0.0",
3232
"opentelemetry-api ~= 1.12",
3333
"opentelemetry-proto == 1.16.0.dev",
34-
"opentelemetry-sdk ~= 1.12",
34+
"opentelemetry-sdk ~= 1.16.0.dev",
3535
]
3636

3737
[project.optional-dependencies]

Diff for: exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py

+40-1
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
1313

14+
from os import environ
1415
from typing import Optional, Sequence
1516
from grpc import ChannelCredentials, Compression
1617
from opentelemetry.exporter.otlp.proto.grpc.exporter import (
1718
OTLPExporterMixin,
1819
get_resource_data,
20+
_get_credentials,
1921
_translate_value,
22+
environ_to_compression,
2023
)
2124
from opentelemetry.proto.collector.logs.v1.logs_service_pb2 import (
2225
ExportLogsServiceRequest,
@@ -34,6 +37,15 @@
3437
from opentelemetry.sdk._logs import LogData
3538
from opentelemetry.sdk._logs.export import LogExporter, LogExportResult
3639

40+
from opentelemetry.sdk.environment_variables import (
41+
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE,
42+
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION,
43+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
44+
OTEL_EXPORTER_OTLP_LOGS_HEADERS,
45+
OTEL_EXPORTER_OTLP_LOGS_INSECURE,
46+
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
47+
)
48+
3749

3850
class OTLPLogExporter(
3951
LogExporter,
@@ -52,13 +64,40 @@ def __init__(
5264
timeout: Optional[int] = None,
5365
compression: Optional[Compression] = None,
5466
):
67+
if insecure is None:
68+
insecure = environ.get(OTEL_EXPORTER_OTLP_LOGS_INSECURE)
69+
if insecure is not None:
70+
insecure = insecure.lower() == "true"
71+
72+
if (
73+
not insecure
74+
and environ.get(OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE) is not None
75+
):
76+
credentials = _get_credentials(
77+
credentials, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE
78+
)
79+
80+
environ_timeout = environ.get(OTEL_EXPORTER_OTLP_LOGS_TIMEOUT)
81+
environ_timeout = (
82+
int(environ_timeout) if environ_timeout is not None else None
83+
)
84+
85+
compression = (
86+
environ_to_compression(OTEL_EXPORTER_OTLP_LOGS_COMPRESSION)
87+
if compression is None
88+
else compression
89+
)
90+
endpoint = endpoint or environ.get(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT)
91+
92+
headers = headers or environ.get(OTEL_EXPORTER_OTLP_LOGS_HEADERS)
93+
5594
super().__init__(
5695
**{
5796
"endpoint": endpoint,
5897
"insecure": insecure,
5998
"credentials": credentials,
6099
"headers": headers,
61-
"timeout": timeout,
100+
"timeout": timeout or environ_timeout,
62101
"compression": compression,
63102
}
64103
)

Diff for: exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py

+37-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414

1515
import time
1616
from concurrent.futures import ThreadPoolExecutor
17+
from os.path import dirname
1718
from unittest import TestCase
1819
from unittest.mock import patch
1920

2021
from google.protobuf.duration_pb2 import Duration
2122
from google.rpc.error_details_pb2 import RetryInfo
22-
from grpc import StatusCode, server
23+
from grpc import ChannelCredentials, Compression, StatusCode, server
2324

2425
from opentelemetry._logs import SeverityNumber
2526
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import (
@@ -47,10 +48,19 @@
4748
)
4849
from opentelemetry.sdk._logs import LogData, LogRecord
4950
from opentelemetry.sdk._logs.export import LogExportResult
51+
from opentelemetry.sdk.environment_variables import (
52+
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE,
53+
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION,
54+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
55+
OTEL_EXPORTER_OTLP_LOGS_HEADERS,
56+
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
57+
)
5058
from opentelemetry.sdk.resources import Resource as SDKResource
5159
from opentelemetry.sdk.util.instrumentation import InstrumentationScope
5260
from opentelemetry.trace import TraceFlags
5361

62+
THIS_DIR = dirname(__file__)
63+
5464

5565
class LogsServiceServicerUNAVAILABLEDelay(LogsServiceServicer):
5666
# pylint: disable=invalid-name,unused-argument,no-self-use
@@ -100,7 +110,6 @@ def Export(self, request, context):
100110

101111
class TestOTLPLogExporter(TestCase):
102112
def setUp(self):
103-
104113
self.exporter = OTLPLogExporter()
105114

106115
self.server = server(ThreadPoolExecutor(max_workers=10))
@@ -164,6 +173,32 @@ def test_exporting(self):
164173
# pylint: disable=protected-access
165174
self.assertEqual(self.exporter._exporting, "logs")
166175

176+
@patch.dict(
177+
"os.environ",
178+
{
179+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317",
180+
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR
181+
+ "/../fixtures/test.cert",
182+
OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2",
183+
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10",
184+
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip",
185+
},
186+
)
187+
@patch(
188+
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
189+
)
190+
def test_env_variables(self, mock_exporter_mixin):
191+
OTLPLogExporter()
192+
193+
self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
194+
_, kwargs = mock_exporter_mixin.call_args_list[0]
195+
self.assertEqual(kwargs["endpoint"], "logs:4317")
196+
self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = VALUE=2")
197+
self.assertEqual(kwargs["timeout"], 10)
198+
self.assertEqual(kwargs["compression"], Compression.Gzip)
199+
self.assertIsNotNone(kwargs["credentials"])
200+
self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
201+
167202
@patch(
168203
"opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials"
169204
)

Diff for: exporter/opentelemetry-exporter-otlp-proto-http/pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ dependencies = [
3030
"googleapis-common-protos ~= 1.52",
3131
"opentelemetry-api ~= 1.12",
3232
"opentelemetry-proto == 1.16.0.dev",
33-
"opentelemetry-sdk ~= 1.12",
33+
"opentelemetry-sdk ~= 1.16.0.dev",
3434
"requests ~= 2.7",
3535
]
3636

Diff for: exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py

+26-6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
OTEL_EXPORTER_OTLP_ENDPOINT,
3030
OTEL_EXPORTER_OTLP_HEADERS,
3131
OTEL_EXPORTER_OTLP_TIMEOUT,
32+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
33+
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE,
34+
OTEL_EXPORTER_OTLP_LOGS_HEADERS,
35+
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
36+
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION,
3237
)
3338
from opentelemetry.sdk._logs import LogData
3439
from opentelemetry.sdk._logs.export import (
@@ -79,16 +84,26 @@ def __init__(
7984
compression: Optional[Compression] = None,
8085
session: Optional[requests.Session] = None,
8186
):
82-
self._endpoint = endpoint or _append_logs_path(
83-
environ.get(OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_ENDPOINT)
87+
self._endpoint = endpoint or environ.get(
88+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
89+
_append_logs_path(
90+
environ.get(OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_ENDPOINT)
91+
),
8492
)
8593
self._certificate_file = certificate_file or environ.get(
86-
OTEL_EXPORTER_OTLP_CERTIFICATE, True
94+
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE,
95+
environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE, True),
96+
)
97+
headers_string = environ.get(
98+
OTEL_EXPORTER_OTLP_LOGS_HEADERS,
99+
environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""),
87100
)
88-
headers_string = environ.get(OTEL_EXPORTER_OTLP_HEADERS, "")
89101
self._headers = headers or parse_env_headers(headers_string)
90102
self._timeout = timeout or int(
91-
environ.get(OTEL_EXPORTER_OTLP_TIMEOUT, DEFAULT_TIMEOUT)
103+
environ.get(
104+
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
105+
environ.get(OTEL_EXPORTER_OTLP_TIMEOUT, DEFAULT_TIMEOUT),
106+
)
92107
)
93108
self._compression = compression or _compression_from_env()
94109
self._session = session or requests.Session()
@@ -170,7 +185,12 @@ def shutdown(self):
170185

171186
def _compression_from_env() -> Compression:
172187
compression = (
173-
environ.get(OTEL_EXPORTER_OTLP_COMPRESSION, "none").lower().strip()
188+
environ.get(
189+
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION,
190+
environ.get(OTEL_EXPORTER_OTLP_COMPRESSION, "none"),
191+
)
192+
.lower()
193+
.strip()
174194
)
175195
return Compression(compression)
176196

Diff for: exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py

+37
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@
6161
OTEL_EXPORTER_OTLP_COMPRESSION,
6262
OTEL_EXPORTER_OTLP_ENDPOINT,
6363
OTEL_EXPORTER_OTLP_HEADERS,
64+
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE,
65+
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION,
66+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
67+
OTEL_EXPORTER_OTLP_LOGS_HEADERS,
68+
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
6469
OTEL_EXPORTER_OTLP_TIMEOUT,
6570
)
6671
from opentelemetry.sdk.resources import Resource as SDKResource
@@ -92,6 +97,38 @@ def test_constructor_default(self):
9297
"application/x-protobuf",
9398
)
9499

100+
@patch.dict(
101+
"os.environ",
102+
{
103+
OTEL_EXPORTER_OTLP_CERTIFICATE: ENV_CERTIFICATE,
104+
OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value,
105+
OTEL_EXPORTER_OTLP_ENDPOINT: ENV_ENDPOINT,
106+
OTEL_EXPORTER_OTLP_HEADERS: ENV_HEADERS,
107+
OTEL_EXPORTER_OTLP_TIMEOUT: ENV_TIMEOUT,
108+
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: "logs/certificate.env",
109+
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: Compression.Deflate.value,
110+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "https://logs.endpoint.env",
111+
OTEL_EXPORTER_OTLP_LOGS_HEADERS: "logsEnv1=val1,logsEnv2=val2,logsEnv3===val3==",
112+
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "40",
113+
},
114+
)
115+
def test_exporter_metrics_env_take_priority(self):
116+
exporter = OTLPLogExporter()
117+
118+
self.assertEqual(exporter._endpoint, "https://logs.endpoint.env")
119+
self.assertEqual(exporter._certificate_file, "logs/certificate.env")
120+
self.assertEqual(exporter._timeout, 40)
121+
self.assertIs(exporter._compression, Compression.Deflate)
122+
self.assertEqual(
123+
exporter._headers,
124+
{
125+
"logsenv1": "val1",
126+
"logsenv2": "val2",
127+
"logsenv3": "==val3==",
128+
},
129+
)
130+
self.assertIsInstance(exporter._session, requests.Session)
131+
95132
@patch.dict(
96133
"os.environ",
97134
{

Diff for: opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py

+50
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,15 @@
344344
A scheme of https indicates a secure connection and takes precedence over this configuration setting.
345345
"""
346346

347+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"
348+
"""
349+
.. envvar:: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
350+
351+
The :envvar:`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` target to which the log exporter is going to send logs.
352+
The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path.
353+
A scheme of https indicates a secure connection and takes precedence over this configuration setting.
354+
"""
355+
347356
OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE"
348357
"""
349358
.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE
@@ -378,6 +387,14 @@
378387
associated with gRPC or HTTP requests.
379388
"""
380389

390+
OTEL_EXPORTER_OTLP_LOGS_HEADERS = "OTEL_EXPORTER_OTLP_LOGS_HEADERS"
391+
"""
392+
.. envvar:: OTEL_EXPORTER_OTLP_LOGS_HEADERS
393+
394+
The :envvar:`OTEL_EXPORTER_OTLP_LOGS_HEADERS` contains the key-value pairs to be used as headers for logs
395+
associated with gRPC or HTTP requests.
396+
"""
397+
381398
OTEL_EXPORTER_OTLP_TRACES_COMPRESSION = "OTEL_EXPORTER_OTLP_TRACES_COMPRESSION"
382399
"""
383400
.. envvar:: OTEL_EXPORTER_OTLP_TRACES_COMPRESSION
@@ -396,6 +413,14 @@
396413
exporter. If both are present, this takes higher precedence.
397414
"""
398415

416+
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = "OTEL_EXPORTER_OTLP_LOGS_COMPRESSION"
417+
"""
418+
.. envvar:: OTEL_EXPORTER_OTLP_LOGS_COMPRESSION
419+
420+
Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the log
421+
exporter. If both are present, this takes higher precedence.
422+
"""
423+
399424
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT"
400425
"""
401426
.. envvar:: OTEL_EXPORTER_OTLP_TRACES_TIMEOUT
@@ -421,6 +446,15 @@
421446
Default: False
422447
"""
423448

449+
OTEL_EXPORTER_OTLP_LOGS_INSECURE = "OTEL_EXPORTER_OTLP_LOGS_INSECURE"
450+
"""
451+
.. envvar:: OTEL_EXPORTER_OTLP_LOGS_INSECURE
452+
453+
The :envvar:`OTEL_EXPORTER_OTLP_LOGS_INSECURE` represents whether to enable client transport security
454+
for gRPC requests for metrics. A scheme of https takes precedence over the this configuration setting.
455+
Default: False
456+
"""
457+
424458
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT"
425459
"""
426460
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
@@ -440,6 +474,14 @@
440474
TLS credentials of gRPC client for traces. Should only be used for a secure connection for tracing.
441475
"""
442476

477+
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = "OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE"
478+
"""
479+
.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE
480+
481+
The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE` stores the path to the certificate file for
482+
TLS credentials of gRPC client for traces. Should only be used for a secure connection for tracing.
483+
"""
484+
443485
OTEL_EXPORTER_OTLP_METRICS_HEADERS = "OTEL_EXPORTER_OTLP_METRICS_HEADERS"
444486
"""
445487
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_HEADERS
@@ -456,6 +498,14 @@
456498
wait for each batch export for metrics.
457499
"""
458500

501+
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT = "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT"
502+
"""
503+
.. envvar:: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT
504+
505+
The :envvar:`OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` is the maximum time the OTLP exporter will
506+
wait for each batch export for logs.
507+
"""
508+
459509
OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = (
460510
"OTEL_EXPORTER_OTLP_METRICS_COMPRESSION"
461511
)

0 commit comments

Comments
 (0)