Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
6fb98f5
Add support for detecting synthetic source.
JacksonWeber Aug 4, 2025
24537f6
Update CHANGELOG.md
JacksonWeber Aug 4, 2025
10353ad
Update __init__.py
JacksonWeber Aug 4, 2025
8cfb235
Move const values to a constants file.
JacksonWeber Aug 8, 2025
9db1219
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Aug 11, 2025
4703e5f
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Aug 18, 2025
dddba48
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Aug 19, 2025
1385bce
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Aug 22, 2025
2672bd5
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Aug 25, 2025
4ab76d3
use existing sem conv.
JacksonWeber Aug 25, 2025
a64956a
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Aug 29, 2025
401d59d
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 16, 2025
d29cb64
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 17, 2025
11b557e
Move changes to the http package.
JacksonWeber Sep 17, 2025
19be82c
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 17, 2025
a11b69a
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 22, 2025
6e189c1
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 23, 2025
5283de4
Update util/opentelemetry-util-http/tests/test_detect_synthetic_user_…
JacksonWeber Sep 23, 2025
202c6db
Add synthetic detection on the server side.
JacksonWeber Sep 24, 2025
f44f2fb
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 24, 2025
f04f046
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 24, 2025
c112f99
Fix linting.
JacksonWeber Sep 24, 2025
755f41d
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 24, 2025
be71c94
Update test_asgi_middleware.py
JacksonWeber Sep 24, 2025
c1a971f
Update test_asgi_middleware.py
JacksonWeber Sep 24, 2025
46cbd48
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 25, 2025
30a7951
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 29, 2025
e0cbcee
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 30, 2025
a7513f2
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Sep 30, 2025
cf99868
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 1, 2025
9f31267
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 6, 2025
bb14d64
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 7, 2025
68446f2
Update nitpick-exceptions.ini
JacksonWeber Oct 7, 2025
e694bd6
Update conf.py
JacksonWeber Oct 7, 2025
7211314
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 7, 2025
b71132b
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 8, 2025
dacf4ce
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 9, 2025
b6851fb
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 10, 2025
8b113cc
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 13, 2025
125c56f
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 13, 2025
f60ed86
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 15, 2025
bcd7ee0
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 21, 2025
57f6a7b
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Oct 30, 2025
e8543f0
Update based on comments.
JacksonWeber Nov 1, 2025
e29f3f5
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 1, 2025
c20ca80
Update tests.
JacksonWeber Nov 1, 2025
5a6d1dd
Merge branch 'jacksonweber/populate-synthetic-attributes' of https://…
JacksonWeber Nov 1, 2025
f54b9a9
Update __init__.py
JacksonWeber Nov 1, 2025
7e98a95
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 3, 2025
ea31d7b
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 6, 2025
47a0e16
Update __init__.py
JacksonWeber Nov 7, 2025
d891c80
Update __init__.py
JacksonWeber Nov 7, 2025
cd0579e
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 8, 2025
565c6cb
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 10, 2025
0d303c4
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 12, 2025
b27b5ef
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 13, 2025
44cf919
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 14, 2025
667d495
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 19, 2025
4cfe7e5
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 21, 2025
a89c10c
Merge branch 'main' into jacksonweber/populate-synthetic-attributes
JacksonWeber Nov 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use existing sem conv.
  • Loading branch information
JacksonWeber committed Aug 25, 2025
commit 4ab76d333cfe0f898e82e739aab7e5ffc7c2723d
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,17 @@ def response_hook(span, request_obj, response):
TEST_PATTERNS,
)
from opentelemetry.instrumentation.requests.package import _instruments
from opentelemetry.instrumentation.requests.semconv import (
ATTR_USER_AGENT_SYNTHETIC_TYPE,
USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT,
USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST,
)
from opentelemetry.instrumentation.requests.version import __version__
from opentelemetry.instrumentation.utils import (
is_http_instrumentation_enabled,
suppress_http_instrumentation,
)
from opentelemetry.metrics import Histogram, get_meter
from opentelemetry.propagate import inject
from opentelemetry.semconv._incubating.attributes.user_agent_attributes import (
USER_AGENT_SYNTHETIC_TYPE,
UserAgentSyntheticTypeValues,
)
from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE
from opentelemetry.semconv.attributes.network_attributes import (
NETWORK_PEER_ADDRESS,
Expand Down Expand Up @@ -175,8 +174,8 @@ def _detect_synthetic_user_agent(user_agent: str) -> Optional[str]:
user_agent: The user agent string to analyze

Returns:
USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST if user agent contains any pattern from TEST_PATTERNS
USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT if user agent contains any pattern from BOT_PATTERNS
UserAgentSyntheticTypeValues.TEST if user agent contains any pattern from TEST_PATTERNS
UserAgentSyntheticTypeValues.BOT if user agent contains any pattern from BOT_PATTERNS
None otherwise

Note: Test patterns take priority over bot patterns.
Expand All @@ -187,9 +186,9 @@ def _detect_synthetic_user_agent(user_agent: str) -> Optional[str]:
user_agent_lower = user_agent.lower()

if any(test_pattern in user_agent_lower for test_pattern in TEST_PATTERNS):
return USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST
return UserAgentSyntheticTypeValues.TEST.value
if any(bot_pattern in user_agent_lower for bot_pattern in BOT_PATTERNS):
return USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT
return UserAgentSyntheticTypeValues.BOT.value

return None

Expand Down Expand Up @@ -286,7 +285,7 @@ def get_or_create_headers():
user_agent = headers.get("User-Agent")
synthetic_type = _detect_synthetic_user_agent(user_agent)
if synthetic_type:
span_attributes[ATTR_USER_AGENT_SYNTHETIC_TYPE] = synthetic_type
span_attributes[USER_AGENT_SYNTHETIC_TYPE] = synthetic_type

metric_labels = {}
_set_http_method(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@
import requests

from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.instrumentation.requests.semconv import (
ATTR_USER_AGENT_SYNTHETIC_TYPE,
USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT,
USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST,
from opentelemetry.semconv._incubating.attributes.user_agent_attributes import (
USER_AGENT_SYNTHETIC_TYPE,
UserAgentSyntheticTypeValues,
)
from opentelemetry.test.test_base import TestBase

Expand Down Expand Up @@ -56,8 +55,8 @@ def test_user_agent_bot_googlebot(self):

span = self.assert_span()
self.assertEqual(
span.attributes.get(ATTR_USER_AGENT_SYNTHETIC_TYPE),
USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT,
span.attributes.get(USER_AGENT_SYNTHETIC_TYPE),
UserAgentSyntheticTypeValues.BOT.value,
)

def test_user_agent_bot_bingbot(self):
Expand All @@ -69,8 +68,8 @@ def test_user_agent_bot_bingbot(self):

span = self.assert_span()
self.assertEqual(
span.attributes.get(ATTR_USER_AGENT_SYNTHETIC_TYPE),
USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT,
span.attributes.get(USER_AGENT_SYNTHETIC_TYPE),
UserAgentSyntheticTypeValues.BOT.value,
)

def test_user_agent_test_alwayson(self):
Expand All @@ -80,8 +79,8 @@ def test_user_agent_test_alwayson(self):

span = self.assert_span()
self.assertEqual(
span.attributes.get(ATTR_USER_AGENT_SYNTHETIC_TYPE),
USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST,
span.attributes.get(USER_AGENT_SYNTHETIC_TYPE),
UserAgentSyntheticTypeValues.TEST.value,
)

def test_user_agent_case_insensitive(self):
Expand All @@ -91,8 +90,8 @@ def test_user_agent_case_insensitive(self):

span = self.assert_span()
self.assertEqual(
span.attributes.get(ATTR_USER_AGENT_SYNTHETIC_TYPE),
USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT,
span.attributes.get(USER_AGENT_SYNTHETIC_TYPE),
UserAgentSyntheticTypeValues.BOT.value,
)

self.memory_exporter.clear()
Expand All @@ -102,8 +101,8 @@ def test_user_agent_case_insensitive(self):

span = self.assert_span()
self.assertEqual(
span.attributes.get(ATTR_USER_AGENT_SYNTHETIC_TYPE),
USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST,
span.attributes.get(USER_AGENT_SYNTHETIC_TYPE),
UserAgentSyntheticTypeValues.TEST.value,
)

def test_user_agent_normal_browser(self):
Expand All @@ -114,22 +113,22 @@ def test_user_agent_normal_browser(self):
requests.get(self.URL, headers=headers, timeout=5)

span = self.assert_span()
self.assertNotIn(ATTR_USER_AGENT_SYNTHETIC_TYPE, span.attributes)
self.assertNotIn(USER_AGENT_SYNTHETIC_TYPE, span.attributes)

def test_no_user_agent_header(self):
"""Test that requests without user agent don't get synthetic type"""
requests.get(self.URL, timeout=5)

span = self.assert_span()
self.assertNotIn(ATTR_USER_AGENT_SYNTHETIC_TYPE, span.attributes)
self.assertNotIn(USER_AGENT_SYNTHETIC_TYPE, span.attributes)

def test_empty_user_agent_header(self):
"""Test that empty user agent doesn't get synthetic type"""
headers = {"User-Agent": ""}
requests.get(self.URL, headers=headers, timeout=5)

span = self.assert_span()
self.assertNotIn(ATTR_USER_AGENT_SYNTHETIC_TYPE, span.attributes)
self.assertNotIn(USER_AGENT_SYNTHETIC_TYPE, span.attributes)

def test_user_agent_substring_match(self):
"""Test that substrings are detected correctly"""
Expand All @@ -139,8 +138,8 @@ def test_user_agent_substring_match(self):

span = self.assert_span()
self.assertEqual(
span.attributes.get(ATTR_USER_AGENT_SYNTHETIC_TYPE),
USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT,
span.attributes.get(USER_AGENT_SYNTHETIC_TYPE),
UserAgentSyntheticTypeValues.BOT.value,
)

self.memory_exporter.clear()
Expand All @@ -151,8 +150,8 @@ def test_user_agent_substring_match(self):

span = self.assert_span()
self.assertEqual(
span.attributes.get(ATTR_USER_AGENT_SYNTHETIC_TYPE),
USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST,
span.attributes.get(USER_AGENT_SYNTHETIC_TYPE),
UserAgentSyntheticTypeValues.TEST.value,
)

def test_user_agent_priority_alwayson_over_bot(self):
Expand All @@ -163,6 +162,6 @@ def test_user_agent_priority_alwayson_over_bot(self):
span = self.assert_span()
# alwayson should be checked first and return 'test'
self.assertEqual(
span.attributes.get(ATTR_USER_AGENT_SYNTHETIC_TYPE),
USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST,
span.attributes.get(USER_AGENT_SYNTHETIC_TYPE),
UserAgentSyntheticTypeValues.TEST.value,
)