
com.github.jcustenborder.netty.syslog.CEFMessageParser Maven / Gradle / Ivy
/**
* Copyright © 2018 Jeremy Custenborder ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.jcustenborder.netty.syslog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
public class CEFMessageParser extends MessageParser {
private static final Logger log = LoggerFactory.getLogger(CEFMessageParser.class);
private static final String CEF_PREFIX_PATTERN = "^(<(?\\d+)>)?(?([a-zA-Z]{3}\\s+\\d+\\s+\\d+:\\d+:\\d+)|([0-9T:.Z-]+))\\s+(?\\S+)\\s+CEF:(?\\d+)\\|(?.*)$";
private static final String CEF_MAIN_PATTERN = "(? matcherCEFPrefix;
private final ThreadLocal matcherCEFMain;
private final ThreadLocal matcherCEFExtension;
public CEFMessageParser() {
this.matcherCEFPrefix = initMatcher(CEF_PREFIX_PATTERN);
this.matcherCEFMain = initMatcher(CEF_MAIN_PATTERN);
this.matcherCEFExtension = initMatcher(PATTERN_EXTENSION);
}
List splitToList(String data) {
List result = new ArrayList<>(10);
final Matcher matcherData = this.matcherCEFMain.get().reset(data);
int start = 0;
int end = 0;
while (matcherData.find()) {
end = matcherData.end();
String part = data.substring(start, end - 1);
start = end;
result.add(part);
}
if (data.length() > end) {
result.add(data.substring(end));
}
return result;
}
@Override
public Message parse(SyslogRequest request) {
log.trace("parse() - request = '{}'", request);
final Matcher matcherPrefix = this.matcherCEFPrefix.get().reset(request.rawMessage());
if (!matcherPrefix.find()) {
log.trace("parse() - Could not match message. request = '{}'", request);
return null;
}
log.trace("parse() - Parsed message as CEF.");
final String groupPriority = matcherPrefix.group("priority");
final String groupDate = matcherPrefix.group("date");
final String groupHost = matcherPrefix.group("host");
final String groupCEFVersion = matcherPrefix.group("version");
final String groupData = matcherPrefix.group("data");
final Integer priority = (groupPriority == null || groupPriority.isEmpty()) ? null : Integer.parseInt(groupPriority);
final Integer facility = null == priority ? null : Priority.facility(priority);
final Integer level = null == priority ? null : Priority.level(priority, facility);
final LocalDateTime date = parseDate(groupDate);
final Integer cefVersion = Integer.parseInt(groupCEFVersion);
final List parts = splitToList(groupData);
ImmutableMessage.Builder builder = ImmutableMessage.builder();
builder.type(MessageType.CEF);
builder.rawMessage(request.rawMessage());
builder.remoteAddress(request.remoteAddress());
builder.date(date);
builder.version(cefVersion);
builder.host(groupHost);
builder.level(level);
builder.facility(facility);
int index = 0;
for (String token : parts) {
token = token.replace("\\|", "|");
log.trace("parse() - index={}, token='{}'", index, token);
switch (index) {
case 0:
builder.deviceVendor(token);
break;
case 1:
builder.deviceProduct(token);
break;
case 2:
builder.deviceVersion(token);
break;
case 3:
builder.deviceEventClassId(token);
break;
case 4:
builder.name(token);
break;
case 5:
builder.severity(token);
break;
case 6:
Map extension = parseExtension(token);
builder.extension(extension);
break;
default:
break;
}
index++;
}
return builder.build();
}
private Map parseExtension(String token) {
log.trace("parseExtension() - token = '{}'", token);
final Map result = new LinkedHashMap<>();
if (null == token || token.isEmpty()) {
return result;
}
Matcher matcher = this.matcherCEFExtension.get().reset(token);
String key = null;
String value;
int lastEnd = -1, lastStart = -1;
while (matcher.find()) {
log.trace("parseExtension() - matcher.start() = {}, matcher.end() = {}", matcher.start(), matcher.end());
if (lastEnd > -1) {
value = token.substring(lastEnd, matcher.start()).trim();
result.put(key, value);
log.trace("parseExtension() - key='{}' value='{}'", key, value);
}
key = matcher.group(1);
lastStart = matcher.start();
lastEnd = matcher.end();
}
if (lastStart > -1 && !result.containsKey(key)) {
value = token.substring(lastEnd).trim();
result.put(key, value);
log.trace("parseExtension() - key='{}' value='{}'", key, value);
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy