Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
__init__.py449 linesDownload Raw Back to _internal
1# Copyright The OpenTelemetry Authors2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7#     http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14"""15The OpenTelemetry logging API describes the classes used to generate logs and events.16 17The :class:`.LoggerProvider` provides users access to the :class:`.Logger`.18 19This module provides abstract (i.e. unimplemented) classes required for20logging, and a concrete no-op implementation :class:`.NoOpLogger` that allows applications21to use the API package alone without a supporting implementation.22 23To get a logger, you need to provide the package name from which you are24calling the logging APIs to OpenTelemetry by calling `LoggerProvider.get_logger`25with the calling module name and the version of your package.26 27The following code shows how to obtain a logger using the global :class:`.LoggerProvider`::28 29    from opentelemetry._logs import get_logger30 31    logger = get_logger("example-logger")32 33.. versionadded:: 1.15.034"""35 36from __future__ import annotations37 38from abc import ABC, abstractmethod39from logging import getLogger40from os import environ41from time import time_ns42from typing import Optional, cast, overload43 44from typing_extensions import deprecated45 46from opentelemetry._logs.severity import SeverityNumber47from opentelemetry.context import get_current48from opentelemetry.context.context import Context49from opentelemetry.environment_variables import _OTEL_PYTHON_LOGGER_PROVIDER50from opentelemetry.trace import get_current_span51from opentelemetry.trace.span import TraceFlags52from opentelemetry.util._once import Once53from opentelemetry.util._providers import _load_provider54from opentelemetry.util.types import AnyValue, _ExtendedAttributes55 56_logger = getLogger(__name__)57 58 59class LogRecord(ABC):60    """A LogRecord instance represents an event being logged.61 62    LogRecord instances are created and emitted via `Logger`63    every time something is logged. They contain all the information64    pertinent to the event being logged.65    """66 67    @overload68    def __init__(69        self,70        *,71        timestamp: Optional[int] = None,72        observed_timestamp: Optional[int] = None,73        context: Optional[Context] = None,74        severity_text: Optional[str] = None,75        severity_number: Optional[SeverityNumber] = None,76        body: AnyValue = None,77        attributes: Optional[_ExtendedAttributes] = None,78        event_name: Optional[str] = None,79    ) -> None: ...80 81    @overload82    @deprecated(83        "LogRecord init with `trace_id`, `span_id`, and/or `trace_flags` is deprecated since 1.35.0. Use `context` instead."84    )85    def __init__(86        self,87        *,88        timestamp: Optional[int] = None,89        observed_timestamp: Optional[int] = None,90        trace_id: Optional[int] = None,91        span_id: Optional[int] = None,92        trace_flags: Optional[TraceFlags] = None,93        severity_text: Optional[str] = None,94        severity_number: Optional[SeverityNumber] = None,95        body: AnyValue = None,96        attributes: Optional[_ExtendedAttributes] = None,97    ) -> None: ...98 99    def __init__(100        self,101        *,102        timestamp: Optional[int] = None,103        observed_timestamp: Optional[int] = None,104        context: Optional[Context] = None,105        trace_id: Optional[int] = None,106        span_id: Optional[int] = None,107        trace_flags: Optional[TraceFlags] = None,108        severity_text: Optional[str] = None,109        severity_number: Optional[SeverityNumber] = None,110        body: AnyValue = None,111        attributes: Optional[_ExtendedAttributes] = None,112        event_name: Optional[str] = None,113    ) -> None:114        if not context:115            context = get_current()116        span_context = get_current_span(context).get_span_context()117        self.timestamp = timestamp118        if observed_timestamp is None:119            observed_timestamp = time_ns()120        self.observed_timestamp = observed_timestamp121        self.context = context122        self.trace_id = trace_id or span_context.trace_id123        self.span_id = span_id or span_context.span_id124        self.trace_flags = trace_flags or span_context.trace_flags125        self.severity_text = severity_text126        self.severity_number = severity_number127        self.body = body128        self.attributes = attributes129        self.event_name = event_name130 131 132class Logger(ABC):133    """Handles emitting events and logs via `LogRecord`."""134 135    def __init__(136        self,137        name: str,138        version: Optional[str] = None,139        schema_url: Optional[str] = None,140        attributes: Optional[_ExtendedAttributes] = None,141    ) -> None:142        super().__init__()143        self._name = name144        self._version = version145        self._schema_url = schema_url146        self._attributes = attributes147 148    @overload149    def emit(150        self,151        *,152        timestamp: int | None = None,153        observed_timestamp: int | None = None,154        context: Context | None = None,155        severity_number: SeverityNumber | None = None,156        severity_text: str | None = None,157        body: AnyValue | None = None,158        attributes: _ExtendedAttributes | None = None,159        event_name: str | None = None,160    ) -> None: ...161 162    @overload163    def emit(164        self,165        record: LogRecord,166    ) -> None: ...167 168    @abstractmethod169    def emit(170        self,171        record: LogRecord | None = None,172        *,173        timestamp: int | None = None,174        observed_timestamp: int | None = None,175        context: Context | None = None,176        severity_number: SeverityNumber | None = None,177        severity_text: str | None = None,178        body: AnyValue | None = None,179        attributes: _ExtendedAttributes | None = None,180        event_name: str | None = None,181    ) -> None:182        """Emits a :class:`LogRecord` representing a log to the processing pipeline."""183 184 185class NoOpLogger(Logger):186    """The default Logger used when no Logger implementation is available.187 188    All operations are no-op.189    """190 191    @overload192    def emit(193        self,194        *,195        timestamp: int | None = None,196        observed_timestamp: int | None = None,197        context: Context | None = None,198        severity_number: SeverityNumber | None = None,199        severity_text: str | None = None,200        body: AnyValue | None = None,201        attributes: _ExtendedAttributes | None = None,202        event_name: str | None = None,203    ) -> None: ...204 205    @overload206    def emit(  # pylint:disable=arguments-differ207        self,208        record: LogRecord,209    ) -> None: ...210 211    def emit(212        self,213        record: LogRecord | None = None,214        *,215        timestamp: int | None = None,216        observed_timestamp: int | None = None,217        context: Context | None = None,218        severity_number: SeverityNumber | None = None,219        severity_text: str | None = None,220        body: AnyValue | None = None,221        attributes: _ExtendedAttributes | None = None,222        event_name: str | None = None,223    ) -> None:224        pass225 226 227class ProxyLogger(Logger):228    def __init__(  # pylint: disable=super-init-not-called229        self,230        name: str,231        version: Optional[str] = None,232        schema_url: Optional[str] = None,233        attributes: Optional[_ExtendedAttributes] = None,234    ):235        self._name = name236        self._version = version237        self._schema_url = schema_url238        self._attributes = attributes239        self._real_logger: Optional[Logger] = None240        self._noop_logger = NoOpLogger(name)241 242    @property243    def _logger(self) -> Logger:244        if self._real_logger:245            return self._real_logger246 247        if _LOGGER_PROVIDER:248            self._real_logger = _LOGGER_PROVIDER.get_logger(249                self._name,250                self._version,251                self._schema_url,252                self._attributes,253            )254            return self._real_logger255        return self._noop_logger256 257    @overload258    def emit(259        self,260        *,261        timestamp: int | None = None,262        observed_timestamp: int | None = None,263        context: Context | None = None,264        severity_number: SeverityNumber | None = None,265        severity_text: str | None = None,266        body: AnyValue | None = None,267        attributes: _ExtendedAttributes | None = None,268        event_name: str | None = None,269    ) -> None: ...270 271    @overload272    def emit(  # pylint:disable=arguments-differ273        self,274        record: LogRecord,275    ) -> None: ...276 277    def emit(278        self,279        record: LogRecord | None = None,280        *,281        timestamp: int | None = None,282        observed_timestamp: int | None = None,283        context: Context | None = None,284        severity_number: SeverityNumber | None = None,285        severity_text: str | None = None,286        body: AnyValue | None = None,287        attributes: _ExtendedAttributes | None = None,288        event_name: str | None = None,289    ) -> None:290        if record:291            self._logger.emit(record)292        else:293            self._logger.emit(294                timestamp=timestamp,295                observed_timestamp=observed_timestamp,296                context=context,297                severity_number=severity_number,298                severity_text=severity_text,299                body=body,300                attributes=attributes,301                event_name=event_name,302            )303 304 305class LoggerProvider(ABC):306    """307    LoggerProvider is the entry point of the API. It provides access to Logger instances.308    """309 310    @abstractmethod311    def get_logger(312        self,313        name: str,314        version: Optional[str] = None,315        schema_url: Optional[str] = None,316        attributes: Optional[_ExtendedAttributes] = None,317    ) -> Logger:318        """Returns a `Logger` for use by the given instrumentation library.319 320        For any two calls with identical parameters, it is undefined whether the same321        or different `Logger` instances are returned.322 323        This function may return different `Logger` types (e.g. a no-op logger324        vs. a functional logger).325 326        Args:327            name: The name of the instrumenting module, package or class.328                This should *not* be the name of the module, package or class that is329                instrumented but the name of the code doing the instrumentation.330                E.g., instead of ``"requests"``, use331                ``"opentelemetry.instrumentation.requests"``.332 333                For log sources which define a logger name (e.g. logging.Logger.name)334                the Logger Name should be recorded as the instrumentation scope name.335 336            version: Optional. The version string of the337                instrumenting library.  Usually this should be the same as338                ``importlib.metadata.version(instrumenting_library_name)``.339 340            schema_url: Optional. Specifies the Schema URL of the emitted telemetry.341 342            attributes: Optional. Specifies the instrumentation scope attributes to343                associate with emitted telemetry.344        """345 346 347class NoOpLoggerProvider(LoggerProvider):348    """The default LoggerProvider used when no LoggerProvider implementation is available."""349 350    def get_logger(351        self,352        name: str,353        version: Optional[str] = None,354        schema_url: Optional[str] = None,355        attributes: Optional[_ExtendedAttributes] = None,356    ) -> Logger:357        """Returns a NoOpLogger."""358        return NoOpLogger(359            name, version=version, schema_url=schema_url, attributes=attributes360        )361 362 363class ProxyLoggerProvider(LoggerProvider):364    def get_logger(365        self,366        name: str,367        version: Optional[str] = None,368        schema_url: Optional[str] = None,369        attributes: Optional[_ExtendedAttributes] = None,370    ) -> Logger:371        if _LOGGER_PROVIDER:372            return _LOGGER_PROVIDER.get_logger(373                name,374                version=version,375                schema_url=schema_url,376                attributes=attributes,377            )378        return ProxyLogger(379            name,380            version=version,381            schema_url=schema_url,382            attributes=attributes,383        )384 385 386_LOGGER_PROVIDER_SET_ONCE = Once()387_LOGGER_PROVIDER: Optional[LoggerProvider] = None388_PROXY_LOGGER_PROVIDER = ProxyLoggerProvider()389 390 391def get_logger_provider() -> LoggerProvider:392    """Gets the current global :class:`~.LoggerProvider` object."""393    global _LOGGER_PROVIDER  # pylint: disable=global-variable-not-assigned394    if _LOGGER_PROVIDER is None:395        if _OTEL_PYTHON_LOGGER_PROVIDER not in environ:396            return _PROXY_LOGGER_PROVIDER397 398        logger_provider: LoggerProvider = _load_provider(  # type: ignore399            _OTEL_PYTHON_LOGGER_PROVIDER, "logger_provider"400        )401        _set_logger_provider(logger_provider, log=False)402 403    # _LOGGER_PROVIDER will have been set by one thread404    return cast("LoggerProvider", _LOGGER_PROVIDER)405 406 407def _set_logger_provider(logger_provider: LoggerProvider, log: bool) -> None:408    def set_lp() -> None:409        global _LOGGER_PROVIDER  # pylint: disable=global-statement410        _LOGGER_PROVIDER = logger_provider411 412    did_set = _LOGGER_PROVIDER_SET_ONCE.do_once(set_lp)413 414    if log and not did_set:415        _logger.warning("Overriding of current LoggerProvider is not allowed")416 417 418def set_logger_provider(logger_provider: LoggerProvider) -> None:419    """Sets the current global :class:`~.LoggerProvider` object.420 421    This can only be done once, a warning will be logged if any further attempt422    is made.423    """424    _set_logger_provider(logger_provider, log=True)425 426 427def get_logger(428    instrumenting_module_name: str,429    instrumenting_library_version: str = "",430    logger_provider: Optional[LoggerProvider] = None,431    schema_url: Optional[str] = None,432    attributes: Optional[_ExtendedAttributes] = None,433) -> Logger:434    """Returns a `Logger` for use within a python process.435 436    This function is a convenience wrapper for437    opentelemetry.sdk._logs.LoggerProvider.get_logger.438 439    If logger_provider param is omitted the current configured one is used.440    """441    if logger_provider is None:442        logger_provider = get_logger_provider()443    return logger_provider.get_logger(444        instrumenting_module_name,445        instrumenting_library_version,446        schema_url,447        attributes,448    )449 
codekingpro/portable-devtools · Team Ai