Skip to content

Commit 41779c2

Browse files
committed
Add waf_error tag to appsec.waf.requests metric
1 parent b74cc24 commit 41779c2

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

dd-java-agent/appsec/src/main/java/com/datadog/appsec/powerwaf/PowerWAFModule.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ public void onDataAvailable(
448448
if (!reqCtx.isAdditiveClosed()) {
449449
log.error("Error calling WAF", e);
450450
}
451+
WafMetricCollector.get().wafRequestError();
451452
return;
452453
} finally {
453454
if (log.isDebugEnabled()) {

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ private WafMetricCollector() {
3434
private static final AtomicRequestCounter wafTriggeredRequestCounter = new AtomicRequestCounter();
3535
private static final AtomicRequestCounter wafBlockedRequestCounter = new AtomicRequestCounter();
3636
private static final AtomicRequestCounter wafTimeoutRequestCounter = new AtomicRequestCounter();
37+
private static final AtomicRequestCounter wafErrorRequestCounter = new AtomicRequestCounter();
3738
private static final AtomicLongArray raspRuleEvalCounter =
3839
new AtomicLongArray(RuleType.getNumValues());
3940
private static final AtomicLongArray raspRuleMatchCounter =
@@ -92,6 +93,10 @@ public void wafRequestTimeout() {
9293
wafTimeoutRequestCounter.increment();
9394
}
9495

96+
public void wafRequestError() {
97+
wafErrorRequestCounter.increment();
98+
}
99+
95100
public void raspRuleEval(final RuleType ruleType) {
96101
raspRuleEvalCounter.incrementAndGet(ruleType.ordinal());
97102
}
@@ -136,6 +141,7 @@ public void prepareMetrics() {
136141
WafMetricCollector.rulesVersion,
137142
false,
138143
false,
144+
false,
139145
false))) {
140146
return;
141147
}
@@ -150,6 +156,7 @@ public void prepareMetrics() {
150156
WafMetricCollector.rulesVersion,
151157
true,
152158
false,
159+
false,
153160
false))) {
154161
return;
155162
}
@@ -164,6 +171,7 @@ public void prepareMetrics() {
164171
WafMetricCollector.rulesVersion,
165172
true,
166173
true,
174+
false,
167175
false))) {
168176
return;
169177
}
@@ -178,11 +186,27 @@ public void prepareMetrics() {
178186
WafMetricCollector.rulesVersion,
179187
false,
180188
false,
189+
false,
181190
true))) {
182191
return;
183192
}
184193
}
185194

195+
// WAF error requests
196+
if (wafErrorRequestCounter.get() > 0) {
197+
if (!rawMetricsQueue.offer(
198+
new WafRequestsRawMetric(
199+
wafErrorRequestCounter.getAndReset(),
200+
WafMetricCollector.wafVersion,
201+
WafMetricCollector.rulesVersion,
202+
false,
203+
false,
204+
true,
205+
false))) {
206+
return;
207+
}
208+
}
209+
186210
// RASP rule eval per rule type
187211
for (RuleType ruleType : RuleType.values()) {
188212
long counter = raspRuleEvalCounter.getAndSet(ruleType.ordinal(), 0);
@@ -307,6 +331,7 @@ public WafRequestsRawMetric(
307331
final String rulesVersion,
308332
final boolean triggered,
309333
final boolean blocked,
334+
final boolean wafError,
310335
final boolean wafTimeout) {
311336
super(
312337
"waf.requests",
@@ -315,6 +340,7 @@ public WafRequestsRawMetric(
315340
"event_rules_version:" + rulesVersion,
316341
"rule_triggered:" + triggered,
317342
"request_blocked:" + blocked,
343+
"waf_error:" + wafError,
318344
"waf_timeout:" + wafTimeout);
319345
}
320346
}

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class WafMetricCollectorTest extends DDSpecification {
2727
WafMetricCollector.get().wafRequestTriggered()
2828
WafMetricCollector.get().wafRequestBlocked()
2929
WafMetricCollector.get().wafRequestTimeout()
30+
WafMetricCollector.get().wafRequestError()
3031
WafMetricCollector.get().raspRuleEval(RuleType.SQL_INJECTION)
3132
WafMetricCollector.get().raspRuleEval(RuleType.SQL_INJECTION)
3233
WafMetricCollector.get().raspRuleMatch(RuleType.SQL_INJECTION)
@@ -69,6 +70,7 @@ class WafMetricCollectorTest extends DDSpecification {
6970
'event_rules_version:rules.3',
7071
'rule_triggered:false',
7172
'request_blocked:false',
73+
'waf_error:false',
7274
'waf_timeout:false'
7375
].toSet()
7476

@@ -81,6 +83,7 @@ class WafMetricCollectorTest extends DDSpecification {
8183
'event_rules_version:rules.3',
8284
'rule_triggered:true',
8385
'request_blocked:false',
86+
'waf_error:false',
8487
'waf_timeout:false'
8588
].toSet()
8689

@@ -95,6 +98,7 @@ class WafMetricCollectorTest extends DDSpecification {
9598
'event_rules_version:rules.3',
9699
'rule_triggered:true',
97100
'request_blocked:true',
101+
'waf_error:false',
98102
'waf_timeout:false'
99103
].toSet()
100104

@@ -108,24 +112,39 @@ class WafMetricCollectorTest extends DDSpecification {
108112
'event_rules_version:rules.3',
109113
'rule_triggered:false',
110114
'request_blocked:false',
115+
'waf_error:false',
111116
'waf_timeout:true'
112117
].toSet()
113118

114-
def raspRuleEvalSqli = (WafMetricCollector.RaspRuleEval)metrics[7]
119+
def requestWafErrorMetric = (WafMetricCollector.WafRequestsRawMetric)metrics[7]
120+
requestWafErrorMetric.namespace == 'appsec'
121+
requestWafErrorMetric.metricName == 'waf.requests'
122+
requestWafErrorMetric.type == 'count'
123+
requestWafErrorMetric.value == 1
124+
requestWafErrorMetric.tags.toSet() == [
125+
'waf_version:waf_ver1',
126+
'event_rules_version:rules.3',
127+
'rule_triggered:false',
128+
'request_blocked:false',
129+
'waf_error:true',
130+
'waf_timeout:false'
131+
].toSet()
132+
133+
def raspRuleEvalSqli = (WafMetricCollector.RaspRuleEval)metrics[8]
115134
raspRuleEvalSqli.type == 'count'
116135
raspRuleEvalSqli.value == 3
117136
raspRuleEvalSqli.namespace == 'appsec'
118137
raspRuleEvalSqli.metricName == 'rasp.rule.eval'
119138
raspRuleEvalSqli.tags.toSet() == ['rule_type:sql_injection', 'waf_version:waf_ver1'].toSet()
120139

121-
def raspRuleMatch = (WafMetricCollector.RaspRuleMatch)metrics[8]
140+
def raspRuleMatch = (WafMetricCollector.RaspRuleMatch)metrics[9]
122141
raspRuleMatch.type == 'count'
123142
raspRuleMatch.value == 1
124143
raspRuleMatch.namespace == 'appsec'
125144
raspRuleMatch.metricName == 'rasp.rule.match'
126145
raspRuleMatch.tags.toSet() == ['rule_type:sql_injection', 'waf_version:waf_ver1'].toSet()
127146

128-
def raspTimeout = (WafMetricCollector.RaspTimeout)metrics[9]
147+
def raspTimeout = (WafMetricCollector.RaspTimeout)metrics[10]
129148
raspTimeout.type == 'count'
130149
raspTimeout.value == 1
131150
raspTimeout.namespace == 'appsec'

telemetry/src/test/groovy/datadog/telemetry/metric/WafMetricPeriodicActionSpecification.groovy

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
4949
WafMetricCollector.get().wafRequestBlocked()
5050
WafMetricCollector.get().wafRequest()
5151
WafMetricCollector.get().wafRequestTimeout()
52+
WafMetricCollector.get().wafRequestError()
5253
WafMetricCollector.get().prepareMetrics()
5354
periodicAction.doIteration(telemetryService)
5455

@@ -66,6 +67,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
6667
'event_rules_version:rules_ver_1',
6768
'rule_triggered:false',
6869
'request_blocked:false',
70+
'waf_error:false',
6971
'waf_timeout:false'
7072
]
7173
} )
@@ -78,6 +80,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
7880
'event_rules_version:rules_ver_1',
7981
'rule_triggered:true',
8082
'request_blocked:false',
83+
'waf_error:false',
8184
'waf_timeout:false'
8285
]
8386
} )
@@ -90,6 +93,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
9093
'event_rules_version:rules_ver_1',
9194
'rule_triggered:true',
9295
'request_blocked:true',
96+
'waf_error:false',
9397
'waf_timeout:false'
9498
]
9599
} )
@@ -102,9 +106,23 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
102106
'event_rules_version:rules_ver_1',
103107
'rule_triggered:false',
104108
'request_blocked:false',
109+
'waf_error:false',
105110
'waf_timeout:true'
106111
]
107112
} )
113+
1 * telemetryService.addMetric( { Metric metric ->
114+
metric.namespace == 'appsec' &&
115+
metric.metric == 'waf.requests' &&
116+
metric.points[0][1] == 1 &&
117+
metric.tags == [
118+
'waf_version:0.0.0',
119+
'event_rules_version:rules_ver_1',
120+
'rule_triggered:false',
121+
'request_blocked:false',
122+
'waf_error:true',
123+
'waf_timeout:false'
124+
]
125+
} )
108126
0 * _._
109127

110128
when: 'waf.updates happens'
@@ -113,6 +131,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
113131
WafMetricCollector.get().wafRequestTriggered()
114132
WafMetricCollector.get().wafRequestBlocked()
115133
WafMetricCollector.get().wafRequestTimeout()
134+
WafMetricCollector.get().wafRequestError()
116135
WafMetricCollector.get().prepareMetrics()
117136
periodicAction.doIteration(telemetryService)
118137

@@ -130,6 +149,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
130149
'event_rules_version:rules_ver_2',
131150
'rule_triggered:false',
132151
'request_blocked:false',
152+
'waf_error:false',
133153
'waf_timeout:false'
134154
]
135155
} )
@@ -142,6 +162,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
142162
'event_rules_version:rules_ver_2',
143163
'rule_triggered:true',
144164
'request_blocked:false',
165+
'waf_error:false',
145166
'waf_timeout:false'
146167
]
147168
} )
@@ -154,6 +175,7 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
154175
'event_rules_version:rules_ver_2',
155176
'rule_triggered:true',
156177
'request_blocked:true',
178+
'waf_error:false',
157179
'waf_timeout:false'
158180
]
159181
} )
@@ -166,9 +188,23 @@ class WafMetricPeriodicActionSpecification extends DDSpecification {
166188
'event_rules_version:rules_ver_2',
167189
'rule_triggered:false',
168190
'request_blocked:false',
191+
'waf_error:false',
169192
'waf_timeout:true'
170193
]
171194
} )
195+
1 * telemetryService.addMetric( { Metric metric ->
196+
metric.namespace == 'appsec' &&
197+
metric.metric == 'waf.requests' &&
198+
metric.points[0][1] == 1 &&
199+
metric.tags == [
200+
'waf_version:0.0.0',
201+
'event_rules_version:rules_ver_2',
202+
'rule_triggered:false',
203+
'request_blocked:false',
204+
'waf_error:true',
205+
'waf_timeout:false'
206+
]
207+
} )
172208
0 * _._
173209
}
174210
}

0 commit comments

Comments
 (0)