001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.microservice.jetty; 018 019import static java.util.logging.Level.*; 020import static org.apache.juneau.commons.utils.Utils.*; 021 022import java.util.logging.*; 023import java.util.logging.Logger; 024 025import org.slf4j.*; 026import org.slf4j.spi.*; 027 028/** 029 * Implementation of Jetty {@link Logger} based on {@link java.util.logging.Logger}. 030 * 031 * <p> 032 * Allows Jetty to log to the Java Util logging framework (and thus to the main log file defined in the 033 * <cc>[Logging]</cc> section). 034 * 035 * <p> 036 * Can be used by setting the following system property in the microservice config file. 037 * 038 * <p class='bini'> 039 * <cs>[SystemProperties]</cs> 040 * 041 * <cc># Configure Jetty to log using java-util logging</cc> 042 * <ck>org.eclipse.jetty.util.log.class</ck> = org.apache.juneau.microservice.jetty.JettyLogger 043 * </p> 044 * 045 * <h5 class='section'>See Also:</h5><ul> 046 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauMicroserviceJettyBasics">juneau-microservice-jetty Basics</a> 047 * </ul> 048 */ 049public class JettyLogger implements LocationAwareLogger { 050 private static final boolean SHOW_SOURCE = env("org.eclipse.jetty.util.log.SOURCE", env("org.eclipse.jetty.util.log.javautil.SOURCE", true)); 051 052 /** 053 * Formats a log message by replacing "{}" placeholders with the provided arguments. 054 * 055 * @param msg The message template with "{}" placeholders. 056 * @param args The arguments to substitute into the message. 057 * @return The formatted message string. 058 */ 059 private static String format(String msg, Object...args) { 060 return f(msg, args); 061 } 062 063 /** 064 * The originally configured log level, used to restore the level when debug mode is disabled. 065 */ 066 private Level configuredLevel; 067 068 /** 069 * The underlying Java Util Logger instance. 070 */ 071 private Logger logger; 072 073 /** 074 * Default constructor. 075 * 076 * <p> 077 * Returns the logger with name <js>"org.eclipse.jetty.util.log.javautil"</js>. 078 */ 079 public JettyLogger() { 080 this("org.eclipse.jetty.util.log.javautil"); 081 } 082 083 /** 084 * Normal constructor. 085 * 086 * @param name The logger name. 087 */ 088 public JettyLogger(String name) { 089 logger = Logger.getLogger(name); 090 configuredLevel = logger.getLevel(); 091 } 092 093 @Override 094 public void debug(Marker marker, String msg) { 095 // TODO Auto-generated method stub 096 097 } 098 099 @Override 100 public void debug(Marker marker, String format, Object arg) { 101 // TODO Auto-generated method stub 102 103 } 104 105 @Override 106 public void debug(Marker marker, String format, Object...arguments) { 107 // TODO Auto-generated method stub 108 109 } 110 111 @Override 112 public void debug(Marker marker, String format, Object arg1, Object arg2) { 113 // TODO Auto-generated method stub 114 115 } 116 117 @Override 118 public void debug(Marker marker, String msg, Throwable t) { 119 // TODO Auto-generated method stub 120 121 } 122 123 @Override 124 public void debug(String msg) { 125 // TODO Auto-generated method stub 126 127 } 128 129 /** 130 * Logs a debug message with a long argument. 131 * 132 * @param msg The message template with "{}" placeholder. 133 * @param arg The long argument to substitute into the message. 134 */ 135 public void debug(String msg, long arg) { 136 if (isLoggable(FINE)) 137 log(FINE, format(msg, arg), null); 138 } 139 140 @Override 141 public void debug(String msg, Object...args) { 142 if (isLoggable(FINE)) 143 log(FINE, format(msg, args), null); 144 } 145 146 @Override 147 public void debug(String format, Object arg) { 148 // TODO Auto-generated method stub 149 150 } 151 152 @Override 153 public void debug(String format, Object arg1, Object arg2) { 154 // TODO Auto-generated method stub 155 156 } 157 158 @Override 159 public void debug(String msg, Throwable thrown) { 160 if (isLoggable(FINE)) 161 log(FINE, msg, thrown); 162 } 163 164 /** 165 * Logs a debug message with only a throwable. 166 * 167 * @param thrown The throwable to log. 168 */ 169 public void debug(Throwable thrown) { 170 if (isLoggable(FINE)) 171 log(FINE, "", thrown); 172 } 173 174 @Override 175 public void error(Marker marker, String msg) { 176 // TODO Auto-generated method stub 177 } 178 179 @Override 180 public void error(Marker marker, String format, Object arg) { 181 // TODO Auto-generated method stub 182 } 183 184 @Override 185 public void error(Marker marker, String format, Object...arguments) { 186 // TODO Auto-generated method stub 187 } 188 189 @Override 190 public void error(Marker marker, String format, Object arg1, Object arg2) { 191 // TODO Auto-generated method stub 192 } 193 194 @Override 195 public void error(Marker marker, String msg, Throwable t) { 196 // TODO Auto-generated method stub 197 } 198 199 @Override 200 public void error(String msg) { 201 // TODO Auto-generated method stub 202 } 203 204 @Override 205 public void error(String format, Object arg) { 206 // TODO Auto-generated method stub 207 } 208 209 @Override 210 public void error(String format, Object...arguments) { 211 // TODO Auto-generated method stub 212 } 213 214 @Override 215 public void error(String format, Object arg1, Object arg2) { 216 // TODO Auto-generated method stub 217 } 218 219 @Override 220 public void error(String msg, Throwable t) { 221 // TODO Auto-generated method stub 222 } 223 224 /** 225 * Creates a child logger with the specified name. 226 * 227 * @param name The logger name. 228 * @return A new JettyLogger instance for the specified name. 229 */ 230 public JettyLogger getLogger(String name) { 231 return new JettyLogger(name); 232 } 233 234 @Override 235 public String getName() { return logger.getName(); } 236 237 /** 238 * Logs an ignored exception at the FINEST level. 239 * 240 * @param ignored The exception to log as ignored. 241 */ 242 public void ignore(Throwable ignored) { 243 if (isLoggable(FINEST)) 244 log(FINEST, "IGNORED EXCEPTION ", ignored); 245 } 246 247 @Override 248 public void info(Marker marker, String msg) { 249 // TODO Auto-generated method stub 250 } 251 252 @Override 253 public void info(Marker marker, String format, Object arg) { 254 // TODO Auto-generated method stub 255 256 } 257 258 @Override 259 public void info(Marker marker, String format, Object...arguments) { 260 // TODO Auto-generated method stub 261 } 262 263 @Override 264 public void info(Marker marker, String format, Object arg1, Object arg2) { 265 // TODO Auto-generated method stub 266 } 267 268 @Override 269 public void info(Marker marker, String msg, Throwable t) { 270 // TODO Auto-generated method stub 271 272 } 273 274 @Override 275 public void info(String msg) { 276 // TODO Auto-generated method stub 277 } 278 279 @Override 280 public void info(String msg, Object...args) { 281 if (isLoggable(INFO)) 282 log(INFO, format(msg, args), null); 283 } 284 285 @Override 286 public void info(String format, Object arg) { 287 // TODO Auto-generated method stub 288 } 289 290 @Override 291 public void info(String format, Object arg1, Object arg2) { 292 // TODO Auto-generated method stub 293 } 294 295 @Override 296 public void info(String msg, Throwable thrown) { 297 if (isLoggable(INFO)) 298 log(INFO, msg, thrown); 299 } 300 301 /** 302 * Logs an info message with only a throwable. 303 * 304 * @param thrown The throwable to log. 305 */ 306 public void info(Throwable thrown) { 307 if (isLoggable(INFO)) 308 log(INFO, "", thrown); 309 } 310 311 @Override 312 public boolean isDebugEnabled() { return isLoggable(FINE); } 313 314 @Override 315 public boolean isDebugEnabled(Marker marker) { 316 // TODO Auto-generated method stub 317 return false; 318 } 319 320 @Override 321 public boolean isErrorEnabled() { 322 // TODO Auto-generated method stub 323 return false; 324 } 325 326 @Override 327 public boolean isErrorEnabled(Marker marker) { 328 // TODO Auto-generated method stub 329 return false; 330 } 331 332 @Override 333 public boolean isInfoEnabled() { 334 // TODO Auto-generated method stub 335 return false; 336 } 337 338 @Override 339 public boolean isInfoEnabled(Marker marker) { 340 // TODO Auto-generated method stub 341 return false; 342 } 343 344 @Override 345 public boolean isTraceEnabled() { 346 // TODO Auto-generated method stub 347 return false; 348 } 349 350 @Override 351 public boolean isTraceEnabled(Marker marker) { 352 // TODO Auto-generated method stub 353 return false; 354 } 355 356 @Override 357 public boolean isWarnEnabled() { 358 // TODO Auto-generated method stub 359 return false; 360 } 361 362 @Override 363 public boolean isWarnEnabled(Marker marker) { 364 // TODO Auto-generated method stub 365 return false; 366 } 367 368 @Override 369 public void log(Marker marker, String fqcn, int level, String message, Object[] argArray, Throwable t) { 370 // TODO Auto-generated method stub 371 } 372 373 /** 374 * Enables or disables debug logging. 375 * 376 * <p> 377 * When enabled, sets the log level to FINE. When disabled, restores the previously configured log level. 378 * 379 * @param enabled <jk>true</jk> to enable debug logging, <jk>false</jk> to disable. 380 */ 381 public void setDebugEnabled(boolean enabled) { 382 if (enabled) { 383 configuredLevel = logger.getLevel(); 384 logger.setLevel(FINE); 385 } else { 386 logger.setLevel(configuredLevel); 387 } 388 } 389 390 @Override 391 public void trace(Marker marker, String msg) { 392 // TODO Auto-generated method stub 393 394 } 395 396 @Override 397 public void trace(Marker marker, String format, Object arg) { 398 // TODO Auto-generated method stub 399 400 } 401 402 @Override 403 public void trace(Marker marker, String format, Object...argArray) { 404 // TODO Auto-generated method stub 405 406 } 407 408 @Override 409 public void trace(Marker marker, String format, Object arg1, Object arg2) { 410 // TODO Auto-generated method stub 411 412 } 413 414 @Override 415 public void trace(Marker marker, String msg, Throwable t) { 416 // TODO Auto-generated method stub 417 418 } 419 420 @Override 421 public void trace(String msg) { 422 // TODO Auto-generated method stub 423 424 } 425 426 @Override 427 public void trace(String format, Object arg) { 428 // TODO Auto-generated method stub 429 430 } 431 432 @Override 433 public void trace(String format, Object...arguments) { 434 // TODO Auto-generated method stub 435 436 } 437 438 @Override 439 public void trace(String format, Object arg1, Object arg2) { 440 // TODO Auto-generated method stub 441 442 } 443 444 @Override 445 public void trace(String msg, Throwable t) { 446 // TODO Auto-generated method stub 447 448 } 449 450 @Override 451 public void warn(Marker marker, String msg) { 452 // TODO Auto-generated method stub 453 } 454 455 @Override 456 public void warn(Marker marker, String format, Object arg) { 457 // TODO Auto-generated method stub 458 } 459 460 @Override 461 public void warn(Marker marker, String format, Object...arguments) { 462 // TODO Auto-generated method stub 463 } 464 465 @Override 466 public void warn(Marker marker, String format, Object arg1, Object arg2) { 467 // TODO Auto-generated method stub 468 } 469 470 @Override 471 public void warn(Marker marker, String msg, Throwable t) { 472 // TODO Auto-generated method stub 473 } 474 475 @Override 476 public void warn(String msg) { 477 // TODO Auto-generated method stub 478 } 479 480 @Override 481 public void warn(String msg, Object...args) { 482 if (isLoggable(WARNING)) 483 log(WARNING, format(msg, args), null); 484 } 485 486 @Override 487 public void warn(String format, Object arg) { 488 // TODO Auto-generated method stub 489 } 490 491 @Override 492 public void warn(String format, Object arg1, Object arg2) { 493 // TODO Auto-generated method stub 494 495 } 496 497 @Override 498 public void warn(String msg, Throwable thrown) { 499 if (isLoggable(WARNING)) 500 log(WARNING, msg, thrown); 501 } 502 503 /** 504 * Logs a warning message with only a throwable. 505 * 506 * @param thrown The throwable to log. 507 */ 508 public void warn(Throwable thrown) { 509 if (isLoggable(WARNING)) 510 log(WARNING, "", thrown); 511 } 512 513 /** 514 * Checks if a message at the specified level would be logged. 515 * 516 * @param level The log level to check. 517 * @return <jk>true</jk> if the level is loggable, <jk>false</jk> otherwise. 518 */ 519 private boolean isLoggable(Level level) { 520 return logger.isLoggable(level); 521 } 522 523 /** 524 * Internal log method that creates a LogRecord and logs it. 525 * 526 * <p> 527 * Optionally includes source class and method name in the log record if SHOW_SOURCE is enabled. 528 * 529 * @param level The log level. 530 * @param msg The log message. 531 * @param thrown The throwable to log, or <jk>null</jk> if none. 532 */ 533 private void log(Level level, String msg, Throwable thrown) { 534 var r = new LogRecord(level, msg); 535 if (nn(thrown)) 536 r.setThrown(thrown); 537 r.setLoggerName(logger.getName()); 538 if (SHOW_SOURCE) { 539 StackTraceElement[] stack = new Throwable().getStackTrace(); 540 for (var e : stack) { 541 if (! e.getClassName().equals(getClass().getName())) { 542 r.setSourceClassName(e.getClassName()); 543 r.setSourceMethodName(e.getMethodName()); 544 break; 545 } 546 } 547 } 548 logger.log(r); 549 } 550}