下面列出了怎么用org.apache.logging.log4j.core.LogEvent的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void overnightForward() {
final TimeFilter filter = new TimeFilter(LocalTime.of(23,0), LocalTime.of(2,0),
ZoneId.of("America/Los_Angeles"), null, null, LocalDate.of(2020, 3, 7));
filter.start();
assertTrue(filter.isStarted());
ZonedDateTime date = ZonedDateTime.of(2020, 3, 7, 23, 30, 30, 0, ZoneId.of("America/Los_Angeles")).withEarlierOffsetAtOverlap();
CLOCKTIME = date.toInstant().toEpochMilli();
LogEvent event = Log4jLogEvent.newBuilder().setTimeMillis(CLOCKTIME).build();
assertSame("Time " + CLOCKTIME + " is not within range: " + filter.toString(), Filter.Result.NEUTRAL, filter.filter(event));
date = date.plusHours(1);
CLOCKTIME = date.toInstant().toEpochMilli();
event = Log4jLogEvent.newBuilder().setTimeMillis(CLOCKTIME).build();
assertSame("Time " + CLOCKTIME + " is not within range: " + filter.toString(), Filter.Result.NEUTRAL, filter.filter(event));
date = date.plusHours(2);
CLOCKTIME = date.toInstant().toEpochMilli();
event = Log4jLogEvent.newBuilder().setTimeMillis(CLOCKTIME).build();
assertSame("Time " + CLOCKTIME + " is within range: " + filter.toString(), Filter.Result.DENY, filter.filter(event));
date = date.plusDays(1).withHour(0);
CLOCKTIME = date.toInstant().toEpochMilli();
event = Log4jLogEvent.newBuilder().setTimeMillis(CLOCKTIME).build();
assertSame("Time " + CLOCKTIME + " is not within range: " + filter.toString(), Filter.Result.NEUTRAL, filter.filter(event));
}
@Test
public void test() {
LOGGER.info("This message contains \r\n line feeds");
// Check the message being logged is correct
LogEvent nulEvent = appender.getEvents().get(0);
final String[] options = new String[] { "%msg" };
final EncodingPatternConverter converter = EncodingPatternConverter
.newInstance(context.getConfiguration(), options);
final StringBuilder sb = new StringBuilder();
converter.format(nulEvent, sb);
assertTrue(sb.toString().contains(
"This message contains \\r\\n line feeds"));
}
@Test
public void testEqualsMarkerWithMessageSubstitution() throws Exception {
// replace "[]" with the empty string
final PatternLayout layout = PatternLayout.newBuilder().setPattern("[%logger]%equals{[%marker]}{[]}{[%msg]}")
.setConfiguration(ctx.getConfiguration()).build();
// Not empty marker
final LogEvent event1 = Log4jLogEvent.newBuilder() //
.setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.Logger") //
.setLevel(Level.INFO) //
.setMarker(MarkerManager.getMarker("TestMarker"))
.setMessage(new SimpleMessage("Hello, world!")).build();
final byte[] result1 = layout.toByteArray(event1);
assertEquals("[org.apache.logging.log4j.core.layout.PatternLayoutTest][TestMarker]", new String(result1));
// empty marker
final LogEvent event2 = Log4jLogEvent.newBuilder() //
.setLoggerName(this.getClass().getName()).setLoggerFqcn("org.apache.logging.log4j.core.Logger") //
.setLevel(Level.INFO)
.setMessage(new SimpleMessage("Hello, world!")).build();
final byte[] result2 = layout.toByteArray(event2);
assertEquals("[org.apache.logging.log4j.core.layout.PatternLayoutTest][Hello, world!]", new String(result2));
}
@Test
public void testLevelMapWithLength() {
final Message msg = new SimpleMessage("Hello");
LogEvent event = Log4jLogEvent.newBuilder() //
.setLoggerName("MyLogger") //
.setLevel(Level.DEBUG) //
.setMessage(msg).build();
final StringBuilder sb = new StringBuilder();
LevelPatternConverter converter = LevelPatternConverter.newInstance(null);
converter.format(event, sb);
assertEquals(Level.DEBUG.toString(), sb.toString());
final String[] opts = new String[] { "WARN=Warning, length=2" };
converter = LevelPatternConverter.newInstance(opts);
sb.setLength(0);
converter.format(event, sb);
assertEquals("DE", sb.toString());
event = Log4jLogEvent.newBuilder() //
.setLoggerName("MyLogger") //
.setLevel(Level.WARN) //
.setMessage(msg).build();
sb.setLength(0);
converter.format(event, sb);
assertEquals("Warning", sb.toString());
}
@Test
public void defaultIsAdd() {
final MapRewritePolicy addPolicy = MapRewritePolicy.createPolicy(null, rewrite);
LogEvent rewritten = addPolicy.rewrite(logEvent0);
compareLogEvents(logEvent0, rewritten);
assertEquals("Simple log message changed", logEvent0.getMessage(), rewritten.getMessage());
rewritten = addPolicy.rewrite(logEvent1);
compareLogEvents(logEvent1, rewritten);
checkAdded(((StringMapMessage)rewritten.getMessage()).getData());
rewritten = addPolicy.rewrite(logEvent2);
compareLogEvents(logEvent2, rewritten);
checkAdded(((StructuredDataMessage)rewritten.getMessage()).getData());
rewritten = addPolicy.rewrite(logEvent3);
compareLogEvents(logEvent3, rewritten);
checkAdded(((StringMapMessage)rewritten.getMessage()).getData());
}
@Test
public void shouldNotAddExceptionToFullMessage() throws InterruptedException {
// given
final GelfAppender gelfAppender = createGelfAppender(true, true);
final LogEvent event = createLogEventMock();
given(event.getThrown()).willReturn(new RuntimeException("Outer Exception", new Exception("Inner Exception")));
// when
gelfAppender.append(event);
// then
ArgumentCaptor<GelfMessage> gelfMessageCaptor = ArgumentCaptor.forClass(GelfMessage.class);
verify(mockedGelfTransport).trySend(gelfMessageCaptor.capture());
final String fullMessage = gelfMessageCaptor.getValue().getFullMessage();
assertThat(fullMessage, is("Some Message"));
}
@Test
public void testConverterWithKeysAndPrefix() {
final Message msg = new SimpleMessage("Hello");
final String [] options = new String[] {"object, subject"};
final MdcPatternConverter converter = MdcPatternConverter.newInstance(options);
final LogEvent event = Log4jLogEvent.newBuilder() //
.setLoggerName("MyLogger") //
.setLevel(Level.DEBUG) //
.setMessage(msg) //
.build();
final StringBuilder sb = new StringBuilder();
sb.append("prefix ");
converter.format(event, sb);
final String str = sb.toString();
final String expected = "prefix {object=Log4j, subject=I}";
assertEquals(expected, str);
}
public byte[] toByteArray(final LogEvent event) {
if (event.getMessage().getParameters().length != 1
|| !(event.getMessage().getParameters()[0] instanceof StructuredLogMessage)) {
throw new IllegalArgumentException(
"LogEvent must contain a single parameter of type StructuredLogMessage");
}
final StructuredLogMessage schemaAndValue
= (StructuredLogMessage) event.getMessage().getParameters()[0];
final Struct logRecord = logRecordStructBuilderFactory.get()
.withLoggerName(event.getLoggerName())
.withLevel(event.getLevel().name())
.withTimeMs(event.getTimeMillis())
.withMessageSchemaAndValue(schemaAndValue.getMessage())
.build();
return serializer.apply(logRecord);
}
@Test
public void shouldNotAppendExceptionInformationIfNotRequested() throws InterruptedException {
// given
final GelfAppender gelfAppender = createGelfAppender(false, false);
final LogEvent event = createLogEventMock();
given(event.getThrown()).willReturn(new RuntimeException("Outer Exception", new Exception("Inner Exception")));
// when
gelfAppender.append(event);
// then
ArgumentCaptor<GelfMessage> gelfMessageCaptor = ArgumentCaptor.forClass(GelfMessage.class);
verify(mockedGelfTransport).trySend(gelfMessageCaptor.capture());
final Object exceptionMessage = gelfMessageCaptor.getValue()
.getAdditionalFields()
.get("exceptionMessage");
final Object exceptionClass = gelfMessageCaptor.getValue()
.getAdditionalFields()
.get("exceptionClass");
final Object exceptionStackTrace = gelfMessageCaptor.getValue()
.getAdditionalFields()
.get("exceptionStackTrace");
assertThat(exceptionMessage, nullValue());
assertThat(exceptionClass, nullValue());
assertThat(exceptionStackTrace, nullValue());
}
@Test
public void testAppend_Simple() {
SystemdJournalAppender journalAppender = new SystemdJournalAppender("Journal", null, null, false, journalLibrary,
false, false, false, false, false, false, null, null, null);
when(message.getFormattedMessage()).thenReturn("some message");
LogEvent event = new Log4jLogEvent.Builder().setMessage(message).setLevel(Level.INFO).build();
journalAppender.append(event);
List<Object> expectedArgs = new ArrayList<>();
expectedArgs.add("some message");
expectedArgs.add("PRIORITY=%d");
expectedArgs.add(6);
expectedArgs.add(null);
verify(journalLibrary).sd_journal_send("MESSAGE=%s", expectedArgs.toArray());
}
@Test
public void testConverterFullSingle() {
ThreadContext.clearMap();
ThreadContext.put("foo", "bar");
final Message msg = new SimpleMessage("Hello");
final MdcPatternConverter converter = MdcPatternConverter.newInstance(null);
final LogEvent event = Log4jLogEvent.newBuilder() //
.setLoggerName("MyLogger") //
.setLevel(Level.DEBUG) //
.setMessage(msg) //
.build();
final StringBuilder sb = new StringBuilder();
converter.format(event, sb);
final String str = sb.toString();
final String expected = "{foo=bar}";
assertTrue("Incorrect result. Expected " + expected + ", actual " + str, str.equals(expected));
}
private void test_lineSeparator_suffix(
final LogEvent logEvent,
final boolean prettyPrintEnabled) {
// Create the layout.
final JsonTemplateLayout layout = JsonTemplateLayout
.newBuilder()
.setConfiguration(CONFIGURATION)
.setEventTemplateUri("classpath:LogstashJsonEventLayoutV1.json")
.build();
// Check the serialized event.
final String serializedLogEvent = layout.toSerializable(logEvent);
final String assertionCaption = String.format("testing lineSeperator (prettyPrintEnabled=%s)", prettyPrintEnabled);
assertThat(serializedLogEvent).as(assertionCaption).endsWith("}" + System.lineSeparator());
}
/**
* {@inheritDoc}
*/
@Override
public void format(final LogEvent event, final StringBuilder toAppendTo) {
int start = 0;
int end = 0;
if (!noAnsi) { // use ANSI: set prefix
start = toAppendTo.length();
toAppendTo.append(style);
end = toAppendTo.length();
}
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = patternFormatters.size(); i < size; i++) {
patternFormatters.get(i).format(event, toAppendTo);
}
// if we use ANSI we need to add the postfix or erase the unnecessary prefix
if (!noAnsi) {
if (toAppendTo.length() == end) {
toAppendTo.setLength(start); // erase prefix
} else {
toAppendTo.append(defaultStyle); // add postfix
}
}
}
@Test
public void testAppendToQueue() throws Exception {
final JmsAppender appender = (JmsAppender) ctx.getRequiredAppender("JmsAppender");
final LogEvent event = createLogEvent();
appender.append(event);
then(session).should().createTextMessage(eq(LOG_MESSAGE));
then(textMessage).should().setJMSTimestamp(anyLong());
then(messageProducer).should().send(textMessage);
appender.stop();
then(session).should().close();
then(connection).should().close();
}
/**
* Formats a {@link org.apache.logging.log4j.core.LogEvent}.
*
* @param event The LogEvent.
* @return The XML representation of the LogEvent.
*/
@Override
public String toSerializable(final LogEvent event) {
String loggerName = event.getLoggerName();
String level = event.getLevel().toString();
String message = event.getMessage().getFormattedMessage();
if (!message.startsWith("{") && !message.startsWith("[")) {
message = "\"" + message + "\"";
}
String threadName = event.getThreadName();
Date timeStamp = new Date(event.getTimeMillis());
String context = Context.toJSON();
Throwable throwable = event.getThrown();
String exception = "";
if (throwable != null) {
exception = ",\"exception\":{\"message\":\"";
String exceptionMessage = throwable.getMessage() != null ? throwable.getMessage() : "";
//need to be careful here, sanitizing, since the message may already contain a chunk of JSON, so escaping or cleaning double quotes is not prudent:)
exception += sanitize(exceptionMessage, false, '\n', '\t', '\r') + "\",\"stacktrace\":\"" + escapeControlChars(Util.getStackTraceString(throwable)) + "\"}";
}
String contextJson = context != null ? ",\"context\":" + context : "";
String timestampString = this.simpleDateFormat == null ? timeStamp.toString() : simpleDateFormat.format(timeStamp);
return "{\"level\":\"" + level + "\",\"timestamp\":\"" + timestampString
+ "\",\"thread\":\"" + threadName + "\",\"logger\":\"" + loggerName + "\",\"message\":"
+ message + contextJson + exception + "}" + System.getProperty("line.separator");
}
private void testMessage(final 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));
}
}
@Override
public StringBuilder toSerializable(final LogEvent event, final StringBuilder buffer) {
final PatternFormatter[] formatters = patternSelector.getFormatters(event);
final int len = formatters.length;
for (int i = 0; i < len; i++) {
formatters[i].format(event, buffer);
}
if (replace != null) { // creates temporary objects
String str = buffer.toString();
str = replace.format(str);
buffer.setLength(0);
buffer.append(str);
}
return buffer;
}
@Override
public LogEvent parseFrom(final String input) throws ParseException {
try {
return objectReader.readValue(input);
} catch (final IOException e) {
throw new ParseException(e);
}
}
/**
* Rewrite the event.
* @param source a logging event that may be returned or
* used to create a new logging event.
* @return The LogEvent after rewriting.
*/
@Override
public LogEvent rewrite(final LogEvent source) {
final Message msg = source.getMessage();
if (msg == null || !(msg instanceof MapMessage)) {
return source;
}
@SuppressWarnings("unchecked")
final MapMessage<?, Object> mapMsg = (MapMessage<?, Object>) msg;
final Map<String, Object> newMap = new HashMap<>(mapMsg.getData());
switch (mode) {
case Add: {
newMap.putAll(map);
break;
}
default: {
for (final Map.Entry<String, Object> entry : map.entrySet()) {
if (newMap.containsKey(entry.getKey())) {
newMap.put(entry.getKey(), entry.getValue());
}
}
}
}
final Message message = mapMsg.newInstance(newMap);
return new Log4jLogEvent.Builder(source).setMessage(message).build();
}
@Test
public void test_serialized_event() throws IOException {
final String lookupTestKey = "lookup_test_key";
final String lookupTestVal =
String.format("lookup_test_value_%d", (int) (1000 * Math.random()));
System.setProperty(lookupTestKey, lookupTestVal);
for (final LogEvent logEvent : LOG_EVENTS) {
checkLogEvent(logEvent, lookupTestKey, lookupTestVal);
}
}
@Test
public void testConverterAppendsLogEventNanoTimeToStringBuilder() {
final LogEvent event = Log4jLogEvent.newBuilder() //
.setThreadId(1).build();
final StringBuilder sb = new StringBuilder();
final ThreadIdPatternConverter converter = ThreadIdPatternConverter.newInstance(null);
converter.format(event, sb);
assertEquals("1", sb.toString());
}
private boolean handleInterruptedException(final LogEvent memento) {
final boolean appendSuccessful = queue.offer(memento);
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();
return appendSuccessful;
}
private static <K> Map<K, Object> appendAndCollect(
final List<LogEvent> logEvents,
final Layout<?> layout,
final int port,
final Function<Map<String, Object>, K> keyMapper,
final Set<String> excludedKeys) throws IOException {
try (final RestHighLevelClient client = createClient()) {
final Appender appender = createStartedAppender(layout, port);
try {
// Append the event.
LOGGER.info("appending events");
logEvents.forEach(appender::append);
LOGGER.info("completed appending events");
// Wait the message to arrive.
Awaitility
.await()
.atMost(Duration.ofSeconds(60))
.pollDelay(Duration.ofSeconds(2))
.until(() -> queryDocumentCount(client) == LOG_EVENT_COUNT);
// Retrieve the persisted messages.
return queryDocuments(client)
.stream()
.collect(Collectors.toMap(
keyMapper,
(final Map<String, Object> source) -> {
excludedKeys.forEach(source::remove);
return source;
}));
} finally {
appender.stop();
}
}
}
protected String serializeToString(final Serializer serializer) {
if (serializer == null) {
return null;
}
final LoggerConfig rootLogger = getConfiguration().getRootLogger();
// Using "" for the FQCN, does it matter?
final LogEvent logEvent = getLogEventFactory().createEvent(rootLogger.getName(), null, Strings.EMPTY,
rootLogger.getLevel(), null, null, null);
return serializer.toSerializable(logEvent);
}
/**
* {@inheritDoc}
*/
@Override
public String getStyleClass(final Object e) {
if (e instanceof LogEvent) {
return "level " + ((LogEvent) e).getLevel().name().toLowerCase(Locale.ENGLISH);
}
return "level";
}
/**
* Looks up the value of the JNDI resource.
* @param event The current LogEvent (is ignored by this StrLookup).
* @param key the JNDI resource name to be looked up, may be null
* @return The String value of the JNDI resource.
*/
@Override
public String lookup(final LogEvent event, final String key) {
if (key == null) {
return null;
}
final String jndiName = convertJndiName(key);
try (final JndiManager jndiManager = JndiManager.getDefaultManager()) {
return Objects.toString(jndiManager.lookup(jndiName), null);
} catch (final NamingException e) {
LOGGER.warn(LOOKUP, "Error looking up JNDI resource [{}].", jndiName, e);
return null;
}
}
public LogSearchJsonLayout(Charset charset) {
super(charset);
SimpleModule module = new SimpleModule();
module.addSerializer(LogEvent.class, new LogEventSerializer());
module.addSerializer(ReadOnlyStringMap.class, new ContextDataSerializer() {
});
objectMapper = new ObjectMapper();
objectMapper.registerModule(module);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
}
private String getLogMessage(LogEvent logEvent) {
String logMessage = logEvent.getMessage() != null ? logEvent.getMessage().getFormattedMessage() : "";
if (logEvent.getThrown() != null) {
logMessage += NEW_LINE;
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
logEvent.getThrown().printStackTrace(pw);
logMessage += sw.toString();
}
return logMessage;
}
@Test
public void messageOnlyItemSourceLayout() {
// given
ItemAppenderFactory factory = new ItemAppenderFactory();
String formattedIndexName = UUID.randomUUID().toString();
BatchDelivery batchDelivery = mock(BatchDelivery.class);
ItemSourceLayout itemSourceLayout = spy(new TestItemSourceLayout());
ItemSourceAppender itemAppender =
factory.createInstance(true, itemSourceLayout, batchDelivery);
String expectedMessage = UUID.randomUUID().toString();
ItemSource itemSource = new StringItemSource(expectedMessage);
when(itemSourceLayout.serialize(any(Message.class))).thenReturn(itemSource);
LogEvent logEvent = mock(LogEvent.class);
Message message = mock(Message.class);
when(logEvent.getMessage()).thenReturn(message);
// when
itemAppender.append(formattedIndexName, logEvent);
// then
assertEquals(ItemSourceAppender.class, itemAppender.getClass());
verify(itemSourceLayout).serialize(messageCaptor.capture());
assertEquals(message, messageCaptor.getValue());
verify(batchDelivery).add(indexNameCaptor.capture(), itemSourceCaptor.capture());
assertEquals(formattedIndexName, indexNameCaptor.getValue());
assertEquals(expectedMessage, itemSourceCaptor.getValue().getSource());
}
/**
* {@inheritDoc}
*/
@Override
public void format(final LogEvent event, final StringBuilder toAppendTo) {
final int start = toAppendTo.length();
for (int i = 0; i < formatters.size(); i++) {
formatters.get(i).format(event, toAppendTo);
}
escapeFormat.escape(toAppendTo, start);
}