1313
1414public class WafMetricCollector implements MetricCollector <WafMetricCollector .WafMetric > {
1515
16+ private static final int MASK_STRING_TOO_LONG = 1 ; // 0b001
17+ private static final int MASK_LIST_MAP_TOO_LARGE = 1 << 1 ; // 0b010
18+ private static final int MASK_OBJECT_TOO_DEEP = 1 << 2 ; // 0b100
19+
1620 public static WafMetricCollector INSTANCE = new WafMetricCollector ();
1721
1822 public static WafMetricCollector get () {
@@ -34,6 +38,9 @@ private WafMetricCollector() {
3438 private static final int WAF_REQUEST_COMBINATIONS = 128 ; // 2^7
3539 private final AtomicLongArray wafRequestCounter = new AtomicLongArray (WAF_REQUEST_COMBINATIONS );
3640
41+ private static final AtomicLongArray wafInputTruncatedCounter =
42+ new AtomicLongArray (1 << 3 ); // 3 flags → 2^3 = 8 possible bit combinations
43+
3744 private static final AtomicLongArray raspRuleEvalCounter =
3845 new AtomicLongArray (RuleType .getNumValues ());
3946 private static final AtomicLongArray raspRuleSkippedCounter =
@@ -104,6 +111,12 @@ public void wafRequest(
104111 wafRequestCounter .incrementAndGet (index );
105112 }
106113
114+ public void wafInputTruncated (
115+ final boolean stringTooLong , final boolean listMapTooLarge , final boolean objectTooDeep ) {
116+ int index = computeWafInputTruncatedIndex (stringTooLong , listMapTooLarge , objectTooDeep );
117+ wafInputTruncatedCounter .incrementAndGet (index );
118+ }
119+
107120 static int computeWafRequestIndex (
108121 boolean ruleTriggered ,
109122 boolean requestBlocked ,
@@ -123,6 +136,15 @@ static int computeWafRequestIndex(
123136 return index ;
124137 }
125138
139+ static int computeWafInputTruncatedIndex (
140+ boolean stringTooLong , boolean listMapTooLarge , boolean objectTooDeep ) {
141+ int index = 0 ;
142+ if (stringTooLong ) index |= MASK_STRING_TOO_LONG ;
143+ if (listMapTooLarge ) index |= MASK_LIST_MAP_TOO_LARGE ;
144+ if (objectTooDeep ) index |= MASK_OBJECT_TOO_DEEP ;
145+ return index ;
146+ }
147+
126148 public void raspRuleEval (final RuleType ruleType ) {
127149 raspRuleEvalCounter .incrementAndGet (ruleType .ordinal ());
128150 }
@@ -216,6 +238,16 @@ public void prepareMetrics() {
216238 }
217239 }
218240
241+ // WAF input truncated
242+ for (int i = 0 ; i < (1 << 3 ); i ++) {
243+ long counter = wafInputTruncatedCounter .getAndSet (i , 0 );
244+ if (counter > 0 ) {
245+ if (!rawMetricsQueue .offer (new WafInputTruncated (counter , i ))) {
246+ return ;
247+ }
248+ }
249+ }
250+
219251 // RASP rule eval per rule type
220252 for (RuleType ruleType : RuleType .values ()) {
221253 long counter = raspRuleEvalCounter .getAndSet (ruleType .ordinal (), 0 );
@@ -516,6 +548,12 @@ public WafError(final long counter, final String wafVersion, final Integer ddwaf
516548 }
517549 }
518550
551+ public static class WafInputTruncated extends WafMetric {
552+ public WafInputTruncated (final long counter , final int bitfield ) {
553+ super ("waf.input_truncated" , counter , "truncation_reason:" + bitfield );
554+ }
555+ }
556+
519557 /**
520558 * Mirror of the {@code WafErrorCode} enum defined in the {@code libddwaf-java} module.
521559 *
0 commit comments