Skip to content

Commit 2c64576

Browse files
Set Labeler Max at init
1 parent 27348be commit 2c64576

File tree

2 files changed

+67
-20
lines changed

2 files changed

+67
-20
lines changed

opentelemetry-instrumentation/src/opentelemetry/instrumentation/_labeler/_internal/__init__.py

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,76 @@ class Labeler:
2929
This feature is experimental and unstable.
3030
"""
3131

32-
def __init__(self):
32+
def __init__(
33+
self, max_custom_attrs: int = 20, max_attr_value_length: int = 100
34+
):
35+
"""
36+
Initialize a new Labeler instance.
37+
38+
Args:
39+
max_custom_attrs: Maximum number of custom attributes to store.
40+
When this limit is reached, new attributes will be ignored;
41+
existing attributes can still be updated.
42+
max_attr_value_length: Maximum length for string attribute values.
43+
String values exceeding this length will be truncated.
44+
"""
3345
self._lock = threading.Lock()
3446
self._attributes: Dict[str, Union[str, int, float, bool]] = {}
47+
self._max_custom_attrs = max_custom_attrs
48+
self._max_attr_value_length = max_attr_value_length
3549

3650
def add(self, key: str, value: Union[str, int, float, bool]) -> None:
3751
"""
38-
Add a single attribute to the labeler.
52+
Add a single attribute to the labeler, subject to the labeler's limits:
53+
- If max_custom_attrs limit is reached and this is a new key, the attribute is ignored
54+
- String values exceeding max_attr_value_length are truncated
3955
4056
Args:
41-
key: The attribute key
42-
value: The attribute value (must be a primitive type)
57+
key: attribute key
58+
value: attribute value, must be a primitive type: str, int, float, or bool
4359
"""
4460
with self._lock:
61+
if (
62+
len(self._attributes) >= self._max_custom_attrs
63+
and key not in self._attributes
64+
):
65+
return
66+
67+
if (
68+
isinstance(value, str)
69+
and len(value) > self._max_attr_value_length
70+
):
71+
value = value[: self._max_attr_value_length]
72+
4573
self._attributes[key] = value
4674

4775
def add_attributes(
4876
self, attributes: Dict[str, Union[str, int, float, bool]]
4977
) -> None:
5078
"""
51-
Add multiple attributes to the labeler.
79+
Add multiple attributes to the labeler, subject to the labeler's limits:
80+
- If max_custom_attrs limit is reached and this is a new key, the attribute is ignored
81+
- String values exceeding max_attr_value_length are truncated
5282
5383
Args:
54-
attributes: Dictionary of attributes to add
84+
attributes: Dictionary of attributes to add. Values must be primitive types
85+
(str, int, float, or bool)
5586
"""
5687
with self._lock:
57-
self._attributes.update(attributes)
88+
for key, value in attributes.items():
89+
if (
90+
len(self._attributes) >= self._max_custom_attrs
91+
and key not in self._attributes
92+
):
93+
break
94+
95+
if (
96+
isinstance(value, str)
97+
and len(value) > self._max_attr_value_length
98+
):
99+
value = value[: self._max_attr_value_length]
100+
101+
self._attributes[key] = value
58102

59103
def get_attributes(self) -> Dict[str, Union[str, int, float, bool]]:
60104
"""
@@ -123,21 +167,17 @@ def get_labeler_attributes() -> Dict[str, Union[str, int, float, bool]]:
123167
def enhance_metric_attributes(
124168
base_attributes: Dict[str, Any],
125169
include_custom: bool = True,
126-
max_custom_attrs: int = 20,
127-
max_attr_value_length: int = 100,
128170
) -> Dict[str, Any]:
129171
"""
130172
Combines base_attributes with custom attributes from the current labeler,
131-
returning a new dictionary of attributes. Custom attributes are skipped
132-
if they would override base_attributes, or exceed max_custom_attrs number.
133-
If custom attributes have string values exceeding the max_attr_value_length,
134-
then they are truncated.
173+
returning a new dictionary of attributes according to the labeler configuration:
174+
- Attributes that would override base_attributes are skipped
175+
- If max_custom_attrs limit is reached and this is a new key, the attribute is ignored
176+
- String values exceeding max_attr_value_length are truncated
135177
136178
Args:
137179
base_attributes: The base attributes for the metric
138180
include_custom: Whether to include custom labeler attributes
139-
max_custom_attrs: Maximum number of custom attributes to include
140-
max_attr_value_length: Maximum length for string attribute values
141181
142182
Returns:
143183
Dictionary combining base and custom attributes. If no custom attributes,
@@ -146,21 +186,28 @@ def enhance_metric_attributes(
146186
if not include_custom:
147187
return base_attributes.copy()
148188

149-
custom_attributes = get_labeler_attributes()
189+
labeler = _labeler_context.get()
190+
if labeler is None:
191+
return base_attributes.copy()
192+
193+
custom_attributes = labeler.get_attributes()
150194
if not custom_attributes:
151195
return base_attributes.copy()
152196

153197
enhanced_attributes = base_attributes.copy()
154198

155199
added_count = 0
156200
for key, value in custom_attributes.items():
157-
if added_count >= max_custom_attrs:
201+
if added_count >= labeler._max_custom_attrs:
158202
break
159203
if key in base_attributes:
160204
continue
161205

162-
if isinstance(value, str) and len(value) > max_attr_value_length:
163-
value = value[:max_attr_value_length]
206+
if (
207+
isinstance(value, str)
208+
and len(value) > labeler._max_attr_value_length
209+
):
210+
value = value[: labeler._max_attr_value_length]
164211

165212
enhanced_attributes[key] = value
166213
added_count += 1

opentelemetry-instrumentation/tests/test_labeler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def test_clear_attributes(self):
7777
self.assertEqual(len(labeler), 0)
7878

7979
def test_thread_safety(self):
80-
labeler = Labeler()
80+
labeler = Labeler(max_custom_attrs=1000)
8181
num_threads = 10
8282
num_operations = 100
8383

0 commit comments

Comments
 (0)