001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.core.async; 018 019import org.apache.logging.log4j.Level; 020import org.apache.logging.log4j.Marker; 021import org.apache.logging.log4j.ThreadContext.ContextStack; 022import org.apache.logging.log4j.core.ContextDataInjector; 023import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory; 024import org.apache.logging.log4j.core.util.Clock; 025import org.apache.logging.log4j.core.util.NanoClock; 026import org.apache.logging.log4j.util.StringMap; 027import org.apache.logging.log4j.message.Message; 028 029import com.lmax.disruptor.EventTranslator; 030 031/** 032 * This class is responsible for writing elements that make up a log event into 033 * the ringbuffer {@code RingBufferLogEvent}. After this translator populated 034 * the ringbuffer event, the disruptor will update the sequence number so that 035 * the event can be consumed by another thread. 036 */ 037public class RingBufferLogEventTranslator implements 038 EventTranslator<RingBufferLogEvent> { 039 040 private static final ContextDataInjector INJECTOR = ContextDataInjectorFactory.createInjector(); 041 private AsyncLogger asyncLogger; 042 String loggerName; 043 protected Marker marker; 044 protected String fqcn; 045 protected Level level; 046 protected Message message; 047 protected Throwable thrown; 048 private ContextStack contextStack; 049 private long threadId = Thread.currentThread().getId(); 050 private String threadName = Thread.currentThread().getName(); 051 private int threadPriority = Thread.currentThread().getPriority(); 052 private StackTraceElement location; 053 private Clock clock; 054 private NanoClock nanoClock; 055 056 // @Override 057 @Override 058 public void translateTo(final RingBufferLogEvent event, final long sequence) { 059 try { 060 event.setValues(asyncLogger, loggerName, marker, fqcn, level, message, thrown, 061 // config properties are taken care of in the EventHandler thread 062 // in the AsyncLogger#actualAsyncLog method 063 INJECTOR.injectContextData(null, (StringMap) event.getContextData()), contextStack, 064 threadId, threadName, threadPriority, location, clock, nanoClock); 065 } finally { 066 clear(); // clear the translator 067 } 068 } 069 070 /** 071 * Release references held by this object to allow objects to be garbage-collected. 072 */ 073 void clear() { 074 setBasicValues(null, // asyncLogger 075 null, // loggerName 076 null, // marker 077 null, // fqcn 078 null, // level 079 null, // data 080 null, // t 081 null, // contextStack 082 null, // location 083 null, // clock 084 null // nanoClock 085 ); 086 } 087 088 public void setBasicValues(final AsyncLogger anAsyncLogger, final String aLoggerName, final Marker aMarker, 089 final String theFqcn, final Level aLevel, final Message msg, final Throwable aThrowable, 090 final ContextStack aContextStack, final StackTraceElement aLocation, 091 final Clock aClock, final NanoClock aNanoClock) { 092 this.asyncLogger = anAsyncLogger; 093 this.loggerName = aLoggerName; 094 this.marker = aMarker; 095 this.fqcn = theFqcn; 096 this.level = aLevel; 097 this.message = msg; 098 this.thrown = aThrowable; 099 this.contextStack = aContextStack; 100 this.location = aLocation; 101 this.clock = aClock; 102 this.nanoClock = aNanoClock; 103 } 104 105 public void updateThreadValues() { 106 final Thread currentThread = Thread.currentThread(); 107 this.threadId = currentThread.getId(); 108 this.threadName = currentThread.getName(); 109 this.threadPriority = currentThread.getPriority(); 110 } 111}