28
28
OTEL_PYTHON_ID_GENERATOR ,
29
29
OTEL_TRACES_EXPORTER ,
30
30
)
31
+ from opentelemetry .sdk ._logs import (
32
+ LogEmitterProvider ,
33
+ set_log_emitter_provider ,
34
+ )
35
+ from opentelemetry .sdk ._logs .export import BatchLogProcessor , LogExporter
31
36
from opentelemetry .sdk .resources import Resource
32
37
from opentelemetry .sdk .trace import TracerProvider
33
38
from opentelemetry .sdk .trace .export import BatchSpanProcessor , SpanExporter
34
39
from opentelemetry .sdk .trace .id_generator import IdGenerator
35
40
from opentelemetry .semconv .resource import ResourceAttributes
36
41
37
42
_EXPORTER_OTLP = "otlp"
38
- _EXPORTER_OTLP_SPAN = "otlp_proto_grpc"
43
+ _EXPORTER_OTLP_PROTO_GRPC = "otlp_proto_grpc"
39
44
40
45
_RANDOM_ID_GENERATOR = "random"
41
46
_DEFAULT_ID_GENERATOR = _RANDOM_ID_GENERATOR
42
47
48
+ # TODO: add log exporter env variable
49
+ _OTEL_LOGS_EXPORTER = "OTEL_LOGS_EXPORTER"
50
+
43
51
44
52
def _get_id_generator () -> str :
45
53
return environ .get (OTEL_PYTHON_ID_GENERATOR , _DEFAULT_ID_GENERATOR )
46
54
47
55
48
- def _get_exporter_names () -> Sequence [str ]:
49
- trace_exporters = environ .get (OTEL_TRACES_EXPORTER )
50
-
56
+ def _get_exporter_names (names : str ) -> Sequence [str ]:
51
57
exporters = set ()
52
58
53
- if trace_exporters and trace_exporters .lower ().strip () != "none" :
54
- exporters .update (
55
- {
56
- trace_exporter .strip ()
57
- for trace_exporter in trace_exporters .split ("," )
58
- }
59
- )
59
+ if names and names .lower ().strip () != "none" :
60
+ exporters .update ({_exporter .strip () for _exporter in names .split ("," )})
60
61
61
62
if _EXPORTER_OTLP in exporters :
62
63
exporters .remove (_EXPORTER_OTLP )
63
- exporters .add (_EXPORTER_OTLP_SPAN )
64
+ exporters .add (_EXPORTER_OTLP_PROTO_GRPC )
64
65
65
66
return list (exporters )
66
67
@@ -91,7 +92,29 @@ def _init_tracing(
91
92
)
92
93
93
94
94
- def _import_tracer_provider_config_components (
95
+ def _init_logging (
96
+ exporters : Dict [str , Sequence [LogExporter ]],
97
+ auto_instrumentation_version : Optional [str ] = None ,
98
+ ):
99
+ # if env var OTEL_RESOURCE_ATTRIBUTES is given, it will read the service_name
100
+ # from the env variable else defaults to "unknown_service"
101
+ auto_resource = {}
102
+ # populate version if using auto-instrumentation
103
+ if auto_instrumentation_version :
104
+ auto_resource [
105
+ ResourceAttributes .TELEMETRY_AUTO_VERSION
106
+ ] = auto_instrumentation_version
107
+ provider = LogEmitterProvider (resource = Resource .create (auto_resource ))
108
+ set_log_emitter_provider (provider )
109
+
110
+ for _ , exporter_class in exporters .items ():
111
+ exporter_args = {}
112
+ provider .add_log_processor (
113
+ BatchLogProcessor (exporter_class (** exporter_args ))
114
+ )
115
+
116
+
117
+ def _import_config_components (
95
118
selected_components , entry_point_name
96
119
) -> Sequence [Tuple [str , object ]]:
97
120
component_entry_points = {
@@ -112,28 +135,34 @@ def _import_tracer_provider_config_components(
112
135
113
136
114
137
def _import_exporters (
115
- exporter_names : Sequence [str ],
116
- ) -> Dict [str , Type [SpanExporter ]]:
138
+ trace_exporter_names : Sequence [str ],
139
+ log_exporter_names : Sequence [str ],
140
+ ) -> Tuple [Dict [str , Type [SpanExporter ]], Dict [str , Type [LogExporter ]]]:
117
141
trace_exporters = {}
142
+ log_exporters = {}
118
143
119
- for (
120
- exporter_name ,
121
- exporter_impl ,
122
- ) in _import_tracer_provider_config_components (
123
- exporter_names , "opentelemetry_traces_exporter"
144
+ for (exporter_name , exporter_impl ,) in _import_config_components (
145
+ trace_exporter_names , "opentelemetry_traces_exporter"
124
146
):
125
147
if issubclass (exporter_impl , SpanExporter ):
126
148
trace_exporters [exporter_name ] = exporter_impl
127
149
else :
128
150
raise RuntimeError (f"{ exporter_name } is not a trace exporter" )
129
- return trace_exporters
151
+
152
+ for (exporter_name , exporter_impl ,) in _import_config_components (
153
+ log_exporter_names , "opentelemetry_logs_exporter"
154
+ ):
155
+ if issubclass (exporter_impl , LogExporter ):
156
+ log_exporters [exporter_name ] = exporter_impl
157
+ else :
158
+ raise RuntimeError (f"{ exporter_name } is not a log exporter" )
159
+
160
+ return trace_exporters , log_exporters
130
161
131
162
132
163
def _import_id_generator (id_generator_name : str ) -> IdGenerator :
133
164
# pylint: disable=unbalanced-tuple-unpacking
134
- [
135
- (id_generator_name , id_generator_impl )
136
- ] = _import_tracer_provider_config_components (
165
+ [(id_generator_name , id_generator_impl )] = _import_config_components (
137
166
[id_generator_name .strip ()], "opentelemetry_id_generator"
138
167
)
139
168
@@ -144,11 +173,14 @@ def _import_id_generator(id_generator_name: str) -> IdGenerator:
144
173
145
174
146
175
def _initialize_components (auto_instrumentation_version ):
147
- exporter_names = _get_exporter_names ()
148
- trace_exporters = _import_exporters (exporter_names )
176
+ trace_exporters , log_exporters = _import_exporters (
177
+ _get_exporter_names (environ .get (OTEL_TRACES_EXPORTER )),
178
+ _get_exporter_names (environ .get (_OTEL_LOGS_EXPORTER )),
179
+ )
149
180
id_generator_name = _get_id_generator ()
150
181
id_generator = _import_id_generator (id_generator_name )
151
182
_init_tracing (trace_exporters , id_generator , auto_instrumentation_version )
183
+ _init_logging (log_exporters , auto_instrumentation_version )
152
184
153
185
154
186
class _BaseConfigurator (ABC ):
0 commit comments