Skip to content

Commit 641a35f

Browse files
author
alrex
authored
Merge branch 'master' into issue_1236
2 parents d9c4da6 + 42abfb7 commit 641a35f

File tree

9 files changed

+187
-16
lines changed

9 files changed

+187
-16
lines changed

Diff for: .github/workflows/docs.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on:
1010
- 'instrumentation/**'
1111
- 'opentelemetry-python/opentelemetry-api/src/opentelemetry/**'
1212
- 'opentelemetry-python/opentelemetry-sdk/src/opentelemetry/sdk/**'
13-
13+
1414
jobs:
1515
docs:
1616
runs-on: ubuntu-latest
@@ -19,7 +19,7 @@ jobs:
1919
- name: Set up Python py38
2020
uses: actions/setup-python@v2
2121
with:
22-
python-version: py38
22+
python-version: '3.8'
2323
- name: Build docs
2424
run: |
2525
pip install --upgrade tox

Diff for: docs/examples/basic_meter/observer.py

-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ def get_cpu_usage_callback(observer):
4040
description="per-cpu usage",
4141
unit="1",
4242
value_type=float,
43-
observer_type=ValueObserver,
4443
)
4544

4645

@@ -56,7 +55,6 @@ def get_ram_usage_callback(observer):
5655
description="RAM memory usage",
5756
unit="1",
5857
value_type=float,
59-
observer_type=ValueObserver,
6058
)
6159

6260
input("Metrics will be printed soon. Press a key to finish...\n")

Diff for: exporter/opentelemetry-exporter-otlp/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Add Env variables in OTLP exporter
6+
([#1101](https://github.com/open-telemetry/opentelemetry-python/pull/1101))
57
- Do not use bound instruments in OTLP exporter
68
([#1237](https://github.com/open-telemetry/opentelemetry-python/pull/1237))
79

Diff for: exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py

+43-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""OTLP Exporter"""
1616

1717
import logging
18+
import os
1819
from abc import ABC, abstractmethod
1920
from collections.abc import Mapping, Sequence
2021
from time import sleep
@@ -30,8 +31,10 @@
3031
StatusCode,
3132
insecure_channel,
3233
secure_channel,
34+
ssl_channel_credentials,
3335
)
3436

37+
from opentelemetry.configuration import Configuration
3538
from opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue
3639
from opentelemetry.proto.resource.v1.resource_pb2 import Resource
3740
from opentelemetry.sdk.resources import Resource as SDKResource
@@ -113,6 +116,16 @@ def _get_resource_data(
113116
return resource_data
114117

115118

119+
def _load_credential_from_file(filepath) -> ChannelCredentials:
120+
try:
121+
with open(filepath, "rb") as f:
122+
credential = f.read()
123+
return ssl_channel_credentials(credential)
124+
except FileNotFoundError:
125+
logger.exception("Failed to read credential file")
126+
return None
127+
128+
116129
# pylint: disable=no-member
117130
class OTLPExporterMixin(
118131
ABC, Generic[SDKDataT, ExportServiceRequestT, ExportResultT]
@@ -121,24 +134,47 @@ class OTLPExporterMixin(
121134
122135
Args:
123136
endpoint: OpenTelemetry Collector receiver endpoint
137+
insecure: Connection type
124138
credentials: ChannelCredentials object for server authentication
125139
metadata: Metadata to send when exporting
140+
timeout: Backend request timeout in seconds
126141
"""
127142

128143
def __init__(
129144
self,
130-
endpoint: str = "localhost:55680",
131-
credentials: ChannelCredentials = None,
132-
metadata: Optional[Tuple[Any]] = None,
145+
endpoint: Optional[str] = None,
146+
insecure: Optional[bool] = None,
147+
credentials: Optional[ChannelCredentials] = None,
148+
headers: Optional[str] = None,
149+
timeout: Optional[int] = None,
133150
):
134151
super().__init__()
135152

136-
self._metadata = metadata
153+
endpoint = (
154+
endpoint
155+
or Configuration().EXPORTER_OTLP_ENDPOINT
156+
or "localhost:55680"
157+
)
158+
159+
if insecure is None:
160+
insecure = Configuration().EXPORTER_OTLP_INSECURE
161+
if insecure is None:
162+
insecure = False
163+
164+
self._headers = headers or Configuration().EXPORTER_OTLP_HEADERS
165+
self._timeout = (
166+
timeout
167+
or Configuration().EXPORTER_OTLP_TIMEOUT
168+
or 10 # default: 10 seconds
169+
)
137170
self._collector_span_kwargs = None
138171

139-
if credentials is None:
172+
if insecure:
140173
self._client = self._stub(insecure_channel(endpoint))
141174
else:
175+
credentials = credentials or _load_credential_from_file(
176+
Configuration().EXPORTER_OTLP_CERTIFICATE
177+
)
142178
self._client = self._stub(secure_channel(endpoint, credentials))
143179

144180
@abstractmethod
@@ -164,7 +200,8 @@ def _export(self, data: TypingSequence[SDKDataT]) -> ExportResultT:
164200
try:
165201
self._client.Export(
166202
request=self._translate_data(data),
167-
metadata=self._metadata,
203+
metadata=self._headers,
204+
timeout=self._timeout,
168205
)
169206

170207
return self._result.SUCCESS

Diff for: exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py

+40-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@
1515
"""OTLP Metrics Exporter"""
1616

1717
import logging
18-
from typing import List, Sequence, Type, TypeVar
18+
import os
19+
from typing import List, Optional, Sequence, Type, TypeVar, Union
1920

20-
# pylint: disable=duplicate-code
21+
from grpc import ChannelCredentials
22+
23+
from opentelemetry.configuration import Configuration
2124
from opentelemetry.exporter.otlp.exporter import (
2225
OTLPExporterMixin,
2326
_get_resource_data,
27+
_load_credential_from_file,
2428
)
2529
from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import (
2630
ExportMetricsServiceRequest,
@@ -115,13 +119,47 @@ class OTLPMetricsExporter(
115119
116120
Args:
117121
endpoint: OpenTelemetry Collector receiver endpoint
122+
insecure: Connection type
118123
credentials: Credentials object for server authentication
119124
metadata: Metadata to send when exporting
125+
timeout: Backend request timeout in seconds
120126
"""
121127

122128
_stub = MetricsServiceStub
123129
_result = MetricsExportResult
124130

131+
def __init__(
132+
self,
133+
endpoint: Optional[str] = None,
134+
insecure: Optional[bool] = None,
135+
credentials: Optional[ChannelCredentials] = None,
136+
headers: Optional[str] = None,
137+
timeout: Optional[int] = None,
138+
):
139+
if insecure is None:
140+
insecure = Configuration().EXPORTER_OTLP_METRIC_INSECURE
141+
142+
if (
143+
not insecure
144+
and Configuration().EXPORTER_OTLP_METRIC_CERTIFICATE is not None
145+
):
146+
credentials = credentials or _load_credential_from_file(
147+
Configuration().EXPORTER_OTLP_METRIC_CERTIFICATE
148+
)
149+
150+
super().__init__(
151+
**{
152+
"endpoint": endpoint
153+
or Configuration().EXPORTER_OTLP_METRIC_ENDPOINT,
154+
"insecure": insecure,
155+
"credentials": credentials,
156+
"headers": headers
157+
or Configuration().EXPORTER_OTLP_METRIC_HEADERS,
158+
"timeout": timeout
159+
or Configuration().EXPORTER_OTLP_METRIC_TIMEOUT,
160+
}
161+
)
162+
125163
# pylint: disable=no-self-use
126164
def _translate_data(
127165
self, data: Sequence[MetricRecord]

Diff for: exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py

+40-1
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414
"""OTLP Span Exporter"""
1515

1616
import logging
17-
from typing import Sequence
17+
import os
18+
from typing import Optional, Sequence
1819

20+
from grpc import ChannelCredentials
21+
22+
from opentelemetry.configuration import Configuration
1923
from opentelemetry.exporter.otlp.exporter import (
2024
OTLPExporterMixin,
2125
_get_resource_data,
26+
_load_credential_from_file,
2227
_translate_key_values,
2328
)
2429
from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (
@@ -50,13 +55,47 @@ class OTLPSpanExporter(
5055
5156
Args:
5257
endpoint: OpenTelemetry Collector receiver endpoint
58+
insecure: Connection type
5359
credentials: Credentials object for server authentication
5460
metadata: Metadata to send when exporting
61+
timeout: Backend request timeout in seconds
5562
"""
5663

5764
_result = SpanExportResult
5865
_stub = TraceServiceStub
5966

67+
def __init__(
68+
self,
69+
endpoint: Optional[str] = None,
70+
insecure: Optional[bool] = None,
71+
credentials: Optional[ChannelCredentials] = None,
72+
headers: Optional[str] = None,
73+
timeout: Optional[int] = None,
74+
):
75+
if insecure is None:
76+
insecure = Configuration().EXPORTER_OTLP_SPAN_INSECURE
77+
78+
if (
79+
not insecure
80+
and Configuration().EXPORTER_OTLP_SPAN_CERTIFICATE is not None
81+
):
82+
credentials = credentials or _load_credential_from_file(
83+
Configuration().EXPORTER_OTLP_SPAN_CERTIFICATE
84+
)
85+
86+
super().__init__(
87+
**{
88+
"endpoint": endpoint
89+
or Configuration().EXPORTER_OTLP_SPAN_ENDPOINT,
90+
"insecure": insecure,
91+
"credentials": credentials,
92+
"headers": headers
93+
or Configuration().EXPORTER_OTLP_SPAN_HEADERS,
94+
"timeout": timeout
95+
or Configuration().EXPORTER_OTLP_SPAN_TIMEOUT,
96+
}
97+
)
98+
6099
def _translate_name(self, sdk_span: SDKSpan) -> None:
61100
self._collector_span_kwargs["name"] = sdk_span.name
62101

Diff for: exporter/opentelemetry-exporter-otlp/tests/fixtures/test.cert

Whitespace-only changes.

Diff for: exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py

+32-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
from unittest import TestCase
1717
from unittest.mock import patch
1818

19+
from grpc import ChannelCredentials
20+
21+
from opentelemetry.configuration import Configuration
1922
from opentelemetry.exporter.otlp.metrics_exporter import OTLPMetricsExporter
2023
from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import (
2124
ExportMetricsServiceRequest,
@@ -44,8 +47,9 @@
4447

4548
class TestOTLPMetricExporter(TestCase):
4649
def setUp(self):
47-
self.exporter = OTLPMetricsExporter()
50+
self.exporter = OTLPMetricsExporter(insecure=True)
4851
resource = SDKResource(OrderedDict([("a", 1), ("b", False)]))
52+
4953
self.counter_metric_record = MetricRecord(
5054
Counter(
5155
"c",
@@ -60,6 +64,33 @@ def setUp(self):
6064
resource,
6165
)
6266

67+
Configuration._reset() # pylint: disable=protected-access
68+
69+
def tearDown(self):
70+
Configuration._reset() # pylint: disable=protected-access
71+
72+
@patch.dict(
73+
"os.environ",
74+
{
75+
"OTEL_EXPORTER_OTLP_METRIC_ENDPOINT": "collector:55680",
76+
"OTEL_EXPORTER_OTLP_METRIC_CERTIFICATE": "fixtures/test.cert",
77+
"OTEL_EXPORTER_OTLP_METRIC_HEADERS": "key1:value1;key2:value2",
78+
"OTEL_EXPORTER_OTLP_METRIC_TIMEOUT": "10",
79+
},
80+
)
81+
@patch("opentelemetry.exporter.otlp.exporter.OTLPExporterMixin.__init__")
82+
def test_env_variables(self, mock_exporter_mixin):
83+
OTLPMetricsExporter()
84+
85+
self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
86+
_, kwargs = mock_exporter_mixin.call_args_list[0]
87+
88+
self.assertEqual(kwargs["endpoint"], "collector:55680")
89+
self.assertEqual(kwargs["headers"], "key1:value1;key2:value2")
90+
self.assertEqual(kwargs["timeout"], 10)
91+
self.assertIsNotNone(kwargs["credentials"])
92+
self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
93+
6394
@patch("opentelemetry.sdk.metrics.export.aggregate.time_ns")
6495
def test_translate_metrics(self, mock_time_ns):
6596
# pylint: disable=no-member

Diff for: exporter/opentelemetry-exporter-otlp/tests/test_otlp_trace_exporter.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919

2020
from google.protobuf.duration_pb2 import Duration
2121
from google.rpc.error_details_pb2 import RetryInfo
22-
from grpc import StatusCode, server
22+
from grpc import ChannelCredentials, StatusCode, server
2323

24+
from opentelemetry.configuration import Configuration
2425
from opentelemetry.exporter.otlp.trace_exporter import OTLPSpanExporter
2526
from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (
2627
ExportTraceServiceRequest,
@@ -102,7 +103,7 @@ def Export(self, request, context):
102103
class TestOTLPSpanExporter(TestCase):
103104
def setUp(self):
104105
tracer_provider = TracerProvider()
105-
self.exporter = OTLPSpanExporter()
106+
self.exporter = OTLPSpanExporter(insecure=True)
106107
tracer_provider.add_span_processor(
107108
SimpleExportSpanProcessor(self.exporter)
108109
)
@@ -154,8 +155,33 @@ def setUp(self):
154155
self.span.start()
155156
self.span.end()
156157

158+
Configuration._reset() # pylint: disable=protected-access
159+
157160
def tearDown(self):
158161
self.server.stop(None)
162+
Configuration._reset() # pylint: disable=protected-access
163+
164+
@patch.dict(
165+
"os.environ",
166+
{
167+
"OTEL_EXPORTER_OTLP_SPAN_ENDPOINT": "collector:55680",
168+
"OTEL_EXPORTER_OTLP_SPAN_CERTIFICATE": "fixtures/test.cert",
169+
"OTEL_EXPORTER_OTLP_SPAN_HEADERS": "key1:value1;key2:value2",
170+
"OTEL_EXPORTER_OTLP_SPAN_TIMEOUT": "10",
171+
},
172+
)
173+
@patch("opentelemetry.exporter.otlp.exporter.OTLPExporterMixin.__init__")
174+
def test_env_variables(self, mock_exporter_mixin):
175+
OTLPSpanExporter()
176+
177+
self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
178+
_, kwargs = mock_exporter_mixin.call_args_list[0]
179+
180+
self.assertEqual(kwargs["endpoint"], "collector:55680")
181+
self.assertEqual(kwargs["headers"], "key1:value1;key2:value2")
182+
self.assertEqual(kwargs["timeout"], 10)
183+
self.assertIsNotNone(kwargs["credentials"])
184+
self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
159185

160186
@patch("opentelemetry.exporter.otlp.exporter.expo")
161187
@patch("opentelemetry.exporter.otlp.exporter.sleep")

0 commit comments

Comments
 (0)