/**
* Copyright 2015 Eediom Inc.
*
* 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 org.araqne.logparser.krsyslog.umv;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.araqne.log.api.V1LogParser;
/**
* @since 1.9.2
* @author mindori
*
*/
public class ShellMonitorParser extends V1LogParser {
private final org.slf4j.Logger slog = org.slf4j.LoggerFactory.getLogger(ShellMonitorParser.class.getName());
public final static String[] DETECTION_FIELDS = new String[] { "svr_id", "svr_name", "log_type", "agent_num", "agent_name",
"agent_ip", "group_id", "group_name", "svr_time", "agent_time", "detect_type", "file_type", "file_path", "encoded",
"new_file_time", "new_file_size", "old_file_time", "old_file_size", "line_num", "offset", "pattern_len",
"pattern_string", "known" };
public final static String[] STATUS_FIELDS = new String[] { "svr_id", "svr_name", "log_type", "host_type", "host_id",
"host_name", "host_ip", "group_id", "group_name", "status", "msg_code", "msg" };
public final static String[] TRANSACTION_FIELDS = new String[] { "svr_id", "svr_name", "log_type", "tx_id", "tx_type",
"send_type", "send_id", "send_name", "send_ip", "send_group_id", "send_group_name", "recv_type", "recv_id",
"recv_name", "recv_ip", "recv_group_id", "recv_group_name" };
public final static String[] FILTERING_FIELDS = new String[] { "svr_id", "svr_name", "log_type", "agent_num", "agent_name",
"agent_ip", "group_id", "group_name", "svr_time", "agent_time", "result", "file_path", "quarantined",
"quarantine_time", "new_file_time", "new_file_size", "old_file_time", "old_file_size" };
public final static String[] ALERT_FIELDS = new String[] { "svr_id", "svr_name", "log_type", "agent_num", "agent_name",
"agent_ip", "group_id", "group_name", "svr_time", "pdu", "pdu_msg", "raw_data" };
@Override
public Map<String, Object> parse(Map<String, Object> params) {
String line = (String) params.get("line");
if (line == null)
return params;
try {
int b = line.indexOf(':');
if (b < 0)
return params;
// e.g. skip agent time Apr 17 12:50:24
int e = line.indexOf(' ', b);
if (e < 0)
return params;
b = e + 1;
e = line.indexOf(' ', b);
if (e < 0)
return params;
e = line.indexOf(':', e + 1);
if (e < 0)
return params;
List<String> tokens = new ArrayList<String>(30);
StringBuilder sb = new StringBuilder();
int len = line.length();
int p = e + 1;
while (p < len) {
// skip whitespace
char c = '\0';
while (p < len) {
c = line.charAt(p++);
if (c != ' ' && c != '\t')
break;
}
if (c == ':') {
tokens.add(null);
continue;
}
boolean quoted = c == '"';
boolean bracket = c == '[';
if (bracket) {
// find closing bracket (fucking shellmonitor bug)
e = line.indexOf(']', p + 1);
String token = line.substring(p, e);
tokens.add(token);
p = e + 1;
}
if (quoted) {
// find next quote
char lastChar = '\0';
p++;
while (p < len) {
c = line.charAt(p++);
if (c == '"' && lastChar != '\\')
break;
if (c != '\\' || lastChar == '\\')
sb.append(c);
lastChar = c;
}
if (lastChar == ']')
sb.deleteCharAt(sb.length() - 1);
String token = sb.toString();
sb.delete(0, token.length());
tokens.add(token);
} else {
// find end of string
b = p - 1;
while (p < len) {
c = line.charAt(p);
if (c == ' ' || c == '\t' || c == ':')
break;
p++;
}
if (p == len) {
tokens.add(line.substring(b));
} else if (p > b) {
tokens.add(line.substring(b, p));
}
}
// skip whitespace and next colon
boolean broken = false;
while (p < len) {
c = line.charAt(p++);
if (c == ':')
break;
if (c == ' ' || c == '\t')
continue;
broken = true;
}
// fix fucking shellmonitor bug at alert log
if (broken) {
String fixed = line.substring(b, p - 1).trim();
tokens.remove(tokens.size() - 1);
tokens.add(fixed);
}
}
if (tokens.isEmpty())
return params;
String logType = tokens.get(2);
if (logType.equals("D")) {
return map(tokens, DETECTION_FIELDS);
} else if (logType.equals("S")) {
return map(tokens, STATUS_FIELDS);
} else if (logType.equals("T")) {
return map(tokens, TRANSACTION_FIELDS);
} else if (logType.equals("F")) {
return map(tokens, FILTERING_FIELDS);
} else if (logType.equals("A")) {
return map(tokens, ALERT_FIELDS);
}
return params;
} catch (Throwable t) {
if (slog.isDebugEnabled())
slog.debug("araqne log api: cannot parse umv shellmonitor log - line [{}]", line);
return params;
}
}
private Map<String, Object> map(List<String> tokens, String[] fieldNames) {
Map<String, Object> m = new HashMap<String, Object>();
int i = 0;
int len = fieldNames.length;
for (String token : tokens) {
String field = fieldNames[i++];
m.put(field, token);
if (i >= len)
break;
}
return m;
}
}