AbstractLogParser.java
package com.huawei.logparser.kernel; import java.io.File; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Vector; import com.huawei.logparser.util.ParserConfig; public abstract class AbstractLogParser { // 当前解析文件的规则 protected ParserConfig parserConfig; // 解析文件之后输出的文件,全路径。用于发送Email的附件。 protected String fileName; public ParserConfig getParserConfig() { return parserConfig; } public void setParserConfig(ParserConfig parserConfig) { this.parserConfig = parserConfig; } // 根据parserConfig定义的规则解析文件,子类必须实现该方法 public abstract Vector<String> startParser() ; public boolean getFileList(Vector<String> outFileLists,String filePath,boolean subFolderFlag) { if(outFileLists == null) { outFileLists = new Vector<String>(); } File file = new File(filePath); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar cal = GregorianCalendar.getInstance(); cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DATE)); int zoneOffset = cal.get(Calendar.ZONE_OFFSET); int dstOffset = cal.get(Calendar.DST_OFFSET); Date now = cal.getTime(); int timeBefore = Integer.parseInt(parserConfig.getTimeBefore()); long nowTime = now.getTime(); long oneDay = 24 * 60 * 60 * 1000; //计算一天的毫秒数,24小时*60分钟*60秒*1000毫秒 long todayBeginTime = nowTime - (nowTime % oneDay) - zoneOffset - dstOffset; //获得今天开始的时间,也就是今天凌晨0点0分0秒0毫秒的时间 long lastTime = todayBeginTime - timeBefore * oneDay; //根据timeBefore计算要搜索的时间范围 if(file.exists()) { File files[] = file.listFiles(); if(subFolderFlag) { for(int i = 0; i < files.length; i++) { if(files[i].isFile()) { long createTime = files[i].lastModified(); if((createTime >= lastTime) && (createTime <= nowTime)) { outFileLists.add(filePath + File.separator + files[i].getName()); } //outFileLists.add(files[i].) } else if(files[i].isDirectory()) { getFileList(outFileLists, filePath + File.separator + files[i].getName(), subFolderFlag); } } } else { for(int i = 0; i < files.length; i++) { if(files[i].isFile()) { outFileLists.add(filePath + File.separator + files[i].getName()); } } } } else { return false; } return true; } // 发送邮件 public void sendMail() { System.out.println("send a mail"); } }
LogParserFactory.java
package com.huawei.logparser.kernel; import org.apache.log4j.Logger; import com.huawei.logparser.util.ParserCommonString; public class LogParserFactory { private static Logger logger = Logger.getLogger(LogParserFactory.class.getName()); public static AbstractLogParser createLogParser(String type) { if(ParserCommonString.PARSER_TYPE_FILECONTENT.equals(type)) { return new LogParserFileContent(); } else if(ParserCommonString.PARSER_TYPE_FILENAME.equals(type)) { return new LogParserFileName(); } logger.error("/t/tInvalid type *" + type + "*, No such parser type!!!"); return null; } }
LogParserFileContent.java
package com.huawei.logparser.kernel; import java.io.FileInputStream; import java.nio.CharBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.util.Vector; import org.apache.log4j.Logger; public class LogParserFileContent extends AbstractLogParser { private static Logger logger = Logger.getLogger(LogParserFileContent.class.getName()); @Override public Vector<String> startParser() { // TODO Auto-generated method stub Vector<String> outFileLists = new Vector<String>(); getFileList(outFileLists,parserConfig.getFilePath(),parserConfig.isIncludeSubFolder()); Charset charset = Charset.forName("GB18030"); CharsetDecoder decoder = charset.newDecoder(); String tempFileName = null; try { for (String fileName : outFileLists) { tempFileName = fileName; FileInputStream fis = new FileInputStream(fileName); FileChannel fc = fis.getChannel(); int sz = (int)fc.size(); MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz); CharBuffer cb = decoder.decode(bb); String s = String.valueOf(cb); int n = s.indexOf("东西"); if(n == -1) { outFileLists.remove(fileName); } } } catch(Exception e) { logger.error("/t/tInvalid file path *" + tempFileName + "*"); e.printStackTrace(); } System.out.println("LogParserFileContent is parsering logs......"); logger.info("/t/tSend a mail to " + parserConfig.getTo().toString()); return outFileLists; } // for test public static void main(String args[]) { Vector<String> outFileLists = new Vector<String>(); new LogParserFileContent().getFileList(outFileLists, "D://Test", true); for (String string : outFileLists) { System.out.println(string); } } }
LogParserFileName.java
package com.huawei.logparser.kernel; import java.util.Vector; import org.apache.log4j.Logger; public class LogParserFileName extends AbstractLogParser { private static Logger logger = Logger.getLogger(LogParserFileName.class.getName()); @Override public Vector<String> startParser() { // TODO Auto-generated method stub System.out.println("LogParserFileName is parsering logs......"); logger.info("/t/tSend a mail to " + parserConfig.getTo().toString()); return null; } }
LogParserMain.java
package com.huawei.logparser.main; import java.util.Vector; import org.apache.log4j.Logger; import com.huawei.logparser.kernel.AbstractLogParser; import com.huawei.logparser.kernel.LogParserFactory; import com.huawei.logparser.util.LoadIniConfig; import com.huawei.logparser.util.ParserConfig; public class LogParserMain { private static Logger logger = Logger.getLogger(LogParserMain.class.getName()); /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub LoadIniConfig fileLoader = new LoadIniConfig(); String fullFilePath = null; try { String basedir = System.getProperty("user.dir"); fullFilePath = basedir + System.getProperty("file.separator") + "config.ini"; Vector<ParserConfig> parserConfigs = fileLoader.loadIniFile(fullFilePath); AbstractLogParser parserManager = null; for (ParserConfig parserConfig : parserConfigs) { parserManager = LogParserFactory.createLogParser(parserConfig.getType()); parserManager.setParserConfig(parserConfig); parserManager.startParser(); parserManager.sendMail(); } } catch (Exception e) { // TODO Auto-generated catch block logger.error("/t/tConnot find the file *" + fullFilePath + "*"); e.printStackTrace(); } } }
LoadIniConfig.java
package com.huawei.logparser.util; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Properties; import java.util.Vector; import org.apache.log4j.Logger; public class LoadIniConfig { protected HashMap sections = new HashMap(); private transient String currentSection; private transient Properties current; // 日志输出对象 private static Logger logger = Logger.getLogger(LoadIniConfig.class); public Vector<ParserConfig> loadIniFile(String filename) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(filename)); String line; while((line = reader.readLine()) != null) { line = line.trim(); if(line.matches("//[.*//]")) { currentSection = line.replaceFirst("//[(.*)//]", "$1"); current = new Properties(); sections.put(currentSection, current); } else if(line.matches(".*=.*")) { if(current != null) { int i = line.indexOf('='); String name = line.substring(0,i); String value = line.substring(i + 1); current.setProperty(name.toLowerCase(), value); } } } reader.close(); Vector<ParserConfig> outParserConfigs = new Vector<ParserConfig>(); ParserConfig tempConfig = null; String tempValue = null; for (Iterator iterator = sections.keySet().iterator(); iterator.hasNext();) { String key = (String) iterator.next(); tempConfig = new ParserConfig(); // 读取搜索类型 tempValue = getValue(key,ParserCommonString.CONFIG_NAME_TYPE); if("".equals(tempValue)) { logger.error("/t/t[" + key + "] *" + ParserCommonString.CONFIG_NAME_TYPE + "* is invalid, this section will be ignored!"); continue; } else { tempConfig.setType(tempValue); } // 读取搜索文件路径 tempValue = getValue(key,ParserCommonString.CONFIG_NAME_FILEPATH); if("".equals(tempValue)) { logger.error("/t/t[" + key + "] *" + ParserCommonString.CONFIG_NAME_FILEPATH + "* is invalid, this section will be ignored!"); continue; } else { tempConfig.setFilePath(tempValue); } // 读取搜索条件 tempValue = getValue(key,ParserCommonString.CONFIG_NAME_CONDITION); if("".equals(tempValue)) { logger.error("/t/t[" + key + "] *" + ParserCommonString.CONFIG_NAME_CONDITION + "* is invalid, this section will be ignored!"); continue; } else { tempConfig.setCondition(tempValue); } // 读取搜索时间范围 tempValue = getValue(key,ParserCommonString.CONFIG_NAME_TIMEBEFORE); if("".equals(tempValue)) { logger.error("/t/t[" + key + "] *" + ParserCommonString.CONFIG_NAME_TIMEBEFORE + "* is invalid, this section will be ignored!"); continue; } else { tempConfig.setTimeBefore(tempValue); } // 读取是否包含子目录 tempValue = getValue(key,ParserCommonString.CONFIG_NAME_INCLUDESUBFOLDER); if("".equals(tempValue)) { logger.error("/t/t[" + key + "] *" + ParserCommonString.CONFIG_NAME_INCLUDESUBFOLDER + "* is invalid, this section will be ignored!"); continue; } else { if("1".equals(tempValue.trim())) { tempConfig.setIncludeSubFolder(true); } else { tempConfig.setIncludeSubFolder(false); } } // 读取邮件标题 tempValue = getValue(key,ParserCommonString.CONFIG_NAME_EMAILTITLE); if("".equals(tempValue)) { logger.error("/t/t[" + key + "] *" + ParserCommonString.CONFIG_NAME_EMAILTITLE + "* is invalid, this section will be ignored!"); continue; } else { tempConfig.setEmailTitle(tempValue); } // 读取邮件发送人 tempValue = getValue(key,ParserCommonString.CONFIG_NAME_FROM); if("".equals(tempValue)) { logger.error("/t/t[" + key + "] *" + ParserCommonString.CONFIG_NAME_FROM + "* is invalid, this section will be ignored!"); continue; } else { tempConfig.setFrom(tempValue); } // 读取邮件接收人 tempValue = getValue(key,ParserCommonString.CONFIG_NAME_TO); if("".equals(tempValue)) { logger.error("/t/t[" + key + "] *" + ParserCommonString.CONFIG_NAME_TO + "* is invalid, this section will be ignored!"); continue; } else { String[] arrayTos = tempValue.trim().split(","); Vector<String> tos = new Vector<String>(); for(int i = 0;i < arrayTos.length; i++) { tos.add(arrayTos[i]); } tempConfig.setTo(tos); } outParserConfigs.add(tempConfig); } // for test // for (ParserConfig parserConfig : outParserConfigs) { // System.out.println(parserConfig.getCondition()); // System.out.println(parserConfig.getEmailTitle()); // System.out.println(parserConfig.getFilePath()); // System.out.println(parserConfig.isIncludeSubFolder()); // System.out.println(parserConfig.getFrom()); // System.out.println(parserConfig.getType()); // System.out.println(parserConfig.getTo()); // } return outParserConfigs; } public String getValue(String section ,String name) { Properties p = (Properties)sections.get(section); if(p == null) { return ""; } String value = p.getProperty(name.toLowerCase()); if(null == value) { value = ""; } return value.trim(); } // test public static void main(String args[]) { LoadIniConfig test = new LoadIniConfig(); try { String basedir = System.getProperty("user.dir"); test.loadIniFile(basedir + "//" + "config.ini"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
ParserCommonString.java
package com.huawei.logparser.util; public class ParserCommonString { // 搜索文件名 public final static String PARSER_TYPE_FILENAME = "FILENAME"; // 搜索文件内容 public final static String PARSER_TYPE_FILECONTENT = "FILECONTENT"; // 搜索类型 public final static String CONFIG_NAME_TYPE = "type"; // 搜索路径 public final static String CONFIG_NAME_FILEPATH = "filePath"; // 搜索条件 public final static String CONFIG_NAME_CONDITION = "condition"; // 搜索时间范围,指文件创建时间范围,表示从现在往前几天之内所有创建的日志文件 public final static String CONFIG_NAME_TIMEBEFORE = "timeBefore"; // 是否包含子目录 public final static String CONFIG_NAME_INCLUDESUBFOLDER = "includeSubFolder"; // 邮件标题 public final static String CONFIG_NAME_EMAILTITLE = "emailTitle"; // 邮件发送人地址 public final static String CONFIG_NAME_FROM = "from"; // 邮件接收人地址 public final static String CONFIG_NAME_TO = "to"; }
ParserConfig.java
package com.huawei.logparser.util; import java.util.Vector; public class ParserConfig { private String type; private String filePath; private String condition; private String timeBefore; private boolean includeSubFolder; private String emailTitle; private String from; private Vector<String> to; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getFilePath() { return filePath; } public void setFilePath(String filePath) { this.filePath = filePath; } public String getCondition() { return condition; } public void setCondition(String condition) { this.condition = condition; } public String getTimeBefore() { return timeBefore; } public void setTimeBefore(String timeBefore) { this.timeBefore = timeBefore; } public boolean isIncludeSubFolder() { return includeSubFolder; } public void setIncludeSubFolder(boolean includeSubFolder) { this.includeSubFolder = includeSubFolder; } public String getEmailTitle() { return emailTitle; } public void setEmailTitle(String emailTitle) { this.emailTitle = emailTitle; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public Vector<String> getTo() { return to; } public void setTo(Vector<String> to) { this.to = to; } }
log4j.properites
# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You 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. # An example log4j configuration file that outputs to System.out. The # output information consists of relative time, log level, thread # name, logger name, nested diagnostic context and the message in that # order. # For the general syntax of property based configuration files see the # documenation of org.apache.log4j.PropertyConfigurator. log4j.rootLogger=DEBUG, A1 # A1 is set to be a ConsoleAppender which outputs to System.out. log4j.appender.A1=org.apache.log4j.FileAppender # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.File=parserlog.log # The conversion pattern uses format specifiers. You might want to # change the pattern an watch the output format change. log4j.appender.A1.layout.ConversionPattern=%d{yyy-MM-dd HH/:mm/:ss} /: %-5p [%t] %c %n%m%n # In this example, we are not really interested in INNER loop or SWAP # messages. See the effects of uncommenting and changing the levels of # the following loggers. # log4j.logger.org.apache.log4j.examples.SortAlgo.INNER=WARN # log4j.logger.org.apache.log4j.examples.SortAlgo.SWAP=WARN
config.ini
[CONFIG1] type=FILENAME filePath=d:/test condition=test timeBefore=3 includeSubFolder=1 emailTitle=这是个测试邮件 from=testemail to=00178723 [CONFIG2] type=FILECONTENT filePath=d:/test condition=test timeBefore=1 includeSubFolder=0 emailTitle=这是个测试邮件 from=testemail to=00178723,00178723,00178723