commit a65c54ca805e2845b0f1943110950f23a5061110 Author: Isaac Parenteau Date: Thu Sep 13 21:02:36 2018 -0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f338abb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.project +.classpath +.settings/ +.target/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..012af7c --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +Locusworks Application Logger += + +- Library that can be used for logging events + +Install +== + +Maven +=== +```xml + + net.locusworks + applogger + 0.0.1-SNAPSHOT + +``` \ No newline at end of file diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml new file mode 100644 index 0000000..8a373e0 --- /dev/null +++ b/bitbucket-pipelines.yml @@ -0,0 +1,14 @@ +# This is a sample build configuration for Java (Maven). +# Check our guides at https://confluence.atlassian.com/x/zd-5Mw for more examples. +# Only use spaces to indent your .yml configuration. +# ----- +# You can specify a custom docker image from Docker Hub as your build environment. +image: maven:3.3.9 + +pipelines: + default: + - step: + caches: + - maven + script: # Modify the commands below to build your repository. + - mvn -B verify # -B batch mode makes Maven less verbose \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..623ce97 --- /dev/null +++ b/pom.xml @@ -0,0 +1,61 @@ + + 4.0.0 + net.locusworks + applogger + 0.0.1-SNAPSHOT + Application Logger + Logger library for applications + + + ${project.basedir} + 1.8 + 1.8 + 2.11.0 + 1.7.25 + + + + + + org.apache.maven.plugin + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + + + + + + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j.version} + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + + \ No newline at end of file diff --git a/src/main/java/net/locusworks/logger/ApplicationLogger.java b/src/main/java/net/locusworks/logger/ApplicationLogger.java new file mode 100644 index 0000000..361cf77 --- /dev/null +++ b/src/main/java/net/locusworks/logger/ApplicationLogger.java @@ -0,0 +1,621 @@ +package net.locusworks.logger; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; + +/** + * Logger implementation to use across applications. Extends slf4j logger to work with other logging applications + * @author Isaac Parenteau + * + */ +public class ApplicationLogger implements org.slf4j.Logger { + + protected static final String DEFAULT_FORMAT = "%s"; + + private static final Logger logger = LoggerFactory.getLogger(ApplicationLogger.class); + + private String name; + + private LogLevel level; + + /** + * Default constructor + */ + protected ApplicationLogger() { + this(ApplicationLogger.class.getSimpleName()); + } + + /** + * Constructor + * @param name name of the logger + */ + protected ApplicationLogger(String name) { + this(name, LogLevel.INFO); + } + + /** + * Constructor + * @param name name of the logger + * @param level level of logging to set the logger to + */ + protected ApplicationLogger(String name, LogLevel level) { + this.name = name; + this.level = level; + } + + /** + * Constructor + * @param clazz java class to get the logger name from + */ + protected ApplicationLogger(Class clazz) { + this(clazz.getSimpleName()); + } + + /** + * Constructor + * @param clazz java class to get the logger name from + * @param level level of logging to set the logger to + */ + protected ApplicationLogger(Class clazz, LogLevel level) { + this(clazz.getSimpleName(), level); + } + + /** + * Constructor + * @param clazz java class to get the logger name from + * @param simpleName use the simple class name (removes the package name and just uses the class name) + */ + protected ApplicationLogger(Class clazz, boolean simpleName) { + this(simpleName ? clazz.getSimpleName(): clazz.getName()); + } + + /** + * Constructor + * @param clazz java class to get the logger name from + * @param simpleName use the simple class name (removes the package name and just uses the class name) + * @param level level of logging to set the logger to + */ + protected ApplicationLogger(Class clazz, boolean simpleName, LogLevel level) { + this(simpleName ? clazz.getSimpleName(): clazz.getName(), level); + } + + /** + * Get the current log level of the logger + * @return level + */ + public LogLevel getLogLevel() { + return this.level; + } + + /** + * Set the log level of the logger + * @param logLevel the log level to set + */ + public void setLogLevel(LogLevel logLevel) { + this.level = logLevel; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public boolean isTraceEnabled() { + return this.level.log(LogLevel.TRACE); + } + + @Override + public void trace(String msg) { + trace(DEFAULT_FORMAT, msg); + } + + @Override + public void trace(String format, Object arg) { + trace(format, new Object[] {arg}); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + trace(format, new Object[] {arg1, arg2}); + } + + @Override + public void trace(String format, Object... arguments) { + msgHelper(LogLevel.TRACE, format, arguments); + } + + @Override + public void trace(String msg, Throwable t) { + trace("%s%n%s", msg, getStackTrace(t.getStackTrace())); + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return isTraceEnabled(); + } + + @Override + public void trace(Marker marker, String msg) { + trace(msg); + } + + @Override + public void trace(Marker marker, String format, Object arg) { + trace(format, arg); + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + trace(format, arg1, arg2); + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + trace(format, argArray); + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + trace(msg, t); + } + + @Override + public boolean isDebugEnabled() { + return this.level.log(LogLevel.DEBUG); + } + + @Override + public void debug(String arg0) { + debug(DEFAULT_FORMAT, arg0); + } + + @Override + public void debug(String format, Object arg) { + debug(format, new Object[] {arg}); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + debug(format, new Object[] {arg1, arg2}); + } + + @Override + public void debug(String format, Object... arguments) { + msgHelper(LogLevel.DEBUG, format, arguments); + } + + @Override + public void debug(String msg, Throwable t) { + debug("%s%n%s", msg, getStackTrace(t.getStackTrace())); + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return isDebugEnabled(); + } + + @Override + public void debug(Marker marker, String msg) { + debug(msg); + } + + @Override + public void debug(Marker marker, String format, Object arg) { + debug(format, arg); + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + debug(format, arg1, arg2); + } + + @Override + public void debug(Marker marker, String format, Object... arguments) { + debug(format, arguments); + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + debug(msg, t); + } + + @Override + public boolean isInfoEnabled() { + return this.level.log(LogLevel.INFO); + } + + @Override + public void info(String msg) { + info(DEFAULT_FORMAT, msg); + } + + @Override + public void info(String format, Object arg) { + info(format, new Object[] {arg}); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + info(format, new Object[] {arg1, arg2}); + } + + @Override + public void info(String format, Object... arguments) { + msgHelper(LogLevel.INFO, format, arguments); + } + + @Override + public void info(String msg, Throwable t) { + info("%s%n%s", msg, getStackTrace(t.getStackTrace())); + } + + /** + * Log an info message using values from a map in the format of + * key - value + * @param values Map containing values to log + */ + public void info(Map values) { + info(values, null); + } + + /** + * Log an info message using value from a map in the format of (key - value) + * @param values values to log + * @param sb a string builder to append the message to + */ + public void info(Map values, StringBuilder sb) { + info(values, null, sb); + } + + /** + * Log an info message using values from a map + * @param values Values to log + * @param valueFormat value format to use for the map + * @param sb String builder to append values to + */ + public void info(Map values, String valueFormat, StringBuilder sb) { + msgHelper(LogLevel.INFO, values, valueFormat, sb); + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return isInfoEnabled(); + } + + @Override + public void info(Marker marker, String msg) { + info(msg); + } + + @Override + public void info(Marker marker, String format, Object arg) { + info(format, arg); + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + info(format, arg1, arg2); + } + + @Override + public void info(Marker marker, String format, Object... arguments) { + info(format, arguments); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + info(msg, t); + } + + @Override + public boolean isWarnEnabled() { + return this.level.log(LogLevel.WARN); + } + + @Override + public void warn(String msg) { + warn(DEFAULT_FORMAT, msg); + } + + @Override + public void warn(String format, Object arg) { + warn(format, new Object[] {arg}); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + warn(format, new Object[] {arg1, arg2}); + } + + @Override + public void warn(String format, Object... arguments) { + msgHelper(LogLevel.WARN, format, arguments); + } + + @Override + public void warn(String msg, Throwable t) { + warn("%s%n%s", msg, getStackTrace(t.getStackTrace())); + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return isWarnEnabled(); + } + + @Override + public void warn(Marker marker, String msg) { + warn(msg); + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warn(format, arg); + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warn(format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String format, Object... arguments) { + warn(format, arguments); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + warn(msg, t); + } + + /** + * Log a warning message using the string format method + * @param values values to log + */ + public void warn(Map values) { + warn(values, null, null); + } + + /** + * Log a warning message using values from a map + * @param values values to log + * @param sb String builder to append message to + */ + public void warn(Map values, StringBuilder sb) { + warn(values, null, sb); + } + + /** + * Log an error message using values from a map + * @param values values to log + * @param valueFormat format to use when logging the values + * @param sb string builder to append messages to + */ + public void warn(Map values, String valueFormat, StringBuilder sb) { + msgHelper(LogLevel.WARN, values, valueFormat, sb); + } + + @Override + public boolean isErrorEnabled() { + return this.level.log(LogLevel.ERROR); + } + + @Override + public void error(String msg) { + error(DEFAULT_FORMAT, msg); + } + + public void error(Throwable e) { + error(e.getMessage(), e); + } + + @Override + public void error(String format, Object arg) { + error(format, new Object[] {arg}); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + error(format, new Object[] {arg1, arg2}); + } + + @Override + public void error(String format, Object... arguments) { + msgHelper(LogLevel.ERROR, format, arguments); + } + + @Override + public void error(String msg, Throwable t) { + error("%s%n%s", msg, getStackTrace(t.getStackTrace())); + } + + /** + * Log an error message using values from a map + * @param values values to log + * @param sb String builder to append message to + */ + public void error(Map values, StringBuilder sb) { + error(values, null, sb); + } + + /** + * Log an error message using values from a map + * @param values values to log + * @param sb String builder to append message to + * @param e throwable error to log + */ + public void error(Map values, StringBuilder sb, Throwable e) { + error(values, null, sb); + } + + /** + * Log an error message using values from a map + * @param values values to log + * @param valueFormat format to use when logging the values + * @param sb string builder to append messages to + */ + public void error(Map values, String valueFormat, StringBuilder sb) { + error(values, valueFormat, sb, null); + } + + /** + * Log an error message using values from a map + * @param values values to log + * @param valueFormat format to use when logging the values + * @param sb string builder to append messages to + * @param e Throwable error to log + */ + public void error(Map values, String valueFormat, StringBuilder sb, Throwable e) { + msgHelper(LogLevel.ERROR, values, valueFormat, sb); + if (e != null) { + msgHelper(LogLevel.ERROR, "", e); + } + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return isErrorEnabled(); + } + + @Override + public void error(Marker marker, String msg) { + error(msg); + } + + @Override + public void error(Marker marker, String format, Object arg) { + error(format, arg); + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + error(format, arg1, arg2); + } + + @Override + public void error(Marker marker, String format, Object... arguments) { + error(format, arguments); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + error(msg, t); + } + + /** + * Log the actual message + * @param level log level to use + * @param message message to log + */ + protected void log(LogLevel level, String message) { + if (level == null ||this.level == null || level.toInt() < this.level.toInt()) return; + + switch (level) { + case ALL: + case TRACE: + case DEBUG: + case INFO: + logger.info(format(message)); + break; + case WARN: + logger.warn(format(message)); + break; + case ERROR: + case FATAL: + logger.error(format(message)); + break; + case OFF: + default: + break; + } + } + + /** + * Print the exception stack trace to a string + * @param e Exception to print the stack trace + * @return string representation of the stack trace + */ + protected String getStackTrace(Throwable e) { + return getStackTrace(e.getStackTrace()); + } + + /** + * Print the exception stack trace to a string + * @param elements stack trace elements to print to the string + * @return string representation of the stack trace + */ + protected String getStackTrace(StackTraceElement[] elements) { + StringBuilder sb = new StringBuilder(); + for (StackTraceElement element : elements) { + sb.append(String.format("%s%n",element.toString()));; + } + return sb.toString(); + } + + /** + * Message helper to help format the message for logging + * @param level The log level + * @param values Map values to log + * @param valueFormat value format to map values as + * @param sb String builder to append messages to + */ + private void msgHelper(LogLevel level, Map values, String valueFormat, StringBuilder sb) { + + if (sb == null) { + sb = new StringBuilder(); + } + + if (valueFormat == null || valueFormat.trim().isEmpty()) { + int longest = 0; + for (String key : values.keySet()) { + if (key.length() > longest) { + longest = key.length(); + } + } + valueFormat = "%n%-" + longest + "s: %s"; + } + + final String format = valueFormat; + + final StringBuilder builder = sb; + values.entrySet() + .stream() + .map(entry -> String.format(format, entry.getKey(), entry.getValue())) + .forEach(s -> builder.append(s)); + + log(level, builder.toString()); + } + + /** + * Help format a message for logging + * @param level the log level + * @param format The string format to use + * @param args Arguments to use in the string format + */ + private void msgHelper(LogLevel level, String format, Object...args) { + log(level, String.format(format, args)); + } + + /** + * helper method to format a message for logging + * @param level log level to use + * @param message message to log + * @param e any throwable to log + */ + private void msgHelper(LogLevel level, String message, Throwable e) { + String msg = e == null ? String.format("%n%s", message) : String.format("%n%s%n%s%n%s", message, e.getMessage(), getStackTrace(e)); + log(level, msg); + } + + /** + * Message format to be used for logging + * @param message the message to log + * @return the formatted string + */ + private String format(String message) { + return String.format("th%06d [%-5s] [%s] %s", Thread.currentThread().getId(), this.level.name(), this.name, message); + } +} \ No newline at end of file diff --git a/src/main/java/net/locusworks/logger/ApplicationLoggerFactory.java b/src/main/java/net/locusworks/logger/ApplicationLoggerFactory.java new file mode 100644 index 0000000..742f04b --- /dev/null +++ b/src/main/java/net/locusworks/logger/ApplicationLoggerFactory.java @@ -0,0 +1,217 @@ +package net.locusworks.logger; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.stream.Collectors; + +/*** + * Logger factory to create/retrieve loggers for the portal application + * @author Isaac Parenteau + * @version 1.0.0 + * @date 02/15/2018 + */ +public class ApplicationLoggerFactory { + private static Map loggers = new TreeMap<>(); + private static LogLevel DEFAULT_LEVEL = null; + private static ApplicationLoggerInitializer initializer; + + /** + * Need to get the log level from the properties file. + * Would normally use the configuration service but would create a circular dependency as + * the configuration service use the ApplicationLoggerFactory to create a logger + * @param initializer The initializer + */ + public static void init(ApplicationLoggerInitializer init) { + initializer = init; + DEFAULT_LEVEL = initializer == null ? LogLevel.INFO : initializer.initialize(); + loadLoggers(); + } + + /** + * Load loggers from ApplicationLoggerInitializer interface + */ + public static void loadLoggers() { + loadLoggers(initializer); + } + + /** + * Load loggers from ApplicationLoggerInitializer interface + * @param init interface to try to load loggers from + */ + public static void loadLoggers(ApplicationLoggerInitializer init) { + if (init != null) { + init.loadLoggers(); + } + } + + /** + * Retrieve a portal logger + * @param name Name of the logger to retrieve + * @return the logger representation of the name used + */ + public static ApplicationLogger getLogger(String name) { + return getLogger(name, getDefaultLevel()); + } + + /** + * Get the default logger level. if the default + * has not been set, call the init function + * @return + */ + private static LogLevel getDefaultLevel() { + return DEFAULT_LEVEL; + } + + /** + * Retrieve a portal logger + * @param name Name of the logger to retrieve + * @param level Starting log level of the logger + * @return the logger represented by the given name + */ + public static ApplicationLogger getLogger(String name, LogLevel level) { + if (!loggers.containsKey(name)) { + loggers.put(name, new ApplicationLogger(name, level)); + } + ApplicationLogger logger = loggers.get(name); + if (initializer != null) { + initializer.postGetLogger(logger.getName(), logger.getLogLevel().toName()); + } + return logger; + } + + /** + * Get a portal logger + * @param clazz Class to get the logger for + * @return patchRepoLogger + */ + public static ApplicationLogger getLogger(Class clazz) { + return getLogger(clazz, true); + } + + /** + * Get a portal logger + * @param clazz Class to get the logger for + * @param useSimpleName use the simplified class name + * @return patchRepoLogger + */ + public static ApplicationLogger getLogger(Class clazz, boolean useSimpleName) { + LogLevel level = getDefaultLevel(); + String name = useSimpleName ? clazz.getSimpleName() : clazz.getName(); + if (clazz.isAnnotationPresent(ApplicationLoggerInfo.class)) { + ApplicationLoggerInfo prli = clazz.getAnnotation(ApplicationLoggerInfo.class); + String tmpName = prli.name(); + level = prli.defaultLevel(); + if (tmpName != null && !tmpName.trim().isEmpty()) { + name = tmpName; + } + } + + return getLogger(name, level); + } + + /** + * Set individual loggers to a specified log level + * @param logLevels List of loggers to configure + */ + public static void setLogLevels(List logLevels) { + logLevels + .stream() + .filter(logInfo -> loggers.containsKey(logInfo.getLogger())) + .forEach(logInfo -> { + loggers.get(logInfo.getLogger()).setLogLevel(LogLevel.valueOf(logInfo.getLevel())); + }); + } + + /** + * Add a logger to to the collection to be monitored + * @param logger Logger to add + */ + public static void addLogger(ApplicationLogger logger) { + loggers.put(logger.getName(), logger); + } + + /** + * Add loggers to the current logger set + * @param loggerList List of loggers to add + */ + public static void addLoggers(List loggerList) { + loggerList.stream() + .map(item -> new ApplicationLogger(item.getLogger(), LogLevel.getEnum(item.getLevel()))) + .forEach(item -> loggers.put(item.getName(), item)); + } + + /** + * Get all the currently available loggers + * @return loggers + */ + public static List getLoggers() { + return loggers.entrySet() + .stream() + .filter(entry -> entry.getValue().getLogLevel() != null) + .map(entry -> new LoggerInfo(entry.getKey(), entry.getValue().getLogLevel().toString()) ) + .collect(Collectors.toList()); + } + + /** + * Save the log levels through the interface + */ + public static void saveLogLevels() { + saveLogLevels(initializer); + } + + /** + * Save the log levels through the interface + * @param init ApplicationLoggerInitializer interface + */ + public static void saveLogLevels(ApplicationLoggerInitializer init) { + if (init != null) { + init.saveLogLevels(loggers); + } + } + + /** + * Helper class to display logger information for + * @author Isaac Parenteau + * @since 1.0.0-RELEASE + */ + public static class LoggerInfo { + private String logger; + private String level; + + public LoggerInfo() {} + + public LoggerInfo(String logger, String level) { + this.logger = logger; + this.level = level; + } + + /** + * @return the logger + */ + public String getLogger() { + return logger; + } + + /** + * @param logger the logger to set + */ + public void setLogger(String logger) { + this.logger = logger; + } + + /** + * @return the current logger level + */ + public String getLevel() { + return level; + } + + /** + * @param level the level to set + */ + public void setLevel(String level) { + this.level = level; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/locusworks/logger/ApplicationLoggerInfo.java b/src/main/java/net/locusworks/logger/ApplicationLoggerInfo.java new file mode 100644 index 0000000..51a8b3f --- /dev/null +++ b/src/main/java/net/locusworks/logger/ApplicationLoggerInfo.java @@ -0,0 +1,21 @@ +package net.locusworks.logger; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Annotation for configuring specific naming and log level for log classes + * @author Isaac Parenteau + * @version 1.0.0 + * @date 02/15/2018 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ApplicationLoggerInfo { + String name() default ""; + Class className() default Object.class; + LogLevel defaultLevel() default LogLevel.INFO; +} diff --git a/src/main/java/net/locusworks/logger/ApplicationLoggerInitializer.java b/src/main/java/net/locusworks/logger/ApplicationLoggerInitializer.java new file mode 100644 index 0000000..82f590e --- /dev/null +++ b/src/main/java/net/locusworks/logger/ApplicationLoggerInitializer.java @@ -0,0 +1,17 @@ +package net.locusworks.logger; + +import java.util.Map; + +/** + * Interface used to initialize the application logger + * and set the default log level + * @author Isaac Parenteau + * @version 1.0.0 + * @date 02/15/2018 + */ +public interface ApplicationLoggerInitializer { + LogLevel initialize(); + default void loadLoggers() { } + default void postGetLogger(String logName, String logLevel) {} + default void saveLogLevels(Map loggers) {} +} diff --git a/src/main/java/net/locusworks/logger/LogLevel.java b/src/main/java/net/locusworks/logger/LogLevel.java new file mode 100644 index 0000000..ad108c8 --- /dev/null +++ b/src/main/java/net/locusworks/logger/LogLevel.java @@ -0,0 +1,87 @@ +package net.locusworks.logger; + +/** + * Enumeration specifying th severity level of the logged message + * @author Isaac Parenteau + * @version 1.0.0 + * @date 02/15/2018 + */ +public enum LogLevel { + OFF(7, "OFF"), + FATAL(6, "FATAL"), + ERROR(5, "ERROR"), + WARN(4, "WARN"), + INFO(3, "INFO"), + DEBUG(2, "DEBUG"), + TRACE(1, "TRACE"), + ALL(0, "ALL"); + + private Integer intLevel; + private String levelName; + + private LogLevel(Integer intLevel, String levelName) { + this.intLevel = intLevel; + this.levelName = levelName; + } + + @Override + public String toString() { + return this.toName(); + } + + /** + * Get the name of the log level + * @return levelName + */ + public String toName() { + return this.levelName; + } + + /** + * Get the integer representation of the log level + * @return intLevel + */ + public Integer toInt() { + return this.intLevel; + } + + /** + * Checks to see if this log can log compared to the other log + * @param otherLevel the other level to check + * @return true if the current level is higher than the other level, false otherwise + */ + public boolean log(LogLevel otherLevel) { + if (otherLevel == null) { + return false; + } + return this.toInt() >= otherLevel.toInt(); + } + + /** + * Get the log level based off of an integer value + * @param level The log level integer value + * @return logLevel based on the integer value or null if not found + */ + public static LogLevel getEnum(Integer level) { + for (LogLevel l : values()) { + if (l.toInt().equals(level)) { + return l; + } + } + return null; + } + + /** + * Get the log level based off the level name + * @param levelName level name to get + * @return the log level for the name or null if it cant be found + */ + public static LogLevel getEnum(String levelName) { + for (LogLevel l : values()) { + if (l.toName().equalsIgnoreCase(levelName)) { + return l; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/net/locusworks/logger/SystemDebugLogger.java b/src/main/java/net/locusworks/logger/SystemDebugLogger.java new file mode 100644 index 0000000..5a46181 --- /dev/null +++ b/src/main/java/net/locusworks/logger/SystemDebugLogger.java @@ -0,0 +1,36 @@ +package net.locusworks.logger; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +@ApplicationLoggerInfo(name="System.Debug", defaultLevel=LogLevel.DEBUG) +public class SystemDebugLogger extends PrintStream { + + private ApplicationLogger logger; + + public SystemDebugLogger() { + this(ApplicationLoggerFactory.getLogger(SystemDebugLogger.class)); + } + + public SystemDebugLogger(ApplicationLogger logger) { + super(new ByteArrayOutputStream()); + this.logger = logger; + } + + @Override + public void write(byte[] b) { + logger.debug(new String(b, UTF_8)); + } + + @Override + public void write(byte[] b, int off, int len) { + logger.debug(new String(b, off, len, UTF_8)); + } + + @Override + public void write(int b) { + write(new byte[] { (byte)b }); + } +} diff --git a/src/main/java/net/locusworks/logger/SystemErrLogger.java b/src/main/java/net/locusworks/logger/SystemErrLogger.java new file mode 100644 index 0000000..f7a9552 --- /dev/null +++ b/src/main/java/net/locusworks/logger/SystemErrLogger.java @@ -0,0 +1,36 @@ +package net.locusworks.logger; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +@ApplicationLoggerInfo(name="System.Err", defaultLevel=LogLevel.ERROR) +public class SystemErrLogger extends PrintStream { + + private ApplicationLogger logger; + + public SystemErrLogger() { + this(ApplicationLoggerFactory.getLogger(SystemErrLogger.class)); + } + + public SystemErrLogger(ApplicationLogger logger) { + super(new ByteArrayOutputStream()); + this.logger = logger; + } + + @Override + public void write(byte[] b) { + logger.error(new String(b, UTF_8)); + } + + @Override + public void write(byte[] b, int off, int len) { + logger.error(new String(b, off, len, UTF_8)); + } + + @Override + public void write(int b) { + write(new byte[] { (byte)b }); + } +} diff --git a/src/main/java/net/locusworks/logger/SystemOutLogger.java b/src/main/java/net/locusworks/logger/SystemOutLogger.java new file mode 100644 index 0000000..bf9e057 --- /dev/null +++ b/src/main/java/net/locusworks/logger/SystemOutLogger.java @@ -0,0 +1,36 @@ +package net.locusworks.logger; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +@ApplicationLoggerInfo(name="System.Out", defaultLevel=LogLevel.OFF) +public class SystemOutLogger extends PrintStream { + + private ApplicationLogger logger; + + public SystemOutLogger() { + this(ApplicationLoggerFactory.getLogger(SystemOutLogger.class)); + } + + public SystemOutLogger(ApplicationLogger logger) { + super(new ByteArrayOutputStream()); + this.logger = logger; + } + + @Override + public void write(byte[] b) { + logger.info(new String(b, UTF_8)); + } + + @Override + public void write(byte[] b, int off, int len) { + logger.info(new String(b, off, len, UTF_8)); + } + + @Override + public void write(int b) { + write(new byte[] { (byte)b }); + } +} diff --git a/src/main/java/net/locusworks/logger/package-info.java b/src/main/java/net/locusworks/logger/package-info.java new file mode 100644 index 0000000..c6153ca --- /dev/null +++ b/src/main/java/net/locusworks/logger/package-info.java @@ -0,0 +1,11 @@ +/** + * The logging package extends slf4j which + * allows it to work with other logging library like log4j or commons-logging + * It stores the loggers in a hashmap to allow for applications to set each individual + * logging level programatically. The ApplicationLoggerInfo class allows to customer the logger name and default level + * @seenet.locusworks.logger.ApplicationLoggerInfo + * @author Isaac Parenteau + * @since 1.0.0-RELEASE + * @version 1.0 + */ +package net.locusworks.logger; \ No newline at end of file diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml new file mode 100644 index 0000000..f381635 --- /dev/null +++ b/src/main/resources/log4j.xml @@ -0,0 +1,24 @@ + + + + + + + + + %d{dd-MMM-yyyy HH:mm:ss.SSS} %m%n + + + + + + + + + + + + + +