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

com.quartzdesk.api.agent.log.log4j.Log4jInterceptionAppender Maven / Gradle / Ivy

Go to download

QuartzDesk Public API library required for QuartzDesk Standard and Enterprise edition installations. This library must be placed on the classpath of the Quartz scheduler based application that is managed by QuartzDesk. It is important that this library is loaded by the same classloader that loads the Quartz scheduler API used by the application.

The newest version!
/*
 * Copyright (c) 2013-2024 QuartzDesk.com. All Rights Reserved.
 * QuartzDesk.com PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.quartzdesk.api.agent.log.log4j;

import com.quartzdesk.api.agent.log.LoggingInterceptorWrapper;
import com.quartzdesk.api.agent.log.LoggingInterceptorWrapperException;
import com.quartzdesk.api.agent.log.WorkerThreadLoggingInterceptorRegistry;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;

/**
 * Implementation of a Log4J appender that passes the log events to the QuartzDesk JVM agent that intercepts log
 * messages produced by executed jobs.
 * 
 * ==== Example log4j.xml ====
 * ...
 *
 * <!--
 *   Appender that passes all received log events to the QuartzDesk agent to intercept
 *   log events produced by executed Quartz jobs.
 * -->
 * <appender name="QUARTZDESK_JVM_AGENT" class="com.quartzdesk.api.agent.log.log4j.Log4jInterceptionAppender">
 *   <param name="threshold" value="DEBUG"/>
 *
 *   <layout class="org.apache.log4j.EnhancedPatternLayout">
 *     <param name="conversionPattern" value="[%d{ISO8601}] %!.1p [%t] [%C:%L] - %m%n"/>
 *   </layout>
 * </appender>
 *
 * ...
 *
 * <root>
 *   <priority value="WARN"/>
 *   ...
 *   <appender-ref ref="QUARTZDESK_JVM_AGENT"/>
 * </root>
 * 
* * This implementation is not statically bound to the QuartzDesk JVM Agent API, nor to the domain object API. * Therefore it is safe to use this appender on JVMs running without an installed QuartzDesk JVM Agent. * * @version $Id:$ * @see LoggingInterceptorWrapper */ public class Log4jInterceptionAppender extends AppenderSkeleton { private LoggingInterceptorWrapper loggingInterceptor; /** * Creates a new {@link Log4jInterceptionAppender} instance. */ public Log4jInterceptionAppender() { setName( "QuartzDesk-" + Log4jInterceptionAppender.class.getSimpleName() ); //LogLog.warn( "Starting " + ReflectiveLog4jInterceptionAppender.class.getName() + ", name=" + getName() ); try { loggingInterceptor = LoggingInterceptorWrapper.create(); } catch ( LoggingInterceptorWrapperException e ) { // LogLog.warn( "Cannot initialize " + LoggingInterceptorWrapper.class.getName() + ". Appender " + getName() + // " will be disabled.", e ); LogLog.warn( "Cannot initialize " + LoggingInterceptorWrapper.class.getName() + ". Appender " + getName() + " will be disabled. Cause: " + e.getMessage() ); } } /** * Stops this appender. */ @Override public void close() { loggingInterceptor = null; } @Override public boolean requiresLayout() { return true; } /** * If the QuartzDesk agent's logging interceptor wishes to intercept the specified logging event, then this method * formats the log event using the provided pattern layout and passes the result to the logging interceptor. * * @param event a logging event object. */ @Override protected void append( LoggingEvent event ) { /* * The LoggingEvent object does not contain the emitter's thread ID so we assume the emitter * is the current thread. */ Long threadId = Thread.currentThread().getId(); /* * The emitter thread can be a worker thread (a thread created / used by the main job thread). */ Long jobThreadId = WorkerThreadLoggingInterceptorRegistry.INSTANCE.getJobThreadForWorkerThread( threadId ); if ( jobThreadId != null ) { threadId = jobThreadId; } if ( loggingInterceptor != null && loggingInterceptor.isIntercepting( threadId ) ) { LoggingInterceptorWrapper.MessagePriority priority = convertLevel2Priority( event.getLevel() ); StringBuilder msg = new StringBuilder( getLayout().format( event ) ); /* * If layout ignores throwable (pattern does not contain %throwable macros for custom exception * formatting), then dump the exception as text. */ if ( layout.ignoresThrowable() ) { String[] traceLines = event.getThrowableStrRep(); if ( traceLines != null ) { for ( String traceLine : traceLines ) { msg.append( traceLine ); msg.append( Layout.LINE_SEP ); } } } loggingInterceptor.intercept( threadId, priority, msg.toString() ); } } /** * Returns the {@link LoggingInterceptorWrapper.MessagePriority} for the specified Log4J level. * * @param level a log4j level. * @return the {@link LoggingInterceptorWrapper.MessagePriority} for the specified Log4J level. */ protected LoggingInterceptorWrapper.MessagePriority convertLevel2Priority( Level level ) { if ( level.equals( Level.TRACE ) ) return LoggingInterceptorWrapper.MessagePriority.TRACE; else if ( level.equals( Level.DEBUG ) ) return LoggingInterceptorWrapper.MessagePriority.DEBUG; else if ( level.equals( Level.INFO ) ) return LoggingInterceptorWrapper.MessagePriority.INFO; else if ( level.equals( Level.WARN ) ) return LoggingInterceptorWrapper.MessagePriority.WARN; else if ( level.equals( Level.ERROR ) ) return LoggingInterceptorWrapper.MessagePriority.ERROR; else if ( level.equals( Level.FATAL ) ) // FATAL mapped to ERROR return LoggingInterceptorWrapper.MessagePriority.ERROR; else { LogLog.warn( "Cannot map logging level: " + level + ". Using default message priority: " + LoggingInterceptorWrapper.DEFAULT_MESSAGE_PRIORITY ); return LoggingInterceptorWrapper.DEFAULT_MESSAGE_PRIORITY; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy