| 1 | package dmg.util.logback; |
| 2 | |
| 3 | import java.util.Map; |
| 4 | import java.util.HashMap; |
| 5 | import java.util.List; |
| 6 | import java.util.Collection; |
| 7 | import java.util.Set; |
| 8 | import java.util.HashSet; |
| 9 | import java.util.Formatter; |
| 10 | import java.util.concurrent.ConcurrentHashMap; |
| 11 | |
| 12 | import ch.qos.logback.classic.Logger; |
| 13 | import ch.qos.logback.classic.Level; |
| 14 | import ch.qos.logback.classic.LoggerContext; |
| 15 | |
| 16 | import org.slf4j.LoggerFactory; |
| 17 | |
| 18 | import dmg.util.Args; |
| 19 | |
| 20 | /** |
| 21 | * Provides basic cell shell commands to inspect and manipulate log |
| 22 | * filter thresholds. |
| 23 | * |
| 24 | * Notice that there is a one-to-one correspondence between appenders |
| 25 | * and filters. Hence we refer to appenders in the user interface, but |
| 26 | * the code actually manipulates the filters attached to the |
| 27 | * appenders. |
| 28 | */ |
| 29 | public class FilterShell |
| 30 | { |
| 31 | private final FilterThresholds _thresholds; |
| 32 | private final LoggerContext _context = |
| 33 | (LoggerContext) LoggerFactory.getILoggerFactory(); |
| 34 | |
| 35 | public FilterShell(FilterThresholds thresholds) |
| 36 | { |
| 37 | if (thresholds == null) { |
| 38 | throw new IllegalArgumentException("Null argument is not valid"); |
| 39 | } |
| 40 | _thresholds = thresholds; |
| 41 | } |
| 42 | |
| 43 | private boolean isExistingLogger(LoggerName name) |
| 44 | { |
| 45 | for (Logger logger: getLoggers()) { |
| 46 | if (name.isNameOfLogger(logger)) { |
| 47 | return true; |
| 48 | } |
| 49 | } |
| 50 | return false; |
| 51 | } |
| 52 | |
| 53 | private Collection<Logger> getLoggers() |
| 54 | { |
| 55 | return _context.getLoggerList(); |
| 56 | } |
| 57 | |
| 58 | private Collection<String> getFilters() |
| 59 | { |
| 60 | return _thresholds.getFilters(); |
| 61 | } |
| 62 | |
| 63 | public final static String hh_log_ls = |
| 64 | "[-a] [<appender>] [<logger>]"; |
| 65 | public final static String fh_log_ls = |
| 66 | "Lists current log thresholds. Inherited thresholds are marked\n" + |
| 67 | "with an asterix."; |
| 68 | public String ac_log_ls_$_0_2(Args args) |
| 69 | { |
| 70 | boolean all = (args.getOpt("a") != null); |
| 71 | String appender = args.argv(0); |
| 72 | String logger = args.argv(1); |
| 73 | Formatter out = new Formatter(); |
| 74 | if (logger != null) { |
| 75 | lsLogger(out, all, LoggerName.getInstance(logger), appender); |
| 76 | } else if (appender != null) { |
| 77 | lsFilter(out, all, appender); |
| 78 | } else { |
| 79 | ls(out, all); |
| 80 | } |
| 81 | return out.toString(); |
| 82 | } |
| 83 | |
| 84 | private void ls(Formatter out, boolean all) |
| 85 | { |
| 86 | for (String filter: getFilters()) { |
| 87 | lsFilter(out, all, filter); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | private void lsFilter(Formatter out, boolean all, String filter) |
| 92 | { |
| 93 | out.format("%s:\n", filter); |
| 94 | for (Logger logger: getLoggers()) { |
| 95 | lsLogger(out, all, LoggerName.getInstance(logger), filter); |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | private void lsLogger(Formatter out, boolean all, |
| 100 | LoggerName logger, String filter) |
| 101 | { |
| 102 | Level level = _thresholds.get(logger, filter); |
| 103 | if (level != null) { |
| 104 | out.format(" %s=%s\n", logger, level); |
| 105 | } else { |
| 106 | level = _thresholds.getInheritedMap(logger).get(filter); |
| 107 | if (level != null) { |
| 108 | out.format(" %s=%s*\n", logger, level); |
| 109 | } else if (all) { |
| 110 | out.format(" %s\n", logger); |
| 111 | } |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | public final static String hh_log_set = |
| 116 | "<appender> [<logger>] OFF|ERROR|WARN|INFO|DEBUG|TRACE|ALL"; |
| 117 | public final static String fh_log_set = |
| 118 | "Sets the log level of <appender>."; |
| 119 | public String ac_log_set_$_2_3(Args args) |
| 120 | { |
| 121 | String appender = args.argv(0); |
| 122 | LoggerName logger; |
| 123 | String threshold; |
| 124 | |
| 125 | if (args.argc() == 3) { |
| 126 | logger = LoggerName.getInstance(args.argv(1)); |
| 127 | threshold = args.argv(2); |
| 128 | } else { |
| 129 | logger = LoggerName.ROOT; |
| 130 | threshold = args.argv(1); |
| 131 | } |
| 132 | |
| 133 | if (!getFilters().contains(appender)) { |
| 134 | throw new IllegalArgumentException("Appender not found"); |
| 135 | } |
| 136 | |
| 137 | if (!isExistingLogger(logger)) { |
| 138 | throw new IllegalArgumentException("Logger not found"); |
| 139 | } |
| 140 | |
| 141 | _thresholds.setThreshold(logger, appender, Level.valueOf(threshold)); |
| 142 | return ""; |
| 143 | } |
| 144 | |
| 145 | public final static String hh_log_reset = |
| 146 | "[-a] <appender> [<logger>]"; |
| 147 | public final static String fh_log_reset = |
| 148 | "Resets the log level of <appender>. The log level for <appender>\n" + |
| 149 | "will be inherited from the parent cell."; |
| 150 | public String ac_log_reset_$_1_2(Args args) |
| 151 | { |
| 152 | String appender = args.argv(0); |
| 153 | if (args.argc() == 2) { |
| 154 | _thresholds.remove(LoggerName.getInstance(args.argv(1)), appender); |
| 155 | } else if (args.getOpt("a") == null) { |
| 156 | _thresholds.remove(LoggerName.ROOT, appender); |
| 157 | } else { |
| 158 | for (Logger logger: getLoggers()) { |
| 159 | _thresholds.remove(LoggerName.getInstance(logger), appender); |
| 160 | } |
| 161 | } |
| 162 | return ""; |
| 163 | } |
| 164 | } |