Skip to content

Commit 242afd5

Browse files
committed
Replace ConcurrentHashMap with AtomicLongArray for raspErrorCodeCounter to improve performance and memory efficiency
1 parent bced00d commit 242afd5

File tree

2 files changed

+27
-27
lines changed

2 files changed

+27
-27
lines changed

internal-api/src/main/java/datadog/trace/api/telemetry/WafMetricCollector.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
import java.util.Map;
99
import java.util.concurrent.ArrayBlockingQueue;
1010
import java.util.concurrent.BlockingQueue;
11-
import java.util.concurrent.ConcurrentMap;
12-
import java.util.concurrent.ConcurrentSkipListMap;
1311
import java.util.concurrent.atomic.AtomicInteger;
1412
import java.util.concurrent.atomic.AtomicLong;
1513
import java.util.concurrent.atomic.AtomicLongArray;
@@ -53,8 +51,8 @@ private WafMetricCollector() {
5351
new AtomicLongArray(RuleType.getNumValues());
5452
private static final AtomicLongArray raspTimeoutCounter =
5553
new AtomicLongArray(RuleType.getNumValues());
56-
private static final ConcurrentMap<Integer, AtomicLongArray> raspErrorCodeCounter =
57-
new ConcurrentSkipListMap<>();
54+
private static final AtomicLongArray raspErrorCodeCounter =
55+
new AtomicLongArray(WafErrorCode.values().length * RuleType.getNumValues());
5856
private static final AtomicLongArray wafErrorCodeCounter =
5957
new AtomicLongArray(WafErrorCode.values().length);
6058
private static final AtomicLongArray missingUserLoginQueue =
@@ -143,10 +141,14 @@ public void raspTimeout(final RuleType ruleType) {
143141
raspTimeoutCounter.incrementAndGet(ruleType.ordinal());
144142
}
145143

146-
public void raspErrorCode(final RuleType ruleType, final int errorCode) {
147-
raspErrorCodeCounter
148-
.computeIfAbsent(errorCode, code -> new AtomicLongArray(RuleType.getNumValues()))
149-
.incrementAndGet(ruleType.ordinal());
144+
public void raspErrorCode(RuleType ruleType, final int errorCode) {
145+
WafErrorCode wafErrorCode = WafErrorCode.fromCode(errorCode);
146+
// Unsupported waf error code
147+
if (wafErrorCode == null) {
148+
return;
149+
}
150+
int index = wafErrorCode.ordinal() * RuleType.getNumValues() + ruleType.ordinal();
151+
raspErrorCodeCounter.incrementAndGet(index);
150152
}
151153

152154
public void wafErrorCode(final int errorCode) {
@@ -319,15 +321,13 @@ public void prepareMetrics() {
319321
}
320322

321323
// RASP rule type for each possible error code
322-
for (Map.Entry<Integer, AtomicLongArray> entry : raspErrorCodeCounter.entrySet()) {
323-
int errorCode = entry.getKey();
324-
AtomicLongArray counters = entry.getValue();
325-
324+
for (WafErrorCode errorCode : WafErrorCode.values()) {
326325
for (RuleType ruleType : RuleType.values()) {
327-
long count = counters.getAndSet(ruleType.ordinal(), 0);
326+
int index = errorCode.ordinal() * RuleType.getNumValues() + ruleType.ordinal();
327+
long count = raspErrorCodeCounter.getAndSet(index, 0);
328328
if (count > 0) {
329329
if (!rawMetricsQueue.offer(
330-
new RaspError(count, ruleType, WafMetricCollector.wafVersion, errorCode))) {
330+
new RaspError(count, ruleType, WafMetricCollector.wafVersion, errorCode.getCode()))) {
331331
return;
332332
}
333333
}

internal-api/src/test/groovy/datadog/trace/api/telemetry/WafMetricCollectorTest.groovy

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,19 @@ class WafMetricCollectorTest extends DDSpecification {
182182
raspTimeout.metricName == 'rasp.timeout'
183183
raspTimeout.tags.toSet() == ['rule_type:sql_injection', 'waf_version:waf_ver1'].toSet()
184184

185-
def raspInvalidCode = (WafMetricCollector.RaspError) metrics[11]
185+
def raspInvalidObjectCode = (WafMetricCollector.RaspError)metrics[11]
186+
raspInvalidObjectCode.type == 'count'
187+
raspInvalidObjectCode.value == 1
188+
raspInvalidObjectCode.namespace == 'appsec'
189+
raspInvalidObjectCode.metricName == 'rasp.error'
190+
raspInvalidObjectCode.tags.toSet() == [
191+
'rule_type:sql_injection',
192+
'waf_version:waf_ver1',
193+
'waf_error:' + DD_WAF_RUN_INVALID_OBJECT_ERROR
194+
]
195+
.toSet()
196+
197+
def raspInvalidCode = (WafMetricCollector.RaspError)metrics[12]
186198
raspInvalidCode.type == 'count'
187199
raspInvalidCode.value == 1
188200
raspInvalidCode.namespace == 'appsec'
@@ -195,18 +207,6 @@ class WafMetricCollectorTest extends DDSpecification {
195207
'waf_error:' + DD_WAF_RUN_INTERNAL_ERROR
196208
].toSet()
197209

198-
def raspInvalidObjectCode = (WafMetricCollector.RaspError)metrics[12]
199-
raspInvalidObjectCode.type == 'count'
200-
raspInvalidObjectCode.value == 1
201-
raspInvalidObjectCode.namespace == 'appsec'
202-
raspInvalidObjectCode.metricName == 'rasp.error'
203-
raspInvalidObjectCode.tags.toSet() == [
204-
'rule_type:sql_injection',
205-
'waf_version:waf_ver1',
206-
'waf_error:' + DD_WAF_RUN_INVALID_OBJECT_ERROR
207-
]
208-
.toSet()
209-
210210
def wafInvalidCode = (WafMetricCollector.WafError)metrics[13]
211211
wafInvalidCode.type == 'count'
212212
wafInvalidCode.value == 1

0 commit comments

Comments
 (0)