package storm.applications.model.log;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Class that encapsulates the data and parsing logic for a single log record (json) in a log file
* Log record json structure sent from logstash:
* {
* "@source":"file://PATH",
* "@tags":[],
* "@fields":{},
* "@timestamp":"yyyy-MM-ddThh:mm:ss.SSS",
* "@source_host":"hostname",
* "@source_path":"path",
* "@message":"Syslog log line contents",
* "@type":"syslog"
* }
*/
public class LogEntry {
public static final Logger LOG = LoggerFactory.getLogger(LogEntry.class);
private String source;
private String type;
private List<String> tags = new ArrayList<String>();
private Map<String,String> fields = new HashMap<String, String>();
private Date timestamp;
private String sourceHost;
private String sourcePath;
private String message = "";
private boolean filter = false;
private NotificationDetails notifyAbout = null;
private static final String[] FORMATS = new String[] {
"yyyy-MM-dd'T'HH:mm:ss.SSS",
"yyyy.MM.dd G 'at' HH:mm:ss z",
"yyyyy.MMMMM.dd GGG hh:mm aaa",
"EEE, d MMM yyyy HH:mm:ss Z",
"yyMMddHHmmssZ"
};
public LogEntry(JSONObject json){
source = (String) json.get("@source");
timestamp = parseDate((String)json.get("@timestamp"));
sourceHost = (String)json.get("@source_host");
sourcePath = (String)json.get("@source_path");
message = (String)json.get("@message");
type = (String)json.get("@type");
JSONArray array = (JSONArray)json.get("@tags");
tags.addAll(array);
JSONObject fieldsTmp = (JSONObject)json.get("@fields");
fields.putAll(fieldsTmp);
}
/*
* The date format can vary from log entry to entry, therefore parseDate() provides a best effort approach to
* parsing the date
*/
public final Date parseDate(String value){
for (String format : FORMATS) {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
Date temp;
try {
temp = dateFormat.parse(value);
if(temp != null)
return temp;
} catch (ParseException e) {}
}
LOG.error("Could not parse timestamp for log");
return null;
}
public JSONObject toJSON(){
JSONObject json = new JSONObject();
json.put("@source", source);
json.put("@timestamp", DateFormat.getDateInstance().format(timestamp));
json.put("@source_host",sourceHost);
json.put("@source_path",sourcePath);
json.put("@message",message);
json.put("@type",type);
JSONArray temp = new JSONArray();
temp.addAll(tags);
json.put("@tags", temp);
JSONObject fieldTemp = new JSONObject();
fieldTemp.putAll(fields);
json.put("@fields",fieldTemp);
return json;
}
public boolean isFilter() {
return filter;
}
public void setFilter(boolean filter) {
this.filter = filter;
}
public NotificationDetails getNotificationDetails() {
return notifyAbout;
}
public void notifyAbout(NotificationDetails notifyAbout) {
this.notifyAbout = notifyAbout;
}
public String getSource() {
return source;
}
public List<String> getTags() {
return tags;
}
public Map<String, String> getFields() {
return fields;
}
public void addField(String name, String value){
fields.put(name, value);
}
public void addTag(String tag){
tags.add(tag);
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public String getSourceHost() {
return sourceHost;
}
public String getSourcePath() {
//sourcePath.contains("");
return sourcePath;
}
public String getMessage() {
return message;
}
public void setSource(String source) {
this.source = source;
}
public void setSourceHost(String sourceHost) {
this.sourceHost = sourceHost;
}
public void setSourcePath(String sourcePath) {
this.sourcePath = sourcePath;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((fields == null) ? 0 : fields.hashCode());
result = prime * result + (filter ? 1231 : 1237);
result = prime * result + ((message == null) ? 0 : message.hashCode());
result = prime * result + ((source == null) ? 0 : source.hashCode());
result = prime * result
+ ((sourceHost == null) ? 0 : sourceHost.hashCode());
result = prime * result
+ ((sourcePath == null) ? 0 : sourcePath.hashCode());
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
result = prime * result
+ ((timestamp == null) ? 0 : timestamp.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LogEntry other = (LogEntry) obj;
if (fields == null) {
if (other.fields != null)
return false;
} else if (!fields.equals(other.fields))
return false;
if (filter != other.filter)
return false;
if (message == null) {
if (other.message != null)
return false;
} else if (!message.equals(other.message))
return false;
if (source == null) {
if (other.source != null)
return false;
} else if (!source.equals(other.source))
return false;
if (sourceHost == null) {
if (other.sourceHost != null)
return false;
} else if (!sourceHost.equals(other.sourceHost))
return false;
if (sourcePath == null) {
if (other.sourcePath != null)
return false;
} else if (!sourcePath.equals(other.sourcePath))
return false;
if (tags == null) {
if (other.tags != null)
return false;
} else if (!tags.equals(other.tags))
return false;
if (timestamp == null) {
if (other.timestamp != null)
return false;
} else if (!timestamp.equals(other.timestamp))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
}