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 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 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 066 clear(); // clear the translator 067 } 068 069 /** 070 * Release references held by this object to allow objects to be garbage-collected. 071 */ 072 private void clear() { 073 setBasicValues(null, // asyncLogger 074 null, // loggerName 075 null, // marker 076 null, // fqcn 077 null, // level 078 null, // data 079 null, // t 080 null, // contextStack 081 null, // location 082 null, // clock 083 null // nanoClock 084 ); 085 } 086 087 public void setBasicValues(final AsyncLogger anAsyncLogger, final String aLoggerName, final Marker aMarker, 088 final String theFqcn, final Level aLevel, final Message msg, final Throwable aThrowable, 089 final ContextStack aContextStack, final StackTraceElement aLocation, 090 final Clock aClock, final NanoClock aNanoClock) { 091 this.asyncLogger = anAsyncLogger; 092 this.loggerName = aLoggerName; 093 this.marker = aMarker; 094 this.fqcn = theFqcn; 095 this.level = aLevel; 096 this.message = msg; 097 this.thrown = aThrowable; 098 this.contextStack = aContextStack; 099 this.location = aLocation; 100 this.clock = aClock; 101 this.nanoClock = aNanoClock; 102 } 103 104 public void updateThreadValues() { 105 final Thread currentThread = Thread.currentThread(); 106 this.threadId = currentThread.getId(); 107 this.threadName = currentThread.getName(); 108 this.threadPriority = currentThread.getPriority(); 109 } 110}