From f050819a659cdb378ed5a73ff49eac9efccabfb0 Mon Sep 17 00:00:00 2001 From: Wilbert Guo Date: Mon, 2 Nov 2020 19:14:35 -0800 Subject: [PATCH] [Issue #1107] Add gzip compression support for OTLP exporter (#1141) Co-authored-by: Aaron Abbott Co-authored-by: Leighton Chen --- .../opentelemetry-exporter-otlp/CHANGELOG.md | 2 + .../opentelemetry/exporter/otlp/__init__.py | 10 +++++ .../opentelemetry/exporter/otlp/exporter.py | 42 +++++++++++++++++-- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md index c67b9e997e..4233ddded0 100644 --- a/exporter/opentelemetry-exporter-otlp/CHANGELOG.md +++ b/exporter/opentelemetry-exporter-otlp/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Add Gzip compression for exporter + ([#1141](https://github.com/open-telemetry/opentelemetry-python/pull/1141)) ## Version 0.15b0 Released 2020-11-02 diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py index a4d8f46d4c..3aca014eda 100644 --- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py +++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py @@ -26,6 +26,16 @@ .. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/ .. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ +.. envvar:: OTEL_EXPORTER_OTLP_COMPRESSION + +The :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` environment variable allows a +compression algorithm to be passed to the OTLP exporter. The compression +algorithms that are supported include gzip and no compression. The value should +be in the format of a string "gzip" for gzip compression, and no value specified +if no compression is the desired choice. +Additional details are available `in the specification +`_. + .. code:: python from opentelemetry import trace diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py index 9595c35f64..8a569e79b1 100644 --- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py +++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/exporter.py @@ -14,19 +14,20 @@ """OTLP Exporter""" +import enum import logging -import os from abc import ABC, abstractmethod from collections.abc import Mapping, Sequence from time import sleep from typing import Any, Callable, Dict, Generic, List, Optional from typing import Sequence as TypingSequence -from typing import Text, Tuple, TypeVar +from typing import Text, TypeVar from backoff import expo from google.rpc.error_details_pb2 import RetryInfo from grpc import ( ChannelCredentials, + Compression, RpcError, StatusCode, insecure_channel, @@ -47,6 +48,10 @@ ExportResultT = TypeVar("ExportResultT") +class OTLPCompression(enum.Enum): + gzip = "gzip" + + def _translate_key_values(key: Text, value: Any) -> KeyValue: if isinstance(value, bool): @@ -137,6 +142,7 @@ class OTLPExporterMixin( insecure: Connection type credentials: ChannelCredentials object for server authentication metadata: Metadata to send when exporting + compression: Compression algorithm to be used in channel timeout: Backend request timeout in seconds """ @@ -147,6 +153,7 @@ def __init__( credentials: Optional[ChannelCredentials] = None, headers: Optional[str] = None, timeout: Optional[int] = None, + compression: str = None, ): super().__init__() @@ -169,13 +176,40 @@ def __init__( ) self._collector_span_kwargs = None + if compression is None: + compression_algorithm = Compression.NoCompression + elif ( + compression in OTLPCompression._value2member_map_ + and OTLPCompression(compression) is OTLPCompression.gzip + ): + compression_algorithm = Compression.Gzip + else: + compression_str = Configuration().EXPORTER_OTLP_INSECURE or None + if compression_str is None: + compression_algorithm = Compression.NoCompression + elif ( + compression_str in OTLPCompression._value2member_map_ + and OTLPCompression(compression_str) is OTLPCompression.gzip + ): + compression_algorithm = Compression.Gzip + else: + raise ValueError( + "OTEL_EXPORTER_OTLP_COMPRESSION environment variable does not match gzip." + ) + if insecure: - self._client = self._stub(insecure_channel(endpoint)) + self._client = self._stub( + insecure_channel(endpoint, compression=compression_algorithm) + ) else: credentials = credentials or _load_credential_from_file( Configuration().EXPORTER_OTLP_CERTIFICATE ) - self._client = self._stub(secure_channel(endpoint, credentials)) + self._client = self._stub( + secure_channel( + endpoint, credentials, compression=compression_algorithm + ) + ) @abstractmethod def _translate_data(