From b2b753a67fd7bf3bc6dcf3c8c8d3cab2f83c03df Mon Sep 17 00:00:00 2001 From: Judah Rand <17158624+judahrand@users.noreply.github.com> Date: Sat, 15 Jun 2024 15:44:08 +0100 Subject: [PATCH 1/2] feat(monitoring): support GRPC LogExporter --- src/bentoml/_internal/monitoring/otlp.py | 32 ++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/bentoml/_internal/monitoring/otlp.py b/src/bentoml/_internal/monitoring/otlp.py index 4db36836c18..4ca501bd1c0 100644 --- a/src/bentoml/_internal/monitoring/otlp.py +++ b/src/bentoml/_internal/monitoring/otlp.py @@ -27,7 +27,12 @@ from .base import MonitorBase try: - from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter + from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( + OTLPLogExporter as OTLPGrpcLogExporter, + ) + from opentelemetry.exporter.otlp.proto.http._log_exporter import ( + OTLPLogExporter as OTLPHttpLogExporter, + ) except ImportError: raise MissingDependencyException( "'opentelemetry-exporter-otlp' is required to use OTLP exporter. Make sure to install it with 'pip install \"bentoml[monitor-otlp]\"" @@ -106,6 +111,7 @@ def __init__( timeout: int | str | None = None, compression: str | None = None, meta_sample_rate: float = 1.0, + protocol: t.Literal["http", "grpc"] = "http", **_: t.Any, ) -> None: """ @@ -119,6 +125,7 @@ def __init__( headers: The headers to use. timeout: The timeout to use. compression: The compression to use. + protocol: The protocol to use. """ super().__init__(name, **_) @@ -135,6 +142,8 @@ def __init__( self._schema: dict[str, dict[str, str]] = {} self._will_export_schema = False + self.protocol = protocol + def _init_logger(self) -> None: from opentelemetry.sdk.resources import SERVICE_INSTANCE_ID from opentelemetry.sdk.resources import SERVICE_NAME @@ -169,7 +178,26 @@ def _init_logger(self) -> None: if self.compression is not None: os.environ[OTEL_EXPORTER_OTLP_COMPRESSION] = self.compression - exporter = OTLPLogExporter() + exporter: OTLPHttpLogExporter | OTLPGrpcLogExporter + if self.protocol == "http": + exporter = OTLPHttpLogExporter( + endpoint=self.endpoint, + headers=self.headers, + timeout=self.timeout, + compression=self.compression, + ) + elif self.protocol == "grpc": + exporter = OTLPGrpcLogExporter( + endpoint=self.endpoint, + insecure=self.insecure, + credentials=self.credentials, + headers=self.headers, + timeout=self.timeout, + compression=self.compression, + ) + else: + raise ValueError(f"Invalid protocol: {self.protocol}") + self.logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter)) handler = LoggingHandler( level=logging.NOTSET, logger_provider=self.logger_provider From 1f14094075ae4baf6a747db64af7f30036ffa17d Mon Sep 17 00:00:00 2001 From: Judah Rand <17158624+judahrand@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:39:12 +0100 Subject: [PATCH 2/2] fix(monitoring): don't override user set environment variables --- src/bentoml/_internal/monitoring/otlp.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/bentoml/_internal/monitoring/otlp.py b/src/bentoml/_internal/monitoring/otlp.py index 4ca501bd1c0..328da1f4fa9 100644 --- a/src/bentoml/_internal/monitoring/otlp.py +++ b/src/bentoml/_internal/monitoring/otlp.py @@ -4,7 +4,6 @@ import datetime import logging import logging.config -import os import random import typing as t @@ -13,12 +12,6 @@ from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk._logs import LoggingHandler from opentelemetry.sdk._logs.export import BatchLogRecordProcessor -from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_CERTIFICATE -from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_COMPRESSION -from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_ENDPOINT -from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_HEADERS -from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_INSECURE -from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_TIMEOUT from opentelemetry.sdk.resources import Resource from ...exceptions import MissingDependencyException @@ -165,19 +158,6 @@ def _init_logger(self) -> None: ) set_logger_provider(self.logger_provider) - if self.endpoint is not None: - os.environ[OTEL_EXPORTER_OTLP_ENDPOINT] = self.endpoint - if self.insecure is not None: - os.environ[OTEL_EXPORTER_OTLP_INSECURE] = str(self.insecure) - if self.credentials is not None: - os.environ[OTEL_EXPORTER_OTLP_CERTIFICATE] = self.credentials - if self.headers is not None: - os.environ[OTEL_EXPORTER_OTLP_HEADERS] = self.headers - if self.timeout is not None: - os.environ[OTEL_EXPORTER_OTLP_TIMEOUT] = str(self.timeout) - if self.compression is not None: - os.environ[OTEL_EXPORTER_OTLP_COMPRESSION] = self.compression - exporter: OTLPHttpLogExporter | OTLPGrpcLogExporter if self.protocol == "http": exporter = OTLPHttpLogExporter(