|
14 | 14 |
|
15 | 15 | import abc
|
16 | 16 | import atexit
|
17 |
| -from typing import Any, Optional |
| 17 | +import logging |
| 18 | +import os |
| 19 | +from typing import Any, Optional, cast |
18 | 20 |
|
| 21 | +from opentelemetry.sdk.environment_variables import ( |
| 22 | + OTEL_PYTHON_LOG_EMITTER_PROVIDER, |
| 23 | +) |
19 | 24 | from opentelemetry.sdk.logs.severity import SeverityNumber
|
20 | 25 | from opentelemetry.sdk.resources import Resource
|
21 | 26 | from opentelemetry.sdk.util.instrumentation import InstrumentationInfo
|
22 | 27 | from opentelemetry.trace.span import TraceFlags
|
| 28 | +from opentelemetry.util._providers import _load_provider |
23 | 29 | from opentelemetry.util.types import Attributes
|
24 | 30 |
|
| 31 | +_logger = logging.getLogger(__name__) |
| 32 | + |
25 | 33 |
|
26 | 34 | class LogRecord:
|
27 | 35 | """A LogRecord instance represents an event being logged.
|
@@ -172,3 +180,60 @@ def force_flush(self, timeout_millis: int = 30000) -> bool:
|
172 | 180 | False otherwise.
|
173 | 181 | """
|
174 | 182 | # TODO: multi_log_processor.force_flush
|
| 183 | + |
| 184 | + |
| 185 | +_LOG_EMITTER_PROVIDER = None |
| 186 | + |
| 187 | + |
| 188 | +def get_log_emitter_provider() -> LogEmitterProvider: |
| 189 | + """Gets the current global :class:`~.LogEmitterProvider` object.""" |
| 190 | + global _LOG_EMITTER_PROVIDER # pylint: disable=global-statement |
| 191 | + if _LOG_EMITTER_PROVIDER is None: |
| 192 | + if OTEL_PYTHON_LOG_EMITTER_PROVIDER not in os.environ: |
| 193 | + _LOG_EMITTER_PROVIDER = LogEmitterProvider() |
| 194 | + return _LOG_EMITTER_PROVIDER |
| 195 | + |
| 196 | + _LOG_EMITTER_PROVIDER = cast( |
| 197 | + "LogEmitterProvider", |
| 198 | + _load_provider( |
| 199 | + OTEL_PYTHON_LOG_EMITTER_PROVIDER, "log_emitter_provider" |
| 200 | + ), |
| 201 | + ) |
| 202 | + |
| 203 | + return _LOG_EMITTER_PROVIDER |
| 204 | + |
| 205 | + |
| 206 | +def set_log_emitter_provider(log_emitter_provider: LogEmitterProvider) -> None: |
| 207 | + """Sets the current global :class:`~.LogEmitterProvider` object. |
| 208 | +
|
| 209 | + This can only be done once, a warning will be logged if any furter attempt |
| 210 | + is made. |
| 211 | + """ |
| 212 | + global _LOG_EMITTER_PROVIDER # pylint: disable=global-statement |
| 213 | + |
| 214 | + if _LOG_EMITTER_PROVIDER is not None: |
| 215 | + _logger.warning( |
| 216 | + "Overriding of current LogEmitterProvider is not allowed" |
| 217 | + ) |
| 218 | + return |
| 219 | + |
| 220 | + _LOG_EMITTER_PROVIDER = log_emitter_provider |
| 221 | + |
| 222 | + |
| 223 | +def get_log_emitter( |
| 224 | + instrumenting_module_name: str, |
| 225 | + instrumenting_library_version: str = "", |
| 226 | + log_emitter_provider: Optional[LogEmitterProvider] = None, |
| 227 | +) -> LogEmitter: |
| 228 | + """Returns a `LogEmitter` for use within a python process. |
| 229 | +
|
| 230 | + This function is a convenience wrapper for |
| 231 | + opentelemetry.sdk.logs.LogEmitterProvider.get_log_emitter. |
| 232 | +
|
| 233 | + If log_emitter_provider param is omitted the current configured one is used. |
| 234 | + """ |
| 235 | + if log_emitter_provider is None: |
| 236 | + log_emitter_provider = get_log_emitter_provider() |
| 237 | + return log_emitter_provider.get_log_emitter( |
| 238 | + instrumenting_module_name, instrumenting_library_version |
| 239 | + ) |
0 commit comments