/** * Checks that the message factory a logger was created with is the same as the given messageFactory. If they are * different log a warning to the {@linkplain StatusLogger}. A null MessageFactory translates to the default * MessageFactory {@link #DEFAULT_MESSAGE_FACTORY_CLASS}. * * @param logger * The logger to check * @param messageFactory * The message factory to check. */ public static void checkMessageFactory(final Logger logger, final MessageFactory messageFactory) { final String name = logger.getName(); final MessageFactory loggerMessageFactory = logger.getMessageFactory(); if (messageFactory != null && !loggerMessageFactory.equals(messageFactory)) { StatusLogger .getLogger() .warn("The Logger {} was created with the message factory {} and is now requested with the " + "message factory {}, which may create log events with unexpected formatting.", name, loggerMessageFactory, messageFactory); } else if (messageFactory == null && !loggerMessageFactory.getClass().equals(DEFAULT_MESSAGE_FACTORY_CLASS)) { StatusLogger .getLogger() .warn("The Logger {} was created with the message factory {} and is now requested with a null " + "message factory (defaults to {}), which may create log events with unexpected formatting.", name, loggerMessageFactory, DEFAULT_MESSAGE_FACTORY_CLASS.getName()); } }
@Override public Log4jTaglibLogger getLogger(final String name, final MessageFactory factory) { Log4jTaglibLogger logger = this.loggers.get(name); if (logger != null) { AbstractLogger.checkMessageFactory(logger, factory); return logger; } synchronized (this.loggers) { logger = this.loggers.get(name); if (logger == null) { final Logger original = factory == null ? LogManager.getLogger(name) : LogManager.getLogger(name, factory); if (!(original instanceof AbstractLogger)) { throw new LoggingException( "Log4j Tag Library requires base logging system to extend Log4j AbstractLogger." ); } // wrap a logger from an underlying implementation logger = new Log4jTaglibLogger((AbstractLogger) original, name, original.getMessageFactory()); this.loggers.put(name, logger); } } return logger; }
static Log4jTaglibLogger resolveLogger(final Log4jTaglibLoggerContext context, final Object logger, final MessageFactory factory) throws JspException { if (logger instanceof Logger) { if (logger instanceof Log4jTaglibLogger) { return (Log4jTaglibLogger) logger; } if (logger instanceof AbstractLogger) { if (LOGGER.isInfoEnabled() && !WARNED_FOR.contains(logger)) { LOGGER.info("Constructing new Log4jTaglibLogger from AbstractLogger {} name and message factory.", logger.getClass().getName()); WARNED_FOR.add(logger); } final AbstractLogger original = (AbstractLogger) logger; return getLogger(context, original.getName(), original.getMessageFactory()); } throw new JspException( "Log4j Tag Library requires base logging system to extend Log4j AbstractLogger."); } if (logger instanceof String) { return getLogger(context, (String) logger, factory); } throw new JspException("Logger must be of type String or org.apache.logging.log4j.Logger."); }
@Test public void testDoEndTagStringFactoryVarPageScope() throws Exception { this.tag.setLogger("testDoEndTagStringFactoryVarPageScope"); final MessageFactory factory = new StringFormatterMessageFactory(); this.tag.setFactory(factory); this.tag.setVar("goodbyeCruelWorld"); assertNull("The default logger should be null.", TagUtils.getDefaultLogger(this.context)); assertEquals("The return value is not correct.", Tag.EVAL_PAGE, this.tag.doEndTag()); assertNull("The default logger should still be null.", TagUtils.getDefaultLogger(this.context)); final Object attribute = this.context.getAttribute("goodbyeCruelWorld", PageContext.PAGE_SCOPE); assertNotNull("The attribute should not be null.", attribute); assertTrue("The attribute should be a Log4jTaglibLogger.", attribute instanceof Log4jTaglibLogger); final Log4jTaglibLogger logger = (Log4jTaglibLogger)attribute; assertEquals("The logger name is not correct.", "testDoEndTagStringFactoryVarPageScope", logger.getName()); assertSame("The message factory is not correct.", factory, logger.getMessageFactory()); }
@Test public void testDoEndTagStringFactoryVarApplicationScope() throws Exception { this.tag.setLogger("testDoEndTagStringFactoryVarApplicationScope"); final MessageFactory factory = new StringFormatterMessageFactory(); this.tag.setFactory(factory); this.tag.setVar("goodbyeCruelWorld"); this.tag.setScope("application"); assertNull("The default logger should be null.", TagUtils.getDefaultLogger(this.context)); assertEquals("The return value is not correct.", Tag.EVAL_PAGE, this.tag.doEndTag()); assertNull("The default logger should still be null.", TagUtils.getDefaultLogger(this.context)); final Object attribute = this.context.getAttribute("goodbyeCruelWorld", PageContext.APPLICATION_SCOPE); assertNotNull("The attribute should not be null.", attribute); assertTrue("The attribute should be a Log4jTaglibLogger.", attribute instanceof Log4jTaglibLogger); final Log4jTaglibLogger logger = (Log4jTaglibLogger)attribute; assertEquals("The logger name is not correct.", "testDoEndTagStringFactoryVarApplicationScope", logger.getName()); assertSame("The message factory is not correct.", factory, logger.getMessageFactory()); }
@Test public void testDoEndTagStringFactoryDefault() throws Exception { this.tag.setLogger("testDoEndTagStringFactoryDefault"); final MessageFactory factory = new StringFormatterMessageFactory(); this.tag.setFactory(factory); assertNull("The default logger should be null.", TagUtils.getDefaultLogger(this.context)); assertEquals("The return value is not correct.", Tag.EVAL_PAGE, this.tag.doEndTag()); final Log4jTaglibLogger logger = TagUtils.getDefaultLogger(this.context); assertNotNull("The default logger should not be null anymore.", logger); assertEquals("The logger name is not correct.", "testDoEndTagStringFactoryDefault", logger.getName()); assertSame("The message factory is not correct.", factory, logger.getMessageFactory()); }
/** * Checks that the message factory a logger was created with is the same as the given messageFactory. If they are * different log a warning to the {@linkplain StatusLogger}. A null MessageFactory translates to the default * MessageFactory {@link #DEFAULT_MESSAGE_FACTORY_CLASS}. * * @param logger The logger to check * @param messageFactory The message factory to check. */ public static void checkMessageFactory(final ExtendedLogger logger, final MessageFactory messageFactory) { final String name = logger.getName(); final MessageFactory loggerMessageFactory = logger.getMessageFactory(); if (messageFactory != null && !loggerMessageFactory.equals(messageFactory)) { StatusLogger.getLogger().warn( "The Logger {} was created with the message factory {} and is now requested with the " + "message factory {}, which may create log events with unexpected formatting.", name, loggerMessageFactory, messageFactory); } else if (messageFactory == null && !loggerMessageFactory.getClass().equals(DEFAULT_MESSAGE_FACTORY_CLASS)) { StatusLogger .getLogger() .warn("The Logger {} was created with the message factory {} and is now requested with a null " + "message factory (defaults to {}), which may create log events with unexpected " + "formatting.", name, loggerMessageFactory, DEFAULT_MESSAGE_FACTORY_CLASS.getName()); } }
@Override public Log4jTaglibLogger getLogger(final String name, final MessageFactory messageFactory) { // Note: This is the only method where we add entries to the 'loggerRegistry' ivar. Log4jTaglibLogger logger = this.loggerRegistry.getLogger(name, messageFactory); if (logger != null) { AbstractLogger.checkMessageFactory(logger, messageFactory); return logger; } synchronized (this.loggerRegistry) { logger = this.loggerRegistry.getLogger(name, messageFactory); if (logger == null) { final LoggerContext context = LogManager.getContext(false); final ExtendedLogger original = messageFactory == null ? context.getLogger(name) : context.getLogger(name, messageFactory); // wrap a logger from an underlying implementation logger = new Log4jTaglibLogger(original, name, original.getMessageFactory()); this.loggerRegistry.putIfAbsent(name, messageFactory, logger); } } return logger; }
@Test public void testDoEndTagStringFactoryVarPageScope() throws Exception { this.tag.setLogger("testDoEndTagStringFactoryVarPageScope"); final MessageFactory factory = new StringFormatterMessageFactory(); this.tag.setFactory(factory); this.tag.setVar("goodbyeCruelWorld"); assertNull("The default logger should be null.", TagUtils.getDefaultLogger(this.context)); assertEquals("The return value is not correct.", Tag.EVAL_PAGE, this.tag.doEndTag()); assertNull("The default logger should still be null.", TagUtils.getDefaultLogger(this.context)); final Object attribute = this.context.getAttribute("goodbyeCruelWorld", PageContext.PAGE_SCOPE); assertNotNull("The attribute should not be null.", attribute); assertTrue("The attribute should be a Log4jTaglibLogger.", attribute instanceof Log4jTaglibLogger); final Log4jTaglibLogger logger = (Log4jTaglibLogger)attribute; assertEquals("The logger name is not correct.", "testDoEndTagStringFactoryVarPageScope", logger.getName()); checkMessageFactory("The message factory is not correct.", factory, logger); }
@Test public void testDoEndTagStringFactoryVarApplicationScope() throws Exception { this.tag.setLogger("testDoEndTagStringFactoryVarApplicationScope"); final MessageFactory factory = new StringFormatterMessageFactory(); this.tag.setFactory(factory); this.tag.setVar("goodbyeCruelWorld"); this.tag.setScope("application"); assertNull("The default logger should be null.", TagUtils.getDefaultLogger(this.context)); assertEquals("The return value is not correct.", Tag.EVAL_PAGE, this.tag.doEndTag()); assertNull("The default logger should still be null.", TagUtils.getDefaultLogger(this.context)); final Object attribute = this.context.getAttribute("goodbyeCruelWorld", PageContext.APPLICATION_SCOPE); assertNotNull("The attribute should not be null.", attribute); assertTrue("The attribute should be a Log4jTaglibLogger.", attribute instanceof Log4jTaglibLogger); final Log4jTaglibLogger logger = (Log4jTaglibLogger)attribute; assertEquals("The logger name is not correct.", "testDoEndTagStringFactoryVarApplicationScope", logger.getName()); checkMessageFactory("The message factory is not correct.", factory, logger); }
@Test public void testDoEndTagStringFactoryDefault() throws Exception { this.tag.setLogger("testDoEndTagStringFactoryDefault"); final MessageFactory factory = new StringFormatterMessageFactory(); this.tag.setFactory(factory); assertNull("The default logger should be null.", TagUtils.getDefaultLogger(this.context)); assertEquals("The return value is not correct.", Tag.EVAL_PAGE, this.tag.doEndTag()); final Log4jTaglibLogger logger = TagUtils.getDefaultLogger(this.context); assertNotNull("The default logger should not be null anymore.", logger); assertEquals("The logger name is not correct.", "testDoEndTagStringFactoryDefault", logger.getName()); checkMessageFactory("The message factory is not correct.", factory, logger); }
@Test public void testLoggerWithTwoArguments() { final MessageFactory MF = new MessageFormatMessageFactory(); String name = testName.getMethodName(); Module module = loginject(Logger.class, LogManager::getLogger, parameter(name), parameter(MF)).as(Module.class); Injector injector = Guice.createInjector(module); TestClass service = injector.getInstance(TestClass.class); assertEquals(name, service.injectedLogger.getName()); assertEquals(MF, service.injectedLogger.getMessageFactory()); }
@Test public void testGetLoggerWithTwoArgumentsWithInferredLoggerType() { final MessageFactory MF = new MessageFormatMessageFactory(); String name = testName.getMethodName(); Module module = loginject(LogManager::getLogger, parameter(name), parameter(MF)).as(Module.class); Injector injector = Guice.createInjector(module); TestClass service = injector.getInstance(TestClass.class); assertEquals(name, service.injectedLogger.getName()); assertEquals(MF, service.injectedLogger.getMessageFactory()); }
public SimpleLogger(final String name, final Level defaultLevel, final boolean showLogName, final boolean showShortLogName, final boolean showDateTime, final boolean showContextMap, final String dateTimeFormat, final MessageFactory messageFactory, final PropertiesUtil props, final PrintStream stream) { super(name, messageFactory); final String lvl = props.getStringProperty(SimpleLoggerContext.SYSTEM_PREFIX + name + ".level"); this.level = Level.toLevel(lvl, defaultLevel); if (showShortLogName) { final int index = name.lastIndexOf("."); if (index > 0 && index < name.length()) { this.logName = name.substring(index + 1); } else { this.logName = name; } } else if (showLogName) { this.logName = name; } else { this.logName = null; } this.showDateTime = showDateTime; this.showContextMap = showContextMap; this.stream = stream; if (showDateTime) { try { this.dateFormatter = new SimpleDateFormat(dateTimeFormat); } catch (final IllegalArgumentException e) { // If the format pattern is invalid - use the default format this.dateFormatter = new SimpleDateFormat(SimpleLoggerContext.DEFAULT_DATE_TIME_FORMAT); } } }
@Override public Logger getLogger(final String name, final MessageFactory messageFactory) { if (loggers.containsKey(name)) { final Logger logger = loggers.get(name); AbstractLogger.checkMessageFactory(logger, messageFactory); return logger; } loggers.putIfAbsent(name, new SimpleLogger(name, defaultLevel, showLogName, showShortName, showDateTime, showContextMap, dateTimeFormat, messageFactory, props, stream)); return loggers.get(name); }
private static Log4jTaglibLogger getLogger(final Log4jTaglibLoggerContext context, final String name, final MessageFactory factory) throws JspException { try { return context.getLogger(name, factory); } catch (final LoggingException e) { throw new JspException(e.getMessage(), e); } }
@Override public Logger getLogger(final String name, final MessageFactory messageFactory) { if (!loggers.containsKey(name)) { loggers.putIfAbsent(name, new SLF4JLogger(name, messageFactory, LoggerFactory.getLogger(name))); } return loggers.get(name); }
private Logger testMessageFactoryMismatch(final String name, final MessageFactory messageFactory1, final MessageFactory messageFactory2) { final Logger testLogger = LogManager.getLogger(name, messageFactory1); assertNotNull(testLogger); assertEquals(messageFactory1, testLogger.getMessageFactory()); final Logger testLogger2 = LogManager.getLogger(name, messageFactory2); assertEquals(messageFactory1, testLogger2.getMessageFactory()); return testLogger; }
/** * Obtain a Logger from the Context. * @param name The name of the Logger to return. * @param messageFactory The message factory is used only when creating a * logger, subsequent use does not change the logger but will log * a warning if mismatched. * @return The Logger. */ @Override public Logger getLogger(final String name, final MessageFactory messageFactory) { Logger logger = loggers.get(name); if (logger != null) { AbstractLogger.checkMessageFactory(logger, messageFactory); return logger; } logger = newInstance(this, name, messageFactory); final Logger prev = loggers.putIfAbsent(name, logger); return prev == null ? logger : prev; }
private Logger testMessageFactoryMismatch(final String name, final MessageFactory messageFactory1, final MessageFactory messageFactory2) { final Logger testLogger = (Logger) LogManager.getLogger(name, messageFactory1); assertNotNull(testLogger); assertEquals(messageFactory1, testLogger.getMessageFactory()); final Logger testLogger2 = (Logger) LogManager.getLogger(name, messageFactory2); assertEquals(messageFactory1, testLogger2.getMessageFactory()); return testLogger; }
/** * Returns a {@link JULLogger} with the specified name, and the name prepended with the prefix of this JULContext as its julName (the name of the underlaying {@link java.util.logging.Logger}) * * @param name name of the logger to return * @param messageFactory the message factory is used only when creating a logger, subsequent use fails silently */ @Override public Logger getLogger(String name, MessageFactory messageFactory) { JULLogger logger = this.loggers.get(name); if (logger != null) { return logger; } logger = new JULLogger(name, this.prefix + name, messageFactory); final JULLogger prev = this.loggers.putIfAbsent(name, logger); return prev == null ? logger : prev; }
private StatusLogger(final String name, final MessageFactory messageFactory) { super(name, messageFactory); this.logger = new SimpleLogger("StatusLogger", Level.ERROR, false, true, false, false, Strings.EMPTY, messageFactory, PROPS, System.err); this.listenersLevel = Level.toLevel(DEFAULT_STATUS_LEVEL, Level.WARN).intLevel(); // LOG4J2-1813 if system property "log4j2.debug" is defined, print all status logging if (isDebugPropertyEnabled()) { logger.setLevel(Level.TRACE); } }
private static Logger testMessageFactoryMismatch(final String name, final MessageFactory messageFactory1, final MessageFactory messageFactory2) { final Logger testLogger1 = (Logger) LogManager.getLogger(name, messageFactory1); assertNotNull(testLogger1); checkMessageFactory(messageFactory1, testLogger1); final Logger testLogger2 = (Logger) LogManager.getLogger(name, messageFactory2); assertNotNull(testLogger2); checkMessageFactory(messageFactory2, testLogger2); return testLogger1; }
private static Class<? extends MessageFactory> createClassForProperty(final String property, final Class<ReusableMessageFactory> reusableParameterizedMessageFactoryClass, final Class<ParameterizedMessageFactory> parameterizedMessageFactoryClass) { try { final String fallback = Constants.ENABLE_THREADLOCALS ? reusableParameterizedMessageFactoryClass.getName() : parameterizedMessageFactoryClass.getName(); final String clsName = PropertiesUtil.getProperties().getStringProperty(property, fallback); return LoaderUtil.loadClass(clsName).asSubclass(MessageFactory.class); } catch (final Throwable t) { return parameterizedMessageFactoryClass; } }
private static MessageFactory2 createDefaultMessageFactory() { try { final MessageFactory result = DEFAULT_MESSAGE_FACTORY_CLASS.newInstance(); return narrow(result); } catch (final InstantiationException | IllegalAccessException e) { throw new IllegalStateException(e); } }
public SimpleLogger(final String name, final Level defaultLevel, final boolean showLogName, final boolean showShortLogName, final boolean showDateTime, final boolean showContextMap, final String dateTimeFormat, final MessageFactory messageFactory, final PropertiesUtil props, final PrintStream stream) { super(name, messageFactory); final String lvl = props.getStringProperty(SimpleLoggerContext.SYSTEM_PREFIX + name + ".level"); this.level = Level.toLevel(lvl, defaultLevel); if (showShortLogName) { final int index = name.lastIndexOf("."); if (index > 0 && index < name.length()) { this.logName = name.substring(index + 1); } else { this.logName = name; } } else if (showLogName) { this.logName = name; } else { this.logName = null; } this.showDateTime = showDateTime; this.showContextMap = showContextMap; this.stream = stream; if (showDateTime) { DateFormat format; try { format = new SimpleDateFormat(dateTimeFormat); } catch (final IllegalArgumentException e) { // If the format pattern is invalid - use the default format format = new SimpleDateFormat(SimpleLoggerContext.DEFAULT_DATE_TIME_FORMAT); } this.dateFormatter = format; } else { this.dateFormatter = null; } }
@Override public ExtendedLogger getLogger(final String name, final MessageFactory messageFactory) { // Note: This is the only method where we add entries to the 'loggerRegistry' ivar. final ExtendedLogger extendedLogger = loggerRegistry.getLogger(name, messageFactory); if (extendedLogger != null) { AbstractLogger.checkMessageFactory(extendedLogger, messageFactory); return extendedLogger; } final SimpleLogger simpleLogger = new SimpleLogger(name, defaultLevel, showLogName, showShortName, showDateTime, showContextMap, dateTimeFormat, messageFactory, props, stream); loggerRegistry.putIfAbsent(name, messageFactory, simpleLogger); return loggerRegistry.getLogger(name, messageFactory); }
/** * Returns a Message, either the value supplied by the specified function, or a new Message created by the specified * Factory. * @param supplier a lambda expression or {@code null} * @return the Message resulting from evaluating the lambda expression or the Message created by the factory for * supplied values that are not of type Message */ public static Message getMessage(final Supplier<?> supplier, final MessageFactory messageFactory) { if (supplier == null) { return null; } final Object result = supplier.get(); return result instanceof Message ? (Message) result : messageFactory.newMessage(result); }
private void assertEqualMessageFactory(final MessageFactory messageFactory, final TestLogger testLogger) { MessageFactory actual = testLogger.getMessageFactory(); if (actual instanceof MessageFactory2Adapter) { actual = ((MessageFactory2Adapter) actual).getOriginal(); } assertEquals(messageFactory, actual); }
private static void checkMessageFactory(final String msg, final MessageFactory messageFactory1, final Logger testLogger1) { if (messageFactory1 == null) { assertEquals(msg, AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS, testLogger1.getMessageFactory().getClass()); } else { MessageFactory actual = testLogger1.getMessageFactory(); if (actual instanceof MessageFactory2Adapter) { actual = ((MessageFactory2Adapter) actual).getOriginal(); } assertEquals(msg, messageFactory1, actual); } }
@Override public void log(final LogRecord record) { if (isFiltered(record)) { return; } final org.apache.logging.log4j.Level level = LevelTranslator.toLevel(record.getLevel()); final Object[] parameters = record.getParameters(); final MessageFactory messageFactory = logger.getMessageFactory(); final Message message = parameters == null ? messageFactory.newMessage(record.getMessage()) /* LOG4J2-1251: not formatted case */ : messageFactory.newMessage(record.getMessage(), parameters); final Throwable thrown = record.getThrown(); logger.logIfEnabled(FQCN, level, null, message, thrown); }
@Override public ExtendedLogger getLogger(final String name, final MessageFactory messageFactory) { // FIXME according to LOG4J2-1180, the below line should be: // FIXME if (!loggerRegistry.hasLogger(name, messageFactory)) { if (!loggerRegistry.hasLogger(name)) { // FIXME: should be loggerRegistry.putIfAbsent(name, messageFactory, loggerRegistry.putIfAbsent(name, null, new SLF4JLogger(name, messageFactory, LoggerFactory.getLogger(name))); } // FIXME should be return loggerRegistry.getLogger(name, messageFactory); return loggerRegistry.getLogger(name); // TODO applying the above fixes causes (log4j-to-slf4j) LoggerTest to fail }
private Logger testMessageFactoryMismatch(final String name, final MessageFactory messageFactory1, final MessageFactory messageFactory2) { final Logger testLogger = LogManager.getLogger(name, messageFactory1); assertThat(testLogger, is(notNullValue())); checkMessageFactory(messageFactory1, testLogger); final Logger testLogger2 = LogManager.getLogger(name, messageFactory2); checkMessageFactory(messageFactory1, testLogger2); return testLogger; }
private static void checkMessageFactory(final MessageFactory messageFactory1, final Logger testLogger1) { if (messageFactory1 == null) { assertEquals(AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS, testLogger1.getMessageFactory().getClass()); } else { MessageFactory actual = testLogger1.getMessageFactory(); if (actual instanceof MessageFactory2Adapter) { actual = ((MessageFactory2Adapter) actual).getOriginal(); } assertEquals(messageFactory1, actual); } }
/** * This method is only used for 1.x compatibility. Returns the parent of this Logger. If it doesn't already exist * return a temporary Logger. * * @return The parent Logger. */ public Logger getParent() { final LoggerConfig lc = privateConfig.loggerConfig.getName().equals(getName()) ? privateConfig.loggerConfig .getParent() : privateConfig.loggerConfig; if (lc == null) { return null; } final String lcName = lc.getName(); final MessageFactory messageFactory = getMessageFactory(); if (context.hasLogger(lcName, messageFactory)) { return context.getLogger(lcName, messageFactory); } return new Logger(context, lcName, messageFactory); }
/** * Obtains a Logger from the Context. * * @param name The name of the Logger to return. * @param messageFactory The message factory is used only when creating a logger, subsequent use does not change the * logger but will log a warning if mismatched. * @return The Logger. */ @Override public Logger getLogger(final String name, final MessageFactory messageFactory) { // Note: This is the only method where we add entries to the 'loggerRegistry' ivar. Logger logger = loggerRegistry.getLogger(name, messageFactory); if (logger != null) { AbstractLogger.checkMessageFactory(logger, messageFactory); return logger; } logger = newInstance(this, name, messageFactory); loggerRegistry.putIfAbsent(name, messageFactory, logger); return loggerRegistry.getLogger(name, messageFactory); }
public FastLogger(final ExtendedLogger logger, final String name, final MessageFactory messageFactory) { super(logger, name, messageFactory); }
@Override public MessageFactory getMessageFactory() { return logger.getMessageFactory(); }