Skip to content

Commit 1a371cf

Browse files
author
Liudmila Molkova
committed
merge issue
1 parent cbd2507 commit 1a371cf

File tree

5 files changed

+344
-298
lines changed

5 files changed

+344
-298
lines changed

opentelemetry-api/src/opentelemetry/_logs/__init__.py

Lines changed: 9 additions & 287 deletions
Original file line numberDiff line numberDiff line change
@@ -33,298 +33,20 @@
3333
.. versionadded:: 1.15.0
3434
"""
3535

36-
from abc import ABC, abstractmethod
37-
from logging import getLogger
38-
from os import environ
39-
from typing import Any, Optional, cast
40-
36+
from opentelemetry._logs._internal import (
37+
Logger,
38+
LoggerProvider,
39+
NoOpLogger,
40+
NoOpLoggerProvider,
41+
get_logger,
42+
get_logger_provider,
43+
set_logger_provider,
44+
)
4145
from opentelemetry._logs.severity import SeverityNumber, std_to_otel
42-
from opentelemetry.context.context import Context
43-
from opentelemetry.environment_variables import _OTEL_PYTHON_LOGGER_PROVIDER
44-
from opentelemetry.util._once import Once
45-
from opentelemetry.util._providers import _load_provider
46-
from opentelemetry.util.types import Attributes
47-
48-
_logger = getLogger(__name__)
49-
50-
51-
class Logger(ABC):
52-
"""Handles emitting events and logs via `LogRecord`."""
53-
54-
def __init__(
55-
self,
56-
name: str,
57-
version: Optional[str] = None,
58-
schema_url: Optional[str] = None,
59-
attributes: Optional[Attributes] = None,
60-
) -> None:
61-
super().__init__()
62-
self._name = name
63-
self._version = version
64-
self._schema_url = schema_url
65-
self._attributes = attributes
66-
67-
@abstractmethod
68-
def is_enabled(
69-
self,
70-
severity_number: Optional[SeverityNumber] = None,
71-
context: Optional[Context] = None,
72-
) -> bool:
73-
"""Returns True if the logger is enabled for given severity and context, False otherwise."""
74-
75-
@abstractmethod
76-
def emit(
77-
self,
78-
name: str = None,
79-
timestamp: Optional[int] = None,
80-
observed_timestamp: Optional[int] = None,
81-
severity_number: Optional[SeverityNumber] = None,
82-
severity_text: Optional[str] = None,
83-
context: Optional[Context] = None,
84-
body: Optional[Any] = None,
85-
attributes: Optional[Attributes] = None,
86-
) -> None:
87-
"""Emits a log record."""
88-
89-
90-
class NoOpLogger(Logger):
91-
"""The default Logger used when no Logger implementation is available.
92-
93-
All operations are no-op.
94-
"""
95-
96-
def is_enabled(
97-
self,
98-
severity_number: Optional[SeverityNumber] = None,
99-
context: Optional[Context] = None,
100-
) -> bool:
101-
return False
102-
103-
def emit(
104-
self,
105-
name: str = None,
106-
timestamp: Optional[int] = None,
107-
observed_timestamp: Optional[int] = None,
108-
severity_number: Optional[SeverityNumber] = None,
109-
severity_text: Optional[str] = None,
110-
context: Optional[Context] = None,
111-
body: Optional[Any] = None,
112-
attributes: Optional[Attributes] = None,
113-
) -> None:
114-
pass
115-
116-
117-
class ProxyLogger(Logger):
118-
def __init__( # pylint: disable=super-init-not-called
119-
self,
120-
name: str,
121-
version: Optional[str] = None,
122-
schema_url: Optional[str] = None,
123-
attributes: Optional[Attributes] = None,
124-
):
125-
self._name = name
126-
self._version = version
127-
self._schema_url = schema_url
128-
self._attributes = attributes
129-
self._real_logger: Optional[Logger] = None
130-
self._noop_logger = NoOpLogger(name)
131-
132-
@property
133-
def _logger(self) -> Logger:
134-
if self._real_logger:
135-
return self._real_logger
136-
137-
if _LOGGER_PROVIDER:
138-
self._real_logger = _LOGGER_PROVIDER.get_logger(
139-
self._name,
140-
self._version,
141-
self._schema_url,
142-
self._attributes,
143-
)
144-
return self._real_logger
145-
return self._noop_logger
146-
147-
def is_enabled(
148-
self,
149-
severity_number: Optional[SeverityNumber] = None,
150-
context: Optional[Context] = None,
151-
) -> bool:
152-
return self._logger.is_enabled(
153-
severity_number=severity_number, context=context
154-
)
155-
156-
def emit(
157-
self,
158-
name: str = None,
159-
timestamp: Optional[int] = None,
160-
observed_timestamp: Optional[int] = None,
161-
severity_number: Optional[SeverityNumber] = None,
162-
severity_text: Optional[str] = None,
163-
context: Optional[Context] = None,
164-
body: Optional[Any] = None,
165-
attributes: Optional[Attributes] = None,
166-
) -> None:
167-
self._logger.emit(
168-
name=name,
169-
timestamp=timestamp,
170-
observed_timestamp=observed_timestamp,
171-
severity_number=severity_number,
172-
severity_text=severity_text,
173-
context=context,
174-
body=body,
175-
attributes=attributes,
176-
)
177-
178-
179-
class LoggerProvider(ABC):
180-
"""
181-
LoggerProvider is the entry point of the API. It provides access to Logger instances.
182-
"""
183-
184-
@abstractmethod
185-
def get_logger(
186-
self,
187-
name: str,
188-
version: Optional[str] = None,
189-
schema_url: Optional[str] = None,
190-
attributes: Optional[Attributes] = None,
191-
) -> Logger:
192-
"""Returns a `Logger` for use by the given instrumentation library.
193-
194-
For any two calls it is undefined whether the same or different
195-
`Logger` instances are returned, even for different library names.
196-
197-
This function may return different `Logger` types (e.g. a no-op logger
198-
vs. a functional logger).
199-
200-
Args:
201-
name: The name of the instrumenting module.
202-
``__name__`` may not be used as this can result in
203-
different logger names if the loggers are in different files.
204-
It is better to use a fixed string that can be imported where
205-
needed and used consistently as the name of the logger.
206-
207-
This should *not* be the name of the module that is
208-
instrumented but the name of the module doing the instrumentation.
209-
E.g., instead of ``"requests"``, use
210-
``"opentelemetry.instrumentation.requests"``.
211-
212-
version: Optional. The version string of the
213-
instrumenting library. Usually this should be the same as
214-
``importlib.metadata.version(instrumenting_library_name)``.
215-
216-
schema_url: Optional. Specifies the Schema URL of the emitted telemetry.
217-
"""
218-
219-
220-
class NoOpLoggerProvider(LoggerProvider):
221-
"""The default LoggerProvider used when no LoggerProvider implementation is available."""
222-
223-
def get_logger(
224-
self,
225-
name: str,
226-
version: Optional[str] = None,
227-
schema_url: Optional[str] = None,
228-
attributes: Optional[Attributes] = None,
229-
) -> Logger:
230-
"""Returns a NoOpLogger."""
231-
return NoOpLogger(
232-
name, version=version, schema_url=schema_url, attributes=attributes
233-
)
234-
235-
236-
class ProxyLoggerProvider(LoggerProvider):
237-
def get_logger(
238-
self,
239-
name: str,
240-
version: Optional[str] = None,
241-
schema_url: Optional[str] = None,
242-
attributes: Optional[Attributes] = None,
243-
) -> Logger:
244-
if _LOGGER_PROVIDER:
245-
return _LOGGER_PROVIDER.get_logger(
246-
name,
247-
version=version,
248-
schema_url=schema_url,
249-
attributes=attributes,
250-
)
251-
return ProxyLogger(
252-
name,
253-
version=version,
254-
schema_url=schema_url,
255-
attributes=attributes,
256-
)
257-
258-
259-
_LOGGER_PROVIDER_SET_ONCE = Once()
260-
_LOGGER_PROVIDER: Optional[LoggerProvider] = None
261-
_PROXY_LOGGER_PROVIDER = ProxyLoggerProvider()
262-
263-
264-
def get_logger_provider() -> LoggerProvider:
265-
"""Gets the current global :class:`~.LoggerProvider` object."""
266-
global _LOGGER_PROVIDER # pylint: disable=global-variable-not-assigned
267-
if _LOGGER_PROVIDER is None:
268-
if _OTEL_PYTHON_LOGGER_PROVIDER not in environ:
269-
return _PROXY_LOGGER_PROVIDER
270-
271-
logger_provider: LoggerProvider = _load_provider( # type: ignore
272-
_OTEL_PYTHON_LOGGER_PROVIDER, "logger_provider"
273-
)
274-
_set_logger_provider(logger_provider, log=False)
275-
276-
# _LOGGER_PROVIDER will have been set by one thread
277-
return cast("LoggerProvider", _LOGGER_PROVIDER)
278-
279-
280-
def _set_logger_provider(logger_provider: LoggerProvider, log: bool) -> None:
281-
def set_lp() -> None:
282-
global _LOGGER_PROVIDER # pylint: disable=global-statement
283-
_LOGGER_PROVIDER = logger_provider
284-
285-
did_set = _LOGGER_PROVIDER_SET_ONCE.do_once(set_lp)
286-
287-
if log and not did_set:
288-
_logger.warning("Overriding of current LoggerProvider is not allowed")
289-
290-
291-
def set_logger_provider(logger_provider: LoggerProvider) -> None:
292-
"""Sets the current global :class:`~.LoggerProvider` object.
293-
294-
This can only be done once, a warning will be logged if any further attempt
295-
is made.
296-
"""
297-
_set_logger_provider(logger_provider, log=True)
298-
299-
300-
def get_logger(
301-
instrumenting_module_name: str,
302-
instrumenting_library_version: str = "",
303-
logger_provider: Optional[LoggerProvider] = None,
304-
schema_url: Optional[str] = None,
305-
attributes: Optional[Attributes] = None,
306-
) -> "Logger":
307-
"""Returns a `Logger` for use within a python process.
308-
309-
This function is a convenience wrapper for
310-
opentelemetry.sdk._logs.LoggerProvider.get_logger.
311-
312-
If logger_provider param is omitted the current configured one is used.
313-
"""
314-
if logger_provider is None:
315-
logger_provider = get_logger_provider()
316-
return logger_provider.get_logger(
317-
instrumenting_module_name,
318-
instrumenting_library_version,
319-
schema_url,
320-
attributes,
321-
)
322-
32346

32447
__all__ = [
32548
"Logger",
32649
"LoggerProvider",
327-
"LogRecord",
32850
"NoOpLogger",
32951
"NoOpLoggerProvider",
33052
"get_logger",

0 commit comments

Comments
 (0)