From 0417141a703b2d6f3c9b6afa5b18db5bb59fbaa3 Mon Sep 17 00:00:00 2001 From: danielwiltshire <35703524+danwiltshire@users.noreply.github.com> Date: Sat, 25 Feb 2023 01:27:31 +0000 Subject: [PATCH] Add support for enabling Redis sanitization from environment variable (#1690) * Add support for enabling Redis sanitization from environment variable * add sanitization environment variable docs * strip environment variable * update changelog * lint * lint * lint - hopefully the last time --------- Co-authored-by: Srikanth Chekuri --- CHANGELOG.md | 2 ++ .../instrumentation/redis/__init__.py | 30 ++++++++++++++++++- .../redis/environment_variables.py | 17 +++++++++++ .../tests/test_redis.py | 26 ++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/environment_variables.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c34019d18..ccb1a6626f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add connection attributes to sqlalchemy connect span ([#1608](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1608)) +- Add support for enabling Redis sanitization from environment variable + ([#1690](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1690)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py index 0f18639bd2..c1068bda27 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/__init__.py @@ -88,10 +88,27 @@ def response_hook(span, instance, response): client = redis.StrictRedis(host="localhost", port=6379) client.get("my-key") +Configuration +------------- + +Query sanitization +****************** +To enable query sanitization with an environment variable, set +``OTEL_PYTHON_INSTRUMENTATION_SANITIZE_REDIS`` to "true". + +For example, + +:: + + export OTEL_PYTHON_INSTRUMENTATION_SANITIZE_REDIS="true" + +will result in traced queries like "SET ? ?". + API --- """ import typing +from os import environ from typing import Any, Collection import redis @@ -99,6 +116,9 @@ def response_hook(span, instance, response): from opentelemetry import trace from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.instrumentation.redis.environment_variables import ( + OTEL_PYTHON_INSTRUMENTATION_SANITIZE_REDIS, +) from opentelemetry.instrumentation.redis.package import _instruments from opentelemetry.instrumentation.redis.util import ( _extract_conn_attributes, @@ -287,7 +307,15 @@ def _instrument(self, **kwargs): tracer, request_hook=kwargs.get("request_hook"), response_hook=kwargs.get("response_hook"), - sanitize_query=kwargs.get("sanitize_query", False), + sanitize_query=kwargs.get( + "sanitize_query", + environ.get( + OTEL_PYTHON_INSTRUMENTATION_SANITIZE_REDIS, "false" + ) + .lower() + .strip() + == "true", + ), ) def _uninstrument(self, **kwargs): diff --git a/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/environment_variables.py b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/environment_variables.py new file mode 100644 index 0000000000..750b97445e --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-redis/src/opentelemetry/instrumentation/redis/environment_variables.py @@ -0,0 +1,17 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +OTEL_PYTHON_INSTRUMENTATION_SANITIZE_REDIS = ( + "OTEL_PYTHON_INSTRUMENTATION_SANITIZE_REDIS" +) diff --git a/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py b/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py index 1c64fcb13e..56a0df6a0a 100644 --- a/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py +++ b/instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py @@ -168,6 +168,32 @@ def test_query_sanitizer_enabled(self): span = spans[0] self.assertEqual(span.attributes.get("db.statement"), "SET ? ?") + def test_query_sanitizer_enabled_env(self): + redis_client = redis.Redis() + connection = redis.connection.Connection() + redis_client.connection = connection + + RedisInstrumentor().uninstrument() + + env_patch = mock.patch.dict( + "os.environ", + {"OTEL_PYTHON_INSTRUMENTATION_SANITIZE_REDIS": "true"}, + ) + env_patch.start() + RedisInstrumentor().instrument( + tracer_provider=self.tracer_provider, + ) + + with mock.patch.object(redis_client, "connection"): + redis_client.set("key", "value") + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + + span = spans[0] + self.assertEqual(span.attributes.get("db.statement"), "SET ? ?") + env_patch.stop() + def test_query_sanitizer_disabled(self): redis_client = redis.Redis() connection = redis.connection.Connection()