|
18 | 18 | import java.util.Map; |
19 | 19 | import java.util.logging.ConsoleHandler; |
20 | 20 | import java.util.logging.FileHandler; |
21 | | -import java.util.logging.Handler; |
22 | 21 | import java.util.logging.Level; |
23 | 22 | import java.util.logging.Logger; |
24 | 23 | import com.fasterxml.jackson.databind.JsonNode; |
@@ -116,7 +115,11 @@ public static void main(String... args) throws Exception { |
116 | 115 | final Options options = new Options(); |
117 | 116 |
|
118 | 117 | options.addOption("h", "help", false, "Displays help text"); |
119 | | - options.addOption("d", "debug", false, "Enables debug messages"); |
| 118 | + options.addOption("d", "debug", false, "Enables debug messages (alias for --log-level debug)"); |
| 119 | + |
| 120 | + Option logLevel = new Option(null, "log-level", true, "Set log verbosity. One of: error, warn, info (default), debug, trace. Overrides --debug if both are given."); |
| 121 | + logLevel.setArgName("LEVEL"); |
| 122 | + options.addOption(logLevel); |
120 | 123 |
|
121 | 124 | Option readyfile = new Option("f", "readyfile", true, "This file will be touched when the tunnel is ready for usage"); |
122 | 125 | readyfile.setArgName("FILE"); |
@@ -205,28 +208,91 @@ public static void main(String... args) throws Exception { |
205 | 208 | logger.addHandler(handler); |
206 | 209 |
|
207 | 210 | App app = new App(); |
208 | | - if (commandLine.hasOption("debug")) { |
209 | | - System.setProperty("org.eclipse.jetty.LEVEL", "DEBUG"); |
| 211 | + |
| 212 | + String levelArg = commandLine.getOptionValue("log-level"); |
| 213 | + if (levelArg == null && commandLine.hasOption("debug")) { |
| 214 | + levelArg = "debug"; |
| 215 | + } |
| 216 | + if (levelArg == null) { |
| 217 | + levelArg = "info"; |
| 218 | + } |
| 219 | + |
| 220 | + Level julLevel; |
| 221 | + ch.qos.logback.classic.Level logbackLevel; |
| 222 | + String jettyLevel; |
| 223 | + switch (levelArg.toLowerCase(java.util.Locale.ROOT)) { |
| 224 | + case "error": |
| 225 | + julLevel = Level.SEVERE; |
| 226 | + logbackLevel = ch.qos.logback.classic.Level.ERROR; |
| 227 | + jettyLevel = "ERROR"; |
| 228 | + break; |
| 229 | + case "warn": |
| 230 | + case "warning": |
| 231 | + julLevel = Level.WARNING; |
| 232 | + logbackLevel = ch.qos.logback.classic.Level.WARN; |
| 233 | + jettyLevel = "WARN"; |
| 234 | + break; |
| 235 | + case "info": |
| 236 | + julLevel = Level.INFO; |
| 237 | + logbackLevel = ch.qos.logback.classic.Level.INFO; |
| 238 | + jettyLevel = "INFO"; |
| 239 | + break; |
| 240 | + case "debug": |
| 241 | + julLevel = Level.ALL; |
| 242 | + logbackLevel = ch.qos.logback.classic.Level.DEBUG; |
| 243 | + jettyLevel = "DEBUG"; |
| 244 | + break; |
| 245 | + case "trace": |
| 246 | + julLevel = Level.ALL; |
| 247 | + logbackLevel = ch.qos.logback.classic.Level.TRACE; |
| 248 | + jettyLevel = "TRACE"; |
| 249 | + break; |
| 250 | + default: |
| 251 | + throw new ParseException("Invalid --log-level '" + levelArg + "'. Use one of: error, warn, info, debug, trace."); |
| 252 | + } |
| 253 | + |
| 254 | + logger.setLevel(julLevel); |
| 255 | + System.setProperty("org.eclipse.jetty.LEVEL", jettyLevel); |
| 256 | + |
| 257 | + LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); |
| 258 | + loggerContext.getLogger("ROOT").setLevel(logbackLevel); |
| 259 | + loggerContext.getLogger("org.apache.hc").setLevel(logbackLevel); |
| 260 | + |
| 261 | + boolean debugLike = (logbackLevel.toInt() <= ch.qos.logback.classic.Level.DEBUG.toInt()); |
| 262 | + if (debugLike) { |
| 263 | + loggerContext.getLogger("org.eclipse.jetty").setLevel(logbackLevel); |
| 264 | + loggerContext.getLogger("com.testingbot.tunnel.proxy").setLevel(logbackLevel); |
210 | 265 | logger.log(Level.INFO, "Running in debug-mode"); |
211 | | - logger.setLevel(Level.ALL); |
212 | 266 | app.setDebugMode(true); |
213 | | - |
214 | | - LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); |
215 | | - loggerContext.getLogger("ROOT").setLevel(ch.qos.logback.classic.Level.DEBUG); |
216 | | - loggerContext.getLogger("org.apache.hc").setLevel(ch.qos.logback.classic.Level.DEBUG); |
217 | | - } else { |
218 | | - logger.setLevel(Level.INFO); |
219 | 267 | } |
220 | 268 |
|
221 | 269 | if (commandLine.hasOption("logfile")) { |
| 270 | + String logfilePath = commandLine.getOptionValue("logfile"); |
222 | 271 | try { |
223 | | - Handler handlerFile = new FileHandler(commandLine.getOptionValue("logfile")); |
| 272 | + FileHandler handlerFile = new FileHandler(logfilePath, true); |
224 | 273 | handlerFile.setFormatter(new LogFormatter()); |
225 | 274 | handlerFile.setLevel(Level.ALL); |
226 | | - Logger.getLogger(App.class.getName()).addHandler(handlerFile); |
227 | | - Logger.getLogger(App.class.getName()).log(Level.INFO, "Logging to file {0}", commandLine.getOptionValue("logfile")); |
| 275 | + // Attach to App's logger (useParentHandlers=false above) AND to the JUL root |
| 276 | + // so messages from sibling loggers (HttpProxy, SSHTunnel, Doctor, ...) land in the file too. |
| 277 | + logger.addHandler(handlerFile); |
| 278 | + Logger.getLogger("").addHandler(handlerFile); |
| 279 | + |
| 280 | + ch.qos.logback.classic.encoder.PatternLayoutEncoder encoder = new ch.qos.logback.classic.encoder.PatternLayoutEncoder(); |
| 281 | + encoder.setContext(loggerContext); |
| 282 | + encoder.setPattern("%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n"); |
| 283 | + encoder.start(); |
| 284 | + ch.qos.logback.core.FileAppender<ch.qos.logback.classic.spi.ILoggingEvent> fileAppender = new ch.qos.logback.core.FileAppender<>(); |
| 285 | + fileAppender.setContext(loggerContext); |
| 286 | + fileAppender.setName("FILE"); |
| 287 | + fileAppender.setFile(logfilePath); |
| 288 | + fileAppender.setAppend(true); |
| 289 | + fileAppender.setEncoder(encoder); |
| 290 | + fileAppender.start(); |
| 291 | + loggerContext.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME).addAppender(fileAppender); |
| 292 | + |
| 293 | + logger.log(Level.INFO, "Logging to file {0}", logfilePath); |
228 | 294 | } catch (IOException | SecurityException e) { |
229 | | - System.err.println("Cannot write logfile to " + commandLine.getOptionValue("logfile") + ".\nMake sure the directory exists and that we have the proper rights to write to this directory."); |
| 295 | + System.err.println("Cannot write logfile to " + logfilePath + ".\nMake sure the directory exists and we have permission to write there."); |
230 | 296 | } |
231 | 297 | } |
232 | 298 |
|
|
0 commit comments