001package org.slf4j.helpers; 002 003import java.io.PrintStream; 004 005/** 006 * An internally used class for reporting internal messages generated by SLF4J itself, typically 007 * during initialization. 008 * 009 * <p> 010 * Internal reporting is performed by calling the {@link #debug(String)}, {@link #info(String)}, 011 * {@link #warn(String)} (String)} {@link #error(String)} (String)} and 012 * {@link #error(String, Throwable)} methods. 013 * </p> 014 * <p>See {@link #SLF4J_INTERNAL_VERBOSITY_KEY} and {@link #SLF4J_INTERNAL_REPORT_STREAM_KEY} for 015 * configuration options.</p> 016 * <p> 017 * <p> 018 * Note that this system is independent of the logging back-end in use. 019 * 020 * @since 2.0.10 021 */ 022public class Reporter { 023 024 /** 025 * this class is used internally by Reporter 026 */ 027 private enum Level { 028 DEBUG(0), INFO(1), WARN(2), ERROR(3); 029 030 int levelInt; 031 032 private Level(int levelInt) { 033 this.levelInt = levelInt; 034 } 035 036 private int getLevelInt() { 037 return levelInt; 038 } 039 } 040 041 private enum TargetChoice { 042 Stderr, Stdout; 043 } 044 045 static final String SLF4J_DEBUG_PREFIX = "SLF4J(D): "; 046 static final String SLF4J_INFO_PREFIX = "SLF4J(I): "; 047 static final String SLF4J_WARN_PREFIX = "SLF4J(W): "; 048 static final String SLF4J_ERROR_PREFIX = "SLF4J(E): "; 049 050 051 /** 052 * This system property controls the target for internal reports output by SLF4J. 053 * Recognized values for this key are "System.out", "stdout", "sysout", "System.err", 054 * "stderr" and "syserr". 055 * 056 * <p>By default, output is directed to "stderr".</p> 057 */ 058 public static final String SLF4J_INTERNAL_REPORT_STREAM_KEY = "slf4j.internal.report.stream"; 059 static private final String[] SYSOUT_KEYS = {"System.out", "stdout", "sysout"}; 060 061 /** 062 * This system property controls the internal level of chattiness 063 * of SLF4J. Recognized settings are "INFO", "WARN" and "ERROR". The default value is "INFO". 064 */ 065 public static final String SLF4J_INTERNAL_VERBOSITY_KEY = "slf4j.internal.verbosity"; 066 067 068 static private final TargetChoice TARGET_CHOICE = getTargetChoice(); 069 070 static private final Level INTERNAL_VERBOSITY = initVerbosity(); 071 072 static private TargetChoice getTargetChoice() { 073 String reportStreamStr = System.getProperty(SLF4J_INTERNAL_REPORT_STREAM_KEY); 074 075 if(reportStreamStr == null || reportStreamStr.isEmpty()) { 076 return TargetChoice.Stderr; 077 } 078 079 for(String s : SYSOUT_KEYS) { 080 if(s.equalsIgnoreCase(reportStreamStr)) 081 return TargetChoice.Stdout; 082 } 083 return TargetChoice.Stderr; 084 } 085 086 087 static private Level initVerbosity() { 088 String verbosityStr = System.getProperty(SLF4J_INTERNAL_VERBOSITY_KEY); 089 090 if(verbosityStr == null || verbosityStr.isEmpty()) { 091 return Level.INFO; 092 } 093 094 if(verbosityStr.equalsIgnoreCase("DEBUG")) { 095 return Level.DEBUG; 096 } 097 098 if(verbosityStr.equalsIgnoreCase("ERROR")) { 099 return Level.ERROR; 100 } 101 102 103 if(verbosityStr.equalsIgnoreCase("WARN")) { 104 return Level.WARN; 105 } 106 107 // anything else including verbosityStr.equalsIgnoreCase("INFO") 108 return Level.INFO; 109 } 110 111 static boolean isEnabledFor(Level level) { 112 return (level.levelInt >= INTERNAL_VERBOSITY.levelInt); 113 } 114 115 static private PrintStream getTarget() { 116 switch(TARGET_CHOICE) { 117 case Stdout: 118 return System.out; 119 case Stderr: 120 default: 121 return System.err; 122 } 123 } 124 125 /** 126 * Report an internal message of level DEBUG. Message text is prefixed with the string "SLF4J(D)", 127 * with (D) standing as a shorthand for DEBUG. 128 * 129 * <p>Messages of level DEBUG are be enabled when the {@link #SLF4J_INTERNAL_VERBOSITY_KEY} 130 * system property is set to "DEBUG" and disabled when set to "INFO", "WARN" or "ERROR". By default, 131 * {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is set to "INFO".</p> 132 * 133 * @param msg the message text 134 * @since 2.0.16 135 */ 136 public static void debug(String msg) { 137 if(isEnabledFor(Level.DEBUG)) { 138 getTarget().println(SLF4J_DEBUG_PREFIX + msg); 139 } 140 } 141 142 /** 143 * Report an internal message of level INFO. Message text is prefixed with the string "SLF4J(I)", with 144 * (I) standing as a shorthand for INFO. 145 * 146 * <p>Messages of level INFO are be enabled when the {@link #SLF4J_INTERNAL_VERBOSITY_KEY} system property is 147 * set to "DEBUG" or "INFO" and disabled when set to "WARN" or "ERROR". By default, 148 * {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is set to "INFO".</p> 149 * 150 * @param msg the message text 151 */ 152 public static void info(String msg) { 153 if(isEnabledFor(Level.INFO)) { 154 getTarget().println(SLF4J_INFO_PREFIX + msg); 155 } 156 } 157 158 159 /** 160 * Report an internal message of level "WARN". Message text is prefixed with the string "SLF4J(W)", with 161 * (W) standing as a shorthand for WARN. 162 * 163 * <p>Messages of level WARN are be enabled when the {@link #SLF4J_INTERNAL_VERBOSITY_KEY} system property is 164 * set to "DEBUG", "INFO" or "WARN" and disabled when set to "ERROR". By default, 165 * {@link #SLF4J_INTERNAL_VERBOSITY_KEY} is set to "INFO".</p> 166 * 167 * @param msg the message text 168 */ 169 static final public void warn(String msg) { 170 if(isEnabledFor(Level.WARN)) { 171 getTarget().println(SLF4J_WARN_PREFIX + msg); 172 } 173 } 174 175 /** 176 * Report an internal message of level "ERROR accompanied by a {@link Throwable}. 177 * Message text is prefixed with the string "SLF4J(E)", with (E) standing as a shorthand for ERROR. 178 * 179 * <p>Messages of level ERROR are always enabled. 180 * 181 * @param msg the message text 182 * @param t a Throwable 183 */ 184 static final public void error(String msg, Throwable t) { 185 // error cannot be disabled 186 getTarget().println(SLF4J_ERROR_PREFIX + msg); 187 getTarget().println(SLF4J_ERROR_PREFIX + "Reported exception:"); 188 t.printStackTrace(getTarget()); 189 } 190 191 /** 192 * Report an internal message of level "ERROR". Message text is prefixed with the string "SLF4J(E)", 193 * with (E) standing as a shorthand for ERROR. 194 * 195 * <p>Messages of level ERROR are always enabled. 196 * 197 * @param msg the message text 198 */ 199 200 static final public void error(String msg) { 201 // error cannot be disabled 202 getTarget().println(SLF4J_ERROR_PREFIX + msg); 203 } 204}