1313# limitations under the License.
1414# type: ignore
1515
16+ import logging
1617from os import environ
1718from unittest import TestCase
1819from unittest .mock import patch
2627 _get_id_generator ,
2728 _import_exporters ,
2829 _import_id_generator ,
30+ _init_logging ,
2931 _init_tracing ,
3032)
33+ from opentelemetry .sdk ._logs import OTLPHandler
3134from opentelemetry .sdk ._logs .export import ConsoleLogExporter
3235from opentelemetry .sdk ._metrics .export import ConsoleMetricExporter
3336from opentelemetry .sdk .resources import SERVICE_NAME , Resource
@@ -45,6 +48,45 @@ def add_span_processor(self, processor):
4548 self .processor = processor
4649
4750
51+ class DummyLogEmitterProvider :
52+ def __init__ (self , resource = None ):
53+ self .resource = resource
54+ self .processor = DummyLogProcessor (DummyOTLPLogExporter ())
55+
56+ def add_log_processor (self , processor ):
57+ self .processor = processor
58+
59+ def get_log_emitter (self , name ):
60+ return DummyLogEmitter (name , self .resource , self .processor )
61+
62+
63+ class DummyLogEmitter :
64+ def __init__ (self , name , resource , processor ):
65+ self .name = name
66+ self .resource = resource
67+ self .processor = processor
68+
69+ def emit (self , record ):
70+ self .processor .emit (record )
71+
72+ def flush (self ):
73+ pass
74+
75+
76+ class DummyLogProcessor :
77+ def __init__ (self , exporter ):
78+ self .exporter = exporter
79+
80+ def emit (self , record ):
81+ self .exporter .export ([record ])
82+
83+ def force_flush (self , time ):
84+ pass
85+
86+ def shutdown (self ):
87+ pass
88+
89+
4890class Processor :
4991 def __init__ (self , exporter ):
5092 self .exporter = exporter
@@ -63,10 +105,21 @@ def shutdown(self):
63105 pass
64106
65107
66- class OTLPExporter :
108+ class OTLPSpanExporter :
67109 pass
68110
69111
112+ class DummyOTLPLogExporter :
113+ def __init__ (self , * args , ** kwargs ):
114+ self .export_called = False
115+
116+ def export (self , batch ):
117+ self .export_called = True
118+
119+ def shutdown (self ):
120+ pass
121+
122+
70123class CustomIdGenerator (IdGenerator ):
71124 def generate_span_id (self ):
72125 pass
@@ -133,14 +186,14 @@ def test_trace_init_default(self):
133186 {"OTEL_RESOURCE_ATTRIBUTES" : "service.name=my-otlp-test-service" },
134187 )
135188 def test_trace_init_otlp (self ):
136- _init_tracing ({"otlp" : OTLPExporter }, RandomIdGenerator )
189+ _init_tracing ({"otlp" : OTLPSpanExporter }, RandomIdGenerator )
137190
138191 self .assertEqual (self .set_provider_mock .call_count , 1 )
139192 provider = self .set_provider_mock .call_args [0 ][0 ]
140193 self .assertIsInstance (provider , Provider )
141194 self .assertIsInstance (provider .id_generator , RandomIdGenerator )
142195 self .assertIsInstance (provider .processor , Processor )
143- self .assertIsInstance (provider .processor .exporter , OTLPExporter )
196+ self .assertIsInstance (provider .processor .exporter , OTLPSpanExporter )
144197 self .assertIsInstance (provider .resource , Resource )
145198 self .assertEqual (
146199 provider .resource .attributes .get ("service.name" ),
@@ -163,6 +216,68 @@ def test_trace_init_custom_id_generator(self, mock_iter_entry_points):
163216 self .assertIsInstance (provider .id_generator , CustomIdGenerator )
164217
165218
219+ class TestLoggingInit (TestCase ):
220+ def setUp (self ):
221+ self .processor_patch = patch (
222+ "opentelemetry.sdk._configuration.BatchLogProcessor" ,
223+ DummyLogProcessor ,
224+ )
225+ self .provider_patch = patch (
226+ "opentelemetry.sdk._configuration.LogEmitterProvider" ,
227+ DummyLogEmitterProvider ,
228+ )
229+ self .set_provider_patch = patch (
230+ "opentelemetry.sdk._configuration.set_log_emitter_provider"
231+ )
232+
233+ self .processor_mock = self .processor_patch .start ()
234+ self .provider_mock = self .provider_patch .start ()
235+ self .set_provider_mock = self .set_provider_patch .start ()
236+
237+ def tearDown (self ):
238+ self .processor_patch .stop ()
239+ self .set_provider_patch .stop ()
240+ self .provider_patch .stop ()
241+ root_logger = logging .getLogger ("root" )
242+ root_logger .handlers = [
243+ handler
244+ for handler in root_logger .handlers
245+ if not isinstance (handler , OTLPHandler )
246+ ]
247+
248+ def test_logging_init_empty (self ):
249+ _init_logging ({}, "auto-version" )
250+ self .assertEqual (self .set_provider_mock .call_count , 1 )
251+ provider = self .set_provider_mock .call_args [0 ][0 ]
252+ self .assertIsInstance (provider , DummyLogEmitterProvider )
253+ self .assertIsInstance (provider .resource , Resource )
254+ self .assertEqual (
255+ provider .resource .attributes .get ("telemetry.auto.version" ),
256+ "auto-version" ,
257+ )
258+
259+ @patch .dict (
260+ environ ,
261+ {"OTEL_RESOURCE_ATTRIBUTES" : "service.name=otlp-service" },
262+ )
263+ def test_logging_init_exporter (self ):
264+ _init_logging ({"otlp" : DummyOTLPLogExporter })
265+ self .assertEqual (self .set_provider_mock .call_count , 1 )
266+ provider = self .set_provider_mock .call_args [0 ][0 ]
267+ self .assertIsInstance (provider , DummyLogEmitterProvider )
268+ self .assertIsInstance (provider .resource , Resource )
269+ self .assertEqual (
270+ provider .resource .attributes .get ("service.name" ),
271+ "otlp-service" ,
272+ )
273+ self .assertIsInstance (provider .processor , DummyLogProcessor )
274+ self .assertIsInstance (
275+ provider .processor .exporter , DummyOTLPLogExporter
276+ )
277+ logging .getLogger (__name__ ).error ("hello" )
278+ self .assertTrue (provider .processor .exporter .export_called )
279+
280+
166281class TestExporterNames (TestCase ):
167282 def test_otlp_exporter_overwrite (self ):
168283 for exporter in [_EXPORTER_OTLP , _EXPORTER_OTLP_PROTO_GRPC ]:
0 commit comments