/* * Copyright (c) 2014 EMC Corporation * All Rights Reserved */ package com.emc.storageos.systemservices.impl.logsvc.parse; import java.util.Calendar; import java.util.Date; import com.emc.storageos.management.jmx.logging.ViPRHeaderPatternLayout; import com.emc.storageos.systemservices.impl.logsvc.LogMessage; import com.emc.storageos.systemservices.impl.logsvc.util.LogUtil; import com.emc.vipr.model.sys.logging.LogRequest; import com.emc.vipr.model.sys.logging.LogSeverity; /** * Parser class to parse lines from log file to LogMessage Objects * * @author siy * */ public class LogServiceParser extends LogParser { private static Calendar logDate = Calendar.getInstance(); // length of the time 2013-11-20 13:56:48,063 [ private final int TIME_LENGTH = 25; // milliseconds since epoch, will remain 13 digits for another 2 hundred years private final int HEADER_TIMESTAMP_LENGTH = 13; /** * Parse line from file to LogMessage * If line does not match log format(it * is the message part for multiple lines log), return * LogMessage.CONTINUATION_LOGMESSAGE; if line matches log formant, time is * too late for time filter, return LogMessage.REJECTED_LAST_LOGMESSAGE if * line matches log formant, but does not match all filters, return * LogMessage.REJECTED_LOGMESSAGE; if line matches log formant and all * filters, return LogMessage object */ @Override public LogMessage parseLine(String line, LogRequest info) { int lineLength = line.length(); if (lineLength == ViPRHeaderPatternLayout.HEADER_START_LENGTH + HEADER_TIMESTAMP_LENGTH) { boolean isHeaderStart = true; for (int i = 0; i < ViPRHeaderPatternLayout.HEADER_START_LENGTH; i++) { if (line.charAt(i) != ViPRHeaderPatternLayout.HEADER_START_INDICATOR) { isHeaderStart = false; break; } } if (isHeaderStart) { // find the timestamp at the end of the header start line String timestampStr = line.substring(ViPRHeaderPatternLayout.HEADER_START_LENGTH); long timestamp = Long.parseLong(timestampStr); int inTime = LogUtil.timeInRange(new Date(timestamp), info.getStartTime(), info.getEndTime()); if (inTime < 0) { // too early return LogMessage.REJECTED_LOGMESSAGE; } else if (inTime > 0) { // too late return LogMessage.REJECTED_LAST_LOGMESSAGE; } LogMessage header = LogMessage.makeHeaderLog(timestamp); return header; } } if (lineLength <= TIME_LENGTH || line.charAt(4) != '-' || line.charAt(7) != '-' || line.charAt(10) != ' ' || line.charAt(13) != ':' || line.charAt(16) != ':' || line.charAt(19) != ',' || line.charAt(23) != ' ' || line.charAt(24) != '[') { return LogMessage.CONTINUATION_LOGMESSAGE; } /* * final String[] parts = line.substring(0, * timeLength).split("[\\s-:,]"); if (parts.length < 7) { return * LogMessage.CONTINUATION_LOGMESSAGE; } * * int[] partsInt = new int[7]; for (int i = 0; i < 7; i++) { * partsInt[i] = toNumber(parts[i]); if (partsInt[i] < 0) { return * LogMessage.CONTINUATION_LOGMESSAGE; } } */ String yearStr = line.substring(0, 4); int year = toNumber(yearStr); if (year < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } String monthStr = line.substring(5, 7); int month = toNumber(monthStr); if (month < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } String dayStr = line.substring(8, 10); int day = toNumber(dayStr); if (day < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } String hourStr = line.substring(11, 13); int hour = toNumber(hourStr); if (hour < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } String minStr = line.substring(14, 16); int min = toNumber(minStr); if (min < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } String secStr = line.substring(17, 19); int sec = toNumber(secStr); if (sec < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } String msStr = line.substring(20, 23); int ms = toNumber(msStr); if (ms < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } String timeStr = line.substring(0, TIME_LENGTH - 2); final int endBracket = line.indexOf("]", TIME_LENGTH); if (endBracket < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } if (endBracket - TIME_LENGTH > Short.MAX_VALUE) { return LogMessage.CONTINUATION_LOGMESSAGE; } // Skip white spaces before level int levelStartIndex = endBracket + 1; while (levelStartIndex < lineLength && line.charAt(levelStartIndex) == ' ') { levelStartIndex++; } if (levelStartIndex >= lineLength || levelStartIndex > Short.MAX_VALUE) { return LogMessage.CONTINUATION_LOGMESSAGE; } // Find the next white space after level int levelEndIndex = line.indexOf(' ', levelStartIndex); if (levelEndIndex < 0 || levelEndIndex - levelStartIndex > Short.MAX_VALUE) { return LogMessage.CONTINUATION_LOGMESSAGE; } final String levelString = line.substring(levelStartIndex, levelEndIndex); final int level = LogSeverity.toLevel(levelString); if (level < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } int fileNameStartIndex = levelEndIndex + 1; // Skip white spaces before file name while (fileNameStartIndex < lineLength && line.charAt(fileNameStartIndex) == ' ') { fileNameStartIndex++; } if (fileNameStartIndex >= lineLength || fileNameStartIndex > Short.MAX_VALUE) { return LogMessage.CONTINUATION_LOGMESSAGE; } // Find the next white space after file name final int fileNameEndIndex = line.indexOf(' ', fileNameStartIndex); if (fileNameEndIndex < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } if (fileNameEndIndex + 1 >= lineLength || fileNameEndIndex - fileNameStartIndex > Short.MAX_VALUE) { return LogMessage.CONTINUATION_LOGMESSAGE; } if (line.charAt(fileNameEndIndex + 1) != '(') { return LogMessage.CONTINUATION_LOGMESSAGE; } int classNameStartIndex = fileNameStartIndex; int classNameEndIndex = fileNameEndIndex; if (line.charAt(fileNameEndIndex - 5) == '.') { // remove the trailing .java classNameEndIndex -= 5; } int rightParentheseIndex = line.indexOf(')', fileNameEndIndex + 1); if (rightParentheseIndex <= 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } String[] lineNumber = line.substring(fileNameEndIndex + 1, rightParentheseIndex).split(" "); if (lineNumber.length != 2) { return LogMessage.CONTINUATION_LOGMESSAGE; } int lineNo = toNumber(lineNumber[1]); if (lineNo < 0) { return LogMessage.CONTINUATION_LOGMESSAGE; } // rightParentheseIndex+1 is a white space int messageStartIndex = rightParentheseIndex + 2; if (rightParentheseIndex + 2 > lineLength) { // it could be true, like a stacktrace of an exception // in which case the first line is "" messageStartIndex = lineLength; } if (messageStartIndex > Short.MAX_VALUE) { return LogMessage.CONTINUATION_LOGMESSAGE; } // test time filter // int inTime = inTimeRange(partsInt[0], partsInt[1], partsInt[2], // partsInt[3], partsInt[4], partsInt[5], partsInt[6],info); int inTime = inTimeRange(year, month, day, hour, min, sec, ms, info); if (inTime < 0) { // too early return LogMessage.REJECTED_LOGMESSAGE; } else if (inTime > 0) { // too late return LogMessage.REJECTED_LAST_LOGMESSAGE; } int matchLevel = matchLevelFilter(level, info); if (matchLevel > 0) { // level value bigger than request return LogMessage.REJECTED_LOGMESSAGE; } final int lineNumberStartIndex = line.indexOf(' ', fileNameEndIndex + 1) + 1; if (lineNumberStartIndex > Short.MAX_VALUE || rightParentheseIndex - lineNumberStartIndex > Short.MAX_VALUE) { return LogMessage.CONTINUATION_LOGMESSAGE; } LogMessage log = new LogMessage(getTime(year, month, day, hour, min, sec, ms), line.getBytes()); log.setLogOffset(messageStartIndex); log.setTimeBytes(0, TIME_LENGTH - 2); log.setThreadName(TIME_LENGTH, endBracket - TIME_LENGTH); log.setLevel(level); log.setFileName(classNameStartIndex, classNameEndIndex - classNameStartIndex); log.setLineNumber(lineNumberStartIndex, rightParentheseIndex - lineNumberStartIndex); return log; } }