Skip to content

Commit

Permalink
SNOW-1063081 Bump opentelemetry-python dependencies to 1.23.0 (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-tmonk authored Mar 21, 2024
1 parent 51b5692 commit 01adb2b
Show file tree
Hide file tree
Showing 15 changed files with 435 additions and 209 deletions.
6 changes: 3 additions & 3 deletions anaconda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ requirements:
- setuptools >=40.0.0
run:
- python
- opentelemetry-api ==1.12.0
- opentelemetry-sdk ==1.12.0
- opentelemetry-exporter-otlp ==1.12.0
- opentelemetry-api ==1.23.0
- opentelemetry-exporter-otlp-proto-common ==1.23.0
- opentelemetry-sdk ==1.23.0

about:
home: https://www.snowflake.com/
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
long_description=LONG_DESCRIPTION,
install_requires=[
"setuptools >= 40.0.0, < 66.0.0",
"opentelemetry-api == 1.12.0",
"opentelemetry-exporter-otlp == 1.12.0",
"opentelemetry-sdk == 1.12.0",
"opentelemetry-api == 1.23.0",
"opentelemetry-exporter-otlp-proto-common == 1.23.0",
"opentelemetry-sdk == 1.23.0",
],
packages=find_namespace_packages(
where='src'
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@
import threading
import typing
import opentelemetry.sdk.util.instrumentation as otel_instrumentation
import opentelemetry.sdk._logs._internal as _logs_internal

from opentelemetry.exporter.otlp.proto.common._log_encoder import (
encode_logs,
)
from opentelemetry.proto.logs.v1.logs_pb2 import LogsData
from opentelemetry.sdk import resources
from opentelemetry.sdk._logs import export
from opentelemetry.sdk import _logs
from opentelemetry.util import types
from snowflake.telemetry._internal.encoder.otlp.proto.common.log_encoder import (
_encode_logs,
)


# pylint: disable=too-few-public-methods
Expand Down Expand Up @@ -69,7 +70,7 @@ def _serialize_logs_data(batch: typing.Sequence[_logs.LogData]) -> bytes:
# pylint gets confused by protobuf-generated code, that's why we must
# disable the no-member check below.
return LogsData(
resource_logs=_encode_logs(batch).resource_logs # pylint: disable=no-member
resource_logs=encode_logs(batch).resource_logs # pylint: disable=no-member
).SerializeToString()

def shutdown(self):
Expand All @@ -82,19 +83,18 @@ class SnowflakeLoggingHandler(_logs.LoggingHandler):
discarded by the original implementation.
"""

_FILEPATH_ATTRIBUTE = "code.filepath"
_FUNCTION_NAME_ATTRIBUTE = "code.function"
LOGGER_NAME_TEMP_ATTRIBUTE = "__snow.logging.temp.logger_name"

def __init__(
self,
log_writer: LogWriter,
):
provider = _SnowflakeTelemetryLogEmitterProvider()
_logs.set_log_emitter_provider(provider)
exporter = _ProtoLogExporter(log_writer)
provider.add_log_processor(export.SimpleLogProcessor(exporter))
super().__init__()
provider = _SnowflakeTelemetryLoggerProvider()
provider.add_log_record_processor(
export.SimpleLogRecordProcessor(exporter)
)
super().__init__(logger_provider=provider)

@staticmethod
def _get_snowflake_log_level_name(py_level_name):
Expand All @@ -114,17 +114,11 @@ def _get_snowflake_log_level_name(py_level_name):
def _get_attributes(record: logging.LogRecord) -> types.Attributes:
attributes = _logs.LoggingHandler._get_attributes(record) # pylint: disable=protected-access

# Adding attributes that were discarded by the base class's
# _get_attributes() method
# TODO (SNOW-1210317) Remove these when upgrading to opentelemetry-python 1.23
attributes[SnowflakeLoggingHandler._FILEPATH_ATTRIBUTE] = record.pathname
attributes[SnowflakeLoggingHandler._FUNCTION_NAME_ATTRIBUTE] = record.funcName

# Temporarily storing logger's name in record's attributes.
# This attribute will be removed by the emitter.
# This attribute will be removed by the logger.
#
# TODO(SNOW-1210317): Upgrade to OpenTelemetry 1.20.0 or later
# and use OpenTelemetry's LoggerProvider.
# TODO (SNOW-1235374): opentelemetry-python issue #2485: Record logger
# name as the instrumentation scope name
attributes[SnowflakeLoggingHandler.LOGGER_NAME_TEMP_ATTRIBUTE] = record.name
return attributes

Expand All @@ -136,21 +130,22 @@ def _translate(self, record: logging.LogRecord) -> _logs.LogRecord:
return otel_record


class _SnowflakeTelemetryLogEmitter(_logs.LogEmitter):
class _SnowflakeTelemetryLogger(_logs.Logger):
"""
A log emitter which creates an InstrumentationScope for each logger name it
encounters.
An Open Telemetry Logger which creates an InstrumentationScope for each
logger name it encounters.
"""

def __init__(
self,
resource: resources.Resource,
multi_log_processor: typing.Union[
_logs.SynchronousMultiLogProcessor, _logs.ConcurrentMultiLogProcessor
],
instrumentation_scope: otel_instrumentation.InstrumentationScope,
self,
resource: resources.Resource,
multi_log_record_processor: typing.Union[
_logs_internal.SynchronousMultiLogRecordProcessor,
_logs_internal.ConcurrentMultiLogRecordProcessor,
],
instrumentation_scope: otel_instrumentation.InstrumentationScope,
):
super().__init__(resource, multi_log_processor, instrumentation_scope)
super().__init__(resource, multi_log_record_processor, instrumentation_scope)
self._lock = threading.Lock()
self.cached_scopes = {}

Expand All @@ -175,28 +170,31 @@ def emit(self, record: _logs.LogRecord):

# Emitting a record with a scope that corresponds to the logger
# that logged it. NOT calling the superclass here for two reasons:
# 1. LogEmitter.emit takes a LogRecord, not LogData.
# 1. Logger.emit takes a LogRecord, not LogData.
# 2. It would emit a log record with the default instrumentation scope,
# not with the scope we want.
log_data = _logs.LogData(record, current_scope)
self._multi_log_processor.emit(log_data)
self._multi_log_record_processor.emit(log_data)


class _SnowflakeTelemetryLogEmitterProvider(_logs.LogEmitterProvider):
class _SnowflakeTelemetryLoggerProvider(_logs.LoggerProvider):
"""
A log emitter provider that creates SnowflakeTelemetryLogEmitters
A LoggerProvider that creates SnowflakeTelemetryLoggers
"""

def get_log_emitter(
self,
instrumenting_module_name: str,
instrumenting_module_version: str = "",
) -> _logs.LogEmitter:
return _SnowflakeTelemetryLogEmitter(
def get_logger(
self,
name: str,
version: types.Optional[str] = None,
schema_url: types.Optional[str] = None,
) -> _logs.Logger:
return _SnowflakeTelemetryLogger(
self._resource,
self._multi_log_processor,
self._multi_log_record_processor,
otel_instrumentation.InstrumentationScope(
instrumenting_module_name, instrumenting_module_version
name,
version,
schema_url,
),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
from typing import Dict

import opentelemetry
from opentelemetry.exporter.otlp.proto.common.metrics_encoder import (
encode_metrics,
)
from opentelemetry.proto.metrics.v1.metrics_pb2 import MetricsData as PB2MetricsData
from opentelemetry.sdk.metrics.export import (
AggregationTemporality,
MetricExportResult,
MetricExporter,
MetricsData,
)
from snowflake.telemetry._internal.encoder.otlp.proto.common.metrics_encoder import (
_encode_metrics,
)


# pylint: disable=too-few-public-methods
Expand All @@ -39,7 +39,8 @@ class MetricWriter(abc.ABC):
def write_metrics(self, serialized_metrics: bytes) -> None:
"""
Implement this method to write the serialized protobuf message to your
preferred location.
preferred location. For an example implementation, see
InMemoryMetricWriter in the tests folder.
"""


Expand Down Expand Up @@ -82,7 +83,7 @@ def _serialize_metrics_data(data: MetricsData) -> bytes:
# pylint gets confused by protobuf-generated code, that's why we must
# disable the no-member check below.
return PB2MetricsData(
resource_metrics=_encode_metrics(data).resource_metrics # pylint: disable=no-member
resource_metrics=encode_metrics(data).resource_metrics # pylint: disable=no-member
).SerializeToString()

def force_flush(self, timeout_millis: float = 10_000) -> bool:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
import abc
import typing

from opentelemetry.exporter.otlp.proto.common.trace_encoder import (
encode_spans,
)
from opentelemetry.proto.trace.v1.trace_pb2 import TracesData
from opentelemetry.sdk.trace import ReadableSpan
from opentelemetry.sdk.trace.export import (
SpanExportResult,
SpanExporter,
)
from snowflake.telemetry._internal.encoder.otlp.proto.common.trace_encoder import (
_encode_spans,
)


# pylint: disable=too-few-public-methods
Expand All @@ -37,7 +37,8 @@ class SpanWriter(abc.ABC):
def write_span(self, serialized_spans: bytes) -> None:
"""
Implement this method to write the serialized protobuf message to your
preferred location.
preferred location. For an example implementation, see
InMemorySpanWriter in the tests folder.
"""


Expand Down Expand Up @@ -72,7 +73,7 @@ def _serialize_traces_data(
# pylint gets confused by protobuf-generated code, that's why we must
# disable the no-member check below.
return TracesData(
resource_spans=_encode_spans(sdk_spans).resource_spans # pylint: disable=no-member
resource_spans=encode_spans(sdk_spans).resource_spans # pylint: disable=no-member
).SerializeToString()

def shutdown(self) -> None:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#
# Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved.
#

import typing

from opentelemetry.proto.logs.v1.logs_pb2 import (
LogsData,
)
from snowflake.telemetry._internal.exporter.otlp.proto.logs import (
LogWriter,
)


class InMemoryLogWriter(LogWriter):
"""Implementation of :class:`.LogWriter` that stores protobufs in memory.
This class is intended for testing purposes. It stores the deserialized
protobuf messages in a list in memory that can be retrieved using the
:func:`.get_finished_protos` method.
"""

def __init__(self):
self._protos = []

def write_logs(self, serialized_logs: bytes) -> None:
message = LogsData()
message.ParseFromString(serialized_logs)
self._protos.append(message)

def get_finished_protos(self) -> typing.Tuple[LogsData, ...]:
return tuple(self._protos)

def clear(self):
self._protos.clear()
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#
# Copyright (c) 2012-2024 Snowflake Computing Inc. All rights reserved.
#

import typing

from opentelemetry.proto.metrics.v1.metrics_pb2 import (
MetricsData,
)
from snowflake.telemetry._internal.exporter.otlp.proto.metrics import (
MetricWriter,
)


class InMemoryMetricWriter(MetricWriter):
"""Implementation of :class:`.MetricWriter` that stores protobufs in
memory.
This class is intended for testing purposes. It stores the deserialized
protobuf messages in a list in memory that can be retrieved using the
:func:`.get_finished_protos` method.
"""

def __init__(self):
self._protos = []

def write_metrics(self, serialized_metrics: bytes) -> None:
message = MetricsData()
message.ParseFromString(serialized_metrics)
self._protos.append(message)

def get_finished_protos(self) -> typing.Tuple[MetricsData, ...]:
return tuple(self._protos)

def clear(self):
self._protos.clear()
Loading

0 comments on commit 01adb2b

Please sign in to comment.