Skip to content

Commit

Permalink
[SVLS-5262] log warnings in standard hashing function instead of thro…
Browse files Browse the repository at this point in the history
…wing an exception
  • Loading branch information
apiarian-datadog committed Sep 19, 2024
1 parent 12bcb72 commit 8c78bcd
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 8 deletions.
36 changes: 32 additions & 4 deletions ddtrace/_trace/_span_pointer.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from enum import Enum
from hashlib import sha256
import random
from typing import Any
from typing import Dict
from typing import NamedTuple
from typing import Optional

from ddtrace._trace._span_link import SpanLink
from ddtrace._trace._span_link import SpanLinkKind
from ddtrace.internal.logger import get_logger


log = get_logger(__name__)


_SPAN_POINTER_SPAN_LINK_TRACE_ID = 0
Expand Down Expand Up @@ -56,9 +61,32 @@ def __post_init__(self):
pass


_STANDARD_HASHING_FUNCTION_FAILURE_PREFIX = "HashingFailure"


def _standard_hashing_function(*elements: bytes) -> str:
if not elements:
raise ValueError("elements must not be empty")
try:
if not elements:
raise ValueError("elements must not be empty")

# Please see the tests for more details about this logic.
return sha256(b"|".join(elements)).hexdigest()[:32]

except Exception as e:
log.warning(
"failed to generate standard hash for span pointer: %s",
str(e),
)
return _add_random_suffix(
prefix=_STANDARD_HASHING_FUNCTION_FAILURE_PREFIX,
minimum_length=32,
)


def _add_random_suffix(*, prefix: str, minimum_length: int) -> str:
if len(prefix) >= minimum_length:
return prefix

suffix = "".join(random.choice("0123456789abcdef") for _ in range(minimum_length - len(prefix)))

# Please see the tests for more details about this logic.
return sha256(b"|".join(elements)).hexdigest()[:32]
return prefix + suffix
8 changes: 4 additions & 4 deletions tests/tracer/test_span_pointers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest

from ddtrace._trace._span_pointer import _STANDARD_HASHING_FUNCTION_FAILURE_PREFIX
from ddtrace._trace._span_pointer import _standard_hashing_function


Expand Down Expand Up @@ -44,6 +45,7 @@ def test_validate_hash_size(self) -> None:
expected_hex_digits = desired_bits // bits_per_hex_digit

assert len(_standard_hashing_function(b"foo")) == expected_hex_digits
assert len(_standard_hashing_function("bad-input")) == expected_hex_digits

def test_validate_using_sha256_with_pipe_separator(self) -> None:
# We want this test to break if we change the logic of the standard
Expand All @@ -59,9 +61,7 @@ def test_validate_using_sha256_with_pipe_separator(self) -> None:
assert _standard_hashing_function(b"foo", b"bar") == sha256(b"foo|bar").hexdigest()[:hex_digits]

def test_hashing_requries_arguments(self) -> None:
with pytest.raises(ValueError, match="elements must not be empty"):
_standard_hashing_function()
assert _standard_hashing_function().startswith(_STANDARD_HASHING_FUNCTION_FAILURE_PREFIX)

def test_hashing_requires_bytes(self) -> None:
with pytest.raises(TypeError, match="expected a bytes-like object"):
_standard_hashing_function("foo")
assert _standard_hashing_function("foo").startswith(_STANDARD_HASHING_FUNCTION_FAILURE_PREFIX)

0 comments on commit 8c78bcd

Please sign in to comment.