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.LoggerContext; 010import ch.qos.logback.core.util.StatusPrinter; 011import hm.binkley.util.logging.Level; 012import org.slf4j.LoggerFactory; 013import org.slf4j.bridge.SLF4JBridgeHandler; 014 015import javax.annotation.Nonnull; 016import javax.annotation.Nullable; 017import java.util.Objects; 018 019import static hm.binkley.util.logging.osi.OSI.SystemProperty.LOGBACK_CONFIGURATION_FILE; 020import static hm.binkley.util.logging.osi.OSI.SystemProperty.LOGBACK_CONTEXT_NAME; 021import static hm.binkley.util.logging.osi.OSI.SystemProperty.LOGBACK_DEBUG; 022import static java.lang.String.format; 023import static java.lang.System.clearProperty; 024import static java.lang.System.getProperty; 025import static java.lang.System.out; 026import static java.lang.System.setProperty; 027 028/** 029 * {@code OSI} enable OSI logging for simple cases. 030 * 031 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a> 032 */ 033public final class OSI { 034 /** 035 * Enable OSI logging using the default configuration resource, "osi-logback.xml" as found on 036 * the class path, and the default application name. Control configuration through use of other 037 * {@link SystemProperty OSI system properties}. 038 * <p> 039 * Must be called before first use of logback. 040 * <p> 041 * Do not show status of the logging system. 042 */ 043 @SuppressWarnings({"ConstantConditions", "Annotator"}) 044 public static void enable() { 045 enable(null, false); // Publically applicationName is non-null 046 } 047 048 /** 049 * Enable OSI logging using the default configuration resource, "osi-logback.xml" as found on 050 * the class path, and the default application name. Control configuration through use of other 051 * {@link SystemProperty OSI system properties}. 052 * <p> 053 * Must be called before first use of logback. 054 * 055 * @param showDetail if {@code true} log the status of the logging system including setup 056 * details. 057 */ 058 @SuppressWarnings({"ConstantConditions", "Annotator"}) 059 public static void enable(final boolean showDetail) { 060 enable(null, showDetail); // Publically applicationName is non-null 061 } 062 063 /** 064 * Enable OSI logging using the default configuration resource, "osi-logback.xml" as found on 065 * the class path, and the given <var>applicationName</var>. Control configuration through use 066 * of other {@link SystemProperty OSI system properties}. 067 * <p> 068 * Must be called before first use of logback. 069 * <p> 070 * Do not show status of the logging system. 071 * 072 * @param applicationName the logback context name, never missing 073 */ 074 public static void enable(@Nonnull final String applicationName) { 075 enable(applicationName, false); 076 } 077 078 /** 079 * Enable OSI logging using the default configuration resource, "osi-logback.xml" as found on 080 * the class path, and the given <var>applicationName</var>. Control configuration through use 081 * of other {@link SystemProperty OSI system properties}. 082 * <p> 083 * Must be called before first use of logback. 084 * 085 * @param applicationName the logback context name, never missing 086 * @param showDetail if {@code true} log the status of the logging system including setup 087 * details. 088 * 089 * @see #enable(boolean) 090 */ 091 @SuppressWarnings("ConstantConditions") 092 public static void enable(@Nonnull final String applicationName, final boolean showDetail) { 093 SLF4JBridgeHandler.install(); 094 LOGBACK_CONFIGURATION_FILE.set("osi-logback.xml"); 095 if (null != applicationName) // Publically non-null, internally nullable 096 LOGBACK_CONTEXT_NAME.set(applicationName); 097 if (!showDetail) 098 return; 099 for (final SystemProperty property : SystemProperty.values()) 100 out.println(property); 101 // No point duplicating the status messages 102 if (Boolean.valueOf(LOGBACK_DEBUG.get())) 103 return; 104 StatusPrinter.print((LoggerContext) LoggerFactory.getILoggerFactory()); 105 } 106 107 /** {@code SystemProperty} defines system properties used by OSI. */ 108 public enum SystemProperty { 109 /** 110 * Sets the logback configuration resource, rarely changed except for testing. Default is 111 * "osi-logback.xml". 112 * <p> 113 * Note this is defined by logback. Although looked for on the classpath, logback names 114 * this "configurationFile". 115 * 116 * @see #enable() 117 */ 118 LOGBACK_CONFIGURATION_FILE("logback.configurationFile"), 119 /** 120 * Sets the logback context name, equivalently, a short tag identifying the application. 121 * Default is "default". 122 * <p> 123 * Use this to distinguish merging of logging from multiple application. 124 * 125 * @see <a href="http://logback.qos.ch/manual/configuration.html#contextName">Setting the 126 * context name</a> 127 */ 128 LOGBACK_CONTEXT_NAME("logback.contextName"), 129 /** 130 * As an alternative to setting system properties, put properties here. Default is 131 * "osi-logback.properties" in the classpath root. 132 * <p> 133 * These cannot, however, override these system properties which are used before the 134 * properties resource is loaded: <ul><li>logback.configurationFile</li> 135 * <li>logback.propertiesResource</li> <li>logback.debug</li></ul> 136 */ 137 LOGBACK_PROPERTIES_RESOURCE("logback.propertiesResource"), 138 /** 139 * Sets a custom style file for logging, rarely changed. Default is 140 * "osi-logback-style.properties". 141 * 142 * @see #LOGBACK_STYLES_RESOURCE 143 */ 144 LOGBACK_STYLES_RESOURCE("logback.stylesResource"), 145 /** 146 * Sets the default logging style. Default is "standard". 147 * <p> 148 * See {@code osi-logback-styles.properties} for help and details. 149 * 150 * @see #LOGBACK_STYLES_RESOURCE 151 */ 152 LOGBACK_STYLE("logback.style"), 153 /** 154 * Sets the resource for additional included logging directives. Default is 155 * "osi-logback-included.xml". 156 * <p> 157 * This is often changed (or one named {@code osi-logback-included.xml} is provided in the 158 * application class path) to control logging such as changing log levels. 159 * 160 * @see #LOGBACK_INCLUDED_RESOURCE 161 */ 162 LOGBACK_INCLUDED_RESOURCE("logback.includedResource"), 163 /** Enables JMX support for logback. Default is "true". */ 164 LOGBACK_JMX("logback.jmx"), 165 /** 166 * Enables logback debugging. Default is "false". 167 * <p> 168 * Enabling logback debugging sets {@code log.level} to "DEBUG". 169 * 170 * @see #LOG_LEVEL 171 */ 172 LOGBACK_DEBUG("logback.debug"), 173 /** 174 * Adjusts the general logging level when no more specific level is configured for a logger. 175 * Default is "WARN". 176 * 177 * @see Level 178 */ 179 LOG_LEVEL("log.level"), 180 /** 181 * Sets the root appender. Default is "console". 182 * <p> 183 * Use in combination with a custom appender defined in {@code osi-logback-included.xml}. 184 * 185 * @see #LOGBACK_INCLUDED_RESOURCE 186 */ 187 LOGBACK_ROOT_APPENDER("logback.rootAppender"), 188 /** Enables ANSI color codes for logging, including Windows. Default is "false". */ 189 LOGBACK_JANSI("logback.jansi"); 190 191 @Nonnull 192 private final String key; 193 194 SystemProperty(@Nonnull final String key) { 195 this.key = key; 196 } 197 198 /** 199 * Gets the key string used with system properties. 200 * 201 * @return the key string, never missing 202 */ 203 @Nonnull 204 public final String key() { 205 return key; 206 } 207 208 /** 209 * Gets the value of the corresponding system property. 210 * 211 * @return the system property value or {@code null} if undefined 212 */ 213 @Nullable 214 public final String get() { 215 return getProperty(key); 216 } 217 218 /** 219 * Sets the value of the corresponding system property, or clears it if {@code null}. 220 * 221 * @param value the system property value or {@code null} to clear 222 */ 223 public final void set(@Nullable final String value) { 224 if (null == value) 225 clearProperty(key); 226 else 227 setProperty(key, value); 228 } 229 230 /** Clears the value to the corresponding system property. */ 231 public final void clear() { 232 clearProperty(key); 233 } 234 235 @Nonnull 236 @Override 237 public final String toString() { 238 return format("%s(%s)=%s", name(), key, 239 Objects.toString(getProperty(key), "<default>")); 240 } 241 } 242}