org.apache.logging.log4j.core.layout.GelfLayoutTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.logging.log4j.core.layout.GelfLayoutTest.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */
package org.apache.logging.log4j.core.layout;

import com.fasterxml.jackson.core.io.JsonStringEncoder;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.*;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.layout.GelfLayout.CompressionType;
import org.apache.logging.log4j.core.lookup.JavaLookup;
import org.apache.logging.log4j.core.util.KeyValuePair;
import org.apache.logging.log4j.core.util.NetUtils;
import org.apache.logging.log4j.junit.ThreadContextRule;
import org.apache.logging.log4j.test.appender.EncodingListAppender;
import org.apache.logging.log4j.test.appender.ListAppender;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;

import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
import static org.junit.Assert.assertEquals;

public class GelfLayoutTest {

    static ConfigurationFactory configFactory = new BasicConfigurationFactory();

    private static final String HOSTNAME = "TheHost";
    private static final String KEY1 = "Key1";
    private static final String KEY2 = "Key2";
    private static final String LINE1 = "empty mdc";
    private static final String LINE2 = "filled mdc";
    private static final String LINE3 = "error message";
    private static final String MDCKEY1 = "MdcKey1";
    private static final String MDCKEY2 = "MdcKey2";
    private static final String MDCVALUE1 = "MdcValue1";
    private static final String MDCVALUE2 = "MdcValue2";
    private static final String VALUE1 = "Value1";

    @Rule
    public final ThreadContextRule threadContextRule = new ThreadContextRule();

    @AfterClass
    public static void cleanupClass() {
        ConfigurationFactory.removeConfigurationFactory(configFactory);
    }

    @BeforeClass
    public static void setupClass() {
        ConfigurationFactory.setConfigurationFactory(configFactory);
        final LoggerContext ctx = LoggerContext.getContext();
        ctx.reconfigure();
    }

    LoggerContext ctx = LoggerContext.getContext();

    Logger root = ctx.getRootLogger();

    private void testCompressedLayout(final CompressionType compressionType, final boolean includeStacktrace,
            final boolean includeThreadContext, String host, final boolean includeNullDelimiter)
            throws IOException {
        for (final Appender appender : root.getAppenders().values()) {
            root.removeAppender(appender);
        }
        // set up appenders
        final GelfLayout layout = GelfLayout.newBuilder().setConfiguration(ctx.getConfiguration()).setHost(host)
                .setAdditionalFields(new KeyValuePair[] { new KeyValuePair(KEY1, VALUE1),
                        new KeyValuePair(KEY2, "${java:runtime}"), })
                .setCompressionType(compressionType).setCompressionThreshold(1024)
                .setIncludeStacktrace(includeStacktrace).setIncludeThreadContext(includeThreadContext)
                .setIncludeNullDelimiter(includeNullDelimiter).build();
        final ListAppender eventAppender = new ListAppender("Events", null, null, true, false);
        final ListAppender rawAppender = new ListAppender("Raw", null, layout, true, true);
        final ListAppender formattedAppender = new ListAppender("Formatted", null, layout, true, false);
        final EncodingListAppender encodedAppender = new EncodingListAppender("Encoded", null, layout, false, true);
        eventAppender.start();
        rawAppender.start();
        formattedAppender.start();
        encodedAppender.start();

        if (host == null)
            host = NetUtils.getLocalHostname();

        final JavaLookup javaLookup = new JavaLookup();

        // set appenders on root and set level to debug
        root.addAppender(eventAppender);
        root.addAppender(rawAppender);
        root.addAppender(formattedAppender);
        root.addAppender(encodedAppender);
        root.setLevel(Level.DEBUG);

        root.debug(LINE1);

        ThreadContext.put(MDCKEY1, MDCVALUE1);
        ThreadContext.put(MDCKEY2, MDCVALUE2);

        root.info(LINE2);

        final Exception exception = new RuntimeException("some error");
        root.error(LINE3, exception);

        formattedAppender.stop();

        final List<LogEvent> events = eventAppender.getEvents();
        final List<byte[]> raw = rawAppender.getData();
        final List<String> messages = formattedAppender.getMessages();
        final List<byte[]> raw2 = encodedAppender.getData();
        final String threadName = Thread.currentThread().getName();

        //@formatter:off
        assertJsonEquals("{" + "\"version\": \"1.1\"," + "\"host\": \"" + host + "\"," + "\"timestamp\": "
                + GelfLayout.formatTimestamp(events.get(0).getTimeMillis()) + "," + "\"level\": 7,"
                + "\"_thread\": \"" + threadName + "\"," + "\"_logger\": \"\"," + "\"short_message\": \"" + LINE1
                + "\"," + "\"_" + KEY1 + "\": \"" + VALUE1 + "\"," + "\"_" + KEY2 + "\": \""
                + javaLookup.getRuntime() + "\"" + "}", messages.get(0));

        assertJsonEquals("{" + "\"version\": \"1.1\"," + "\"host\": \"" + host + "\"," + "\"timestamp\": "
                + GelfLayout.formatTimestamp(events.get(1).getTimeMillis()) + "," + "\"level\": 6,"
                + "\"_thread\": \"" + threadName + "\"," + "\"_logger\": \"\"," + "\"short_message\": \"" + LINE2
                + "\","
                + (includeThreadContext
                        ? "\"_" + MDCKEY1 + "\": \"" + MDCVALUE1 + "\"," + "\"_" + MDCKEY2 + "\": \"" + MDCVALUE2
                                + "\","
                        : "")
                + "\"_" + KEY1 + "\": \"" + VALUE1 + "\"," + "\"_" + KEY2 + "\": \"" + javaLookup.getRuntime()
                + "\"" + "}", messages.get(1));
        //@formatter:on
        final byte[] compressed = raw.get(2);
        final byte[] compressed2 = raw2.get(2);
        final ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
        final ByteArrayInputStream bais2 = new ByteArrayInputStream(compressed2);
        InputStream inflaterStream;
        InputStream inflaterStream2;
        switch (compressionType) {
        case GZIP:
            inflaterStream = new GZIPInputStream(bais);
            inflaterStream2 = new GZIPInputStream(bais2);
            break;
        case ZLIB:
            inflaterStream = new InflaterInputStream(bais);
            inflaterStream2 = new InflaterInputStream(bais2);
            break;
        case OFF:
            inflaterStream = bais;
            inflaterStream2 = bais2;
            break;
        default:
            throw new IllegalStateException("Missing test case clause");
        }
        final byte[] uncompressed = IOUtils.toByteArray(inflaterStream);
        final byte[] uncompressed2 = IOUtils.toByteArray(inflaterStream2);
        inflaterStream.close();
        inflaterStream2.close();
        final String uncompressedString = new String(uncompressed, layout.getCharset());
        final String uncompressedString2 = new String(uncompressed2, layout.getCharset());
        //@formatter:off
        final String expected = "{" + "\"version\": \"1.1\"," + "\"host\": \"" + host + "\"," + "\"timestamp\": "
                + GelfLayout.formatTimestamp(events.get(2).getTimeMillis()) + "," + "\"level\": 3,"
                + "\"_thread\": \"" + threadName + "\"," + "\"_logger\": \"\"," + "\"short_message\": \"" + LINE3
                + "\"," + "\"full_message\": \""
                + String.valueOf(JsonStringEncoder.getInstance()
                        .quoteAsString(includeStacktrace ? GelfLayout.formatThrowable(exception).toString()
                                : exception.toString()))
                + "\","
                + (includeThreadContext
                        ? "\"_" + MDCKEY1 + "\": \"" + MDCVALUE1 + "\"," + "\"_" + MDCKEY2 + "\": \"" + MDCVALUE2
                                + "\","
                        : "")
                + "\"_" + KEY1 + "\": \"" + VALUE1 + "\"," + "\"_" + KEY2 + "\": \"" + javaLookup.getRuntime()
                + "\"" + "}";
        //@formatter:on
        assertJsonEquals(expected, uncompressedString);
        assertJsonEquals(expected, uncompressedString2);
    }

    @Test
    public void testLayoutGzipCompression() throws Exception {
        testCompressedLayout(CompressionType.GZIP, true, true, HOSTNAME, false);
    }

    @Test
    public void testLayoutNoCompression() throws Exception {
        testCompressedLayout(CompressionType.OFF, true, true, HOSTNAME, false);
    }

    @Test
    public void testLayoutZlibCompression() throws Exception {
        testCompressedLayout(CompressionType.ZLIB, true, true, HOSTNAME, false);
    }

    @Test
    public void testLayoutNoStacktrace() throws Exception {
        testCompressedLayout(CompressionType.OFF, false, true, HOSTNAME, false);
    }

    @Test
    public void testLayoutNoThreadContext() throws Exception {
        testCompressedLayout(CompressionType.OFF, true, false, HOSTNAME, false);
    }

    @Test
    public void testLayoutNoHost() throws Exception {
        testCompressedLayout(CompressionType.OFF, true, true, null, false);
    }

    @Test
    public void testLayoutNullDelimiter() throws Exception {
        testCompressedLayout(CompressionType.OFF, false, true, HOSTNAME, true);
    }

    @Test
    public void testFormatTimestamp() {
        assertEquals("0", GelfLayout.formatTimestamp(0L).toString());
        assertEquals("1.000", GelfLayout.formatTimestamp(1000L).toString());
        assertEquals("1.001", GelfLayout.formatTimestamp(1001L).toString());
        assertEquals("1.010", GelfLayout.formatTimestamp(1010L).toString());
        assertEquals("1.100", GelfLayout.formatTimestamp(1100L).toString());
        assertEquals("1458741206.653", GelfLayout.formatTimestamp(1458741206653L).toString());
        assertEquals("9223372036854775.807", GelfLayout.formatTimestamp(Long.MAX_VALUE).toString());
    }
}