private String getNormalizedMessageFromLogEvent() { List<LogEvent> loggingEvents = testLogAppender.getEvents(); assertThat(loggingEvents.size(), is(1)); LogEvent loggingEvent = loggingEvents.get(0); assertThat(loggingEvent.getLevel(), is(Level.INFO)); return loggingEvent.getMessage().getFormattedMessage().replace(LS, " ").replaceAll(" +", " "); }
@Override public String lookup(final LogEvent event, final String key) { final boolean isMapMessage = event.getMessage() instanceof MapMessage; if (map == null && !isMapMessage) { return null; } if (map != null && map.containsKey(key)) { final String obj = map.get(key); if (obj != null) { return obj; } } if (isMapMessage) { return ((MapMessage) event.getMessage()).get(key); } return null; }
/** * Actual writing occurs here. * * @param logEvent The LogEvent. */ @Override public void append(LogEvent logEvent) { if (!isStarted()) { throw new IllegalStateException("AsyncAppender " + getName() + " is not active"); } if (!(logEvent instanceof Log4jLogEvent)) { if (!(logEvent instanceof RingBufferLogEvent)) { return; // only know how to Serialize Log4jLogEvents and RingBufferLogEvents } logEvent = ((RingBufferLogEvent) logEvent).createMemento(); } logEvent.getMessage().getFormattedMessage(); // LOG4J2-763: ask message to freeze parameters final Log4jLogEvent coreEvent = (Log4jLogEvent) logEvent; boolean appendSuccessful = false; if (blocking) { if (isAppenderThread.get() == Boolean.TRUE && queue.remainingCapacity() == 0) { // LOG4J2-485: avoid deadlock that would result from trying // to add to a full queue from appender thread coreEvent.setEndOfBatch(false); // queue is definitely not empty! appendSuccessful = thread.callAppenders(coreEvent); } else { final Serializable serialized = Log4jLogEvent.serialize(coreEvent, includeLocation); try { // wait for free slots in the queue queue.put(serialized); appendSuccessful = true; } catch (final InterruptedException e) { // LOG4J2-1049: Some applications use Thread.interrupt() to send // messages between application threads. This does not necessarily // mean that the queue is full. To prevent dropping a log message, // quickly try to offer the event to the queue again. // (Yes, this means there is a possibility the same event is logged twice.) // // Finally, catching the InterruptedException means the // interrupted flag has been cleared on the current thread. // This may interfere with the application's expectation of // being interrupted, so when we are done, we set the interrupted // flag again. appendSuccessful = queue.offer(serialized); if (!appendSuccessful) { LOGGER.warn( "Interrupted while waiting for a free slot in the AsyncAppender LogEvent-queue {}", getName()); } // set the interrupted flag again. Thread.currentThread().interrupt(); } } } else { appendSuccessful = queue.offer(Log4jLogEvent.serialize(coreEvent, includeLocation)); if (!appendSuccessful) { error("Appender " + getName() + " is unable to write primary appenders. queue is full"); } } if (!appendSuccessful && errorAppender != null) { errorAppender.callAppender(coreEvent); } }
@Test public void testLog() throws Exception { logger.info("Informative message here."); final List<LogEvent> events = eventAppender.getEvents(); assertThat(events, hasSize(1)); final LogEvent event = events.get(0); assertThat(event, instanceOf(Log4jLogEvent.class)); assertEquals(Level.INFO, event.getLevel()); assertEquals(LOGGER_NAME, event.getLoggerName()); assertEquals("Informative message here.", event.getMessage().getFormattedMessage()); assertEquals(ApiLogger.class.getName(), event.getLoggerFqcn()); }
private void testMessage(String string) { final Logger root = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); root.info("Test info " + string); root.config("Test info " + string); root.fine("Test info " + string); final List<LogEvent> events = eventAppender.getEvents(); assertThat(events, hasSize(3)); for (final LogEvent event : events) { final String message = event.getMessage().getFormattedMessage(); assertThat(message, equalTo("Test info " + string)); } }
/** * Actual writing occurs here. * * @param logEvent The LogEvent. */ @Override public void append(final LogEvent logEvent) { if (!isStarted()) { throw new IllegalStateException("AsyncAppender " + getName() + " is not active"); } if (!canFormatMessageInBackground(logEvent.getMessage())) { logEvent.getMessage().getFormattedMessage(); // LOG4J2-763: ask message to freeze parameters } final Log4jLogEvent memento = Log4jLogEvent.createMemento(logEvent, includeLocation); if (!transfer(memento)) { if (blocking) { // delegate to the event router (which may discard, enqueue and block, or log in current // thread) final EventRoute route = asyncQueueFullPolicy.getRoute(thread.getId(), memento.getLevel()); route.logMessage(this, memento); } else { error("Appender " + getName() + " is unable to write primary appenders. queue is full"); logToErrorAppenderIfNecessary(false, memento); } } }
@Test public void testGlobalLogger() throws Exception { final Logger root = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); root.info("Test info message"); root.config("Test info message"); root.fine("Test info message"); final List<LogEvent> events = eventAppender.getEvents(); assertThat(events, hasSize(3)); for (final LogEvent event : events) { final String message = event.getMessage().getFormattedMessage(); assertThat(message, equalTo("Test info message")); } }
/** * Formats a {@link org.apache.logging.log4j.core.LogEvent} in conformance with the RFC 5424 * Syslog specification. * * @param event The LogEvent. * @return The RFC 5424 String representation of the LogEvent. */ @Override public String toSerializable(final LogEvent event) { final StringBuilder buf = new StringBuilder(); appendPriority(buf, event.getLevel()); appendTimestamp(buf, event.getTimeMillis()); appendSpace(buf); appendHostName(buf); appendSpace(buf); appendAppName(buf); appendSpace(buf); appendProcessId(buf); appendSpace(buf); appendMessageId(buf, event.getMessage()); appendSpace(buf); appendStructuredElements(buf, event); appendMessage(buf, event); if (useTlsMessageFormat) { return new TlsSyslogFrame(buf.toString()).toString(); } return buf.toString(); }
private void appendMessage(final StringBuilder buffer, final LogEvent event) { final Message message = event.getMessage(); // This layout formats StructuredDataMessages instead of delegating to the Message itself. final String text = (message instanceof StructuredDataMessage) ? message.getFormat() : message.getFormattedMessage(); if (text != null && text.length() > 0) { buffer.append(' ').append(escapeNewlines(text, escapeNewLine)); } if (exceptionFormatters != null && event.getThrown() != null) { final StringBuilder exception = new StringBuilder(LF); for (final PatternFormatter formatter : exceptionFormatters) { formatter.format(event, exception); } buffer.append(escapeNewlines(exception.toString(), escapeNewLine)); } if (includeNewLine) { buffer.append(LF); } }
private void appendStructuredElements(final StringBuilder buffer, final LogEvent event) { final Message message = event.getMessage(); final boolean isStructured = message instanceof StructuredDataMessage; if (!isStructured && (fieldFormatters != null && fieldFormatters.isEmpty()) && !includeMdc) { buffer.append('-'); return; } final Map<String, StructuredDataElement> sdElements = new HashMap<String, StructuredDataElement>(); final Map<String, String> contextMap = event.getContextMap(); if (mdcRequired != null) { checkRequired(contextMap); } if (fieldFormatters != null) { for (final Map.Entry<String, FieldFormatter> sdElement : fieldFormatters.entrySet()) { final String sdId = sdElement.getKey(); final StructuredDataElement elem = sdElement.getValue().format(event); sdElements.put(sdId, elem); } } if (includeMdc && contextMap.size() > 0) { if (sdElements.containsKey(mdcSdId.toString())) { final StructuredDataElement union = sdElements.get(mdcSdId.toString()); union.union(contextMap); sdElements.put(mdcSdId.toString(), union); } else { final StructuredDataElement formattedContextMap = new StructuredDataElement(contextMap, false); sdElements.put(mdcSdId.toString(), formattedContextMap); } } if (isStructured) { final StructuredDataMessage data = (StructuredDataMessage) message; final Map<String, String> map = data.getData(); final StructuredDataId id = data.getId(); final String sdId = getId(id); if (sdElements.containsKey(sdId)) { final StructuredDataElement union = sdElements.get(id.toString()); union.union(map); sdElements.put(sdId, union); } else { final StructuredDataElement formattedData = new StructuredDataElement(map, false); sdElements.put(sdId, formattedData); } } if (sdElements.isEmpty()) { buffer.append('-'); return; } for (final Map.Entry<String, StructuredDataElement> entry : sdElements.entrySet()) { formatStructuredElement(entry.getKey(), mdcPrefix, entry.getValue(), buffer, checker); } }