All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.logstash.logback.encoder.CompositeJsonEncoder Maven / Gradle / Ivy

Go to download

Provides logback encoders, layouts, and appenders to log in JSON and other formats supported by Jackson

There is a newer version: 8.0
Show newest version
/**
 * Licensed 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 net.logstash.logback.encoder;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;

import net.logstash.logback.composite.CompositeJsonFormatter;
import net.logstash.logback.composite.JsonProviders;
import net.logstash.logback.decorate.JsonFactoryDecorator;
import net.logstash.logback.decorate.JsonGeneratorDecorator;

import org.apache.commons.io.IOUtils;

import ch.qos.logback.core.encoder.Encoder;
import ch.qos.logback.core.encoder.EncoderBase;
import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
import ch.qos.logback.core.pattern.PatternLayoutBase;
import ch.qos.logback.core.spi.DeferredProcessingAware;

public abstract class CompositeJsonEncoder
        extends EncoderBase {
    
    private boolean immediateFlush = true;
    
    private Encoder prefix;
    private Encoder suffix;
    
    private final CompositeJsonFormatter formatter;
    
    private String lineSeparator = System.getProperty("line.separator");
    
    private Charset charset;
    
    public CompositeJsonEncoder() {
        super();
        this.formatter = createFormatter();
    }
    
    protected abstract CompositeJsonFormatter createFormatter();
    
    @Override
    public void init(OutputStream os) throws IOException {
        
        initWrapped(prefix, os);
        super.init(os);
        initWrapped(suffix, os);
        
    }

    private void initWrapped(Encoder wrapped, OutputStream os) throws IOException {
        if (wrapped != null) {
            wrapped.init(os);
        }
    }

    @Override
    public void doEncode(Event event) throws IOException {
        
        doEncodeWrapped(prefix, event);
        
        formatter.writeEventToOutputStream(event, outputStream);

        doEncodeWrapped(suffix, event);
        
        if (this.lineSeparator != null) {
            IOUtils.write(this.lineSeparator, outputStream, charset);
        }
        
        if (immediateFlush) {
            outputStream.flush();
        }
        
    }

    private void doEncodeWrapped(Encoder wrapped, Event event) throws IOException {
        if (wrapped != null) {
            wrapped.doEncode(event);
        }
    }
    
    @Override
    public void start() {
        super.start();
        formatter.setContext(getContext());
        formatter.start();
        charset = Charset.forName(formatter.getEncoding());
        startWrapped(prefix);
        startWrapped(suffix);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void startWrapped(Encoder wrapped) {
        if (wrapped instanceof LayoutWrappingEncoder) {
            /*
             * Convenience hack to ensure the same charset is used in most cases.
             * 
             * The charset for other encoders must be configured
             * on the wrapped encoder configuration.
             */
            LayoutWrappingEncoder layoutWrappedEncoder = (LayoutWrappingEncoder) wrapped;
            layoutWrappedEncoder.setCharset(charset);
            
            if (layoutWrappedEncoder.getLayout() instanceof PatternLayoutBase) {
                /*
                 * Don't ensure exception output (for ILoggingEvents)
                 * or line separation (for IAccessEvents) 
                 */
                PatternLayoutBase layout = (PatternLayoutBase) layoutWrappedEncoder.getLayout();
                layout.setPostCompileProcessor(null);
                /*
                 * The pattern will be re-parsed during start.
                 * Needed so that the pattern is re-parsed without
                 * the postCompileProcessor.
                 */
                layout.start();
            }
        }
        
        if (wrapped != null && !wrapped.isStarted()) {
            wrapped.start();
        }
    }
    
    @Override
    public void stop() {
        super.stop();
        formatter.stop();
        stopWrapped(prefix);
        stopWrapped(suffix);
    }
    
    private void stopWrapped(Encoder wrapped) {
        if (wrapped != null && !wrapped.isStarted()) {
            wrapped.stop();
        }
    }
    
    @Override
    public void close() throws IOException {
        closeWrapped(prefix);
        closeWrapped(suffix);
    }
    
    private void closeWrapped(Encoder wrapped) throws IOException {
        if (wrapped != null && !wrapped.isStarted()) {
            wrapped.close();
        }
    }
    
    public JsonProviders getProviders() {
        return formatter.getProviders();
    }

    public void setProviders(JsonProviders jsonProviders) {
        formatter.setProviders(jsonProviders);
    }
    
    public boolean isImmediateFlush() {
        return immediateFlush;
    }
    
    public void setImmediateFlush(boolean immediateFlush) {
        this.immediateFlush = immediateFlush;
    }
    
    public JsonFactoryDecorator getJsonFactoryDecorator() {
        return formatter.getJsonFactoryDecorator();
    }

    public void setJsonFactoryDecorator(JsonFactoryDecorator jsonFactoryDecorator) {
        formatter.setJsonFactoryDecorator(jsonFactoryDecorator);
    }

    public JsonGeneratorDecorator getJsonGeneratorDecorator() {
        return formatter.getJsonGeneratorDecorator();
    }
    
    public String getEncoding() {
        return formatter.getEncoding();
    }

    /**
     * The character encoding to use (default = "UTF-8").
     * Must an encoding supported by {@link com.fasterxml.jackson.core.JsonEncoding}
     */
    public void setEncoding(String encodingName) {
        formatter.setEncoding(encodingName);
    }

    public void setJsonGeneratorDecorator(JsonGeneratorDecorator jsonGeneratorDecorator) {
        formatter.setJsonGeneratorDecorator(jsonGeneratorDecorator);
    }
    
    public String getLineSeparator() {
        return lineSeparator;
    }
    
    /**
     * Sets which lineSeparator to use between events.
     * 

* * The following values have special meaning: *

    *
  • null or empty string = no new line.
  • *
  • "SYSTEM" = operating system new line (default).
  • *
  • "UNIX" = unix line ending (\n).
  • *
  • "WINDOWS" = windows line ending (\r\n).
  • *
*

* Any other value will be used as given as the lineSeparator. */ public void setLineSeparator(String lineSeparator) { this.lineSeparator = SeparatorParser.parseSeparator(lineSeparator); } protected CompositeJsonFormatter getFormatter() { return formatter; } public Encoder getPrefix() { return prefix; } public void setPrefix(Encoder prefix) { this.prefix = prefix; } public Encoder getSuffix() { return suffix; } public void setSuffix(Encoder suffix) { this.suffix = suffix; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy