java 34 lines · 9 steps

Streaming log redaction in Java

A file-to-file processor scrubs secrets and emails from logs line by line while counting how many lines changed.

Explained by highlit
1public final class LogRedactor {
2 
3 private static final Pattern SECRET = Pattern.compile(
4 "(?i)(password|token|api[_-]?key|secret|authorization)\\s*[=:]\\s*\\S+");
5 
6 private static final Pattern EMAIL = Pattern.compile(
7 "[\\w.+-]+@[\\w-]+\\.[\\w.-]+");
8 
9 public long redact(Path source, Path target) throws IOException {
10 long redactedCount = 0;
11 try (BufferedReader reader = Files.newBufferedReader(source, StandardCharsets.UTF_8);
12 BufferedWriter writer = Files.newBufferedWriter(target, StandardCharsets.UTF_8,
13 StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
14 
15 String line;
16 while ((line = reader.readLine()) != null) {
17 String sanitized = sanitize(line);
18 if (!sanitized.equals(line)) {
19 redactedCount++;
20 }
21 writer.write(sanitized);
22 writer.newLine();
23 }
24 }
25 return redactedCount;
26 }
27 
28 private String sanitize(String line) {
29 String result = SECRET.matcher(line).replaceAll(mr ->
30 Matcher.quoteReplacement(mr.group(1) + "=***REDACTED***"));
31 result = EMAIL.matcher(result).replaceAll("[email redacted]");
32 return result;
33 }
34}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Compiling patterns once as static finals avoids recompiling regex on every line processed.
  2. 2Streaming line by line with buffered reader and writer keeps memory flat regardless of file size.
  3. 3Comparing sanitized output against the original is a cheap way to count how many lines were actually changed.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Streaming log redaction in Java — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code