From 2f0ac3126541af6f8ec9204edb6d4093e51dc119 Mon Sep 17 00:00:00 2001 From: aionJoey Date: Thu, 17 May 2018 11:47:31 -0400 Subject: [PATCH 01/13] added logger features --- .../src/org/aion/log/AionLoggerFactory.java | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/modLogger/src/org/aion/log/AionLoggerFactory.java b/modLogger/src/org/aion/log/AionLoggerFactory.java index 5600bdbf29..9b9299fe6e 100644 --- a/modLogger/src/org/aion/log/AionLoggerFactory.java +++ b/modLogger/src/org/aion/log/AionLoggerFactory.java @@ -36,6 +36,13 @@ import ch.qos.logback.core.ConsoleAppender; import ch.qos.logback.core.FileAppender; import ch.qos.logback.core.rolling.*; +import ch.qos.logback.core.rolling.RollingFileAppender; +import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy; +import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy; +import ch.qos.logback.core.rolling.helper.FileNamePattern; +import ch.qos.logback.core.util.FileSize; + + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,12 +62,13 @@ public class AionLoggerFactory { /** - * Due to Cfg is abstract, use this static atribute to hold muti-chains + * Due to Cfg is abstract, use this static attribute to hold muti-chains * config attribute List, which is chain neural. */ private static Map logModules; private static LoggerContext loggerContext; private static ConsoleAppender appender = new ConsoleAppender<>(); + private static RollingFileAppender fileAppender; // JAY T private final static PatternLayoutEncoder encoder = new PatternLayoutEncoder(); static { logModules = new HashMap<>(); @@ -76,6 +84,54 @@ public static void init(final Map _logModules) { loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); + /** + * Initialize Rolling-File-Appender + */ + String fileName = "./log/aionLog.dat"; + fileAppender = new RollingFileAppender(); + fileAppender.setContext(loggerContext); + fileAppender.setName("aionlogger"); + fileAppender.setFile(fileName); + + /** + * Initialize Triggering-Policy (CONDITION) + */ + SizeBasedTriggeringPolicy tp = new SizeBasedTriggeringPolicy(); + tp.setContext(loggerContext); + tp.start(); + + /** + * Initialize Rolling-Policy (BEHAVIOUR) + */ + SizeAndTimeBasedRollingPolicy rp = new SizeAndTimeBasedRollingPolicy(); + rp.setContext(loggerContext); + + /** + * To modify period of each rollover; + * PER DAY: "aion.%d{yyyy-MM-dd}.%i.log" + * PER HOUR: "aion.%d{yyyy-MM-dd_HH}.%i.log" + * PER MIN: "aion.%d{yyyy-MM-dd_HH-mm}.%i.log" + * Link: https://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy + * Currently set to PER HOUR + */ + FileNamePattern fnp = new FileNamePattern("./log/%d{yyyy/MM, aux}/aion.%d{yyyy-MM-dd_HH}.%i.log", loggerContext); + rp.setFileNamePattern(fnp.getPattern()); + + /** + * To modify size of each rollover file; + * Link: https://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy + * Currently set to 100MB + */ + rp.setMaxFileSize(new FileSize(100*1000*1000)); + rp.setParent(fileAppender); + rp.start(); + + /** + * Sets TRIGGER & ROLLING policy + */ + fileAppender.setTriggeringPolicy(tp); + fileAppender.setRollingPolicy(rp); + encoder.setContext(loggerContext); encoder.setPattern("%date{yy-MM-dd HH:mm:ss.SSS} %-5level %-4c [%thread]: %message%n"); encoder.start(); @@ -84,6 +140,14 @@ public static void init(final Map _logModules) { appender.setEncoder(encoder); appender.start(); + /** + * Set fileAppender configurations + */ + fileAppender.setContext(loggerContext); + fileAppender.setEncoder(encoder); + fileAppender.setAppend(true); + fileAppender.start(); + ch.qos.logback.classic.Logger rootlogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME); rootlogger.detachAndStopAllAppenders(); } @@ -106,6 +170,7 @@ private static Logger newLogger(String label) { ch.qos.logback.classic.Logger newlogger = loggerContext.getLogger(label); newlogger.addAppender(appender); + newlogger.addAppender(fileAppender); boolean flag = false; Iterator> it = logModules.entrySet().iterator(); From 0d89dae088329f90232509e6f9d5714bb06ecde0 Mon Sep 17 00:00:00 2001 From: aionJoey Date: Thu, 17 May 2018 12:16:18 -0400 Subject: [PATCH 02/13] logger feature added --- .../src/org/aion/log/AionLoggerFactory.java | 158 ++++++++---------- 1 file changed, 70 insertions(+), 88 deletions(-) diff --git a/modLogger/src/org/aion/log/AionLoggerFactory.java b/modLogger/src/org/aion/log/AionLoggerFactory.java index 9b9299fe6e..6b2a2c248d 100644 --- a/modLogger/src/org/aion/log/AionLoggerFactory.java +++ b/modLogger/src/org/aion/log/AionLoggerFactory.java @@ -1,75 +1,67 @@ -/******************************************************************************* - * Copyright (c) 2017-2018 Aion foundation. +/** + * ***************************************************************************** Copyright (c) + * 2017-2018 Aion foundation. * - * This file is part of the aion network project. + *

This file is part of the aion network project. * - * The aion network project is free software: you can redistribute it - * and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or any later version. + *

The aion network project is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software Foundation, either + * version 3 of the License, or any later version. * - * The aion network project is distributed in the hope that it will - * be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. + *

The aion network project is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with the aion network project source files. - * If not, see . + *

You should have received a copy of the GNU General Public License along with the aion network + * project source files. If not, see . * - * Contributors: - * Aion foundation. - * - ******************************************************************************/ - + *

Contributors: Aion foundation. + * + *

**************************************************************************** + */ package org.aion.log; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.ConsoleAppender; -import ch.qos.logback.core.FileAppender; import ch.qos.logback.core.rolling.*; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy; import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy; import ch.qos.logback.core.rolling.helper.FileNamePattern; import ch.qos.logback.core.util.FileSize; - - +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.LoggerContext; - /** * Used to override SimpleLogger current log level - * - * final public int TRACE_INT = 00; final public int DEBUG_INT = 10; - * finalConcurrentHashMap public int INFO_INT = 20; final public int WARN_INT = - * 30; final public int ERROR_INT = 40; - * - * Default set to 50 which ignore output + * + *

final public int TRACE_INT = 00; final public int DEBUG_INT = 10; finalConcurrentHashMap + * public int INFO_INT = 20; final public int WARN_INT = 30; final public int ERROR_INT = 40; + * + *

Default set to 50 which ignore output */ - public class AionLoggerFactory { /** - * Due to Cfg is abstract, use this static attribute to hold muti-chains - * config attribute List, which is chain neural. + * Due to Cfg is abstract, use this static attribute to hold muti-chains config attribute + * List, which is chain neural. */ private static Map logModules; + private static LoggerContext loggerContext; private static ConsoleAppender appender = new ConsoleAppender<>(); - private static RollingFileAppender fileAppender; // JAY T - private final static PatternLayoutEncoder encoder = new PatternLayoutEncoder(); + private static RollingFileAppender fileAppender; // JAY T + private static final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); + static { logModules = new HashMap<>(); String level = LogLevels.INFO.name(); @@ -84,51 +76,43 @@ public static void init(final Map _logModules) { loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); - /** - * Initialize Rolling-File-Appender - */ + /** Initialize Rolling-File-Appender */ String fileName = "./log/aionLog.dat"; fileAppender = new RollingFileAppender(); fileAppender.setContext(loggerContext); fileAppender.setName("aionlogger"); fileAppender.setFile(fileName); - /** - * Initialize Triggering-Policy (CONDITION) - */ + /** Initialize Triggering-Policy (CONDITION) */ SizeBasedTriggeringPolicy tp = new SizeBasedTriggeringPolicy(); tp.setContext(loggerContext); tp.start(); - /** - * Initialize Rolling-Policy (BEHAVIOUR) - */ + /** Initialize Rolling-Policy (BEHAVIOUR) */ SizeAndTimeBasedRollingPolicy rp = new SizeAndTimeBasedRollingPolicy(); rp.setContext(loggerContext); /** - * To modify period of each rollover; - * PER DAY: "aion.%d{yyyy-MM-dd}.%i.log" - * PER HOUR: "aion.%d{yyyy-MM-dd_HH}.%i.log" - * PER MIN: "aion.%d{yyyy-MM-dd_HH-mm}.%i.log" - * Link: https://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy - * Currently set to PER HOUR + * To modify period of each rollover; PER DAY: "aion.%d{yyyy-MM-dd}.%i.log" PER HOUR: + * "aion.%d{yyyy-MM-dd_HH}.%i.log" PER MIN: "aion.%d{yyyy-MM-dd_HH-mm}.%i.log" Link: + * https://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy Currently set to PER + * HOUR */ - FileNamePattern fnp = new FileNamePattern("./log/%d{yyyy/MM, aux}/aion.%d{yyyy-MM-dd_HH}.%i.log", loggerContext); + FileNamePattern fnp = + new FileNamePattern( + "./log/%d{yyyy/MM, aux}/aion.%d{yyyy-MM-dd_HH}.%i.log", loggerContext); rp.setFileNamePattern(fnp.getPattern()); /** - * To modify size of each rollover file; - * Link: https://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy - * Currently set to 100MB + * To modify size of each rollover file; Link: + * https://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy Currently set + * to 100MB */ - rp.setMaxFileSize(new FileSize(100*1000*1000)); + rp.setMaxFileSize(new FileSize(100 * 1000 * 1000)); rp.setParent(fileAppender); rp.start(); - /** - * Sets TRIGGER & ROLLING policy - */ + /** Sets TRIGGER & ROLLING policy */ fileAppender.setTriggeringPolicy(tp); fileAppender.setRollingPolicy(rp); @@ -140,9 +124,7 @@ public static void init(final Map _logModules) { appender.setEncoder(encoder); appender.start(); - /** - * Set fileAppender configurations - */ + /** Set fileAppender configurations */ fileAppender.setContext(loggerContext); fileAppender.setEncoder(encoder); fileAppender.setAppend(true); @@ -152,7 +134,8 @@ public static void init(final Map _logModules) { rootlogger.detachAndStopAllAppenders(); } - private static ConcurrentMap loggerMap = new ConcurrentHashMap(); + private static ConcurrentMap loggerMap = + new ConcurrentHashMap(); public static Logger getLogger(String label) { @@ -179,27 +162,26 @@ private static Logger newLogger(String label) { if (logModule.getKey().equals(label)) { LogLevels logLevel = LogLevels.valueOf(logModule.getValue()); switch (logLevel) { - case TRACE: - newlogger.setLevel(Level.TRACE); - flag = true; - break; - case ERROR: - newlogger.setLevel(Level.ERROR); - flag = true; - break; - case INFO: - newlogger.setLevel(Level.INFO); - flag = true; - break; - case DEBUG: - newlogger.setLevel(Level.DEBUG); - flag = true; - break; + case TRACE: + newlogger.setLevel(Level.TRACE); + flag = true; + break; + case ERROR: + newlogger.setLevel(Level.ERROR); + flag = true; + break; + case INFO: + newlogger.setLevel(Level.INFO); + flag = true; + break; + case DEBUG: + newlogger.setLevel(Level.DEBUG); + flag = true; + break; } } - if (flag) - break; + if (flag) break; } if (!flag) { From 07c93e17a8c4a9ad7fb05fb09e1ad2f2a506bab6 Mon Sep 17 00:00:00 2001 From: aionJoey Date: Thu, 17 May 2018 12:25:21 -0400 Subject: [PATCH 03/13] logger feature added --- modLogger/src/org/aion/log/AionLoggerFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modLogger/src/org/aion/log/AionLoggerFactory.java b/modLogger/src/org/aion/log/AionLoggerFactory.java index 6b2a2c248d..15ed1acecc 100644 --- a/modLogger/src/org/aion/log/AionLoggerFactory.java +++ b/modLogger/src/org/aion/log/AionLoggerFactory.java @@ -77,7 +77,7 @@ public static void init(final Map _logModules) { loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); /** Initialize Rolling-File-Appender */ - String fileName = "./log/aionLog.dat"; + String fileName = "./log/aionCurrentLog.dat"; fileAppender = new RollingFileAppender(); fileAppender.setContext(loggerContext); fileAppender.setName("aionlogger"); From a2186ad55a26bdbad76b887041fed1284c456c8a Mon Sep 17 00:00:00 2001 From: aionJoey Date: Fri, 18 May 2018 10:55:48 -0400 Subject: [PATCH 04/13] allows user to toggle logger --- modApiServer/src/org/aion/api/server/Api.java | 8 ++ modBoot/src/org/aion/Aion.java | 7 +- .../src/org/aion/log/AionLoggerFactory.java | 115 +++++++++++------- modMcf/src/org/aion/mcf/config/CfgLog.java | 44 ++++++- 4 files changed, 124 insertions(+), 50 deletions(-) diff --git a/modApiServer/src/org/aion/api/server/Api.java b/modApiServer/src/org/aion/api/server/Api.java index 743ba51e9e..2dc1402a3b 100644 --- a/modApiServer/src/org/aion/api/server/Api.java +++ b/modApiServer/src/org/aion/api/server/Api.java @@ -109,6 +109,14 @@ public Map contract_compileSolidity(final String _contrac Compiler.Result res = solc.compile(_contract.getBytes(), Compiler.Options.ABI, Compiler.Options.BIN); if (res.isFailed()) { LOG.info("contract compile error: [{}]", res.errors); + + /** + * Enhance performance by separating the log threads and kernel + * TODO: Implement a queue for strings + * TODO: Put every LOG message onto the queue + * TODO: Use a thread service to process these message + */ + CompiledContr ret = new CompiledContr(); ret.error = res.errors; compiledContracts.put("compile-error", ret); diff --git a/modBoot/src/org/aion/Aion.java b/modBoot/src/org/aion/Aion.java index ab9742bfbb..6cbb30558f 100644 --- a/modBoot/src/org/aion/Aion.java +++ b/modBoot/src/org/aion/Aion.java @@ -36,6 +36,7 @@ import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.config.CfgApiRpc; +import org.aion.mcf.config.CfgLog; import org.aion.mcf.mine.IMineRunner; import org.aion.zero.impl.blockchain.AionFactory; import org.aion.zero.impl.blockchain.IAionChain; @@ -84,7 +85,11 @@ public static void main(String args[]) throws InterruptedException { // If commit this out, the config setting will be ignore. all log module been set to "INFO" Level - AionLoggerFactory.init(cfg.getLog().getModules()); + + /** Change INITIALIZE signature to include LOGFILE */ + // AionLoggerFactory.init(cfg.getLog().getModules()); + AionLoggerFactory.init(cfg.getLog().getModules(), cfg.getLog().getLogFile()); + Logger LOG = AionLoggerFactory.getLogger(LogEnum.GEN.toString()); System.out.println( diff --git a/modLogger/src/org/aion/log/AionLoggerFactory.java b/modLogger/src/org/aion/log/AionLoggerFactory.java index 15ed1acecc..cc61dbd76b 100644 --- a/modLogger/src/org/aion/log/AionLoggerFactory.java +++ b/modLogger/src/org/aion/log/AionLoggerFactory.java @@ -26,7 +26,7 @@ import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.ConsoleAppender; -import ch.qos.logback.core.rolling.*; +import ch.qos.logback.core.FileAppender; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy; import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy; @@ -59,9 +59,13 @@ public class AionLoggerFactory { private static LoggerContext loggerContext; private static ConsoleAppender appender = new ConsoleAppender<>(); - private static RollingFileAppender fileAppender; // JAY T private static final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); + /** Static declaration of logFile */ + private static boolean logToFile; + + private static RollingFileAppender fileAppender; + static { logModules = new HashMap<>(); String level = LogLevels.INFO.name(); @@ -70,51 +74,69 @@ public class AionLoggerFactory { } } + /** Change INITIALIZE signature to include LOGFILE */ public static void init(final Map _logModules) { + init(_logModules, false); + } + + // public static void init(final Map _logModules) { + public static void init(final Map _logModules, boolean _logToFile ) { logModules = _logModules; + /** Passed in argument */ + logToFile = _logToFile; + // logToFile = true; + loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); - /** Initialize Rolling-File-Appender */ - String fileName = "./log/aionCurrentLog.dat"; - fileAppender = new RollingFileAppender(); - fileAppender.setContext(loggerContext); - fileAppender.setName("aionlogger"); - fileAppender.setFile(fileName); - - /** Initialize Triggering-Policy (CONDITION) */ - SizeBasedTriggeringPolicy tp = new SizeBasedTriggeringPolicy(); - tp.setContext(loggerContext); - tp.start(); - - /** Initialize Rolling-Policy (BEHAVIOUR) */ - SizeAndTimeBasedRollingPolicy rp = new SizeAndTimeBasedRollingPolicy(); - rp.setContext(loggerContext); - - /** - * To modify period of each rollover; PER DAY: "aion.%d{yyyy-MM-dd}.%i.log" PER HOUR: - * "aion.%d{yyyy-MM-dd_HH}.%i.log" PER MIN: "aion.%d{yyyy-MM-dd_HH-mm}.%i.log" Link: - * https://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy Currently set to PER - * HOUR - */ - FileNamePattern fnp = + /** Toggles file appending configurations */ + if(logToFile) { + /** Initialize Rolling-File-Appender */ + String fileName = "./log/aionCurrentLog.dat"; + fileAppender = new RollingFileAppender(); + fileAppender.setContext(loggerContext); + fileAppender.setName("aionlogger"); + fileAppender.setFile(fileName); + + /** Initialize Triggering-Policy (CONDITION) */ + SizeBasedTriggeringPolicy tp = new SizeBasedTriggeringPolicy(); + tp.setContext(loggerContext); + tp.start(); + + /** Initialize Rolling-Policy (BEHAVIOUR) */ + SizeAndTimeBasedRollingPolicy rp = new SizeAndTimeBasedRollingPolicy(); + rp.setContext(loggerContext); + + /** + * To modify period of each rollover; + * https://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy + * (Currently set to PER DAY) + */ + FileNamePattern fnp = new FileNamePattern( - "./log/%d{yyyy/MM, aux}/aion.%d{yyyy-MM-dd_HH}.%i.log", loggerContext); - rp.setFileNamePattern(fnp.getPattern()); - - /** - * To modify size of each rollover file; Link: - * https://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy Currently set - * to 100MB - */ - rp.setMaxFileSize(new FileSize(100 * 1000 * 1000)); - rp.setParent(fileAppender); - rp.start(); - - /** Sets TRIGGER & ROLLING policy */ - fileAppender.setTriggeringPolicy(tp); - fileAppender.setRollingPolicy(rp); + "./log/%d{yyyy/MM, aux}/aion.%d{yyyy-MM-dd}.%i.log", loggerContext); + rp.setFileNamePattern(fnp.getPattern()); + + /** + * To modify size of each rollover file; + * https://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy + * (Currently set to 100MB) + */ + rp.setMaxFileSize(new FileSize(100 * 1000 * 1000)); + rp.setParent(fileAppender); + rp.start(); + + /** Sets TRIGGER & ROLLING policy */ + fileAppender.setTriggeringPolicy(tp); + fileAppender.setRollingPolicy(rp); + + /** Set fileAppender configurations */ + fileAppender.setContext(loggerContext); + fileAppender.setEncoder(encoder); + fileAppender.setAppend(true); + fileAppender.start(); + } encoder.setContext(loggerContext); encoder.setPattern("%date{yy-MM-dd HH:mm:ss.SSS} %-5level %-4c [%thread]: %message%n"); @@ -124,12 +146,6 @@ public static void init(final Map _logModules) { appender.setEncoder(encoder); appender.start(); - /** Set fileAppender configurations */ - fileAppender.setContext(loggerContext); - fileAppender.setEncoder(encoder); - fileAppender.setAppend(true); - fileAppender.start(); - ch.qos.logback.classic.Logger rootlogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME); rootlogger.detachAndStopAllAppenders(); } @@ -148,12 +164,17 @@ private static Logger newLogger(String label) { if (loggerContext == null) { // System.out.println("If you see this line, meaning you are under // the unit test!!! If you are not. should report an issue."); + //init(new HashMap<>(), false); init(new HashMap<>()); } ch.qos.logback.classic.Logger newlogger = loggerContext.getLogger(label); newlogger.addAppender(appender); - newlogger.addAppender(fileAppender); + + /** Toggle file appending */ + if(logToFile) { + newlogger.addAppender(fileAppender); + } boolean flag = false; Iterator> it = logModules.entrySet().iterator(); diff --git a/modMcf/src/org/aion/mcf/config/CfgLog.java b/modMcf/src/org/aion/mcf/config/CfgLog.java index 0af4527b04..80de09cc46 100644 --- a/modMcf/src/org/aion/mcf/config/CfgLog.java +++ b/modMcf/src/org/aion/mcf/config/CfgLog.java @@ -43,6 +43,9 @@ public class CfgLog { private Map modules; + /** Declaree logFile variable */ + private boolean logFile; + public CfgLog() { modules = new HashMap<>(); modules.put(LogEnum.CONS.name(), LogLevels.INFO.name()); @@ -53,6 +56,10 @@ public CfgLog() { modules.put(LogEnum.API.name(), LogLevels.INFO.name()); modules.put(LogEnum.TX.name(), LogLevels.ERROR.name()); modules.put(LogEnum.TXPOOL.name(), LogLevels.ERROR.name()); + + /** TOGGLES LOGGING TO FILE - initializes logFile as FALSE */ + this.logFile = false; + } public void fromXML(final XMLStreamReader sr) throws XMLStreamException { @@ -62,7 +69,19 @@ public void fromXML(final XMLStreamReader sr) throws XMLStreamException { int eventType = sr.next(); switch (eventType) { case XMLStreamReader.START_ELEMENT: - String elementName = sr.getLocalName().toUpperCase(); + + /** XML - Takes the input in config.xml and parse as T/F */ + String elementName = sr.getLocalName().toLowerCase(); + switch (elementName) { + case "log-file": + this.logFile = Boolean.parseBoolean(Cfg.readValue(sr)); + break; + default: + break; + } + + elementName = sr.getLocalName().toUpperCase(); + /** String elementName = sr.getLocalName().toUpperCase(); */ if (LogEnum.contains(elementName)) this.modules.put(elementName, Cfg.readValue(sr).toUpperCase()); break; @@ -83,8 +102,24 @@ public String toXML() { Writer strWriter = new StringWriter(); xmlWriter = output.createXMLStreamWriter(strWriter); xmlWriter.writeCharacters("\r\n\t"); - xmlWriter.writeStartElement("log"); + xmlWriter.writeStartElement("Log"); + xmlWriter.writeCharacters("\r\n"); + + /** XML - Displays tag/entry in the config.xml */ + xmlWriter.writeCharacters("\t\t"); + xmlWriter.writeStartElement("log-file"); + xmlWriter.writeCharacters(this.logFile + ""); + xmlWriter.writeEndElement(); xmlWriter.writeCharacters("\r\n"); + + /** Testing whether logFile retrieves boolean value */ + /** if(logFile) { + xmlWriter.writeCharacters("\t\t"); + xmlWriter.writeCharacters("testing for T"); + xmlWriter.writeCharacters("\r\n"); + } */ + + for (Map.Entry module : this.modules.entrySet()) { xmlWriter.writeCharacters("\t\t"); xmlWriter.writeStartElement(module.getKey().toUpperCase()); @@ -109,4 +144,9 @@ public Map getModules() { return this.modules; } + /** Method checks value of logFile as T/F */ + public boolean getLogFile() { + return this.logFile; + } + } \ No newline at end of file From 236dddf3fe2e6618455414b950c4a189f11b8a14 Mon Sep 17 00:00:00 2001 From: aionJoey Date: Tue, 22 May 2018 12:01:38 -0400 Subject: [PATCH 05/13] file path check --- modBoot/src/org/aion/Aion.java | 167 +++++++++--------- .../src/org/aion/log/AionLoggerFactory.java | 64 ++++--- modMcf/src/org/aion/mcf/config/CfgLog.java | 118 ++++++++----- 3 files changed, 194 insertions(+), 155 deletions(-) diff --git a/modBoot/src/org/aion/Aion.java b/modBoot/src/org/aion/Aion.java index 6cbb30558f..5ced73e85b 100644 --- a/modBoot/src/org/aion/Aion.java +++ b/modBoot/src/org/aion/Aion.java @@ -17,14 +17,17 @@ * along with the aion network project source files. * If not, see . * - * Contributors to the aion source files in decreasing order of code volume: - * + * Contributors: * Aion foundation. - * + * ******************************************************************************/ - package org.aion; +import static org.aion.crypto.ECKeyFac.ECKeyType.ED25519; +import static org.aion.crypto.HashUtil.H256Type.BLAKE2B_256; +import static org.aion.zero.impl.Version.KERNEL_VERSION; + +import java.util.ServiceLoader; import org.aion.api.server.http.NanoServer; import org.aion.api.server.pb.ApiAion0; import org.aion.api.server.pb.IHdlr; @@ -36,7 +39,6 @@ import org.aion.log.AionLoggerFactory; import org.aion.log.LogEnum; import org.aion.mcf.config.CfgApiRpc; -import org.aion.mcf.config.CfgLog; import org.aion.mcf.mine.IMineRunner; import org.aion.zero.impl.blockchain.AionFactory; import org.aion.zero.impl.blockchain.IAionChain; @@ -44,12 +46,6 @@ import org.aion.zero.impl.config.CfgAion; import org.slf4j.Logger; -import java.util.ServiceLoader; - -import static org.aion.crypto.ECKeyFac.ECKeyType.ED25519; -import static org.aion.crypto.HashUtil.H256Type.BLAKE2B_256; -import static org.aion.zero.impl.Version.KERNEL_VERSION; - public class Aion { public static void main(String args[]) throws InterruptedException { @@ -72,10 +68,8 @@ public static void main(String args[]) throws InterruptedException { * if in the config.xml id is set as default [NODE-ID-PLACEHOLDER] * return true which means should save back to xml config */ - if(cfg.fromXML()) - cfg.toXML(new String[]{ "--id=" + cfg.getId() }); + if (cfg.fromXML()) cfg.toXML(new String[] {"--id=" + cfg.getId()}); - try { ServiceLoader.load(AionLoggerFactory.class); } catch (Exception e) { @@ -83,27 +77,31 @@ public static void main(String args[]) throws InterruptedException { throw e; } - - // If commit this out, the config setting will be ignore. all log module been set to "INFO" Level - - /** Change INITIALIZE signature to include LOGFILE */ - // AionLoggerFactory.init(cfg.getLog().getModules()); - AionLoggerFactory.init(cfg.getLog().getModules(), cfg.getLog().getLogFile()); - + // If commit this out, the config setting will be ignore. all log module been set to "INFO" + // Level + /** Changed INITIALIZE signature to include LOGFILE and LOGPATH*/ + AionLoggerFactory.init(cfg.getLog().getModules(), cfg.getLog().getLogFile(), cfg.getLog().getLogPath()); Logger LOG = AionLoggerFactory.getLogger(LogEnum.GEN.toString()); - System.out.println( - " _____ \n" + - " .'. | .~ ~. |.. |\n" + - " .' `. | | | | ``.. |\n" + - " .''''''''`. | | | | ``.. |\n" + - ".' `. | `._____.' | ``|\n\n" + - " NETWORK v" + KERNEL_VERSION + - "\n\n" - ); + /** Outputs message to console depending on logPath validity */ + if(cfg.getLog().getOriginal()) { + System.out.println("Logger file path: '" + cfg.getLog().getLogPath() + "'\n"); + } else { + System.out.println("File path is invalid; set to default: 'log'\n"); + } + + System.out.println( + " _____ \n" + + " .'. | .~ ~. |.. |\n" + + " .' `. | | | | ``.. |\n" + + " .''''''''`. | | | | ``.. |\n" + + ".' `. | `._____.' | ``|\n\n" + + " NETWORK v" + + KERNEL_VERSION + + "\n\n"); IAionChain ac = AionFactory.create(); - + IMineRunner nm = null; if (!cfg.getConsensus().isSeed()) { @@ -123,21 +121,25 @@ public static void main(String args[]) throws InterruptedException { IHdlr handler = new HdlrZmq(new ApiAion0(ac)); processor = new ProtocolProcessor(handler, cfg.getApi().getZmq()); ProtocolProcessor finalProcessor = processor; - zmqThread = new Thread(() -> { - finalProcessor.run(); - }, "zmq-api"); + zmqThread = + new Thread( + () -> { + finalProcessor.run(); + }, + "zmq-api"); zmqThread.start(); } NanoServer rpcServer = null; - if(cfg.getApi().getRpc().getActive()) { - CfgApiRpc rpcCfg = cfg.getApi().getRpc(); - rpcServer = new NanoServer( - rpcCfg.getIp(), - rpcCfg.getPort(), - rpcCfg.getCorsEnabled(), - rpcCfg.getEnabled(), - rpcCfg.getMaxthread()); + if (cfg.getApi().getRpc().getActive()) { + CfgApiRpc rpcCfg = cfg.getApi().getRpc(); + rpcServer = + new NanoServer( + rpcCfg.getIp(), + rpcCfg.getPort(), + rpcCfg.getCorsEnabled(), + rpcCfg.getEnabled(), + rpcCfg.getMaxthread()); rpcServer.start(); } @@ -150,8 +152,9 @@ class ShutdownThreadHolder { final IMineRunner miner; final ProtocolProcessor pp; final NanoServer rpc; - - private ShutdownThreadHolder(Thread zmqThread, IMineRunner nm, ProtocolProcessor pp, NanoServer rpc) { + + private ShutdownThreadHolder( + Thread zmqThread, IMineRunner nm, ProtocolProcessor pp, NanoServer rpc) { this.zmqThread = zmqThread; this.miner = nm; this.pp = pp; @@ -160,42 +163,46 @@ private ShutdownThreadHolder(Thread zmqThread, IMineRunner nm, ProtocolProcessor } ShutdownThreadHolder holder = new ShutdownThreadHolder(zmqThread, nm, processor, rpcServer); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - - LOG.info("Starting shutdown process..."); - - if (holder.rpc != null) { - LOG.info("Shutting down RpcServer"); - holder.rpc.shutdown(); - LOG.info("Shutdown RpcServer ... Done!"); - } - - if (holder.pp != null) { - LOG.info("Shutting down zmq ProtocolProcessor"); - try { - holder.pp.shutdown(); - LOG.info("Shutdown zmq ProtocolProcessor... Done!"); - } catch (InterruptedException e) { - LOG.info("Shutdown zmq ProtocolProcessor failed! {}", e.getMessage()); - Thread.currentThread().interrupt(); - } - } - - if (holder.miner != null) { - LOG.info("Shutting down sealer"); - holder.miner.stopMining(); - holder.miner.shutdown(); - LOG.info("Shutdown sealer... Done!"); - } - - LOG.info("Shutting down the AionHub..."); - ac.getAionHub().close(); - - LOG.info("---------------------------------------------"); - LOG.info("| Aion kernel graceful shutdown successful! |"); - LOG.info("---------------------------------------------"); - }, "shutdown")); + Runtime.getRuntime() + .addShutdownHook( + new Thread( + () -> { + LOG.info("Starting shutdown process..."); + + if (holder.rpc != null) { + LOG.info("Shutting down RpcServer"); + holder.rpc.shutdown(); + LOG.info("Shutdown RpcServer ... Done!"); + } + + if (holder.pp != null) { + LOG.info("Shutting down zmq ProtocolProcessor"); + try { + holder.pp.shutdown(); + LOG.info("Shutdown zmq ProtocolProcessor... Done!"); + } catch (InterruptedException e) { + LOG.info( + "Shutdown zmq ProtocolProcessor failed! {}", + e.getMessage()); + Thread.currentThread().interrupt(); + } + } + + if (holder.miner != null) { + LOG.info("Shutting down sealer"); + holder.miner.stopMining(); + holder.miner.shutdown(); + LOG.info("Shutdown sealer... Done!"); + } + + LOG.info("Shutting down the AionHub..."); + ac.getAionHub().close(); + + LOG.info("---------------------------------------------"); + LOG.info("| Aion kernel graceful shutdown successful! |"); + LOG.info("---------------------------------------------"); + }, + "shutdown")); } } diff --git a/modLogger/src/org/aion/log/AionLoggerFactory.java b/modLogger/src/org/aion/log/AionLoggerFactory.java index cc61dbd76b..a2f0045ab2 100644 --- a/modLogger/src/org/aion/log/AionLoggerFactory.java +++ b/modLogger/src/org/aion/log/AionLoggerFactory.java @@ -1,24 +1,26 @@ -/** - * ***************************************************************************** Copyright (c) - * 2017-2018 Aion foundation. +/******************************************************************************* + * Copyright (c) 2017-2018 Aion foundation. * - *

This file is part of the aion network project. + * This file is part of the aion network project. * - *

The aion network project is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software Foundation, either - * version 3 of the License, or any later version. + * The aion network project is free software: you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or any later version. * - *

The aion network project is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. + * The aion network project is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. * - *

You should have received a copy of the GNU General Public License along with the aion network - * project source files. If not, see . + * You should have received a copy of the GNU General Public License + * along with the aion network project source files. + * If not, see . * - *

Contributors: Aion foundation. + * Contributors: + * Aion foundation. * - *

**************************************************************************** - */ + ******************************************************************************/ package org.aion.log; import ch.qos.logback.classic.Level; @@ -26,7 +28,6 @@ import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.ConsoleAppender; -import ch.qos.logback.core.FileAppender; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy; import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy; @@ -62,8 +63,8 @@ public class AionLoggerFactory { private static final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); /** Static declaration of logFile */ - private static boolean logToFile; - + private static boolean logFile; + private static String logPath; private static RollingFileAppender fileAppender; static { @@ -74,26 +75,23 @@ public class AionLoggerFactory { } } - /** Change INITIALIZE signature to include LOGFILE */ + /** Change INITIALIZE signature to include LOGFILE and LOGPATH */ public static void init(final Map _logModules) { - init(_logModules, false); + init(_logModules, false, "log"); } - // public static void init(final Map _logModules) { - public static void init(final Map _logModules, boolean _logToFile ) { + public static void init(final Map _logModules, boolean _logToFile, String _logToPath) { logModules = _logModules; - - /** Passed in argument */ - logToFile = _logToFile; - // logToFile = true; + logFile = _logToFile; + logPath = _logToPath; loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); /** Toggles file appending configurations */ - if(logToFile) { + if (logFile) { /** Initialize Rolling-File-Appender */ - String fileName = "./log/aionCurrentLog.dat"; + String fileName = logPath + "/aionCurrentLog.dat"; fileAppender = new RollingFileAppender(); fileAppender.setContext(loggerContext); fileAppender.setName("aionlogger"); @@ -114,8 +112,8 @@ public static void init(final Map _logModules, boolean _logToFil * (Currently set to PER DAY) */ FileNamePattern fnp = - new FileNamePattern( - "./log/%d{yyyy/MM, aux}/aion.%d{yyyy-MM-dd}.%i.log", loggerContext); + new FileNamePattern( + logPath + "/%d{yyyy/MM, aux}/aion.%d{yyyy-MM-dd}.%i.log", loggerContext); rp.setFileNamePattern(fnp.getPattern()); /** @@ -164,15 +162,15 @@ private static Logger newLogger(String label) { if (loggerContext == null) { // System.out.println("If you see this line, meaning you are under // the unit test!!! If you are not. should report an issue."); - //init(new HashMap<>(), false); + // init(new HashMap<>(), false); init(new HashMap<>()); } ch.qos.logback.classic.Logger newlogger = loggerContext.getLogger(label); newlogger.addAppender(appender); - /** Toggle file appending */ - if(logToFile) { + /** Toggles file appending */ + if (logFile) { newlogger.addAppender(fileAppender); } diff --git a/modMcf/src/org/aion/mcf/config/CfgLog.java b/modMcf/src/org/aion/mcf/config/CfgLog.java index 80de09cc46..bfd431a4da 100644 --- a/modMcf/src/org/aion/mcf/config/CfgLog.java +++ b/modMcf/src/org/aion/mcf/config/CfgLog.java @@ -27,24 +27,21 @@ import java.io.StringWriter; import java.io.Writer; import java.util.*; - -import org.aion.log.LogEnum; -import org.aion.log.LogLevels; - import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; +import org.aion.log.LogEnum; +import org.aion.log.LogLevels; -/** - * @author chris - */ +/** @author chris */ public class CfgLog { private Map modules; - - /** Declaree logFile variable */ private boolean logFile; + private String logPath; + private boolean validPath; + private boolean original; public CfgLog() { modules = new HashMap<>(); @@ -56,10 +53,10 @@ public CfgLog() { modules.put(LogEnum.API.name(), LogLevels.INFO.name()); modules.put(LogEnum.TX.name(), LogLevels.ERROR.name()); modules.put(LogEnum.TXPOOL.name(), LogLevels.ERROR.name()); - - /** TOGGLES LOGGING TO FILE - initializes logFile as FALSE */ this.logFile = false; - + this.logPath = "log"; + this.validPath = true; + this.original = true; } public void fromXML(final XMLStreamReader sr) throws XMLStreamException { @@ -68,28 +65,33 @@ public void fromXML(final XMLStreamReader sr) throws XMLStreamException { while (sr.hasNext()) { int eventType = sr.next(); switch (eventType) { - case XMLStreamReader.START_ELEMENT: - - /** XML - Takes the input in config.xml and parse as T/F */ - String elementName = sr.getLocalName().toLowerCase(); - switch (elementName) { - case "log-file": - this.logFile = Boolean.parseBoolean(Cfg.readValue(sr)); - break; - default: - break; - } - - elementName = sr.getLocalName().toUpperCase(); - /** String elementName = sr.getLocalName().toUpperCase(); */ - if (LogEnum.contains(elementName)) - this.modules.put(elementName, Cfg.readValue(sr).toUpperCase()); - break; - case XMLStreamReader.END_ELEMENT: - break loop; - default: - //Cfg.skipElement(sr); - break; + case XMLStreamReader.START_ELEMENT: + + /** XML - Takes the input in config.xml and parse as T/F */ + String elementName = sr.getLocalName().toLowerCase(); + switch (elementName) { + case "log-file": + this.logFile = Boolean.parseBoolean(Cfg.readValue(sr)); + break; + case "log-path": + this.logPath = Cfg.readValue(sr); + if(!isValidPath()) { + this.original = false; + } + break; + default: + break; + } + + elementName = sr.getLocalName().toUpperCase(); + if (LogEnum.contains(elementName)) + this.modules.put(elementName, Cfg.readValue(sr).toUpperCase()); + break; + case XMLStreamReader.END_ELEMENT: + break loop; + default: + // Cfg.skipElement(sr); + break; } } } @@ -102,7 +104,7 @@ public String toXML() { Writer strWriter = new StringWriter(); xmlWriter = output.createXMLStreamWriter(strWriter); xmlWriter.writeCharacters("\r\n\t"); - xmlWriter.writeStartElement("Log"); + xmlWriter.writeStartElement("log"); xmlWriter.writeCharacters("\r\n"); /** XML - Displays tag/entry in the config.xml */ @@ -112,13 +114,17 @@ public String toXML() { xmlWriter.writeEndElement(); xmlWriter.writeCharacters("\r\n"); - /** Testing whether logFile retrieves boolean value */ - /** if(logFile) { - xmlWriter.writeCharacters("\t\t"); - xmlWriter.writeCharacters("testing for T"); - xmlWriter.writeCharacters("\r\n"); - } */ + /** XML - Displays log-path in the config.xml */ + xmlWriter.writeCharacters("\t\t"); + xmlWriter.writeStartElement("log-path"); + xmlWriter.writeCharacters(this.logPath + ""); + xmlWriter.writeEndElement(); + xmlWriter.writeCharacters("\r\n"); + /** If file path is invalid, outputs message to config */ + if(!isValidPath()) { + xmlWriter.writeCharacters("\t\tInvalid file path; set to default: 'log'\r\n" ); + } for (Map.Entry module : this.modules.entrySet()) { xmlWriter.writeCharacters("\t\t"); @@ -149,4 +155,32 @@ public boolean getLogFile() { return this.logFile; } -} \ No newline at end of file + /** Method returns user input path of logFile */ + public String getLogPath() { + if(!isValidPath()) { + return this.logPath = "log"; + } else { + return this.logPath; + } + } + + /** Method checks logPath for illegal inputs */ + public boolean isValidPath() { + if(logPath.contains("-") || logPath.contains("+") || logPath.contains("=") + || logPath.contains("?") || logPath.contains("!") || logPath.contains("@") + || logPath.contains("#") || logPath.contains("$") || logPath.contains("%") + || logPath.contains("^") || logPath.contains("*") || logPath.contains(":") + || logPath.contains(";") || logPath.contains(".") || logPath.contains(",") + || logPath.contains("'") || logPath.contains("|")) { + return this.validPath = false; + } else { + return this.validPath = true; + } + } + + /** Method returns logPath input validity */ + public boolean getOriginal() { + return this.original; + } + +} From 0bdb50963bbb1ef36184d7705fa9a1a1b44d6939 Mon Sep 17 00:00:00 2001 From: aionJoey Date: Wed, 23 May 2018 15:37:13 -0400 Subject: [PATCH 06/13] logger features --- modBoot/src/org/aion/Aion.java | 166 ++++++++++----------- modMcf/src/org/aion/mcf/config/CfgLog.java | 35 +---- 2 files changed, 84 insertions(+), 117 deletions(-) diff --git a/modBoot/src/org/aion/Aion.java b/modBoot/src/org/aion/Aion.java index 5ced73e85b..7d8ceb7b49 100644 --- a/modBoot/src/org/aion/Aion.java +++ b/modBoot/src/org/aion/Aion.java @@ -17,17 +17,14 @@ * along with the aion network project source files. * If not, see . * - * Contributors: + * Contributors to the aion source files in decreasing order of code volume: + * * Aion foundation. * ******************************************************************************/ -package org.aion; -import static org.aion.crypto.ECKeyFac.ECKeyType.ED25519; -import static org.aion.crypto.HashUtil.H256Type.BLAKE2B_256; -import static org.aion.zero.impl.Version.KERNEL_VERSION; +package org.aion; -import java.util.ServiceLoader; import org.aion.api.server.http.NanoServer; import org.aion.api.server.pb.ApiAion0; import org.aion.api.server.pb.IHdlr; @@ -46,6 +43,12 @@ import org.aion.zero.impl.config.CfgAion; import org.slf4j.Logger; +import java.util.ServiceLoader; + +import static org.aion.crypto.ECKeyFac.ECKeyType.ED25519; +import static org.aion.crypto.HashUtil.H256Type.BLAKE2B_256; +import static org.aion.zero.impl.Version.KERNEL_VERSION; + public class Aion { public static void main(String args[]) throws InterruptedException { @@ -68,7 +71,9 @@ public static void main(String args[]) throws InterruptedException { * if in the config.xml id is set as default [NODE-ID-PLACEHOLDER] * return true which means should save back to xml config */ - if (cfg.fromXML()) cfg.toXML(new String[] {"--id=" + cfg.getId()}); + if(cfg.fromXML()) + cfg.toXML(new String[]{ "--id=" + cfg.getId() }); + try { ServiceLoader.load(AionLoggerFactory.class); @@ -77,28 +82,30 @@ public static void main(String args[]) throws InterruptedException { throw e; } - // If commit this out, the config setting will be ignore. all log module been set to "INFO" - // Level - /** Changed INITIALIZE signature to include LOGFILE and LOGPATH*/ - AionLoggerFactory.init(cfg.getLog().getModules(), cfg.getLog().getLogFile(), cfg.getLog().getLogPath()); - Logger LOG = AionLoggerFactory.getLogger(LogEnum.GEN.toString()); - - /** Outputs message to console depending on logPath validity */ - if(cfg.getLog().getOriginal()) { + System.out.println( + " _____ \n" + + " .'. | .~ ~. |.. |\n" + + " .' `. | | | | ``.. |\n" + + " .''''''''`. | | | | ``.. |\n" + + ".' `. | `._____.' | ``|\n\n" + + " NETWORK v" + KERNEL_VERSION + + "\n\n" + ); + + /** Outputs relevant logger configuration */ + if (!cfg.getLog().getLogFile()) { + System.out.println("Logger disabled; to enable please check log settings in config.xml\n"); + } else if (!cfg.getLog().isValidPath() && cfg.getLog().getLogFile()) { + System.out.println("File path is invalid; please check log setting in config.xml\n"); + return; + } else if (cfg.getLog().isValidPath() && cfg.getLog().getLogFile()) { System.out.println("Logger file path: '" + cfg.getLog().getLogPath() + "'\n"); - } else { - System.out.println("File path is invalid; set to default: 'log'\n"); } - System.out.println( - " _____ \n" - + " .'. | .~ ~. |.. |\n" - + " .' `. | | | | ``.. |\n" - + " .''''''''`. | | | | ``.. |\n" - + ".' `. | `._____.' | ``|\n\n" - + " NETWORK v" - + KERNEL_VERSION - + "\n\n"); + // If commit this out, the config setting will be ignore. all log module been set to "INFO" Level + /** Changed INITIALIZE signature to include LOGFILE and LOGPATH*/ + AionLoggerFactory.init(cfg.getLog().getModules(), cfg.getLog().getLogFile(), cfg.getLog().getLogPath()); + Logger LOG = AionLoggerFactory.getLogger(LogEnum.GEN.toString()); IAionChain ac = AionFactory.create(); @@ -121,25 +128,21 @@ public static void main(String args[]) throws InterruptedException { IHdlr handler = new HdlrZmq(new ApiAion0(ac)); processor = new ProtocolProcessor(handler, cfg.getApi().getZmq()); ProtocolProcessor finalProcessor = processor; - zmqThread = - new Thread( - () -> { - finalProcessor.run(); - }, - "zmq-api"); + zmqThread = new Thread(() -> { + finalProcessor.run(); + }, "zmq-api"); zmqThread.start(); } NanoServer rpcServer = null; - if (cfg.getApi().getRpc().getActive()) { - CfgApiRpc rpcCfg = cfg.getApi().getRpc(); - rpcServer = - new NanoServer( - rpcCfg.getIp(), - rpcCfg.getPort(), - rpcCfg.getCorsEnabled(), - rpcCfg.getEnabled(), - rpcCfg.getMaxthread()); + if(cfg.getApi().getRpc().getActive()) { + CfgApiRpc rpcCfg = cfg.getApi().getRpc(); + rpcServer = new NanoServer( + rpcCfg.getIp(), + rpcCfg.getPort(), + rpcCfg.getCorsEnabled(), + rpcCfg.getEnabled(), + rpcCfg.getMaxthread()); rpcServer.start(); } @@ -153,8 +156,7 @@ class ShutdownThreadHolder { final ProtocolProcessor pp; final NanoServer rpc; - private ShutdownThreadHolder( - Thread zmqThread, IMineRunner nm, ProtocolProcessor pp, NanoServer rpc) { + private ShutdownThreadHolder(Thread zmqThread, IMineRunner nm, ProtocolProcessor pp, NanoServer rpc) { this.zmqThread = zmqThread; this.miner = nm; this.pp = pp; @@ -164,45 +166,41 @@ private ShutdownThreadHolder( ShutdownThreadHolder holder = new ShutdownThreadHolder(zmqThread, nm, processor, rpcServer); - Runtime.getRuntime() - .addShutdownHook( - new Thread( - () -> { - LOG.info("Starting shutdown process..."); - - if (holder.rpc != null) { - LOG.info("Shutting down RpcServer"); - holder.rpc.shutdown(); - LOG.info("Shutdown RpcServer ... Done!"); - } - - if (holder.pp != null) { - LOG.info("Shutting down zmq ProtocolProcessor"); - try { - holder.pp.shutdown(); - LOG.info("Shutdown zmq ProtocolProcessor... Done!"); - } catch (InterruptedException e) { - LOG.info( - "Shutdown zmq ProtocolProcessor failed! {}", - e.getMessage()); - Thread.currentThread().interrupt(); - } - } - - if (holder.miner != null) { - LOG.info("Shutting down sealer"); - holder.miner.stopMining(); - holder.miner.shutdown(); - LOG.info("Shutdown sealer... Done!"); - } - - LOG.info("Shutting down the AionHub..."); - ac.getAionHub().close(); - - LOG.info("---------------------------------------------"); - LOG.info("| Aion kernel graceful shutdown successful! |"); - LOG.info("---------------------------------------------"); - }, - "shutdown")); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + + LOG.info("Starting shutdown process..."); + + if (holder.rpc != null) { + LOG.info("Shutting down RpcServer"); + holder.rpc.shutdown(); + LOG.info("Shutdown RpcServer ... Done!"); + } + + if (holder.pp != null) { + LOG.info("Shutting down zmq ProtocolProcessor"); + try { + holder.pp.shutdown(); + LOG.info("Shutdown zmq ProtocolProcessor... Done!"); + } catch (InterruptedException e) { + LOG.info("Shutdown zmq ProtocolProcessor failed! {}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } + + if (holder.miner != null) { + LOG.info("Shutting down sealer"); + holder.miner.stopMining(); + holder.miner.shutdown(); + LOG.info("Shutdown sealer... Done!"); + } + + LOG.info("Shutting down the AionHub..."); + ac.getAionHub().close(); + + LOG.info("---------------------------------------------"); + LOG.info("| Aion kernel graceful shutdown successful! |"); + LOG.info("---------------------------------------------"); + + }, "shutdown")); } -} +} \ No newline at end of file diff --git a/modMcf/src/org/aion/mcf/config/CfgLog.java b/modMcf/src/org/aion/mcf/config/CfgLog.java index bfd431a4da..a86601e8b2 100644 --- a/modMcf/src/org/aion/mcf/config/CfgLog.java +++ b/modMcf/src/org/aion/mcf/config/CfgLog.java @@ -40,8 +40,6 @@ public class CfgLog { private Map modules; private boolean logFile; private String logPath; - private boolean validPath; - private boolean original; public CfgLog() { modules = new HashMap<>(); @@ -55,8 +53,6 @@ public CfgLog() { modules.put(LogEnum.TXPOOL.name(), LogLevels.ERROR.name()); this.logFile = false; this.logPath = "log"; - this.validPath = true; - this.original = true; } public void fromXML(final XMLStreamReader sr) throws XMLStreamException { @@ -75,9 +71,6 @@ public void fromXML(final XMLStreamReader sr) throws XMLStreamException { break; case "log-path": this.logPath = Cfg.readValue(sr); - if(!isValidPath()) { - this.original = false; - } break; default: break; @@ -121,11 +114,6 @@ public String toXML() { xmlWriter.writeEndElement(); xmlWriter.writeCharacters("\r\n"); - /** If file path is invalid, outputs message to config */ - if(!isValidPath()) { - xmlWriter.writeCharacters("\t\tInvalid file path; set to default: 'log'\r\n" ); - } - for (Map.Entry module : this.modules.entrySet()) { xmlWriter.writeCharacters("\t\t"); xmlWriter.writeStartElement(module.getKey().toUpperCase()); @@ -157,30 +145,11 @@ public boolean getLogFile() { /** Method returns user input path of logFile */ public String getLogPath() { - if(!isValidPath()) { - return this.logPath = "log"; - } else { - return this.logPath; - } + return this.logPath; } /** Method checks logPath for illegal inputs */ public boolean isValidPath() { - if(logPath.contains("-") || logPath.contains("+") || logPath.contains("=") - || logPath.contains("?") || logPath.contains("!") || logPath.contains("@") - || logPath.contains("#") || logPath.contains("$") || logPath.contains("%") - || logPath.contains("^") || logPath.contains("*") || logPath.contains(":") - || logPath.contains(";") || logPath.contains(".") || logPath.contains(",") - || logPath.contains("'") || logPath.contains("|")) { - return this.validPath = false; - } else { - return this.validPath = true; - } + return !logPath.matches(".*[-=+,.?;:'!@#$%^&*].*"); } - - /** Method returns logPath input validity */ - public boolean getOriginal() { - return this.original; - } - } From 67209d30ea85a5d72b76384cbbb36ece5c3ad81c Mon Sep 17 00:00:00 2001 From: aionJoey Date: Wed, 23 May 2018 17:43:36 -0400 Subject: [PATCH 07/13] added test for valid log path check --- modMcf/src/org/aion/mcf/config/CfgLog.java | 2 +- .../test/org/aion/mcf/config/CfgLogTest.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 modMcf/test/org/aion/mcf/config/CfgLogTest.java diff --git a/modMcf/src/org/aion/mcf/config/CfgLog.java b/modMcf/src/org/aion/mcf/config/CfgLog.java index a86601e8b2..8004dde48d 100644 --- a/modMcf/src/org/aion/mcf/config/CfgLog.java +++ b/modMcf/src/org/aion/mcf/config/CfgLog.java @@ -39,7 +39,7 @@ public class CfgLog { private Map modules; private boolean logFile; - private String logPath; + protected String logPath; public CfgLog() { modules = new HashMap<>(); diff --git a/modMcf/test/org/aion/mcf/config/CfgLogTest.java b/modMcf/test/org/aion/mcf/config/CfgLogTest.java new file mode 100644 index 0000000000..9990eb080d --- /dev/null +++ b/modMcf/test/org/aion/mcf/config/CfgLogTest.java @@ -0,0 +1,52 @@ +package org.aion.mcf.config; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Tests for CfgLog.java + */ +public class CfgLogTest extends CfgLog { + + private final static String user1 = "logger"; // valid file path + private final static String user2 = "l!@#g"; // invalid file path + private final static String user3 = "log/logger"; // folder hierarchy path + private final static String user4 = ""; // null file path + + @Before + public void setup() { + + } + + @Test + public void testLogPath() { + + // Test for default file path + CfgLog config = new CfgLog(); + assertTrue(config.isValidPath()); + assertEquals("log", config.getLogPath()); + + // Test for valid file path + config.logPath = user1; + assertTrue(config.isValidPath()); + assertEquals("logger", config.getLogPath()); + + // Test for invalid file path + config.logPath = user2; + assertFalse(config.isValidPath()); + + // Test for folder hierarchy path + config.logPath = user3; + assertTrue(config.isValidPath()); + assertEquals("log/logger", config.getLogPath()); + + // Test for null path + config.logPath = user4; + assertTrue(config.isValidPath()); + assertEquals("", config.getLogPath()); + + } + +} \ No newline at end of file From ba2050a865daa3b3022cff480664594ccd19fd6d Mon Sep 17 00:00:00 2001 From: aionJoey Date: Fri, 25 May 2018 16:46:43 -0400 Subject: [PATCH 08/13] added test cases for log file creation --- .../test/org/aion/mcf/config/CfgLogTest.java | 178 +++++++++++++++++- 1 file changed, 168 insertions(+), 10 deletions(-) diff --git a/modMcf/test/org/aion/mcf/config/CfgLogTest.java b/modMcf/test/org/aion/mcf/config/CfgLogTest.java index 9990eb080d..7279525882 100644 --- a/modMcf/test/org/aion/mcf/config/CfgLogTest.java +++ b/modMcf/test/org/aion/mcf/config/CfgLogTest.java @@ -1,8 +1,15 @@ package org.aion.mcf.config; +import org.aion.db.utils.FileUtils; +import org.aion.log.AionLoggerFactory; + +import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.io.File; +import java.util.Map; + import static org.junit.Assert.*; /** @@ -10,18 +17,93 @@ */ public class CfgLogTest extends CfgLog { - private final static String user1 = "logger"; // valid file path - private final static String user2 = "l!@#g"; // invalid file path - private final static String user3 = "log/logger"; // folder hierarchy path - private final static String user4 = ""; // null file path + /** + * User input toggle under "log-file" in config.xml + */ + private final static String[] toggle = { + "true", // valid configuration + "tRuE", // capitalized entry + "maybe?", // invalid config entry + "" // null config entry + }; + + /** + * User input file path under "log-path" in config.xml + */ + private final static String[] path = { + "logger", // valid file path + "l!@#*g", // invalid file path + "log/logging/logger", // folder hierarchy path + "" // null file path + }; + + /** + * Before: Creates folder to create test log files in + * After: Remove the created folder after testing + */ + File testRoot; + // Path: /home/joey/Desktop/IDE/aion/modMcf @Before public void setup() { + testRoot = new File("testLog"); + if (testRoot.exists()) { + FileUtils.deleteRecursively(testRoot); + testRoot.delete(); + } + testRoot.mkdirs(); + } + + //@After + public void shutdown() { + if (testRoot.exists()) { + FileUtils.deleteRecursively(testRoot); + testRoot.delete(); + } + } + + /** + * Test for: + * - if parseBoolean() correctly parses user input + * - if getLogFile() returns the correct configuration + */ + @Test + public void testToggle() { + + // Test for default log configuration + CfgLog config = new CfgLog(); + assertEquals(false, config.logFile); + assertFalse(config.getLogFile()); + + // Test for valid configuration + config.logFile = Boolean.parseBoolean(toggle[0]); + assertEquals(true, config.logFile); + assertTrue(config.getLogFile()); + + // Test for capitalized entry + config.logFile = Boolean.parseBoolean(toggle[1]); + assertEquals(true, config.logFile); + assertTrue(config.getLogFile()); + + // Test for invalid configuration + config.logFile = Boolean.parseBoolean(toggle[2]); + assertEquals(false, config.logFile); + assertFalse(config.getLogFile()); + + // Test for null entry + config.logFile = Boolean.parseBoolean(toggle[3]); + assertEquals(false, config.logFile); + assertFalse(config.getLogFile()); } + /** + * Test for: + * - if isValidPath() validates user input log path + * - if getLogPath() returns the correct log path + */ @Test - public void testLogPath() { + public void testPathInput() { // Test for default file path CfgLog config = new CfgLog(); @@ -29,24 +111,100 @@ public void testLogPath() { assertEquals("log", config.getLogPath()); // Test for valid file path - config.logPath = user1; + config.logPath = path[0]; assertTrue(config.isValidPath()); assertEquals("logger", config.getLogPath()); // Test for invalid file path - config.logPath = user2; + config.logPath = path[1]; assertFalse(config.isValidPath()); // Test for folder hierarchy path - config.logPath = user3; + config.logPath = path[2]; assertTrue(config.isValidPath()); - assertEquals("log/logger", config.getLogPath()); + assertEquals("log/logging/logger", config.getLogPath()); // Test for null path - config.logPath = user4; + config.logPath = path[3]; assertTrue(config.isValidPath()); assertEquals("", config.getLogPath()); } + /** + * Test for: + * - if archives are stored under correct file name + * - if log rollover conditions are correct + * - size roughly equal to 100MB + */ + File generatedPath; + Map _logModules; + + @Test + public void testLoggedPath() { + + // Test Case Default + CfgLog config = new CfgLog(); + + assertFalse(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + assertEquals("log", generatedPath.getName()); + //reset(); + } + + // Test Case 1: Enabled + Valid + config.logFile = true; + config.logPath = "log1"; + + assertTrue(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + assertEquals("log1", generatedPath.getName()); + reset(); + } + + // Test Case 2: Enabled + Invalid + config.logFile = true; + config.logPath = "*log2*"; + + assertFalse(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + assertEquals("log2*", generatedPath.getName()); + reset(); + } + + // Test Case 3: Disabled + Valid + config.logFile = false; + config.logPath = "log3"; + + assertFalse(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + assertEquals("log3", generatedPath.getName()); + reset(); + } + + // Test Case 4: Disabled + Invalid + config.logFile = false; + config.logPath = "*log4*"; + + assertFalse(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + assertEquals("*log4*", generatedPath.getName()); + reset(); + } + } + + public void reset() { + FileUtils.deleteRecursively(generatedPath); + generatedPath.delete(); + } } \ No newline at end of file From fda465f2db6ae4eaaec310c51666f2ae8bc0b8cb Mon Sep 17 00:00:00 2001 From: aionJoey <39343036+aionJoey@users.noreply.github.com> Date: Fri, 25 May 2018 16:49:49 -0400 Subject: [PATCH 09/13] Removed commenting out @After --- modMcf/test/org/aion/mcf/config/CfgLogTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modMcf/test/org/aion/mcf/config/CfgLogTest.java b/modMcf/test/org/aion/mcf/config/CfgLogTest.java index 7279525882..cfe38765be 100644 --- a/modMcf/test/org/aion/mcf/config/CfgLogTest.java +++ b/modMcf/test/org/aion/mcf/config/CfgLogTest.java @@ -54,7 +54,7 @@ public void setup() { testRoot.mkdirs(); } - //@After + @After public void shutdown() { if (testRoot.exists()) { FileUtils.deleteRecursively(testRoot); @@ -207,4 +207,4 @@ public void reset() { FileUtils.deleteRecursively(generatedPath); generatedPath.delete(); } -} \ No newline at end of file +} From 651c4088f63ec7f79ef3148922f56377dcca8452 Mon Sep 17 00:00:00 2001 From: aionJoey Date: Fri, 25 May 2018 18:19:52 -0400 Subject: [PATCH 10/13] null path now returns false --- modMcf/src/org/aion/mcf/config/CfgLog.java | 6 +- .../test/org/aion/mcf/config/CfgLogTest.java | 97 +++++++++++++------ 2 files changed, 73 insertions(+), 30 deletions(-) diff --git a/modMcf/src/org/aion/mcf/config/CfgLog.java b/modMcf/src/org/aion/mcf/config/CfgLog.java index 8004dde48d..1c4d47dd6b 100644 --- a/modMcf/src/org/aion/mcf/config/CfgLog.java +++ b/modMcf/src/org/aion/mcf/config/CfgLog.java @@ -38,8 +38,8 @@ public class CfgLog { private Map modules; - private boolean logFile; - protected String logPath; + boolean logFile; + String logPath; public CfgLog() { modules = new HashMap<>(); @@ -150,6 +150,6 @@ public String getLogPath() { /** Method checks logPath for illegal inputs */ public boolean isValidPath() { - return !logPath.matches(".*[-=+,.?;:'!@#$%^&*].*"); + return logPath.length() > 0 && !logPath.matches(".*[-=+,.?;:'!@#$%^&*].*"); } } diff --git a/modMcf/test/org/aion/mcf/config/CfgLogTest.java b/modMcf/test/org/aion/mcf/config/CfgLogTest.java index 7279525882..a431a93c9e 100644 --- a/modMcf/test/org/aion/mcf/config/CfgLogTest.java +++ b/modMcf/test/org/aion/mcf/config/CfgLogTest.java @@ -21,20 +21,20 @@ public class CfgLogTest extends CfgLog { * User input toggle under "log-file" in config.xml */ private final static String[] toggle = { - "true", // valid configuration - "tRuE", // capitalized entry - "maybe?", // invalid config entry - "" // null config entry + "true", // valid entry + "maybe?", // invalid entry + "tRuE", // special entry + "" // null entry }; /** * User input file path under "log-path" in config.xml */ private final static String[] path = { - "logger", // valid file path - "l!@#*g", // invalid file path - "log/logging/logger", // folder hierarchy path - "" // null file path + "logger", // valid entry + "l!@#*g", // invalid entry + "log/logging/logger", // special entry + "" // null entry }; /** @@ -54,7 +54,7 @@ public void setup() { testRoot.mkdirs(); } - //@After + @After public void shutdown() { if (testRoot.exists()) { FileUtils.deleteRecursively(testRoot); @@ -72,28 +72,30 @@ public void testToggle() { // Test for default log configuration CfgLog config = new CfgLog(); - assertEquals(false, config.logFile); assertFalse(config.getLogFile()); + assertEquals(false, config.logFile); // Test for valid configuration config.logFile = Boolean.parseBoolean(toggle[0]); - assertEquals(true, config.logFile); assertTrue(config.getLogFile()); + assertEquals(true, config.logFile); + // Test for capitalized entry config.logFile = Boolean.parseBoolean(toggle[1]); - assertEquals(true, config.logFile); - assertTrue(config.getLogFile()); + assertFalse(config.getLogFile()); + assertEquals(false, config.logFile); // Test for invalid configuration config.logFile = Boolean.parseBoolean(toggle[2]); - assertEquals(false, config.logFile); - assertFalse(config.getLogFile()); + assertTrue(config.getLogFile()); + assertEquals(true, config.logFile); + // Test for null entry config.logFile = Boolean.parseBoolean(toggle[3]); - assertEquals(false, config.logFile); assertFalse(config.getLogFile()); + assertEquals(false, config.logFile); } @@ -126,7 +128,7 @@ public void testPathInput() { // Test for null path config.logPath = path[3]; - assertTrue(config.isValidPath()); + assertFalse(config.isValidPath()); assertEquals("", config.getLogPath()); } @@ -134,10 +136,9 @@ public void testPathInput() { /** * Test for: * - if archives are stored under correct file name - * - if log rollover conditions are correct - * - size roughly equal to 100MB */ File generatedPath; + String accumulatedPath; Map _logModules; @Test @@ -145,20 +146,21 @@ public void testLoggedPath() { // Test Case Default CfgLog config = new CfgLog(); - assertFalse(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); generatedPath = testRoot.listFiles()[0]; assertEquals("log", generatedPath.getName()); - //reset(); + reset(); } + /* // Test Case 1: Enabled + Valid config.logFile = true; config.logPath = "log1"; - assertTrue(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); generatedPath = testRoot.listFiles()[0]; @@ -169,8 +171,8 @@ public void testLoggedPath() { // Test Case 2: Enabled + Invalid config.logFile = true; config.logPath = "*log2*"; - assertFalse(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); generatedPath = testRoot.listFiles()[0]; @@ -181,8 +183,8 @@ public void testLoggedPath() { // Test Case 3: Disabled + Valid config.logFile = false; config.logPath = "log3"; - assertFalse(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); generatedPath = testRoot.listFiles()[0]; @@ -193,18 +195,59 @@ public void testLoggedPath() { // Test Case 4: Disabled + Invalid config.logFile = false; config.logPath = "*log4*"; - assertFalse(config.logFile && config.isValidPath()); + if(config.logFile && config.isValidPath()) { AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); generatedPath = testRoot.listFiles()[0]; assertEquals("*log4*", generatedPath.getName()); reset(); } + + // Test Case 5: Enable + Special Path + config.logFile = true; + config.logPath = "log/logging/logger"; + assertTrue(config.logFile && config.isValidPath()); + + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + + accumulatedPath = generatedPath.getName(); + while(generatedPath.listFiles()[0].isDirectory()) { + generatedPath = generatedPath.listFiles()[0]; + accumulatedPath = accumulatedPath + "/" + generatedPath.getName(); + } + + assertEquals("log/logging/logger", accumulatedPath); + //reset(); + }*/ + + // All Test Case + for(int a = 0; a < 4; a++){ + for(int b = 0; b < 4; b++){ + config.logFile = Boolean.parseBoolean(toggle[a]); + config.logPath = path[b]; + + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + + accumulatedPath = generatedPath.getName(); + while(generatedPath.listFiles()[0].isDirectory()) { + generatedPath = generatedPath.listFiles()[0]; + accumulatedPath = accumulatedPath + "/" + generatedPath.getName(); + } + assertEquals(path[b], accumulatedPath); + } + reset(); + } + } } public void reset() { - FileUtils.deleteRecursively(generatedPath); - generatedPath.delete(); + testRoot.delete(); + FileUtils.deleteRecursively(testRoot); + testRoot.mkdirs(); } } \ No newline at end of file From 43d206b88e4092d9f0c278d542c3d74dd18b8ef0 Mon Sep 17 00:00:00 2001 From: aionJoey Date: Mon, 28 May 2018 10:38:17 -0400 Subject: [PATCH 11/13] FileUtils dependency avoided --- .../test/org/aion/mcf/config/CfgLogTest.java | 66 ++++++++++++++----- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/modMcf/test/org/aion/mcf/config/CfgLogTest.java b/modMcf/test/org/aion/mcf/config/CfgLogTest.java index beb619ace6..177ac9c819 100644 --- a/modMcf/test/org/aion/mcf/config/CfgLogTest.java +++ b/modMcf/test/org/aion/mcf/config/CfgLogTest.java @@ -1,6 +1,5 @@ package org.aion.mcf.config; -import org.aion.db.utils.FileUtils; import org.aion.log.AionLoggerFactory; import org.junit.After; @@ -8,6 +7,11 @@ import org.junit.Test; import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.Map; import static org.junit.Assert.*; @@ -48,7 +52,7 @@ public class CfgLogTest extends CfgLog { public void setup() { testRoot = new File("testLog"); if (testRoot.exists()) { - FileUtils.deleteRecursively(testRoot); + deleteRecursively(testRoot); testRoot.delete(); } testRoot.mkdirs(); @@ -57,7 +61,7 @@ public void setup() { @After public void shutdown() { if (testRoot.exists()) { - FileUtils.deleteRecursively(testRoot); + deleteRecursively(testRoot); testRoot.delete(); } } @@ -73,29 +77,22 @@ public void testToggle() { // Test for default log configuration CfgLog config = new CfgLog(); assertFalse(config.getLogFile()); - assertEquals(false, config.logFile); // Test for valid configuration config.logFile = Boolean.parseBoolean(toggle[0]); assertTrue(config.getLogFile()); - assertEquals(true, config.logFile); - // Test for capitalized entry config.logFile = Boolean.parseBoolean(toggle[1]); assertFalse(config.getLogFile()); - assertEquals(false, config.logFile); // Test for invalid configuration config.logFile = Boolean.parseBoolean(toggle[2]); assertTrue(config.getLogFile()); - assertEquals(true, config.logFile); - // Test for null entry config.logFile = Boolean.parseBoolean(toggle[3]); assertFalse(config.getLogFile()); - assertEquals(false, config.logFile); } @@ -129,7 +126,6 @@ public void testPathInput() { // Test for null path config.logPath = path[3]; assertFalse(config.isValidPath()); - assertEquals("", config.getLogPath()); } @@ -154,8 +150,7 @@ public void testLoggedPath() { assertEquals("log", generatedPath.getName()); reset(); } - - /* +/* // Test Case 1: Enabled + Valid config.logFile = true; config.logPath = "log1"; @@ -221,8 +216,8 @@ public void testLoggedPath() { assertEquals("log/logging/logger", accumulatedPath); //reset(); - }*/ - + } +*/ // All Test Case for(int a = 0; a < 4; a++){ for(int b = 0; b < 4; b++){ @@ -239,15 +234,50 @@ public void testLoggedPath() { accumulatedPath = accumulatedPath + "/" + generatedPath.getName(); } assertEquals(path[b], accumulatedPath); + reset(); } - reset(); } } } public void reset() { - testRoot.delete(); - FileUtils.deleteRecursively(testRoot); + deleteRecursively(testRoot); testRoot.mkdirs(); } + + public static boolean deleteRecursively(File file) { + Path path = file.toPath(); + try { + java.nio.file.Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { + java.nio.file.Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(final Path file, final IOException e) { + return handleException(e); + } + + private FileVisitResult handleException(final IOException e) { + // e.printStackTrace(); + return FileVisitResult.TERMINATE; + } + + @Override + public FileVisitResult postVisitDirectory(final Path dir, final IOException e) throws IOException { + if (e != null) + return handleException(e); + java.nio.file.Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + return true; + } } From 1f0e5866b9a19fed8e01515ff58d5afdae17f474 Mon Sep 17 00:00:00 2001 From: joey Date: Fri, 1 Jun 2018 11:57:57 -0400 Subject: [PATCH 12/13] added headers and changed comments --- modBoot/resource/config.xml | 4 + modBoot/src/org/aion/Aion.java | 16 +- .../src/org/aion/log/AionLoggerFactory.java | 32 +-- modMcf/src/org/aion/mcf/config/CfgLog.java | 29 +-- .../test/org/aion/mcf/config/CfgLogTest.java | 184 ++++++++++-------- 5 files changed, 151 insertions(+), 114 deletions(-) diff --git a/modBoot/resource/config.xml b/modBoot/resource/config.xml index 06a3f2de99..37ff777e47 100644 --- a/modBoot/resource/config.xml +++ b/modBoot/resource/config.xml @@ -71,6 +71,10 @@ false + + true + + log INFO ERROR INFO diff --git a/modBoot/src/org/aion/Aion.java b/modBoot/src/org/aion/Aion.java index 7d8ceb7b49..1fbd6180fc 100644 --- a/modBoot/src/org/aion/Aion.java +++ b/modBoot/src/org/aion/Aion.java @@ -1,4 +1,4 @@ -/******************************************************************************* +/* * Copyright (c) 2017-2018 Aion foundation. * * This file is part of the aion network project. @@ -17,12 +17,9 @@ * along with the aion network project source files. * If not, see . * - * Contributors to the aion source files in decreasing order of code volume: - * + * Contributors: * Aion foundation. - * - ******************************************************************************/ - + */ package org.aion; import org.aion.api.server.http.NanoServer; @@ -92,7 +89,7 @@ public static void main(String args[]) throws InterruptedException { "\n\n" ); - /** Outputs relevant logger configuration */ + /* Outputs relevant logger configuration */ if (!cfg.getLog().getLogFile()) { System.out.println("Logger disabled; to enable please check log settings in config.xml\n"); } else if (!cfg.getLog().isValidPath() && cfg.getLog().getLogFile()) { @@ -102,8 +99,9 @@ public static void main(String args[]) throws InterruptedException { System.out.println("Logger file path: '" + cfg.getLog().getLogPath() + "'\n"); } - // If commit this out, the config setting will be ignore. all log module been set to "INFO" Level - /** Changed INITIALIZE signature to include LOGFILE and LOGPATH*/ + /* + * Logger initialize with LOGFILE and LOGPATH (user config inputs) + */ AionLoggerFactory.init(cfg.getLog().getModules(), cfg.getLog().getLogFile(), cfg.getLog().getLogPath()); Logger LOG = AionLoggerFactory.getLogger(LogEnum.GEN.toString()); diff --git a/modLogger/src/org/aion/log/AionLoggerFactory.java b/modLogger/src/org/aion/log/AionLoggerFactory.java index a2f0045ab2..08a4e84635 100644 --- a/modLogger/src/org/aion/log/AionLoggerFactory.java +++ b/modLogger/src/org/aion/log/AionLoggerFactory.java @@ -1,4 +1,4 @@ -/******************************************************************************* +/* * Copyright (c) 2017-2018 Aion foundation. * * This file is part of the aion network project. @@ -19,8 +19,7 @@ * * Contributors: * Aion foundation. - * - ******************************************************************************/ + */ package org.aion.log; import ch.qos.logback.classic.Level; @@ -45,10 +44,10 @@ /** * Used to override SimpleLogger current log level * - *

final public int TRACE_INT = 00; final public int DEBUG_INT = 10; finalConcurrentHashMap + * final public int TRACE_INT = 00; final public int DEBUG_INT = 10; finalConcurrentHashMap * public int INFO_INT = 20; final public int WARN_INT = 30; final public int ERROR_INT = 40; * - *

Default set to 50 which ignore output + * Default set to 50 which ignore output */ public class AionLoggerFactory { @@ -75,7 +74,9 @@ public class AionLoggerFactory { } } - /** Change INITIALIZE signature to include LOGFILE and LOGPATH */ + /* + * Added INITIALIZE signature to include LOGFILE and LOGPATH + */ public static void init(final Map _logModules) { init(_logModules, false, "log"); } @@ -88,25 +89,26 @@ public static void init(final Map _logModules, boolean _logToFil loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); - /** Toggles file appending configurations */ + /* Toggles file appending configurations */ if (logFile) { - /** Initialize Rolling-File-Appender */ + + /* Initialize Rolling-File-Appender */ String fileName = logPath + "/aionCurrentLog.dat"; fileAppender = new RollingFileAppender(); fileAppender.setContext(loggerContext); fileAppender.setName("aionlogger"); fileAppender.setFile(fileName); - /** Initialize Triggering-Policy (CONDITION) */ + /* Initialize Triggering-Policy (CONDITION) */ SizeBasedTriggeringPolicy tp = new SizeBasedTriggeringPolicy(); tp.setContext(loggerContext); tp.start(); - /** Initialize Rolling-Policy (BEHAVIOUR) */ + /* Initialize Rolling-Policy (BEHAVIOUR) */ SizeAndTimeBasedRollingPolicy rp = new SizeAndTimeBasedRollingPolicy(); rp.setContext(loggerContext); - /** + /* * To modify period of each rollover; * https://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy * (Currently set to PER DAY) @@ -116,7 +118,7 @@ public static void init(final Map _logModules, boolean _logToFil logPath + "/%d{yyyy/MM, aux}/aion.%d{yyyy-MM-dd}.%i.log", loggerContext); rp.setFileNamePattern(fnp.getPattern()); - /** + /* * To modify size of each rollover file; * https://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy * (Currently set to 100MB) @@ -125,11 +127,11 @@ public static void init(final Map _logModules, boolean _logToFil rp.setParent(fileAppender); rp.start(); - /** Sets TRIGGER & ROLLING policy */ + /* Sets TRIGGER & ROLLING policy */ fileAppender.setTriggeringPolicy(tp); fileAppender.setRollingPolicy(rp); - /** Set fileAppender configurations */ + /* Set fileAppender configurations */ fileAppender.setContext(loggerContext); fileAppender.setEncoder(encoder); fileAppender.setAppend(true); @@ -169,7 +171,7 @@ private static Logger newLogger(String label) { ch.qos.logback.classic.Logger newlogger = loggerContext.getLogger(label); newlogger.addAppender(appender); - /** Toggles file appending */ + /* Toggles file appending */ if (logFile) { newlogger.addAppender(fileAppender); } diff --git a/modMcf/src/org/aion/mcf/config/CfgLog.java b/modMcf/src/org/aion/mcf/config/CfgLog.java index 8004dde48d..74e693ada3 100644 --- a/modMcf/src/org/aion/mcf/config/CfgLog.java +++ b/modMcf/src/org/aion/mcf/config/CfgLog.java @@ -1,4 +1,4 @@ -/******************************************************************************* +/* * Copyright (c) 2017-2018 Aion foundation. * * This file is part of the aion network project. @@ -19,8 +19,7 @@ * * Contributors: * Aion foundation. - * - ******************************************************************************/ + */ package org.aion.mcf.config; import java.io.IOException; @@ -38,8 +37,8 @@ public class CfgLog { private Map modules; - private boolean logFile; - protected String logPath; + boolean logFile; + String logPath; public CfgLog() { modules = new HashMap<>(); @@ -63,7 +62,7 @@ public void fromXML(final XMLStreamReader sr) throws XMLStreamException { switch (eventType) { case XMLStreamReader.START_ELEMENT: - /** XML - Takes the input in config.xml and parse as T/F */ + /* XML - Takes the input in config.xml and parse as T/F */ String elementName = sr.getLocalName().toLowerCase(); switch (elementName) { case "log-file": @@ -100,14 +99,20 @@ public String toXML() { xmlWriter.writeStartElement("log"); xmlWriter.writeCharacters("\r\n"); - /** XML - Displays tag/entry in the config.xml */ + /* + * XML - Displays tag/entry in the config.xml + * Boolean value to allow logger to be toggled ON and OFF + */ xmlWriter.writeCharacters("\t\t"); xmlWriter.writeStartElement("log-file"); xmlWriter.writeCharacters(this.logFile + ""); xmlWriter.writeEndElement(); xmlWriter.writeCharacters("\r\n"); - /** XML - Displays log-path in the config.xml */ + /* + * XML - Displays log-path in the config.xml + * String value to determine the folder path for log files + */ xmlWriter.writeCharacters("\t\t"); xmlWriter.writeStartElement("log-path"); xmlWriter.writeCharacters(this.logPath + ""); @@ -138,18 +143,18 @@ public Map getModules() { return this.modules; } - /** Method checks value of logFile as T/F */ + /* Method checks whether logger is enabled/disabled */ public boolean getLogFile() { return this.logFile; } - /** Method returns user input path of logFile */ + /* Method returns user input folder path of logger */ public String getLogPath() { return this.logPath; } - /** Method checks logPath for illegal inputs */ + /* Method checks folder path for illegal inputs */ public boolean isValidPath() { - return !logPath.matches(".*[-=+,.?;:'!@#$%^&*].*"); + return logPath.length() > 0 && !logPath.matches(".*[-=+,.?;:'!@#$%^&*].*"); } } diff --git a/modMcf/test/org/aion/mcf/config/CfgLogTest.java b/modMcf/test/org/aion/mcf/config/CfgLogTest.java index 7279525882..f6fea21acd 100644 --- a/modMcf/test/org/aion/mcf/config/CfgLogTest.java +++ b/modMcf/test/org/aion/mcf/config/CfgLogTest.java @@ -1,6 +1,27 @@ +/* + * Copyright (c) 2017-2018 Aion foundation. + * + * This file is part of the aion network project. + * + * The aion network project is free software: you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or any later version. + * + * The aion network project is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the aion network project source files. + * If not, see . + * + * Contributors: + * Aion foundation. + */ package org.aion.mcf.config; -import org.aion.db.utils.FileUtils; import org.aion.log.AionLoggerFactory; import org.junit.After; @@ -8,6 +29,11 @@ import org.junit.Test; import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; import java.util.Map; import static org.junit.Assert.*; @@ -17,27 +43,27 @@ */ public class CfgLogTest extends CfgLog { - /** + /* * User input toggle under "log-file" in config.xml */ private final static String[] toggle = { - "true", // valid configuration - "tRuE", // capitalized entry - "maybe?", // invalid config entry - "" // null config entry + "true", // valid entry + "maybe?", // invalid entry + "tRuE", // special entry + "" // null entry }; - /** + /* * User input file path under "log-path" in config.xml */ private final static String[] path = { - "logger", // valid file path - "l!@#*g", // invalid file path - "log/logging/logger", // folder hierarchy path - "" // null file path + "logger", // valid entry + "l!@#*g", // invalid entry + "log/logging/logger", // special entry + "" // null entry }; - /** + /* * Before: Creates folder to create test log files in * After: Remove the created folder after testing */ @@ -48,21 +74,21 @@ public class CfgLogTest extends CfgLog { public void setup() { testRoot = new File("testLog"); if (testRoot.exists()) { - FileUtils.deleteRecursively(testRoot); + deleteRecursively(testRoot); testRoot.delete(); } testRoot.mkdirs(); } - //@After + @After public void shutdown() { if (testRoot.exists()) { - FileUtils.deleteRecursively(testRoot); + deleteRecursively(testRoot); testRoot.delete(); } } - /** + /* * Test for: * - if parseBoolean() correctly parses user input * - if getLogFile() returns the correct configuration @@ -72,32 +98,27 @@ public void testToggle() { // Test for default log configuration CfgLog config = new CfgLog(); - assertEquals(false, config.logFile); assertFalse(config.getLogFile()); // Test for valid configuration config.logFile = Boolean.parseBoolean(toggle[0]); - assertEquals(true, config.logFile); assertTrue(config.getLogFile()); // Test for capitalized entry config.logFile = Boolean.parseBoolean(toggle[1]); - assertEquals(true, config.logFile); - assertTrue(config.getLogFile()); + assertFalse(config.getLogFile()); // Test for invalid configuration config.logFile = Boolean.parseBoolean(toggle[2]); - assertEquals(false, config.logFile); - assertFalse(config.getLogFile()); + assertTrue(config.getLogFile()); // Test for null entry config.logFile = Boolean.parseBoolean(toggle[3]); - assertEquals(false, config.logFile); assertFalse(config.getLogFile()); } - /** + /* * Test for: * - if isValidPath() validates user input log path * - if getLogPath() returns the correct log path @@ -126,18 +147,16 @@ public void testPathInput() { // Test for null path config.logPath = path[3]; - assertTrue(config.isValidPath()); - assertEquals("", config.getLogPath()); + assertFalse(config.isValidPath()); } - /** + /* * Test for: * - if archives are stored under correct file name - * - if log rollover conditions are correct - * - size roughly equal to 100MB */ File generatedPath; + String accumulatedPath; Map _logModules; @Test @@ -145,66 +164,75 @@ public void testLoggedPath() { // Test Case Default CfgLog config = new CfgLog(); - assertFalse(config.logFile && config.isValidPath()); - if(config.logFile && config.isValidPath()) { - AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); - generatedPath = testRoot.listFiles()[0]; - assertEquals("log", generatedPath.getName()); - //reset(); - } - - // Test Case 1: Enabled + Valid - config.logFile = true; - config.logPath = "log1"; - - assertTrue(config.logFile && config.isValidPath()); - if(config.logFile && config.isValidPath()) { - AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); - generatedPath = testRoot.listFiles()[0]; - assertEquals("log1", generatedPath.getName()); - reset(); - } - // Test Case 2: Enabled + Invalid - config.logFile = true; - config.logPath = "*log2*"; - - assertFalse(config.logFile && config.isValidPath()); if(config.logFile && config.isValidPath()) { AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); generatedPath = testRoot.listFiles()[0]; - assertEquals("log2*", generatedPath.getName()); + assertEquals("log", generatedPath.getName()); reset(); } - // Test Case 3: Disabled + Valid - config.logFile = false; - config.logPath = "log3"; - - assertFalse(config.logFile && config.isValidPath()); - if(config.logFile && config.isValidPath()) { - AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); - generatedPath = testRoot.listFiles()[0]; - assertEquals("log3", generatedPath.getName()); - reset(); + // All Test Case + for(int a = 0; a < 4; a++){ + for(int b = 0; b < 4; b++){ + config.logFile = Boolean.parseBoolean(toggle[a]); + config.logPath = path[b]; + + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + + accumulatedPath = generatedPath.getName(); + while(generatedPath.listFiles()[0].isDirectory()) { + generatedPath = generatedPath.listFiles()[0]; + accumulatedPath = accumulatedPath + "/" + generatedPath.getName(); + } + assertEquals(path[b], accumulatedPath); + reset(); + } + } } + } - // Test Case 4: Disabled + Invalid - config.logFile = false; - config.logPath = "*log4*"; + public void reset() { + deleteRecursively(testRoot); + testRoot.mkdirs(); + } - assertFalse(config.logFile && config.isValidPath()); - if(config.logFile && config.isValidPath()) { - AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); - generatedPath = testRoot.listFiles()[0]; - assertEquals("*log4*", generatedPath.getName()); - reset(); + public static boolean deleteRecursively(File file) { + Path path = file.toPath(); + try { + java.nio.file.Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { + java.nio.file.Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(final Path file, final IOException e) { + return handleException(e); + } + + private FileVisitResult handleException(final IOException e) { + // e.printStackTrace(); + return FileVisitResult.TERMINATE; + } + + @Override + public FileVisitResult postVisitDirectory(final Path dir, final IOException e) throws IOException { + if (e != null) + return handleException(e); + java.nio.file.Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + e.printStackTrace(); + return false; } - } - public void reset() { - FileUtils.deleteRecursively(generatedPath); - generatedPath.delete(); + return true; } -} \ No newline at end of file +} From b88dfa1a2c216437672a771735a0c6323a4e1f1b Mon Sep 17 00:00:00 2001 From: joey Date: Fri, 1 Jun 2018 13:31:37 -0400 Subject: [PATCH 13/13] updated commenting --- .../src/org/aion/log/AionLoggerFactory.java | 3 - modMcf/src/org/aion/mcf/config/CfgLog.java | 10 +- .../test/org/aion/mcf/config/CfgLogTest.java | 226 ++++++++++++++++++ 3 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 modMcf/test/org/aion/mcf/config/CfgLogTest.java diff --git a/modLogger/src/org/aion/log/AionLoggerFactory.java b/modLogger/src/org/aion/log/AionLoggerFactory.java index 08a4e84635..e5cf758e91 100644 --- a/modLogger/src/org/aion/log/AionLoggerFactory.java +++ b/modLogger/src/org/aion/log/AionLoggerFactory.java @@ -74,9 +74,6 @@ public class AionLoggerFactory { } } - /* - * Added INITIALIZE signature to include LOGFILE and LOGPATH - */ public static void init(final Map _logModules) { init(_logModules, false, "log"); } diff --git a/modMcf/src/org/aion/mcf/config/CfgLog.java b/modMcf/src/org/aion/mcf/config/CfgLog.java index 74e693ada3..88b0064c4b 100644 --- a/modMcf/src/org/aion/mcf/config/CfgLog.java +++ b/modMcf/src/org/aion/mcf/config/CfgLog.java @@ -104,6 +104,8 @@ public String toXML() { * Boolean value to allow logger to be toggled ON and OFF */ xmlWriter.writeCharacters("\t\t"); + xmlWriter.writeComment("Enable/Disable logback service; if disabled, output will not be logged."); + xmlWriter.writeCharacters("\r\n\t\t"); xmlWriter.writeStartElement("log-file"); xmlWriter.writeCharacters(this.logFile + ""); xmlWriter.writeEndElement(); @@ -114,6 +116,8 @@ public String toXML() { * String value to determine the folder path for log files */ xmlWriter.writeCharacters("\t\t"); + xmlWriter.writeComment("Sets the physical location on disk where log files will be stored."); + xmlWriter.writeCharacters("\r\n\t\t"); xmlWriter.writeStartElement("log-path"); xmlWriter.writeCharacters(this.logPath + ""); xmlWriter.writeEndElement(); @@ -143,17 +147,17 @@ public Map getModules() { return this.modules; } - /* Method checks whether logger is enabled/disabled */ + /** Method checks whether logger is enabled/disabled */ public boolean getLogFile() { return this.logFile; } - /* Method returns user input folder path of logger */ + /** Method returns user input folder path of logger */ public String getLogPath() { return this.logPath; } - /* Method checks folder path for illegal inputs */ + /** Method checks folder path for illegal inputs */ public boolean isValidPath() { return logPath.length() > 0 && !logPath.matches(".*[-=+,.?;:'!@#$%^&*].*"); } diff --git a/modMcf/test/org/aion/mcf/config/CfgLogTest.java b/modMcf/test/org/aion/mcf/config/CfgLogTest.java new file mode 100644 index 0000000000..c3eae3653e --- /dev/null +++ b/modMcf/test/org/aion/mcf/config/CfgLogTest.java @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2017-2018 Aion foundation. + * + * This file is part of the aion network project. + * + * The aion network project is free software: you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or any later version. + * + * The aion network project is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the aion network project source files. + * If not, see . + * + * Contributors: + * Aion foundation. + */ +package org.aion.mcf.config; + +import org.aion.log.AionLoggerFactory; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Map; + +import static org.junit.Assert.*; + +/** + * Tests for CfgLog.java + */ +public class CfgLogTest extends CfgLog { + + private final static String[] toggle = { + "true", // valid entry + "maybe?", // invalid entry + "tRuE", // special entry + "" // null entry + }; + + private final static String[] path = { + "logger", // valid entry + "l!@#*g", // invalid entry + "log/logging/logger", // special entry + "" // null entry + }; + + private File testRoot; // Path: /home/joey/Desktop/IDE/aion/modMcf + private File generatedPath; + private String accumulatedPath; + private Map _logModules; + + @Before + public void setup() { + testRoot = new File("testLog"); + if (testRoot.exists()) { + deleteRecursively(testRoot); + testRoot.delete(); + } + testRoot.mkdirs(); + } + + @After + public void shutdown() { + if (testRoot.exists()) { + deleteRecursively(testRoot); + testRoot.delete(); + } + } + + /** + * Test for: + * - if parseBoolean() correctly parses user input + * - if getLogFile() returns the correct configuration + */ + @Test + public void testToggle() { + + // Test for default log configuration + CfgLog config = new CfgLog(); + assertFalse(config.getLogFile()); + + // Test for valid configuration + config.logFile = Boolean.parseBoolean(toggle[0]); + assertTrue(config.getLogFile()); + + // Test for capitalized entry + config.logFile = Boolean.parseBoolean(toggle[1]); + assertFalse(config.getLogFile()); + + // Test for invalid configuration + config.logFile = Boolean.parseBoolean(toggle[2]); + assertTrue(config.getLogFile()); + + // Test for null entry + config.logFile = Boolean.parseBoolean(toggle[3]); + assertFalse(config.getLogFile()); + + } + + /** + * Test for: + * - if isValidPath() validates user input log path + * - if getLogPath() returns the correct log path + */ + @Test + public void testPathInput() { + + // Test for default file path + CfgLog config = new CfgLog(); + assertTrue(config.isValidPath()); + assertEquals("log", config.getLogPath()); + + // Test for valid file path + config.logPath = path[0]; + assertTrue(config.isValidPath()); + assertEquals("logger", config.getLogPath()); + + // Test for invalid file path + config.logPath = path[1]; + assertFalse(config.isValidPath()); + + // Test for folder hierarchy path + config.logPath = path[2]; + assertTrue(config.isValidPath()); + assertEquals("log/logging/logger", config.getLogPath()); + + // Test for null path + config.logPath = path[3]; + assertFalse(config.isValidPath()); + + } + + /** + * Test for: + * - if archives are stored under correct file name + */ + @Test + public void testLoggedPath() { + + // Test Case Default + CfgLog config = new CfgLog(); + assertFalse(config.logFile && config.isValidPath()); + + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + assertEquals("log", generatedPath.getName()); + reset(); + } + + // All Test Case + for(int a = 0; a < 4; a++){ + for(int b = 0; b < 4; b++){ + config.logFile = Boolean.parseBoolean(toggle[a]); + config.logPath = path[b]; + + if(config.logFile && config.isValidPath()) { + AionLoggerFactory.init(_logModules, config.logFile, "testLog/" + config.logPath); + generatedPath = testRoot.listFiles()[0]; + + accumulatedPath = generatedPath.getName(); + while(generatedPath.listFiles()[0].isDirectory()) { + generatedPath = generatedPath.listFiles()[0]; + accumulatedPath = accumulatedPath + "/" + generatedPath.getName(); + } + assertEquals(path[b], accumulatedPath); + reset(); + } + } + } + } + + public void reset() { + deleteRecursively(testRoot); + testRoot.mkdirs(); + } + + public static boolean deleteRecursively(File file) { + Path path = file.toPath(); + try { + java.nio.file.Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { + java.nio.file.Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(final Path file, final IOException e) { + return handleException(e); + } + + private FileVisitResult handleException(final IOException e) { + // e.printStackTrace(); + return FileVisitResult.TERMINATE; + } + + @Override + public FileVisitResult postVisitDirectory(final Path dir, final IOException e) throws IOException { + if (e != null) + return handleException(e); + java.nio.file.Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + return true; + } +}