001/* 002 * This is free and unencumbered software released into the public domain. 003 * 004 * Please see https://github.com/binkley/binkley/blob/master/LICENSE.md. 005 */ 006 007package hm.binkley.util.logging.osi; 008 009import ch.qos.logback.classic.Level; 010import hm.binkley.util.logging.MarkedLogger; 011import hm.binkley.util.logging.MinimumLogger; 012import org.slf4j.Logger; 013import org.slf4j.LoggerFactory; 014import org.slf4j.ext.XLogger; 015import org.slf4j.ext.XLoggerFactory; 016 017import javax.annotation.Nonnull; 018 019import static ch.qos.logback.classic.Level.ALL; 020import static ch.qos.logback.classic.Level.INFO; 021import static ch.qos.logback.classic.Level.WARN; 022import static org.slf4j.MarkerFactory.getMarker; 023 024/** 025 * {@code SupportLoggers} are custom {@link MarkedLogger}s for specialized use. Methods create new 026 * marked loggers with the enum names as markers. <p> There is one factory method variant for each 027 * style of logger creation: <dl> <dt>{@link #getLogger(Class)}</dt> <dd>Creates a new underlying 028 * logger from a class</dd> <dt>{@link #getLogger(String)}</dt> <dd>Creates a new underlying logger 029 * from a logger name</dd> <dt>{@link #getLogger(Logger)}</dt> <dd>Reuses an existing underlying 030 * logger</dd> </dl> <p> Applications should configure logback or other logging system by marker: 031 * <dl><dt>{@link #ALERT}</dt> <dd>Send alerts for system issues</dd> <dt>{@link #APPLICATION}</dt> 032 * <dd>Logs normally following logback configuration</dd> <dt>{@link #AUDIT}</dt> <dd>Records an 033 * audit trail, typically to a database</dd> <dt>{@link #TRACE}</dt> <dd>A tracing logger for method 034 * entry and exit</dd></dl> 035 * 036 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a> 037 */ 038public enum SupportLoggers { 039 /** 040 * Marks "ALERT" loggers for system issues. Rejects logging at less than {@code WARN} level 041 * (throws {@code IllegalStateException}). 042 */ 043 ALERT(WARN), 044 /** Unmarked loggers for normal logging. */ 045 APPLICATION(ALL) { 046 @Nonnull 047 @Override 048 public Logger getLogger(@Nonnull final Class<?> logger) { 049 return LoggerFactory.getLogger(logger); 050 } 051 052 @Nonnull 053 @Override 054 public Logger getLogger(@Nonnull final String logger) { 055 return LoggerFactory.getLogger(logger); 056 } 057 058 @Nonnull 059 @Override 060 public Logger getLogger(@Nonnull final Logger logger) { 061 return logger; 062 } 063 }, 064 /** 065 * Marks "AUDIT" loggers to record an audit trail, typically to a database. Rejects logging 066 * less than {@code INFO} level (throws {@code IllegalStateException}). 067 */ 068 AUDIT(INFO), 069 /** Trace loggers ({@link XLogger} for debugging. */ 070 TRACE(ALL) { 071 @Nonnull 072 @Override 073 public XLogger getLogger(@Nonnull final Class<?> logger) { 074 return XLoggerFactory.getXLogger(logger); 075 } 076 077 @Nonnull 078 @Override 079 public XLogger getLogger(@Nonnull final String logger) { 080 return XLoggerFactory.getXLogger(logger); 081 } 082 083 @Nonnull 084 @Override 085 public XLogger getLogger(@Nonnull final Logger logger) { 086 return (XLogger) logger; 087 } 088 }; 089 @Nonnull 090 private final Level minimum; 091 092 SupportLoggers(@Nonnull final Level minimum) { 093 this.minimum = minimum; 094 } 095 096 /** 097 * Redundant method for {@link #TRACE} returning {@code XLogger}. 098 * 099 * @param logger the logger class, never missing 100 * 101 * @return the XLogger, never missing 102 * 103 * @todo Java needs anonymous instance covariant returns to avoid casting 104 */ 105 @Nonnull 106 public static XLogger trace(@Nonnull final Class<?> logger) { 107 return trace(logger.getName()); 108 } 109 110 /** 111 * Redundant method for {@link #TRACE} returning {@code XLogger}. 112 * 113 * @param logger the logger name, never missing 114 * 115 * @return the XLogger, never missing 116 * 117 * @todo Java needs anonymous instance covariant returns to avoid casting 118 */ 119 @Nonnull 120 public static XLogger trace(@Nonnull final String logger) { 121 return (XLogger) TRACE.getLogger(logger); 122 } 123 124 /** 125 * Creates a new marked logger for the given <var>logger</var>. 126 * 127 * @param logger the underlying class, never missing 128 * 129 * @return the wrapping marked logger, never missing 130 */ 131 @Nonnull 132 public Logger getLogger(@Nonnull final Class<?> logger) { 133 return getLogger(LoggerFactory.getLogger(logger)); 134 } 135 136 /** 137 * Creates a new marked logger for the given <var>logger</var>. 138 * 139 * @param logger the underlying logger name, never missing 140 * 141 * @return the wrapping marked logger, never missing 142 */ 143 @Nonnull 144 public Logger getLogger(@Nonnull final String logger) { 145 return getLogger(LoggerFactory.getLogger(logger)); 146 } 147 148 /** 149 * Creates a new marked logger for the given <var>logger</var>. 150 * 151 * @param logger the underlying SLF4j logger, never missing 152 * 153 * @return the wrapping marked logger, never missing 154 */ 155 @Nonnull 156 public Logger getLogger(@Nonnull final Logger logger) { 157 return ALL == minimum ? new MarkedLogger(logger, getMarker(name())) : new MinimumLogger( 158 new MarkedLogger(logger, MinimumLogger.class.getName(), getMarker(name())), 159 minimum); 160 } 161}