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

org.daisy.pipeline.logging.JobLogFileAppender Maven / Gradle / Ivy

There is a newer version: 2.1.4
Show newest version
package org.daisy.pipeline.logging;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import ch.qos.logback.classic.ClassicConstants;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.sift.MDCBasedDiscriminator;
import ch.qos.logback.classic.sift.SiftingAppender;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.encoder.Encoder;
import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.spi.RuleStore;
import ch.qos.logback.core.sift.AppenderFactoryBase;
import ch.qos.logback.core.sift.SiftingJoranConfiguratorBase;
import ch.qos.logback.core.FileAppender;

import org.daisy.pipeline.job.JobURIUtils;

/**
 * Append to the detailed job log.
 *
 * Configure like this:
 *
 * <appender name="JOB_FILE" class="org.daisy.pipeline.logging.JobLogFileAppender">
 *   <encoder>
 *     <Pattern>%date [%-5level] %logger{36} - %msg%n</Pattern>
 *   </encoder>
 * </appender>
 */
public class JobLogFileAppender extends SiftingAppender {

	private MDCBasedDiscriminator jobDiscriminator;
	private Encoder encoder;
	private final static String DEFAULT_ENCODER_PATTERN = "%date [%-5level] %logger{36} - %msg%n";

	public void setEncoder(Encoder encoder) {
		this.encoder = encoder;
	}

	@Override
	public void start() {
		if (encoder != null) {
			if (!(encoder instanceof PatternLayoutEncoder))
				throw new RuntimeException(
					"encoder is expected to be of type PatternLayoutEncoder but got " + encoder.getClass());
		}
		jobDiscriminator = new MDCBasedDiscriminator();
		jobDiscriminator.setKey("jobid");
		jobDiscriminator.setDefaultValue("default");
		jobDiscriminator.start();
		setDiscriminator(jobDiscriminator);
		Map> appenders = new HashMap<>();
		setAppenderFactory(
			new AppenderFactoryBase(
				// simulate an empty  element
				Arrays.asList(new SaxEvent[]{null, null})) {
				public SiftingJoranConfiguratorBase getSiftingJoranConfigurator(
						String jobId) {
					return new SiftingJoranConfiguratorBase() {
						protected void addInstanceRules(RuleStore rs) {}
						public Appender getAppender() {
							if (appenders.containsKey(jobId))
								return appenders.get(jobId);
							else {
								FileAppender fileAppender = new FileAppender() {{
										this.name = "FILE-" + jobId;
										// FIXME: We know that the log file is stored in this location because
										// AbstractJobContext also calls JobURIUtils.getLogFile(). Still, it would be
										// nicer to use JobContext.getLogFile(). The problem with this however is that
										// we can not bind the JobManager OSGi service because we're in a fragment (not
										// a bundle).
										this.fileName = JobURIUtils.getLogFile(jobId).getAbsolutePath();
										this.append = false;
										this.encoder = new PatternLayoutEncoder() {{
											if (JobLogFileAppender.this.encoder != null) {
												PatternLayoutEncoder enc = (PatternLayoutEncoder)JobLogFileAppender.this.encoder;
												setPattern(enc.getPattern());
												outputPatternAsHeader = enc.isOutputPatternAsHeader();
												setCharset(enc.getCharset());
												setImmediateFlush(enc.isImmediateFlush());
											} else
												setPattern(DEFAULT_ENCODER_PATTERN);
										}};
									}
										@Override
										public void start() {
											encoder.start();
											super.start();
										}
										@Override
										public void stop() {
											encoder.stop();
											super.stop();
											appenders.remove(jobId);
										}
										@Override
										public void setContext(Context context) {
											encoder.setContext(context);
											super.setContext(context);
										}
									};
								fileAppender.setContext(getContext());
								fileAppender.start();
								appenders.put(jobId, fileAppender);
								return fileAppender;
							}
						}
					};
				}
			}
		);
		super.start();
	}

	@Override
	protected void append(ILoggingEvent event) {
		if (!isStarted()) {
			return;
		}
		String jobId = jobDiscriminator.getDiscriminatingValue(event);
		if (!"default".equals(jobId)) {
			super.append(event);
			// Force closing the logging file when we finish the job
			if (event.getMarker() == ClassicConstants.FINALIZE_SESSION_MARKER) {
				super.stop();
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy