Skip to content

Commit ad56cc5

Browse files
committed
Simplify codebase
1 parent 0034321 commit ad56cc5

File tree

39 files changed

+133
-8686
lines changed

39 files changed

+133
-8686
lines changed

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ Features:
2222

2323
* Mask single values or whole subtrees
2424
* Remove single values or whole subtrees
25-
* Truncate String values
26-
* Truncate document size (max total output size)
27-
* Remove whitespace (for pretty-printed documents)
25+
* Limit String value size
26+
* Limit document size (skip end of document when max size is reached)
27+
* Remove whitespace
2828

29-
The library contains multiple filter implementations as to accommodate combinations of the above features with as little overhead as possible.
29+
The library contains multiple filter implementations as to accommodate combinations of the above features with as little overhead as possible.
3030

3131
The equivalent filters are also implemented using [Jackson]:
3232

@@ -176,15 +176,15 @@ to output like
176176
### Path syntax
177177
A simple syntax is supported, where each path segment corresponds to a `field name`. Expressions are case-sensitive. Supported syntax:
178178

179-
/my/field/name
179+
$.my.field.name
180180

181181
with support for wildcards;
182182

183-
/my/field/*
183+
$.my.field.*
184184

185185
or a simple any-level field name search
186186

187-
//myFieldName
187+
..myFieldName
188188

189189
The filters within this library support using multiple expressions at once. Note that path expressions are see through arrays.
190190

@@ -212,14 +212,14 @@ The resulting metrics could be logged as metadata alongside the JSON payload or
212212
## Performance
213213
The `core` processors within this project are faster than the `Jackson`-based processors. This is expected as parser/serializer features have been traded for performance:
214214

215-
* `core` is something like 3x-9x as fast as `Jackson` processors, where
215+
* `core` processors are multiple times as fast as (streaming) `Jackson` processors, where
216216
* skipping large parts of JSON documents (prune) decreases the difference, and
217217
* small documents increase the difference, as `Jackson` is more expensive to initialize.
218218
* working directly on bytes is faster than working on characters for the `core` processors.
219219

220220
For a typical, light-weight web service, the overall system performance improvement for using the `core` filters over the `Jackson`-based filters will most likely be a few percent.
221221

222-
Memory use will be at 2-8 times the raw JSON byte size; depending on the invoked `JsonFilter` method (some accept string, other raw bytes or chars).
222+
Memory use will be at most 2-8 times the raw JSON byte size; depending on the invoked `JsonFilter` method (some accept string, other raw bytes or chars).
223223

224224
See the benchmark results ([JDK 17](https://jmh.morethan.io/?source=https://raw.githubusercontent.com/skjolber/json-log-filter/master/benchmark/jmh/results/jmh-results-4.1.2.jdk17.json&topBar=off)) and the [JMH] module for running detailed benchmarks.
225225

benchmark/jmh/src/main/java/com/github/skjolber/jsonfilter/jmh/AbstractSingleFullPathMaxStringLengthFilterBenchmark.java

Lines changed: 0 additions & 72 deletions
This file was deleted.

benchmark/jmh/src/main/java/com/github/skjolber/jsonfilter/jmh/AllFilterBenchmark.java

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,12 @@
3131
import com.github.skjolber.jsonfilter.core.MultiPathJsonFilter;
3232
import com.github.skjolber.jsonfilter.core.MultiPathMaxSizeMaxStringLengthJsonFilter;
3333
import com.github.skjolber.jsonfilter.core.MultiPathMaxStringLengthJsonFilter;
34-
import com.github.skjolber.jsonfilter.core.SingleAnyPathMaxStringLengthJsonFilter;
35-
import com.github.skjolber.jsonfilter.core.SingleFullPathJsonFilter;
36-
import com.github.skjolber.jsonfilter.core.SingleFullPathMaxStringLengthJsonFilter;
3734
import com.github.skjolber.jsonfilter.jackson.JacksonJsonFilter;
3835
import com.github.skjolber.jsonfilter.jackson.JacksonMaxSizeJsonFilter;
3936
import com.github.skjolber.jsonfilter.jackson.JacksonMaxStringLengthJsonFilter;
4037
import com.github.skjolber.jsonfilter.jackson.JacksonMultiAnyPathMaxStringLengthJsonFilter;
4138
import com.github.skjolber.jsonfilter.jackson.JacksonMultiPathMaxSizeMaxStringLengthJsonFilter;
4239
import com.github.skjolber.jsonfilter.jackson.JacksonMultiPathMaxStringLengthJsonFilter;
43-
import com.github.skjolber.jsonfilter.jackson.JacksonSingleFullPathMaxStringLengthJsonFilter;
4440
import com.github.skjolber.jsonfilter.jmh.filter.PrimitiveJsonPropertyBodyFilter;
4541
import com.github.skjolber.jsonfilter.jmh.utils.JsonMaskerJsonFilter;
4642

@@ -51,17 +47,15 @@
5147
@State(Scope.Thread)
5248
@BenchmarkMode(Mode.Throughput)
5349
@OutputTimeUnit(TimeUnit.SECONDS)
54-
@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
55-
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
56-
50+
@Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
51+
@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
5752
@Fork(1)
5853
public class AllFilterBenchmark {
5954

6055
public static final String DEFAULT_XPATH = "/address";
6156
public static final String DEFAULT_ANY_XPATH = "//address";
6257

6358
private JacksonBenchmarkRunner jacksonMultiPathMaxSizeMaxStringLengthJsonFilter;
64-
private BenchmarkRunner<JacksonJsonFilter> singleFullPathAnonymizeMaxStringLengthJacksonJsonFilter;
6559
private BenchmarkRunner<JsonFilter> anyPathJsonMaskerJsonFilter;
6660
private BenchmarkRunner<JsonFilter> singlePathJsonMaskerJsonFilter;
6761

@@ -70,12 +64,9 @@ public class AllFilterBenchmark {
7064

7165
private BenchmarkRunner<JsonFilter> defaultJsonFilter;
7266

73-
private BenchmarkRunner<JsonFilter> singleFullPathAnonymizeJsonFilter;
7467
private BenchmarkRunner<JsonFilter> maxStringLengthJsonFilter;
7568
private BenchmarkRunner<JsonFilter> maxSizeJsonFilter;
7669

77-
private BenchmarkRunner<JsonFilter> singleFullPathMaxStringLengthAnonymizeJsonFilter;
78-
7970
private BenchmarkRunner<JsonFilter> multiPathAnonymizeJsonFilter;
8071
private BenchmarkRunner<JsonFilter> multiPathAnonymizeFullPathJsonFilter;
8172
private BenchmarkRunner<JsonFilter> multiPathMaxStringLengthAnonymizeJsonFilter;
@@ -84,7 +75,6 @@ public class AllFilterBenchmark {
8475
private BenchmarkRunner<JacksonJsonFilter> multiAnyPathAnonymizeMaxStringLengthJacksonJsonFilter;
8576
private BenchmarkRunner<JsonFilter> multiAnyPathLogbookJsonFilter;
8677
private BenchmarkRunner<JsonFilter> anyPathAnonymizeJsonFilter;
87-
private BenchmarkRunner<JsonFilter> singleAnyPathAnonymizeMaxStringLengthJsonFilter;
8878

8979
private BenchmarkRunner<JsonFilter> multiPathAnonymizeMaxSizeMaxStringLengthJsonFilter;
9080

@@ -103,7 +93,6 @@ public void init() throws Exception {
10393
// generic filters
10494
// jackson
10595
jacksonMultiPathMaxSizeMaxStringLengthJsonFilter = new JacksonBenchmarkRunner(file, true, new JacksonMultiPathMaxSizeMaxStringLengthJsonFilter(20, -1, new String[] {xpath}, null), prettyPrinted);
106-
singleFullPathAnonymizeMaxStringLengthJacksonJsonFilter = new JacksonBenchmarkRunner(file, true, new JacksonSingleFullPathMaxStringLengthJsonFilter(20, xpath, FilterType.ANON), prettyPrinted);
10796
multiPathAnonymizeMaxStringLengthJacksonJsonFilter = new JacksonBenchmarkRunner(file, true, new JacksonMultiPathMaxStringLengthJsonFilter(20, new String[] {xpath}, null), prettyPrinted);
10897
multiAnyPathAnonymizeMaxStringLengthJacksonJsonFilter = new JacksonBenchmarkRunner(file, true, new JacksonMultiAnyPathMaxStringLengthJsonFilter(20, new String[] {DEFAULT_ANY_XPATH}, null), prettyPrinted);
10998
maxStringLengthJacksonJsonFilter = new JacksonBenchmarkRunner(file, true, new JacksonMaxStringLengthJsonFilter(20), prettyPrinted);
@@ -114,10 +103,7 @@ public void init() throws Exception {
114103
maxSizeJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new MaxSizeJsonFilter(128), prettyPrinted);
115104

116105
// path - single
117-
singleFullPathAnonymizeJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new SingleFullPathJsonFilter(-1, xpath, FilterType.ANON), prettyPrinted);
118-
singleFullPathMaxStringLengthAnonymizeJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new SingleFullPathMaxStringLengthJsonFilter(20, -1, xpath, FilterType.ANON), prettyPrinted);
119106
anyPathAnonymizeJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new AnyPathJsonFilter(-1, new String[]{DEFAULT_ANY_XPATH}, null), prettyPrinted);
120-
singleAnyPathAnonymizeMaxStringLengthJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new SingleAnyPathMaxStringLengthJsonFilter(20, -1, DEFAULT_ANY_XPATH, FilterType.ANON), prettyPrinted);
121107

122108
// path - multiple
123109
multiPathAnonymizeJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new MultiPathJsonFilter(-1, new String[]{xpath}, null), prettyPrinted);
@@ -153,11 +139,6 @@ public long noop_passthrough() throws IOException {
153139
public long multiAnyPathLogbook() throws IOException {
154140
return multiAnyPathLogbookJsonFilter.benchmarkBytes();
155141
}
156-
157-
@Benchmark
158-
public long anonSingleMaxStringLengthJackson() throws IOException {
159-
return singleFullPathAnonymizeMaxStringLengthJacksonJsonFilter.benchmarkBytes();
160-
}
161142

162143
@Benchmark
163144
public long anonMultiMaxStringLengthJackson() throws IOException {
@@ -184,11 +165,6 @@ public long maxSizeJackson() throws IOException {
184165
return maxSizeJacksonJsonFilter.benchmarkBytes();
185166
}
186167

187-
@Benchmark
188-
public long anonSingleFullPath() throws IOException {
189-
return singleFullPathAnonymizeJsonFilter.benchmarkBytes();
190-
}
191-
192168
@Benchmark
193169
public long anonAnyPath() throws IOException {
194170
return anyPathAnonymizeJsonFilter.benchmarkBytes();
@@ -204,16 +180,6 @@ public long anonSingleFullPathJsonMask() throws IOException {
204180
return singlePathJsonMaskerJsonFilter.benchmarkBytesAsArray();
205181
}
206182

207-
@Benchmark
208-
public long anonSingleAnyPathMaxStringLength() throws IOException {
209-
return singleAnyPathAnonymizeMaxStringLengthJsonFilter.benchmarkBytes();
210-
}
211-
212-
@Benchmark
213-
public long anonSingleFullPathMaxStringLength() throws IOException {
214-
return singleFullPathMaxStringLengthAnonymizeJsonFilter.benchmarkBytes();
215-
}
216-
217183
@Benchmark
218184
public long anonMultiPathMaxStringLength() throws IOException {
219185
return multiPathMaxStringLengthAnonymizeJsonFilter.benchmarkBytes();

benchmark/jmh/src/main/java/com/github/skjolber/jsonfilter/jmh/CveFilterBenchmark.java

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.github.skjolber.jsonfilter.jmh;
22
import java.io.File;
33
import java.io.IOException;
4+
import java.util.HashSet;
5+
import java.util.Set;
46
import java.util.concurrent.TimeUnit;
57

68
import org.openjdk.jmh.annotations.Benchmark;
@@ -22,12 +24,12 @@
2224

2325
import com.github.skjolber.jsonfilter.JsonFilter;
2426
import com.github.skjolber.jsonfilter.base.AbstractPathJsonFilter.FilterType;
27+
import com.github.skjolber.jsonfilter.core.AnyPathJsonFilter;
2528
import com.github.skjolber.jsonfilter.core.DefaultJsonLogFilterBuilder;
2629
import com.github.skjolber.jsonfilter.core.MaxSizeJsonFilter;
2730
import com.github.skjolber.jsonfilter.core.MaxStringLengthJsonFilter;
2831
import com.github.skjolber.jsonfilter.core.MaxStringLengthMaxSizeJsonFilter;
2932
import com.github.skjolber.jsonfilter.core.MultiPathMaxSizeMaxStringLengthJsonFilter;
30-
import com.github.skjolber.jsonfilter.core.SingleFullPathMaxSizeMaxStringLengthJsonFilter;
3133
import com.github.skjolber.jsonfilter.core.ws.MaxSizeRemoveWhitespaceJsonFilter;
3234
import com.github.skjolber.jsonfilter.core.ws.MaxStringLengthMaxSizeRemoveWhitespaceJsonFilter;
3335
import com.github.skjolber.jsonfilter.core.ws.MaxStringLengthRemoveWhitespaceJsonFilter;
@@ -37,17 +39,20 @@
3739
import com.github.skjolber.jsonfilter.jackson.JacksonMaxSizeJsonFilter;
3840
import com.github.skjolber.jsonfilter.jackson.JacksonMaxSizeMaxStringLengthJsonFilter;
3941
import com.github.skjolber.jsonfilter.jackson.JacksonMultiPathMaxSizeMaxStringLengthJsonFilter;
40-
import com.github.skjolber.jsonfilter.jackson.JacksonSingleFullPathMaxSizeMaxStringLengthJsonFilter;
42+
import com.github.skjolber.jsonfilter.jmh.utils.JsonMaskerJsonFilter;
43+
44+
import dev.blaauwendraad.masker.json.JsonMasker;
45+
import dev.blaauwendraad.masker.json.config.JsonMaskingConfig;
4146

4247

4348
@State(Scope.Thread)
4449
@BenchmarkMode(Mode.Throughput)
4550
@OutputTimeUnit(TimeUnit.SECONDS)
46-
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
47-
@Measurement(iterations = 15, time = 1, timeUnit = TimeUnit.SECONDS)
51+
@Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS)
52+
@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
4853

4954
@Fork(1)
50-
public abstract class CveFilterBenchmark {
55+
public class CveFilterBenchmark {
5156

5257
private final int maxStringLength = 64;
5358
private static String[] anon = new String[] {"/CVE_Items/cve/affects/vendor/vendor_data/vendor_name"};
@@ -61,7 +66,9 @@ public abstract class CveFilterBenchmark {
6166

6267
private BenchmarkRunner<JsonFilter> multiPathMaxStringLengthJsonFilter;
6368
private BenchmarkRunner<JacksonJsonFilter> multiPathMaxStringLengthJacksonJsonFilter;
64-
69+
70+
private BenchmarkRunner<JsonFilter> anyPathJsonFilter;
71+
6572
private BenchmarkRunner<JsonFilter> maxStringLengthJsonFilter;
6673
private BenchmarkRunner<JacksonJsonFilter> maxStringLengthJacksonJsonFilter;
6774
private BenchmarkRunner<JsonFilter> maxStringLengthRemoveWhitespaceJsonFilter;
@@ -77,13 +84,13 @@ public abstract class CveFilterBenchmark {
7784
private BenchmarkRunner<JsonFilter> maxSizeJsonFilter;
7885
private BenchmarkRunner<JsonFilter> maxSizeRemoveWhitespaceJsonFilter;
7986

80-
private BenchmarkRunner<JsonFilter> singleFullPathMaxSizeMaxStringLengthJsonFilter;
81-
private JacksonBenchmarkRunner singleFullPathMaxSizeMaxStringLengthJacksonJsonFilter;
87+
private BenchmarkRunner<JsonFilter> anyPathJsonMaskerJsonFilter;
88+
private BenchmarkRunner<JsonFilter> singlePathJsonMaskerJsonFilter;
8289

8390
private BenchmarkRunner<JsonFilter> removeWhitespaceJsonFilter;
8491

85-
@Param(value={"2KB","8KB","14KB","22KB","30KB","50KB","70KB","100KB","200KB"})
86-
//@Param(value={"2KB"})
92+
//@Param(value={"2KB","8KB","14KB","22KB","30KB","50KB","70KB","100KB","200KB"})
93+
@Param(value={"8KB"})
8794
private String fileName;
8895
private final boolean prettyPrinted = false;
8996

@@ -115,10 +122,19 @@ public void init() throws Exception {
115122
maxStringLengthMaxSizeRemoveWhitespaceJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new MaxStringLengthMaxSizeRemoveWhitespaceJsonFilter(maxStringLength, size), prettyPrinted);
116123
maxStringLengthMaxSizeJacksonJsonFilter = new BenchmarkRunner<JacksonJsonFilter>(file, true, new JacksonMaxSizeMaxStringLengthJsonFilter(maxStringLength, size), prettyPrinted);
117124

118-
singleFullPathMaxSizeMaxStringLengthJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new SingleFullPathMaxSizeMaxStringLengthJsonFilter(maxStringLength, size, -1, anon[0], FilterType.ANON), prettyPrinted);
119-
singleFullPathMaxSizeMaxStringLengthJacksonJsonFilter = new JacksonBenchmarkRunner(file, true, new JacksonSingleFullPathMaxSizeMaxStringLengthJsonFilter(maxStringLength, size, -1, anon[0], FilterType.ANON), prettyPrinted);
120-
121125
removeWhitespaceJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new RemoveWhitespaceJsonFilter(), prettyPrinted);
126+
127+
anyPathJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new AnyPathJsonFilter(size, new String[] {"//version"}, null), prettyPrinted);
128+
129+
// other filters
130+
var singlePathJsonMasker = JsonMasker.getMasker(
131+
JsonMaskingConfig.builder()
132+
.maskJsonPaths(Set.of("$.CVE_Items.cve.affects.vendor.vendor_data.vendor_name"))
133+
.build()
134+
);
135+
136+
anyPathJsonMaskerJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new JsonMaskerJsonFilter(JsonMasker.getMasker(Set.of("version"))), false);
137+
singlePathJsonMaskerJsonFilter = new BenchmarkRunner<JsonFilter>(file, true, new JsonMaskerJsonFilter(singlePathJsonMasker), false);
122138
}
123139

124140
@Benchmark
@@ -185,16 +201,6 @@ public long maxSizeJackson() {
185201
return maxSizeJacksonJsonFilter.benchmarkBytes();
186202
}
187203

188-
@Benchmark
189-
public long all_single() throws IOException {
190-
return singleFullPathMaxSizeMaxStringLengthJsonFilter.benchmarkCharacters();
191-
}
192-
193-
@Benchmark
194-
public long all_single_jackson() throws IOException {
195-
return singleFullPathMaxSizeMaxStringLengthJacksonJsonFilter.benchmarkCharacters();
196-
}
197-
198204
@Benchmark
199205
public long maxStringLengthMaxSize_core() throws IOException {
200206
return maxStringLengthMaxSizeJsonFilter.benchmarkCharacters();
@@ -210,6 +216,22 @@ public long maxStringLengthMaxSize_jackson() throws IOException {
210216
return maxStringLengthMaxSizeJacksonJsonFilter.benchmarkCharacters();
211217
}
212218

219+
@Benchmark
220+
public long anon_core() throws IOException {
221+
return anyPathJsonFilter.benchmarkBytes();
222+
}
223+
224+
@Benchmark
225+
public long anon_jsonMask() throws IOException {
226+
return anyPathJsonMaskerJsonFilter.benchmarkBytesAsArray();
227+
}
228+
229+
@Benchmark
230+
public long anon_single_jsonMask() throws IOException {
231+
return singlePathJsonMaskerJsonFilter.benchmarkBytesAsArray();
232+
}
233+
234+
213235
public static void main(String[] args) throws RunnerException {
214236
Options opt = new OptionsBuilder()
215237
.include(CveFilterBenchmark.class.getSimpleName())

0 commit comments

Comments
 (0)