Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

Commit e28afdd

Browse files
committed
Switch to UsageSetCounter
1 parent ffd599c commit e28afdd

File tree

2 files changed

+1
-82
lines changed

2 files changed

+1
-82
lines changed

localstack-core/localstack/utils/analytics/usage.py

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import datetime
22
import math
3-
import threading
43
from collections import defaultdict
54
from itertools import count
65
from typing import Any
@@ -50,66 +49,6 @@ def aggregate(self) -> dict:
5049
return self.state
5150

5251

53-
class UsageMultiSetCounter:
54-
"""
55-
Use this counter to count occurrences of unique values for multiple dimensions.
56-
This dynamically creates UsageSetCounters and should be used with care (i.e., with limited keys).
57-
58-
Example:
59-
60-
my_feature_counter = UsageMultiSetCounter("pipes:invocation")
61-
my_feature_counter.record("aws:sqs", "aws:lambda")
62-
my_feature_counter.record("aws:sqs", "aws:lambda")
63-
my_feature_counter.record("aws:sqs", "aws:stepfunctions")
64-
my_feature_counter.record("aws:kinesis", "aws:lambda")
65-
aggregate is implemented for each counter individually
66-
67-
my_feature_counter.aggregate() is available for testing purposes:
68-
{
69-
"aws:sqs": {
70-
"aws:lambda": 2,
71-
"aws:stepfunctions": 1,
72-
},
73-
"aws:kinesis": {
74-
"aws:lambda": 1
75-
}
76-
}
77-
"""
78-
79-
namespace: str
80-
_counters: dict[str, UsageSetCounter]
81-
lock = threading.Lock()
82-
83-
def __init__(self, namespace: str):
84-
self._counters = {}
85-
self.namespace = namespace
86-
87-
def record(self, key: str, value: str):
88-
namespace = f"{self.namespace}:{key}"
89-
if namespace in self._counters:
90-
set_counter = self._counters[namespace]
91-
else:
92-
with self.lock:
93-
if namespace in self._counters:
94-
set_counter = self._counters[namespace]
95-
else:
96-
# We cannot use setdefault here because Python always instantiates a new UsageSetCounter,
97-
# which overwrites the collector_registry
98-
set_counter = UsageSetCounter(namespace)
99-
self._counters[namespace] = set_counter
100-
101-
self._counters[namespace] = set_counter
102-
set_counter.record(value)
103-
104-
def aggregate(self) -> dict:
105-
"""aggregate is invoked on a per UsageSetCounter level because each counter is registered individually.
106-
This utility is only for testing!"""
107-
merged_dict = {}
108-
for namespace, counter in self._counters.items():
109-
merged_dict[namespace] = counter.aggregate()
110-
return merged_dict
111-
112-
11352
class UsageCounter:
11453
"""
11554
Use this counter to count numeric values
Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from localstack.utils.analytics.usage import UsageMultiSetCounter, UsageSetCounter
1+
from localstack.utils.analytics.usage import UsageSetCounter
22

33

44
def test_set_counter():
@@ -7,23 +7,3 @@ def test_set_counter():
77
my_feature_counter.record("nodejs16.x")
88
my_feature_counter.record("nodejs16.x")
99
assert my_feature_counter.aggregate() == {"python3.7": 1, "nodejs16.x": 2}
10-
11-
12-
def test_multi_set_counter():
13-
my_feature_counter = UsageMultiSetCounter("pipes:invocation")
14-
my_feature_counter.record("aws:sqs", "aws:lambda")
15-
my_feature_counter.record("aws:sqs", "aws:lambda")
16-
my_feature_counter.record("aws:sqs", "aws:stepfunctions")
17-
my_feature_counter.record("aws:kinesis", "aws:lambda")
18-
assert my_feature_counter.aggregate() == {
19-
"pipes:invocation:aws:sqs": {
20-
"aws:lambda": 2,
21-
"aws:stepfunctions": 1,
22-
},
23-
"pipes:invocation:aws:kinesis": {"aws:lambda": 1},
24-
}
25-
assert my_feature_counter._counters["pipes:invocation:aws:sqs"].state == {
26-
"aws:lambda": 2,
27-
"aws:stepfunctions": 1,
28-
}
29-
assert my_feature_counter._counters["pipes:invocation:aws:kinesis"].state == {"aws:lambda": 1}

0 commit comments

Comments
 (0)