Repository files navigation

Java Grok

WhaTap Log Monitoring Grok Parser

This is a fork of io.krakens:java-grok, customized for WhaTap Log Monitoring service. It provides enhanced pattern support, ECS-style field names, and reserved keyword handling for WhaTap's internal processing.

Java Grok is a powerful API that allows you to easily parse logs and other files (single line). With Java Grok, you can turn unstructured log and event data into structured data (JSON).

✨ Features

  • 🚀 High Performance: Built with O(1) LRU caching and memory optimization
  • 🔒 Security: ReDoS protection with configurable input length limits
  • 🧵 Thread-Safe: Concurrent pattern compilation and matching
  • 📦 Enum-based Pattern Management: 23 categorized pattern types with 450+ patterns
  • 🔍 Advanced Pattern Search: Find patterns across multiple types and categories
  • 📊 Pattern Statistics: Get comprehensive insights about available patterns
  • 🏷️ Type-safe Pattern Access: Enum-based approach for better IDE support
  • 🔄 ECS Field Support: Supports Elastic Common Schema style field names like [log][level]
  • 🔄 Backward Compatibility: Drop-in replacement for io.krakens:java-grok

⚠️ Breaking Changes (v0.1.1)

Reserved Field Name Changes for WhaTap Log Monitoring

WhaTap Log Monitoring uses certain field names as reserved keywords for internal processing. To avoid conflicts with these system fields, the following field names have been renamed in all built-in patterns:

Original FieldNew FieldReason (WhaTap Reserved)
timestamplog_timestampAbstractPack.time
timelog_timeAbstractPack.time
messagelog_messageSystem reserved
contentlog_contentLogSinkPack.content
categorylog_categoryLogSinkPack.category
pcodelog_pcodeAbstractPack.pcode
logContentlog_bodySystem reserved

Impact: If you are using built-in patterns like COMBINEDAPACHELOG, SYSLOG5424LINE, CATALINA_LOG, etc., the extracted field names have changed. Update your code to use the new field names.

Example Migration:

// Before (v0.1.0)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("timestamp");
Stringmessage = (String) result.get("message");
// After (v0.1.1)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("log_timestamp");
Stringmessage = (String) result.get("log_message");

Note: Custom field names defined in your own patterns (e.g., %{TIMESTAMP_ISO8601:my_timestamp}) are not affected by this change.


What can I use Grok for?

  • Log Processing: Parse Apache, Nginx, MongoDB, PostgreSQL, Redis, Zeek, and more log formats
  • Pattern Discovery: Search and explore 450+ built-in patterns across 23 categories
  • JSON Conversion: Transform unstructured text into structured JSON data
  • ECS Compliance: Extract fields using Elastic Common Schema naming conventions
  • Error Reporting: Extract specific patterns from logs and processes
  • Regular Expression Management: Apply 'write-once use-everywhere' to regex patterns

Maven repository

<!-- https://mvnrepository.com/artifact/io.github.whatap/java-grok -->
<dependency>
<groupId>io.github.whatap</groupId>
<artifactId>java-grok</artifactId>
<version>0.1.1</version>
</dependency>

Or with gradle

// https://mvnrepository.com/artifact/io.github.whatap/java-grok
implementation 'io.github.whatap:java-grok:0.1.1'

What is different from io.krakens:java-grok

Key Improvements:

  1. ECS-Style Field Names: Supports [log][level] style nested field names
  2. Thread Safety: ConcurrentHashMap for pattern definitions
  3. O(1) LRU Cache: Efficient cache eviction using LinkedHashMap
  4. ReDoS Protection: Configurable input length limits
  5. More Patterns: 23 pattern types (vs 18), 450+ patterns (vs 400+)
  6. Better Regex: Improved pattern and subname validation

Pattern Regex Differences:

Featureio.krakens:java-grokio.github.whatap
pattern[A-z0-9]+[a-zA-Z][a-zA-Z0-9_\-\.]*[a-zA-Z0-9]
subname[A-z0-9_:;,\-\/\s\.']+ECS-style [field][name] + legacy

@See GrokUtils.java

🚀 Quick Start

Basic Usage

importio.whatap.grok.api.GrokCompiler;
importio.whatap.grok.api.Grok;
importio.whatap.grok.api.Match;
// Create a new grok compiler instanceGrokCompilergrokCompiler = GrokCompiler.newInstance();
grokCompiler.registerDefaultPatterns();
// Compile a grok pattern for Apache logsfinalGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Parse a log lineStringlog = "112.169.19.192 - - [06/Mar/2013:01:36:30 +0900] \"GET / HTTP/1.1\" 200 44346 \"-\"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22\"";
Matchmatch = grok.match(log);
Map<String, Object> result = match.capture();

🏷️ Enum-based Pattern Management (New!)

importio.whatap.grok.api.*;
// Get pattern management servicePatternManagementServiceservice = newPatternManagementService();
// Get all available pattern typesList<PatternManagementService.PatternTypeInfo> types = service.getAllPatternTypes();
// Get patterns by categoryMap<String, List<PatternManagementService.PatternTypeInfo>> categories = service.getPatternTypesByCategory();
// Load specific pattern typePatternManagementService.PatternTypeDetailsmongoPatterns = service.getPatternTypeDetails(PatternType.MONGODB);
// Search for specific patternsList<PatternManagementService.PatternInfo> patterns = service.searchPatterns("MONGO_QUERY");
// Get comprehensive statisticsPatternManagementService.PatternStatisticsstats = service.getPatternStatistics();
System.out.println("Total patterns: " + stats.getTotalPatterns()); // 450+

📦 Using Specific Pattern Types

// Register only specific pattern typesGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerPatterns(PatternType.MONGODB, PatternType.PATTERNS);
// Or register patterns from specific categoriesPatternRepositoryrepo = PatternRepository.getInstance();
Map<String, String> awsPatterns = repo.loadPatterns(PatternType.AWS);
compiler.register(awsPatterns);

🏷️ ECS-Style Field Names

Supports Elastic Common Schema style nested field names:

GrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
// Use ECS-style field namesGrokgrok = compiler.compile("%{LOGLEVEL:[log][level]} %{IP:[source][ip]}");
Matchmatch = grok.match("ERROR 192.168.1.1");
Map<String, Object> result = match.capture();
// Access nested fields// result = {log.level=ERROR, source.ip=192.168.1.1}

📋 Available Pattern Types

CategoryPattern TypesDescription
CorePATTERNSBase Grok patterns (IP, URI, NUMBER, etc.)
Cloud & InfrastructureAWS, HAPROXY, HTTPD, SQUIDS3, ELB, CloudFront, load balancer, proxy logs
DatabasesMONGODB, POSTGRESQL, REDISDatabase query and server logs
System & NetworkLINUX_SYSLOG, FIREWALLS, BIND, JUNOS, BRO, ZEEKSyslog, iptables, DNS, network security
ApplicationsJAVA, RAILS, RUBY, POSTFIX, EXIMApplication and mail server logs
Monitoring & BackupNAGIOS, BACULA, MCOLLECTIVEMonitoring and backup system logs
Build ToolsMAVENVersion patterns for build tools

Total: 23 pattern types with 450+ patterns

🔒 Security Features

ReDoS Protection

Java Grok includes protection against Regular Expression Denial of Service (ReDoS) attacks:

// Default: 1MB input limitGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Configure custom limitGrok.setMaxInputLength(512 * 1024); // 512KB// Disable limit (not recommended)Grok.setMaxInputLength(0);

Thread Safety

All pattern compilation and matching operations are thread-safe:

// Safe for concurrent useGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
Grokgrok = compiler.compile("%{IP:client}");
// Can be used from multiple threadsExecutorServiceexecutor = Executors.newFixedThreadPool(10);
for (inti = 0; i < 100; i++) {
executor.submit(() -> {
Matchmatch = grok.match("192.168.1.1");
// ...
});
}

🔧 Build & Test

# Build the project
./gradlew assemble
# Run tests
./gradlew test# Run specific tests
./gradlew test --tests PatternManagementServiceTest

📖 Documentation

🤝 Contributing

Any contributions are warmly welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

Grok is inspired by the Logstash Grok filter and builds upon the foundation of io.krakens:java-grok with significant enhancements.

About

Simple API that allows you to easily parse logs and other files

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Java Grok

WhaTap Log Monitoring Grok Parser

This is a fork of io.krakens:java-grok, customized for WhaTap Log Monitoring service. It provides enhanced pattern support, ECS-style field names, and reserved keyword handling for WhaTap's internal processing.

Java Grok is a powerful API that allows you to easily parse logs and other files (single line). With Java Grok, you can turn unstructured log and event data into structured data (JSON).

✨ Features

  • 🚀 High Performance: Built with O(1) LRU caching and memory optimization
  • 🔒 Security: ReDoS protection with configurable input length limits
  • 🧵 Thread-Safe: Concurrent pattern compilation and matching
  • 📦 Enum-based Pattern Management: 23 categorized pattern types with 450+ patterns
  • 🔍 Advanced Pattern Search: Find patterns across multiple types and categories
  • 📊 Pattern Statistics: Get comprehensive insights about available patterns
  • 🏷️ Type-safe Pattern Access: Enum-based approach for better IDE support
  • 🔄 ECS Field Support: Supports Elastic Common Schema style field names like [log][level]
  • 🔄 Backward Compatibility: Drop-in replacement for io.krakens:java-grok

⚠️ Breaking Changes (v0.1.1)

Reserved Field Name Changes for WhaTap Log Monitoring

WhaTap Log Monitoring uses certain field names as reserved keywords for internal processing. To avoid conflicts with these system fields, the following field names have been renamed in all built-in patterns:

Original FieldNew FieldReason (WhaTap Reserved)
timestamplog_timestampAbstractPack.time
timelog_timeAbstractPack.time
messagelog_messageSystem reserved
contentlog_contentLogSinkPack.content
categorylog_categoryLogSinkPack.category
pcodelog_pcodeAbstractPack.pcode
logContentlog_bodySystem reserved

Impact: If you are using built-in patterns like COMBINEDAPACHELOG, SYSLOG5424LINE, CATALINA_LOG, etc., the extracted field names have changed. Update your code to use the new field names.

Example Migration:

// Before (v0.1.0)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("timestamp");
Stringmessage = (String) result.get("message");
// After (v0.1.1)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("log_timestamp");
Stringmessage = (String) result.get("log_message");

Note: Custom field names defined in your own patterns (e.g., %{TIMESTAMP_ISO8601:my_timestamp}) are not affected by this change.


What can I use Grok for?

  • Log Processing: Parse Apache, Nginx, MongoDB, PostgreSQL, Redis, Zeek, and more log formats
  • Pattern Discovery: Search and explore 450+ built-in patterns across 23 categories
  • JSON Conversion: Transform unstructured text into structured JSON data
  • ECS Compliance: Extract fields using Elastic Common Schema naming conventions
  • Error Reporting: Extract specific patterns from logs and processes
  • Regular Expression Management: Apply 'write-once use-everywhere' to regex patterns

Maven repository

<!-- https://mvnrepository.com/artifact/io.github.whatap/java-grok -->
<dependency>
<groupId>io.github.whatap</groupId>
<artifactId>java-grok</artifactId>
<version>0.1.1</version>
</dependency>

Or with gradle

// https://mvnrepository.com/artifact/io.github.whatap/java-grok
implementation 'io.github.whatap:java-grok:0.1.1'

What is different from io.krakens:java-grok

Key Improvements:

  1. ECS-Style Field Names: Supports [log][level] style nested field names
  2. Thread Safety: ConcurrentHashMap for pattern definitions
  3. O(1) LRU Cache: Efficient cache eviction using LinkedHashMap
  4. ReDoS Protection: Configurable input length limits
  5. More Patterns: 23 pattern types (vs 18), 450+ patterns (vs 400+)
  6. Better Regex: Improved pattern and subname validation

Pattern Regex Differences:

Featureio.krakens:java-grokio.github.whatap
pattern[A-z0-9]+[a-zA-Z][a-zA-Z0-9_\-\.]*[a-zA-Z0-9]
subname[A-z0-9_:;,\-\/\s\.']+ECS-style [field][name] + legacy

@See GrokUtils.java

🚀 Quick Start

Basic Usage

importio.whatap.grok.api.GrokCompiler;
importio.whatap.grok.api.Grok;
importio.whatap.grok.api.Match;
// Create a new grok compiler instanceGrokCompilergrokCompiler = GrokCompiler.newInstance();
grokCompiler.registerDefaultPatterns();
// Compile a grok pattern for Apache logsfinalGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Parse a log lineStringlog = "112.169.19.192 - - [06/Mar/2013:01:36:30 +0900] \"GET / HTTP/1.1\" 200 44346 \"-\"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22\"";
Matchmatch = grok.match(log);
Map<String, Object> result = match.capture();

🏷️ Enum-based Pattern Management (New!)

importio.whatap.grok.api.*;
// Get pattern management servicePatternManagementServiceservice = newPatternManagementService();
// Get all available pattern typesList<PatternManagementService.PatternTypeInfo> types = service.getAllPatternTypes();
// Get patterns by categoryMap<String, List<PatternManagementService.PatternTypeInfo>> categories = service.getPatternTypesByCategory();
// Load specific pattern typePatternManagementService.PatternTypeDetailsmongoPatterns = service.getPatternTypeDetails(PatternType.MONGODB);
// Search for specific patternsList<PatternManagementService.PatternInfo> patterns = service.searchPatterns("MONGO_QUERY");
// Get comprehensive statisticsPatternManagementService.PatternStatisticsstats = service.getPatternStatistics();
System.out.println("Total patterns: " + stats.getTotalPatterns()); // 450+

📦 Using Specific Pattern Types

// Register only specific pattern typesGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerPatterns(PatternType.MONGODB, PatternType.PATTERNS);
// Or register patterns from specific categoriesPatternRepositoryrepo = PatternRepository.getInstance();
Map<String, String> awsPatterns = repo.loadPatterns(PatternType.AWS);
compiler.register(awsPatterns);

🏷️ ECS-Style Field Names

Supports Elastic Common Schema style nested field names:

GrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
// Use ECS-style field namesGrokgrok = compiler.compile("%{LOGLEVEL:[log][level]} %{IP:[source][ip]}");
Matchmatch = grok.match("ERROR 192.168.1.1");
Map<String, Object> result = match.capture();
// Access nested fields// result = {log.level=ERROR, source.ip=192.168.1.1}

📋 Available Pattern Types

CategoryPattern TypesDescription
CorePATTERNSBase Grok patterns (IP, URI, NUMBER, etc.)
Cloud & InfrastructureAWS, HAPROXY, HTTPD, SQUIDS3, ELB, CloudFront, load balancer, proxy logs
DatabasesMONGODB, POSTGRESQL, REDISDatabase query and server logs
System & NetworkLINUX_SYSLOG, FIREWALLS, BIND, JUNOS, BRO, ZEEKSyslog, iptables, DNS, network security
ApplicationsJAVA, RAILS, RUBY, POSTFIX, EXIMApplication and mail server logs
Monitoring & BackupNAGIOS, BACULA, MCOLLECTIVEMonitoring and backup system logs
Build ToolsMAVENVersion patterns for build tools

Total: 23 pattern types with 450+ patterns

🔒 Security Features

ReDoS Protection

Java Grok includes protection against Regular Expression Denial of Service (ReDoS) attacks:

// Default: 1MB input limitGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Configure custom limitGrok.setMaxInputLength(512 * 1024); // 512KB// Disable limit (not recommended)Grok.setMaxInputLength(0);

Thread Safety

All pattern compilation and matching operations are thread-safe:

// Safe for concurrent useGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
Grokgrok = compiler.compile("%{IP:client}");
// Can be used from multiple threadsExecutorServiceexecutor = Executors.newFixedThreadPool(10);
for (inti = 0; i < 100; i++) {
executor.submit(() -> {
Matchmatch = grok.match("192.168.1.1");
// ...
});
}

🔧 Build & Test

# Build the project
./gradlew assemble
# Run tests
./gradlew test# Run specific tests
./gradlew test --tests PatternManagementServiceTest

📖 Documentation

🤝 Contributing

Any contributions are warmly welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

Grok is inspired by the Logstash Grok filter and builds upon the foundation of io.krakens:java-grok with significant enhancements.

About

Simple API that allows you to easily parse logs and other files

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Java Grok

WhaTap Log Monitoring Grok Parser

This is a fork of io.krakens:java-grok, customized for WhaTap Log Monitoring service. It provides enhanced pattern support, ECS-style field names, and reserved keyword handling for WhaTap's internal processing.

Java Grok is a powerful API that allows you to easily parse logs and other files (single line). With Java Grok, you can turn unstructured log and event data into structured data (JSON).

✨ Features

  • 🚀 High Performance: Built with O(1) LRU caching and memory optimization
  • 🔒 Security: ReDoS protection with configurable input length limits
  • 🧵 Thread-Safe: Concurrent pattern compilation and matching
  • 📦 Enum-based Pattern Management: 23 categorized pattern types with 450+ patterns
  • 🔍 Advanced Pattern Search: Find patterns across multiple types and categories
  • 📊 Pattern Statistics: Get comprehensive insights about available patterns
  • 🏷️ Type-safe Pattern Access: Enum-based approach for better IDE support
  • 🔄 ECS Field Support: Supports Elastic Common Schema style field names like [log][level]
  • 🔄 Backward Compatibility: Drop-in replacement for io.krakens:java-grok

⚠️ Breaking Changes (v0.1.1)

Reserved Field Name Changes for WhaTap Log Monitoring

WhaTap Log Monitoring uses certain field names as reserved keywords for internal processing. To avoid conflicts with these system fields, the following field names have been renamed in all built-in patterns:

Original FieldNew FieldReason (WhaTap Reserved)
timestamplog_timestampAbstractPack.time
timelog_timeAbstractPack.time
messagelog_messageSystem reserved
contentlog_contentLogSinkPack.content
categorylog_categoryLogSinkPack.category
pcodelog_pcodeAbstractPack.pcode
logContentlog_bodySystem reserved

Impact: If you are using built-in patterns like COMBINEDAPACHELOG, SYSLOG5424LINE, CATALINA_LOG, etc., the extracted field names have changed. Update your code to use the new field names.

Example Migration:

// Before (v0.1.0)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("timestamp");
Stringmessage = (String) result.get("message");
// After (v0.1.1)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("log_timestamp");
Stringmessage = (String) result.get("log_message");

Note: Custom field names defined in your own patterns (e.g., %{TIMESTAMP_ISO8601:my_timestamp}) are not affected by this change.


What can I use Grok for?

  • Log Processing: Parse Apache, Nginx, MongoDB, PostgreSQL, Redis, Zeek, and more log formats
  • Pattern Discovery: Search and explore 450+ built-in patterns across 23 categories
  • JSON Conversion: Transform unstructured text into structured JSON data
  • ECS Compliance: Extract fields using Elastic Common Schema naming conventions
  • Error Reporting: Extract specific patterns from logs and processes
  • Regular Expression Management: Apply 'write-once use-everywhere' to regex patterns

Maven repository

<!-- https://mvnrepository.com/artifact/io.github.whatap/java-grok -->
<dependency>
<groupId>io.github.whatap</groupId>
<artifactId>java-grok</artifactId>
<version>0.1.1</version>
</dependency>

Or with gradle

// https://mvnrepository.com/artifact/io.github.whatap/java-grok
implementation 'io.github.whatap:java-grok:0.1.1'

What is different from io.krakens:java-grok

Key Improvements:

  1. ECS-Style Field Names: Supports [log][level] style nested field names
  2. Thread Safety: ConcurrentHashMap for pattern definitions
  3. O(1) LRU Cache: Efficient cache eviction using LinkedHashMap
  4. ReDoS Protection: Configurable input length limits
  5. More Patterns: 23 pattern types (vs 18), 450+ patterns (vs 400+)
  6. Better Regex: Improved pattern and subname validation

Pattern Regex Differences:

Featureio.krakens:java-grokio.github.whatap
pattern[A-z0-9]+[a-zA-Z][a-zA-Z0-9_\-\.]*[a-zA-Z0-9]
subname[A-z0-9_:;,\-\/\s\.']+ECS-style [field][name] + legacy

@See GrokUtils.java

🚀 Quick Start

Basic Usage

importio.whatap.grok.api.GrokCompiler;
importio.whatap.grok.api.Grok;
importio.whatap.grok.api.Match;
// Create a new grok compiler instanceGrokCompilergrokCompiler = GrokCompiler.newInstance();
grokCompiler.registerDefaultPatterns();
// Compile a grok pattern for Apache logsfinalGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Parse a log lineStringlog = "112.169.19.192 - - [06/Mar/2013:01:36:30 +0900] \"GET / HTTP/1.1\" 200 44346 \"-\"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22\"";
Matchmatch = grok.match(log);
Map<String, Object> result = match.capture();

🏷️ Enum-based Pattern Management (New!)

importio.whatap.grok.api.*;
// Get pattern management servicePatternManagementServiceservice = newPatternManagementService();
// Get all available pattern typesList<PatternManagementService.PatternTypeInfo> types = service.getAllPatternTypes();
// Get patterns by categoryMap<String, List<PatternManagementService.PatternTypeInfo>> categories = service.getPatternTypesByCategory();
// Load specific pattern typePatternManagementService.PatternTypeDetailsmongoPatterns = service.getPatternTypeDetails(PatternType.MONGODB);
// Search for specific patternsList<PatternManagementService.PatternInfo> patterns = service.searchPatterns("MONGO_QUERY");
// Get comprehensive statisticsPatternManagementService.PatternStatisticsstats = service.getPatternStatistics();
System.out.println("Total patterns: " + stats.getTotalPatterns()); // 450+

📦 Using Specific Pattern Types

// Register only specific pattern typesGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerPatterns(PatternType.MONGODB, PatternType.PATTERNS);
// Or register patterns from specific categoriesPatternRepositoryrepo = PatternRepository.getInstance();
Map<String, String> awsPatterns = repo.loadPatterns(PatternType.AWS);
compiler.register(awsPatterns);

🏷️ ECS-Style Field Names

Supports Elastic Common Schema style nested field names:

GrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
// Use ECS-style field namesGrokgrok = compiler.compile("%{LOGLEVEL:[log][level]} %{IP:[source][ip]}");
Matchmatch = grok.match("ERROR 192.168.1.1");
Map<String, Object> result = match.capture();
// Access nested fields// result = {log.level=ERROR, source.ip=192.168.1.1}

📋 Available Pattern Types

CategoryPattern TypesDescription
CorePATTERNSBase Grok patterns (IP, URI, NUMBER, etc.)
Cloud & InfrastructureAWS, HAPROXY, HTTPD, SQUIDS3, ELB, CloudFront, load balancer, proxy logs
DatabasesMONGODB, POSTGRESQL, REDISDatabase query and server logs
System & NetworkLINUX_SYSLOG, FIREWALLS, BIND, JUNOS, BRO, ZEEKSyslog, iptables, DNS, network security
ApplicationsJAVA, RAILS, RUBY, POSTFIX, EXIMApplication and mail server logs
Monitoring & BackupNAGIOS, BACULA, MCOLLECTIVEMonitoring and backup system logs
Build ToolsMAVENVersion patterns for build tools

Total: 23 pattern types with 450+ patterns

🔒 Security Features

ReDoS Protection

Java Grok includes protection against Regular Expression Denial of Service (ReDoS) attacks:

// Default: 1MB input limitGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Configure custom limitGrok.setMaxInputLength(512 * 1024); // 512KB// Disable limit (not recommended)Grok.setMaxInputLength(0);

Thread Safety

All pattern compilation and matching operations are thread-safe:

// Safe for concurrent useGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
Grokgrok = compiler.compile("%{IP:client}");
// Can be used from multiple threadsExecutorServiceexecutor = Executors.newFixedThreadPool(10);
for (inti = 0; i < 100; i++) {
executor.submit(() -> {
Matchmatch = grok.match("192.168.1.1");
// ...
});
}

🔧 Build & Test

# Build the project
./gradlew assemble
# Run tests
./gradlew test# Run specific tests
./gradlew test --tests PatternManagementServiceTest

📖 Documentation

🤝 Contributing

Any contributions are warmly welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

Grok is inspired by the Logstash Grok filter and builds upon the foundation of io.krakens:java-grok with significant enhancements.

About

Simple API that allows you to easily parse logs and other files

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Java Grok

WhaTap Log Monitoring Grok Parser

This is a fork of io.krakens:java-grok, customized for WhaTap Log Monitoring service. It provides enhanced pattern support, ECS-style field names, and reserved keyword handling for WhaTap's internal processing.

Java Grok is a powerful API that allows you to easily parse logs and other files (single line). With Java Grok, you can turn unstructured log and event data into structured data (JSON).

✨ Features

  • 🚀 High Performance: Built with O(1) LRU caching and memory optimization
  • 🔒 Security: ReDoS protection with configurable input length limits
  • 🧵 Thread-Safe: Concurrent pattern compilation and matching
  • 📦 Enum-based Pattern Management: 23 categorized pattern types with 450+ patterns
  • 🔍 Advanced Pattern Search: Find patterns across multiple types and categories
  • 📊 Pattern Statistics: Get comprehensive insights about available patterns
  • 🏷️ Type-safe Pattern Access: Enum-based approach for better IDE support
  • 🔄 ECS Field Support: Supports Elastic Common Schema style field names like [log][level]
  • 🔄 Backward Compatibility: Drop-in replacement for io.krakens:java-grok

⚠️ Breaking Changes (v0.1.1)

Reserved Field Name Changes for WhaTap Log Monitoring

WhaTap Log Monitoring uses certain field names as reserved keywords for internal processing. To avoid conflicts with these system fields, the following field names have been renamed in all built-in patterns:

Original FieldNew FieldReason (WhaTap Reserved)
timestamplog_timestampAbstractPack.time
timelog_timeAbstractPack.time
messagelog_messageSystem reserved
contentlog_contentLogSinkPack.content
categorylog_categoryLogSinkPack.category
pcodelog_pcodeAbstractPack.pcode
logContentlog_bodySystem reserved

Impact: If you are using built-in patterns like COMBINEDAPACHELOG, SYSLOG5424LINE, CATALINA_LOG, etc., the extracted field names have changed. Update your code to use the new field names.

Example Migration:

// Before (v0.1.0)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("timestamp");
Stringmessage = (String) result.get("message");
// After (v0.1.1)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("log_timestamp");
Stringmessage = (String) result.get("log_message");

Note: Custom field names defined in your own patterns (e.g., %{TIMESTAMP_ISO8601:my_timestamp}) are not affected by this change.


What can I use Grok for?

  • Log Processing: Parse Apache, Nginx, MongoDB, PostgreSQL, Redis, Zeek, and more log formats
  • Pattern Discovery: Search and explore 450+ built-in patterns across 23 categories
  • JSON Conversion: Transform unstructured text into structured JSON data
  • ECS Compliance: Extract fields using Elastic Common Schema naming conventions
  • Error Reporting: Extract specific patterns from logs and processes
  • Regular Expression Management: Apply 'write-once use-everywhere' to regex patterns

Maven repository

<!-- https://mvnrepository.com/artifact/io.github.whatap/java-grok -->
<dependency>
<groupId>io.github.whatap</groupId>
<artifactId>java-grok</artifactId>
<version>0.1.1</version>
</dependency>

Or with gradle

// https://mvnrepository.com/artifact/io.github.whatap/java-grok
implementation 'io.github.whatap:java-grok:0.1.1'

What is different from io.krakens:java-grok

Key Improvements:

  1. ECS-Style Field Names: Supports [log][level] style nested field names
  2. Thread Safety: ConcurrentHashMap for pattern definitions
  3. O(1) LRU Cache: Efficient cache eviction using LinkedHashMap
  4. ReDoS Protection: Configurable input length limits
  5. More Patterns: 23 pattern types (vs 18), 450+ patterns (vs 400+)
  6. Better Regex: Improved pattern and subname validation

Pattern Regex Differences:

Featureio.krakens:java-grokio.github.whatap
pattern[A-z0-9]+[a-zA-Z][a-zA-Z0-9_\-\.]*[a-zA-Z0-9]
subname[A-z0-9_:;,\-\/\s\.']+ECS-style [field][name] + legacy

@See GrokUtils.java

🚀 Quick Start

Basic Usage

importio.whatap.grok.api.GrokCompiler;
importio.whatap.grok.api.Grok;
importio.whatap.grok.api.Match;
// Create a new grok compiler instanceGrokCompilergrokCompiler = GrokCompiler.newInstance();
grokCompiler.registerDefaultPatterns();
// Compile a grok pattern for Apache logsfinalGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Parse a log lineStringlog = "112.169.19.192 - - [06/Mar/2013:01:36:30 +0900] \"GET / HTTP/1.1\" 200 44346 \"-\"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22\"";
Matchmatch = grok.match(log);
Map<String, Object> result = match.capture();

🏷️ Enum-based Pattern Management (New!)

importio.whatap.grok.api.*;
// Get pattern management servicePatternManagementServiceservice = newPatternManagementService();
// Get all available pattern typesList<PatternManagementService.PatternTypeInfo> types = service.getAllPatternTypes();
// Get patterns by categoryMap<String, List<PatternManagementService.PatternTypeInfo>> categories = service.getPatternTypesByCategory();
// Load specific pattern typePatternManagementService.PatternTypeDetailsmongoPatterns = service.getPatternTypeDetails(PatternType.MONGODB);
// Search for specific patternsList<PatternManagementService.PatternInfo> patterns = service.searchPatterns("MONGO_QUERY");
// Get comprehensive statisticsPatternManagementService.PatternStatisticsstats = service.getPatternStatistics();
System.out.println("Total patterns: " + stats.getTotalPatterns()); // 450+

📦 Using Specific Pattern Types

// Register only specific pattern typesGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerPatterns(PatternType.MONGODB, PatternType.PATTERNS);
// Or register patterns from specific categoriesPatternRepositoryrepo = PatternRepository.getInstance();
Map<String, String> awsPatterns = repo.loadPatterns(PatternType.AWS);
compiler.register(awsPatterns);

🏷️ ECS-Style Field Names

Supports Elastic Common Schema style nested field names:

GrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
// Use ECS-style field namesGrokgrok = compiler.compile("%{LOGLEVEL:[log][level]} %{IP:[source][ip]}");
Matchmatch = grok.match("ERROR 192.168.1.1");
Map<String, Object> result = match.capture();
// Access nested fields// result = {log.level=ERROR, source.ip=192.168.1.1}

📋 Available Pattern Types

CategoryPattern TypesDescription
CorePATTERNSBase Grok patterns (IP, URI, NUMBER, etc.)
Cloud & InfrastructureAWS, HAPROXY, HTTPD, SQUIDS3, ELB, CloudFront, load balancer, proxy logs
DatabasesMONGODB, POSTGRESQL, REDISDatabase query and server logs
System & NetworkLINUX_SYSLOG, FIREWALLS, BIND, JUNOS, BRO, ZEEKSyslog, iptables, DNS, network security
ApplicationsJAVA, RAILS, RUBY, POSTFIX, EXIMApplication and mail server logs
Monitoring & BackupNAGIOS, BACULA, MCOLLECTIVEMonitoring and backup system logs
Build ToolsMAVENVersion patterns for build tools

Total: 23 pattern types with 450+ patterns

🔒 Security Features

ReDoS Protection

Java Grok includes protection against Regular Expression Denial of Service (ReDoS) attacks:

// Default: 1MB input limitGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Configure custom limitGrok.setMaxInputLength(512 * 1024); // 512KB// Disable limit (not recommended)Grok.setMaxInputLength(0);

Thread Safety

All pattern compilation and matching operations are thread-safe:

// Safe for concurrent useGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
Grokgrok = compiler.compile("%{IP:client}");
// Can be used from multiple threadsExecutorServiceexecutor = Executors.newFixedThreadPool(10);
for (inti = 0; i < 100; i++) {
executor.submit(() -> {
Matchmatch = grok.match("192.168.1.1");
// ...
});
}

🔧 Build & Test

# Build the project
./gradlew assemble
# Run tests
./gradlew test# Run specific tests
./gradlew test --tests PatternManagementServiceTest

📖 Documentation

🤝 Contributing

Any contributions are warmly welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

Grok is inspired by the Logstash Grok filter and builds upon the foundation of io.krakens:java-grok with significant enhancements.

About

Simple API that allows you to easily parse logs and other files

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Java Grok

WhaTap Log Monitoring Grok Parser

This is a fork of io.krakens:java-grok, customized for WhaTap Log Monitoring service. It provides enhanced pattern support, ECS-style field names, and reserved keyword handling for WhaTap's internal processing.

Java Grok is a powerful API that allows you to easily parse logs and other files (single line). With Java Grok, you can turn unstructured log and event data into structured data (JSON).

✨ Features

  • 🚀 High Performance: Built with O(1) LRU caching and memory optimization
  • 🔒 Security: ReDoS protection with configurable input length limits
  • 🧵 Thread-Safe: Concurrent pattern compilation and matching
  • 📦 Enum-based Pattern Management: 23 categorized pattern types with 450+ patterns
  • 🔍 Advanced Pattern Search: Find patterns across multiple types and categories
  • 📊 Pattern Statistics: Get comprehensive insights about available patterns
  • 🏷️ Type-safe Pattern Access: Enum-based approach for better IDE support
  • 🔄 ECS Field Support: Supports Elastic Common Schema style field names like [log][level]
  • 🔄 Backward Compatibility: Drop-in replacement for io.krakens:java-grok

⚠️ Breaking Changes (v0.1.1)

Reserved Field Name Changes for WhaTap Log Monitoring

WhaTap Log Monitoring uses certain field names as reserved keywords for internal processing. To avoid conflicts with these system fields, the following field names have been renamed in all built-in patterns:

Original FieldNew FieldReason (WhaTap Reserved)
timestamplog_timestampAbstractPack.time
timelog_timeAbstractPack.time
messagelog_messageSystem reserved
contentlog_contentLogSinkPack.content
categorylog_categoryLogSinkPack.category
pcodelog_pcodeAbstractPack.pcode
logContentlog_bodySystem reserved

Impact: If you are using built-in patterns like COMBINEDAPACHELOG, SYSLOG5424LINE, CATALINA_LOG, etc., the extracted field names have changed. Update your code to use the new field names.

Example Migration:

// Before (v0.1.0)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("timestamp");
Stringmessage = (String) result.get("message");
// After (v0.1.1)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("log_timestamp");
Stringmessage = (String) result.get("log_message");

Note: Custom field names defined in your own patterns (e.g., %{TIMESTAMP_ISO8601:my_timestamp}) are not affected by this change.


What can I use Grok for?

  • Log Processing: Parse Apache, Nginx, MongoDB, PostgreSQL, Redis, Zeek, and more log formats
  • Pattern Discovery: Search and explore 450+ built-in patterns across 23 categories
  • JSON Conversion: Transform unstructured text into structured JSON data
  • ECS Compliance: Extract fields using Elastic Common Schema naming conventions
  • Error Reporting: Extract specific patterns from logs and processes
  • Regular Expression Management: Apply 'write-once use-everywhere' to regex patterns

Maven repository

<!-- https://mvnrepository.com/artifact/io.github.whatap/java-grok -->
<dependency>
<groupId>io.github.whatap</groupId>
<artifactId>java-grok</artifactId>
<version>0.1.1</version>
</dependency>

Or with gradle

// https://mvnrepository.com/artifact/io.github.whatap/java-grok
implementation 'io.github.whatap:java-grok:0.1.1'

What is different from io.krakens:java-grok

Key Improvements:

  1. ECS-Style Field Names: Supports [log][level] style nested field names
  2. Thread Safety: ConcurrentHashMap for pattern definitions
  3. O(1) LRU Cache: Efficient cache eviction using LinkedHashMap
  4. ReDoS Protection: Configurable input length limits
  5. More Patterns: 23 pattern types (vs 18), 450+ patterns (vs 400+)
  6. Better Regex: Improved pattern and subname validation

Pattern Regex Differences:

Featureio.krakens:java-grokio.github.whatap
pattern[A-z0-9]+[a-zA-Z][a-zA-Z0-9_\-\.]*[a-zA-Z0-9]
subname[A-z0-9_:;,\-\/\s\.']+ECS-style [field][name] + legacy

@See GrokUtils.java

🚀 Quick Start

Basic Usage

importio.whatap.grok.api.GrokCompiler;
importio.whatap.grok.api.Grok;
importio.whatap.grok.api.Match;
// Create a new grok compiler instanceGrokCompilergrokCompiler = GrokCompiler.newInstance();
grokCompiler.registerDefaultPatterns();
// Compile a grok pattern for Apache logsfinalGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Parse a log lineStringlog = "112.169.19.192 - - [06/Mar/2013:01:36:30 +0900] \"GET / HTTP/1.1\" 200 44346 \"-\"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22\"";
Matchmatch = grok.match(log);
Map<String, Object> result = match.capture();

🏷️ Enum-based Pattern Management (New!)

importio.whatap.grok.api.*;
// Get pattern management servicePatternManagementServiceservice = newPatternManagementService();
// Get all available pattern typesList<PatternManagementService.PatternTypeInfo> types = service.getAllPatternTypes();
// Get patterns by categoryMap<String, List<PatternManagementService.PatternTypeInfo>> categories = service.getPatternTypesByCategory();
// Load specific pattern typePatternManagementService.PatternTypeDetailsmongoPatterns = service.getPatternTypeDetails(PatternType.MONGODB);
// Search for specific patternsList<PatternManagementService.PatternInfo> patterns = service.searchPatterns("MONGO_QUERY");
// Get comprehensive statisticsPatternManagementService.PatternStatisticsstats = service.getPatternStatistics();
System.out.println("Total patterns: " + stats.getTotalPatterns()); // 450+

📦 Using Specific Pattern Types

// Register only specific pattern typesGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerPatterns(PatternType.MONGODB, PatternType.PATTERNS);
// Or register patterns from specific categoriesPatternRepositoryrepo = PatternRepository.getInstance();
Map<String, String> awsPatterns = repo.loadPatterns(PatternType.AWS);
compiler.register(awsPatterns);

🏷️ ECS-Style Field Names

Supports Elastic Common Schema style nested field names:

GrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
// Use ECS-style field namesGrokgrok = compiler.compile("%{LOGLEVEL:[log][level]} %{IP:[source][ip]}");
Matchmatch = grok.match("ERROR 192.168.1.1");
Map<String, Object> result = match.capture();
// Access nested fields// result = {log.level=ERROR, source.ip=192.168.1.1}

📋 Available Pattern Types

CategoryPattern TypesDescription
CorePATTERNSBase Grok patterns (IP, URI, NUMBER, etc.)
Cloud & InfrastructureAWS, HAPROXY, HTTPD, SQUIDS3, ELB, CloudFront, load balancer, proxy logs
DatabasesMONGODB, POSTGRESQL, REDISDatabase query and server logs
System & NetworkLINUX_SYSLOG, FIREWALLS, BIND, JUNOS, BRO, ZEEKSyslog, iptables, DNS, network security
ApplicationsJAVA, RAILS, RUBY, POSTFIX, EXIMApplication and mail server logs
Monitoring & BackupNAGIOS, BACULA, MCOLLECTIVEMonitoring and backup system logs
Build ToolsMAVENVersion patterns for build tools

Total: 23 pattern types with 450+ patterns

🔒 Security Features

ReDoS Protection

Java Grok includes protection against Regular Expression Denial of Service (ReDoS) attacks:

// Default: 1MB input limitGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Configure custom limitGrok.setMaxInputLength(512 * 1024); // 512KB// Disable limit (not recommended)Grok.setMaxInputLength(0);

Thread Safety

All pattern compilation and matching operations are thread-safe:

// Safe for concurrent useGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
Grokgrok = compiler.compile("%{IP:client}");
// Can be used from multiple threadsExecutorServiceexecutor = Executors.newFixedThreadPool(10);
for (inti = 0; i < 100; i++) {
executor.submit(() -> {
Matchmatch = grok.match("192.168.1.1");
// ...
});
}

🔧 Build & Test

# Build the project
./gradlew assemble
# Run tests
./gradlew test# Run specific tests
./gradlew test --tests PatternManagementServiceTest

📖 Documentation

🤝 Contributing

Any contributions are warmly welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

Grok is inspired by the Logstash Grok filter and builds upon the foundation of io.krakens:java-grok with significant enhancements.

About

Simple API that allows you to easily parse logs and other files

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Java Grok

WhaTap Log Monitoring Grok Parser

This is a fork of io.krakens:java-grok, customized for WhaTap Log Monitoring service. It provides enhanced pattern support, ECS-style field names, and reserved keyword handling for WhaTap's internal processing.

Java Grok is a powerful API that allows you to easily parse logs and other files (single line). With Java Grok, you can turn unstructured log and event data into structured data (JSON).

✨ Features

  • 🚀 High Performance: Built with O(1) LRU caching and memory optimization
  • 🔒 Security: ReDoS protection with configurable input length limits
  • 🧵 Thread-Safe: Concurrent pattern compilation and matching
  • 📦 Enum-based Pattern Management: 23 categorized pattern types with 450+ patterns
  • 🔍 Advanced Pattern Search: Find patterns across multiple types and categories
  • 📊 Pattern Statistics: Get comprehensive insights about available patterns
  • 🏷️ Type-safe Pattern Access: Enum-based approach for better IDE support
  • 🔄 ECS Field Support: Supports Elastic Common Schema style field names like [log][level]
  • 🔄 Backward Compatibility: Drop-in replacement for io.krakens:java-grok

⚠️ Breaking Changes (v0.1.1)

Reserved Field Name Changes for WhaTap Log Monitoring

WhaTap Log Monitoring uses certain field names as reserved keywords for internal processing. To avoid conflicts with these system fields, the following field names have been renamed in all built-in patterns:

Original FieldNew FieldReason (WhaTap Reserved)
timestamplog_timestampAbstractPack.time
timelog_timeAbstractPack.time
messagelog_messageSystem reserved
contentlog_contentLogSinkPack.content
categorylog_categoryLogSinkPack.category
pcodelog_pcodeAbstractPack.pcode
logContentlog_bodySystem reserved

Impact: If you are using built-in patterns like COMBINEDAPACHELOG, SYSLOG5424LINE, CATALINA_LOG, etc., the extracted field names have changed. Update your code to use the new field names.

Example Migration:

// Before (v0.1.0)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("timestamp");
Stringmessage = (String) result.get("message");
// After (v0.1.1)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("log_timestamp");
Stringmessage = (String) result.get("log_message");

Note: Custom field names defined in your own patterns (e.g., %{TIMESTAMP_ISO8601:my_timestamp}) are not affected by this change.


What can I use Grok for?

  • Log Processing: Parse Apache, Nginx, MongoDB, PostgreSQL, Redis, Zeek, and more log formats
  • Pattern Discovery: Search and explore 450+ built-in patterns across 23 categories
  • JSON Conversion: Transform unstructured text into structured JSON data
  • ECS Compliance: Extract fields using Elastic Common Schema naming conventions
  • Error Reporting: Extract specific patterns from logs and processes
  • Regular Expression Management: Apply 'write-once use-everywhere' to regex patterns

Maven repository

<!-- https://mvnrepository.com/artifact/io.github.whatap/java-grok -->
<dependency>
<groupId>io.github.whatap</groupId>
<artifactId>java-grok</artifactId>
<version>0.1.1</version>
</dependency>

Or with gradle

// https://mvnrepository.com/artifact/io.github.whatap/java-grok
implementation 'io.github.whatap:java-grok:0.1.1'

What is different from io.krakens:java-grok

Key Improvements:

  1. ECS-Style Field Names: Supports [log][level] style nested field names
  2. Thread Safety: ConcurrentHashMap for pattern definitions
  3. O(1) LRU Cache: Efficient cache eviction using LinkedHashMap
  4. ReDoS Protection: Configurable input length limits
  5. More Patterns: 23 pattern types (vs 18), 450+ patterns (vs 400+)
  6. Better Regex: Improved pattern and subname validation

Pattern Regex Differences:

Featureio.krakens:java-grokio.github.whatap
pattern[A-z0-9]+[a-zA-Z][a-zA-Z0-9_\-\.]*[a-zA-Z0-9]
subname[A-z0-9_:;,\-\/\s\.']+ECS-style [field][name] + legacy

@See GrokUtils.java

🚀 Quick Start

Basic Usage

importio.whatap.grok.api.GrokCompiler;
importio.whatap.grok.api.Grok;
importio.whatap.grok.api.Match;
// Create a new grok compiler instanceGrokCompilergrokCompiler = GrokCompiler.newInstance();
grokCompiler.registerDefaultPatterns();
// Compile a grok pattern for Apache logsfinalGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Parse a log lineStringlog = "112.169.19.192 - - [06/Mar/2013:01:36:30 +0900] \"GET / HTTP/1.1\" 200 44346 \"-\"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22\"";
Matchmatch = grok.match(log);
Map<String, Object> result = match.capture();

🏷️ Enum-based Pattern Management (New!)

importio.whatap.grok.api.*;
// Get pattern management servicePatternManagementServiceservice = newPatternManagementService();
// Get all available pattern typesList<PatternManagementService.PatternTypeInfo> types = service.getAllPatternTypes();
// Get patterns by categoryMap<String, List<PatternManagementService.PatternTypeInfo>> categories = service.getPatternTypesByCategory();
// Load specific pattern typePatternManagementService.PatternTypeDetailsmongoPatterns = service.getPatternTypeDetails(PatternType.MONGODB);
// Search for specific patternsList<PatternManagementService.PatternInfo> patterns = service.searchPatterns("MONGO_QUERY");
// Get comprehensive statisticsPatternManagementService.PatternStatisticsstats = service.getPatternStatistics();
System.out.println("Total patterns: " + stats.getTotalPatterns()); // 450+

📦 Using Specific Pattern Types

// Register only specific pattern typesGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerPatterns(PatternType.MONGODB, PatternType.PATTERNS);
// Or register patterns from specific categoriesPatternRepositoryrepo = PatternRepository.getInstance();
Map<String, String> awsPatterns = repo.loadPatterns(PatternType.AWS);
compiler.register(awsPatterns);

🏷️ ECS-Style Field Names

Supports Elastic Common Schema style nested field names:

GrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
// Use ECS-style field namesGrokgrok = compiler.compile("%{LOGLEVEL:[log][level]} %{IP:[source][ip]}");
Matchmatch = grok.match("ERROR 192.168.1.1");
Map<String, Object> result = match.capture();
// Access nested fields// result = {log.level=ERROR, source.ip=192.168.1.1}

📋 Available Pattern Types

CategoryPattern TypesDescription
CorePATTERNSBase Grok patterns (IP, URI, NUMBER, etc.)
Cloud & InfrastructureAWS, HAPROXY, HTTPD, SQUIDS3, ELB, CloudFront, load balancer, proxy logs
DatabasesMONGODB, POSTGRESQL, REDISDatabase query and server logs
System & NetworkLINUX_SYSLOG, FIREWALLS, BIND, JUNOS, BRO, ZEEKSyslog, iptables, DNS, network security
ApplicationsJAVA, RAILS, RUBY, POSTFIX, EXIMApplication and mail server logs
Monitoring & BackupNAGIOS, BACULA, MCOLLECTIVEMonitoring and backup system logs
Build ToolsMAVENVersion patterns for build tools

Total: 23 pattern types with 450+ patterns

🔒 Security Features

ReDoS Protection

Java Grok includes protection against Regular Expression Denial of Service (ReDoS) attacks:

// Default: 1MB input limitGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Configure custom limitGrok.setMaxInputLength(512 * 1024); // 512KB// Disable limit (not recommended)Grok.setMaxInputLength(0);

Thread Safety

All pattern compilation and matching operations are thread-safe:

// Safe for concurrent useGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
Grokgrok = compiler.compile("%{IP:client}");
// Can be used from multiple threadsExecutorServiceexecutor = Executors.newFixedThreadPool(10);
for (inti = 0; i < 100; i++) {
executor.submit(() -> {
Matchmatch = grok.match("192.168.1.1");
// ...
});
}

🔧 Build & Test

# Build the project
./gradlew assemble
# Run tests
./gradlew test# Run specific tests
./gradlew test --tests PatternManagementServiceTest

📖 Documentation

🤝 Contributing

Any contributions are warmly welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

Grok is inspired by the Logstash Grok filter and builds upon the foundation of io.krakens:java-grok with significant enhancements.

About

Simple API that allows you to easily parse logs and other files

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Java Grok

WhaTap Log Monitoring Grok Parser

This is a fork of io.krakens:java-grok, customized for WhaTap Log Monitoring service. It provides enhanced pattern support, ECS-style field names, and reserved keyword handling for WhaTap's internal processing.

Java Grok is a powerful API that allows you to easily parse logs and other files (single line). With Java Grok, you can turn unstructured log and event data into structured data (JSON).

✨ Features

  • 🚀 High Performance: Built with O(1) LRU caching and memory optimization
  • 🔒 Security: ReDoS protection with configurable input length limits
  • 🧵 Thread-Safe: Concurrent pattern compilation and matching
  • 📦 Enum-based Pattern Management: 23 categorized pattern types with 450+ patterns
  • 🔍 Advanced Pattern Search: Find patterns across multiple types and categories
  • 📊 Pattern Statistics: Get comprehensive insights about available patterns
  • 🏷️ Type-safe Pattern Access: Enum-based approach for better IDE support
  • 🔄 ECS Field Support: Supports Elastic Common Schema style field names like [log][level]
  • 🔄 Backward Compatibility: Drop-in replacement for io.krakens:java-grok

⚠️ Breaking Changes (v0.1.1)

Reserved Field Name Changes for WhaTap Log Monitoring

WhaTap Log Monitoring uses certain field names as reserved keywords for internal processing. To avoid conflicts with these system fields, the following field names have been renamed in all built-in patterns:

Original FieldNew FieldReason (WhaTap Reserved)
timestamplog_timestampAbstractPack.time
timelog_timeAbstractPack.time
messagelog_messageSystem reserved
contentlog_contentLogSinkPack.content
categorylog_categoryLogSinkPack.category
pcodelog_pcodeAbstractPack.pcode
logContentlog_bodySystem reserved

Impact: If you are using built-in patterns like COMBINEDAPACHELOG, SYSLOG5424LINE, CATALINA_LOG, etc., the extracted field names have changed. Update your code to use the new field names.

Example Migration:

// Before (v0.1.0)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("timestamp");
Stringmessage = (String) result.get("message");
// After (v0.1.1)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("log_timestamp");
Stringmessage = (String) result.get("log_message");

Note: Custom field names defined in your own patterns (e.g., %{TIMESTAMP_ISO8601:my_timestamp}) are not affected by this change.


What can I use Grok for?

  • Log Processing: Parse Apache, Nginx, MongoDB, PostgreSQL, Redis, Zeek, and more log formats
  • Pattern Discovery: Search and explore 450+ built-in patterns across 23 categories
  • JSON Conversion: Transform unstructured text into structured JSON data
  • ECS Compliance: Extract fields using Elastic Common Schema naming conventions
  • Error Reporting: Extract specific patterns from logs and processes
  • Regular Expression Management: Apply 'write-once use-everywhere' to regex patterns

Maven repository

<!-- https://mvnrepository.com/artifact/io.github.whatap/java-grok -->
<dependency>
<groupId>io.github.whatap</groupId>
<artifactId>java-grok</artifactId>
<version>0.1.1</version>
</dependency>

Or with gradle

// https://mvnrepository.com/artifact/io.github.whatap/java-grok
implementation 'io.github.whatap:java-grok:0.1.1'

What is different from io.krakens:java-grok

Key Improvements:

  1. ECS-Style Field Names: Supports [log][level] style nested field names
  2. Thread Safety: ConcurrentHashMap for pattern definitions
  3. O(1) LRU Cache: Efficient cache eviction using LinkedHashMap
  4. ReDoS Protection: Configurable input length limits
  5. More Patterns: 23 pattern types (vs 18), 450+ patterns (vs 400+)
  6. Better Regex: Improved pattern and subname validation

Pattern Regex Differences:

Featureio.krakens:java-grokio.github.whatap
pattern[A-z0-9]+[a-zA-Z][a-zA-Z0-9_\-\.]*[a-zA-Z0-9]
subname[A-z0-9_:;,\-\/\s\.']+ECS-style [field][name] + legacy

@See GrokUtils.java

🚀 Quick Start

Basic Usage

importio.whatap.grok.api.GrokCompiler;
importio.whatap.grok.api.Grok;
importio.whatap.grok.api.Match;
// Create a new grok compiler instanceGrokCompilergrokCompiler = GrokCompiler.newInstance();
grokCompiler.registerDefaultPatterns();
// Compile a grok pattern for Apache logsfinalGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Parse a log lineStringlog = "112.169.19.192 - - [06/Mar/2013:01:36:30 +0900] \"GET / HTTP/1.1\" 200 44346 \"-\"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22\"";
Matchmatch = grok.match(log);
Map<String, Object> result = match.capture();

🏷️ Enum-based Pattern Management (New!)

importio.whatap.grok.api.*;
// Get pattern management servicePatternManagementServiceservice = newPatternManagementService();
// Get all available pattern typesList<PatternManagementService.PatternTypeInfo> types = service.getAllPatternTypes();
// Get patterns by categoryMap<String, List<PatternManagementService.PatternTypeInfo>> categories = service.getPatternTypesByCategory();
// Load specific pattern typePatternManagementService.PatternTypeDetailsmongoPatterns = service.getPatternTypeDetails(PatternType.MONGODB);
// Search for specific patternsList<PatternManagementService.PatternInfo> patterns = service.searchPatterns("MONGO_QUERY");
// Get comprehensive statisticsPatternManagementService.PatternStatisticsstats = service.getPatternStatistics();
System.out.println("Total patterns: " + stats.getTotalPatterns()); // 450+

📦 Using Specific Pattern Types

// Register only specific pattern typesGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerPatterns(PatternType.MONGODB, PatternType.PATTERNS);
// Or register patterns from specific categoriesPatternRepositoryrepo = PatternRepository.getInstance();
Map<String, String> awsPatterns = repo.loadPatterns(PatternType.AWS);
compiler.register(awsPatterns);

🏷️ ECS-Style Field Names

Supports Elastic Common Schema style nested field names:

GrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
// Use ECS-style field namesGrokgrok = compiler.compile("%{LOGLEVEL:[log][level]} %{IP:[source][ip]}");
Matchmatch = grok.match("ERROR 192.168.1.1");
Map<String, Object> result = match.capture();
// Access nested fields// result = {log.level=ERROR, source.ip=192.168.1.1}

📋 Available Pattern Types

CategoryPattern TypesDescription
CorePATTERNSBase Grok patterns (IP, URI, NUMBER, etc.)
Cloud & InfrastructureAWS, HAPROXY, HTTPD, SQUIDS3, ELB, CloudFront, load balancer, proxy logs
DatabasesMONGODB, POSTGRESQL, REDISDatabase query and server logs
System & NetworkLINUX_SYSLOG, FIREWALLS, BIND, JUNOS, BRO, ZEEKSyslog, iptables, DNS, network security
ApplicationsJAVA, RAILS, RUBY, POSTFIX, EXIMApplication and mail server logs
Monitoring & BackupNAGIOS, BACULA, MCOLLECTIVEMonitoring and backup system logs
Build ToolsMAVENVersion patterns for build tools

Total: 23 pattern types with 450+ patterns

🔒 Security Features

ReDoS Protection

Java Grok includes protection against Regular Expression Denial of Service (ReDoS) attacks:

// Default: 1MB input limitGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Configure custom limitGrok.setMaxInputLength(512 * 1024); // 512KB// Disable limit (not recommended)Grok.setMaxInputLength(0);

Thread Safety

All pattern compilation and matching operations are thread-safe:

// Safe for concurrent useGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
Grokgrok = compiler.compile("%{IP:client}");
// Can be used from multiple threadsExecutorServiceexecutor = Executors.newFixedThreadPool(10);
for (inti = 0; i < 100; i++) {
executor.submit(() -> {
Matchmatch = grok.match("192.168.1.1");
// ...
});
}

🔧 Build & Test

# Build the project
./gradlew assemble
# Run tests
./gradlew test# Run specific tests
./gradlew test --tests PatternManagementServiceTest

📖 Documentation

🤝 Contributing

Any contributions are warmly welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

Grok is inspired by the Logstash Grok filter and builds upon the foundation of io.krakens:java-grok with significant enhancements.

About

Simple API that allows you to easily parse logs and other files

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Java Grok

WhaTap Log Monitoring Grok Parser

This is a fork of io.krakens:java-grok, customized for WhaTap Log Monitoring service. It provides enhanced pattern support, ECS-style field names, and reserved keyword handling for WhaTap's internal processing.

Java Grok is a powerful API that allows you to easily parse logs and other files (single line). With Java Grok, you can turn unstructured log and event data into structured data (JSON).

✨ Features

  • 🚀 High Performance: Built with O(1) LRU caching and memory optimization
  • 🔒 Security: ReDoS protection with configurable input length limits
  • 🧵 Thread-Safe: Concurrent pattern compilation and matching
  • 📦 Enum-based Pattern Management: 23 categorized pattern types with 450+ patterns
  • 🔍 Advanced Pattern Search: Find patterns across multiple types and categories
  • 📊 Pattern Statistics: Get comprehensive insights about available patterns
  • 🏷️ Type-safe Pattern Access: Enum-based approach for better IDE support
  • 🔄 ECS Field Support: Supports Elastic Common Schema style field names like [log][level]
  • 🔄 Backward Compatibility: Drop-in replacement for io.krakens:java-grok

⚠️ Breaking Changes (v0.1.1)

Reserved Field Name Changes for WhaTap Log Monitoring

WhaTap Log Monitoring uses certain field names as reserved keywords for internal processing. To avoid conflicts with these system fields, the following field names have been renamed in all built-in patterns:

Original FieldNew FieldReason (WhaTap Reserved)
timestamplog_timestampAbstractPack.time
timelog_timeAbstractPack.time
messagelog_messageSystem reserved
contentlog_contentLogSinkPack.content
categorylog_categoryLogSinkPack.category
pcodelog_pcodeAbstractPack.pcode
logContentlog_bodySystem reserved

Impact: If you are using built-in patterns like COMBINEDAPACHELOG, SYSLOG5424LINE, CATALINA_LOG, etc., the extracted field names have changed. Update your code to use the new field names.

Example Migration:

// Before (v0.1.0)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("timestamp");
Stringmessage = (String) result.get("message");
// After (v0.1.1)Map<String, Object> result = match.capture();
Stringtimestamp = (String) result.get("log_timestamp");
Stringmessage = (String) result.get("log_message");

Note: Custom field names defined in your own patterns (e.g., %{TIMESTAMP_ISO8601:my_timestamp}) are not affected by this change.


What can I use Grok for?

  • Log Processing: Parse Apache, Nginx, MongoDB, PostgreSQL, Redis, Zeek, and more log formats
  • Pattern Discovery: Search and explore 450+ built-in patterns across 23 categories
  • JSON Conversion: Transform unstructured text into structured JSON data
  • ECS Compliance: Extract fields using Elastic Common Schema naming conventions
  • Error Reporting: Extract specific patterns from logs and processes
  • Regular Expression Management: Apply 'write-once use-everywhere' to regex patterns

Maven repository

<!-- https://mvnrepository.com/artifact/io.github.whatap/java-grok -->
<dependency>
<groupId>io.github.whatap</groupId>
<artifactId>java-grok</artifactId>
<version>0.1.1</version>
</dependency>

Or with gradle

// https://mvnrepository.com/artifact/io.github.whatap/java-grok
implementation 'io.github.whatap:java-grok:0.1.1'

What is different from io.krakens:java-grok

Key Improvements:

  1. ECS-Style Field Names: Supports [log][level] style nested field names
  2. Thread Safety: ConcurrentHashMap for pattern definitions
  3. O(1) LRU Cache: Efficient cache eviction using LinkedHashMap
  4. ReDoS Protection: Configurable input length limits
  5. More Patterns: 23 pattern types (vs 18), 450+ patterns (vs 400+)
  6. Better Regex: Improved pattern and subname validation

Pattern Regex Differences:

Featureio.krakens:java-grokio.github.whatap
pattern[A-z0-9]+[a-zA-Z][a-zA-Z0-9_\-\.]*[a-zA-Z0-9]
subname[A-z0-9_:;,\-\/\s\.']+ECS-style [field][name] + legacy

@See GrokUtils.java

🚀 Quick Start

Basic Usage

importio.whatap.grok.api.GrokCompiler;
importio.whatap.grok.api.Grok;
importio.whatap.grok.api.Match;
// Create a new grok compiler instanceGrokCompilergrokCompiler = GrokCompiler.newInstance();
grokCompiler.registerDefaultPatterns();
// Compile a grok pattern for Apache logsfinalGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Parse a log lineStringlog = "112.169.19.192 - - [06/Mar/2013:01:36:30 +0900] \"GET / HTTP/1.1\" 200 44346 \"-\"\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22\"";
Matchmatch = grok.match(log);
Map<String, Object> result = match.capture();

🏷️ Enum-based Pattern Management (New!)

importio.whatap.grok.api.*;
// Get pattern management servicePatternManagementServiceservice = newPatternManagementService();
// Get all available pattern typesList<PatternManagementService.PatternTypeInfo> types = service.getAllPatternTypes();
// Get patterns by categoryMap<String, List<PatternManagementService.PatternTypeInfo>> categories = service.getPatternTypesByCategory();
// Load specific pattern typePatternManagementService.PatternTypeDetailsmongoPatterns = service.getPatternTypeDetails(PatternType.MONGODB);
// Search for specific patternsList<PatternManagementService.PatternInfo> patterns = service.searchPatterns("MONGO_QUERY");
// Get comprehensive statisticsPatternManagementService.PatternStatisticsstats = service.getPatternStatistics();
System.out.println("Total patterns: " + stats.getTotalPatterns()); // 450+

📦 Using Specific Pattern Types

// Register only specific pattern typesGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerPatterns(PatternType.MONGODB, PatternType.PATTERNS);
// Or register patterns from specific categoriesPatternRepositoryrepo = PatternRepository.getInstance();
Map<String, String> awsPatterns = repo.loadPatterns(PatternType.AWS);
compiler.register(awsPatterns);

🏷️ ECS-Style Field Names

Supports Elastic Common Schema style nested field names:

GrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
// Use ECS-style field namesGrokgrok = compiler.compile("%{LOGLEVEL:[log][level]} %{IP:[source][ip]}");
Matchmatch = grok.match("ERROR 192.168.1.1");
Map<String, Object> result = match.capture();
// Access nested fields// result = {log.level=ERROR, source.ip=192.168.1.1}

📋 Available Pattern Types

CategoryPattern TypesDescription
CorePATTERNSBase Grok patterns (IP, URI, NUMBER, etc.)
Cloud & InfrastructureAWS, HAPROXY, HTTPD, SQUIDS3, ELB, CloudFront, load balancer, proxy logs
DatabasesMONGODB, POSTGRESQL, REDISDatabase query and server logs
System & NetworkLINUX_SYSLOG, FIREWALLS, BIND, JUNOS, BRO, ZEEKSyslog, iptables, DNS, network security
ApplicationsJAVA, RAILS, RUBY, POSTFIX, EXIMApplication and mail server logs
Monitoring & BackupNAGIOS, BACULA, MCOLLECTIVEMonitoring and backup system logs
Build ToolsMAVENVersion patterns for build tools

Total: 23 pattern types with 450+ patterns

🔒 Security Features

ReDoS Protection

Java Grok includes protection against Regular Expression Denial of Service (ReDoS) attacks:

// Default: 1MB input limitGrokgrok = grokCompiler.compile("%{COMBINEDAPACHELOG}");
// Configure custom limitGrok.setMaxInputLength(512 * 1024); // 512KB// Disable limit (not recommended)Grok.setMaxInputLength(0);

Thread Safety

All pattern compilation and matching operations are thread-safe:

// Safe for concurrent useGrokCompilercompiler = GrokCompiler.newInstance();
compiler.registerDefaultPatterns();
Grokgrok = compiler.compile("%{IP:client}");
// Can be used from multiple threadsExecutorServiceexecutor = Executors.newFixedThreadPool(10);
for (inti = 0; i < 100; i++) {
executor.submit(() -> {
Matchmatch = grok.match("192.168.1.1");
// ...
});
}

🔧 Build & Test

# Build the project
./gradlew assemble
# Run tests
./gradlew test# Run specific tests
./gradlew test --tests PatternManagementServiceTest

📖 Documentation

🤝 Contributing

Any contributions are warmly welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📜 License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

🙏 Acknowledgments

Grok is inspired by the Logstash Grok filter and builds upon the foundation of io.krakens:java-grok with significant enhancements.

About

Simple API that allows you to easily parse logs and other files

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages