View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.async;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import org.apache.logging.log4j.Level;
23  import org.apache.logging.log4j.Marker;
24  import org.apache.logging.log4j.ThreadContext.ContextStack;
25  import org.apache.logging.log4j.core.LogEvent;
26  import org.apache.logging.log4j.core.config.Property;
27  import org.apache.logging.log4j.core.lookup.StrSubstitutor;
28  import org.apache.logging.log4j.message.Message;
29  import org.apache.logging.log4j.message.SimpleMessage;
30  
31  import com.lmax.disruptor.EventFactory;
32  
33  /**
34   * When the Disruptor is started, the RingBuffer is populated with event
35   * objects. These objects are then re-used during the life of the RingBuffer.
36   */
37  public class RingBufferLogEvent implements LogEvent {
38      private static final long serialVersionUID = 8462119088943934758L;
39  
40      /**
41       * Creates the events that will be put in the RingBuffer.
42       */
43      private static class Factory implements EventFactory<RingBufferLogEvent> {
44          // @Override
45          @Override
46          public RingBufferLogEvent newInstance() {
47              return new RingBufferLogEvent();
48          }
49      }
50  
51      /** The {@code EventFactory} for {@code RingBufferLogEvent}s. */
52      public static final Factory FACTORY = new Factory();
53  
54      private AsyncLogger asyncLogger;
55      private String loggerName;
56      private Marker marker;
57      private String fqcn;
58      private Level level;
59      private Message message;
60      private Throwable thrown;
61      private Map<String, String> contextMap;
62      private ContextStack contextStack;
63      private String threadName;
64      private StackTraceElement location;
65      private long currentTimeMillis;
66      private boolean endOfBatch;
67      private boolean includeLocation;
68  
69      public void setValues(AsyncLogger asyncLogger, String loggerName,
70              Marker marker, String fqcn, Level level, Message data, Throwable t,
71              Map<String, String> map, ContextStack contextStack,
72              String threadName, StackTraceElement location,
73              long currentTimeMillis) {
74          this.asyncLogger = asyncLogger;
75          this.loggerName = loggerName;
76          this.marker = marker;
77          this.fqcn = fqcn;
78          this.level = level;
79          this.message = data;
80          this.thrown = t;
81          this.contextMap = map;
82          this.contextStack = contextStack;
83          this.threadName = threadName;
84          this.location = location;
85          this.currentTimeMillis = currentTimeMillis;
86      }
87  
88      /**
89       * Event processor that reads the event from the ringbuffer can call this
90       * method.
91       * 
92       * @param endOfBatch flag to indicate if this is the last event in a batch
93       *            from the RingBuffer
94       */
95      public void execute(boolean endOfBatch) {
96          this.endOfBatch = endOfBatch;
97          asyncLogger.actualAsyncLog(this);
98      }
99  
100     /**
101      * Returns {@code true} if this event is the end of a batch, {@code false}
102      * otherwise.
103      * 
104      * @return {@code true} if this event is the end of a batch, {@code false}
105      *         otherwise
106      */
107     @Override
108     public boolean isEndOfBatch() {
109         return endOfBatch;
110     }
111 
112     @Override
113     public void setEndOfBatch(boolean endOfBatch) {
114         this.endOfBatch = endOfBatch;
115     }
116 
117     @Override
118     public boolean isIncludeLocation() {
119         return includeLocation;
120     }
121 
122     @Override
123     public void setIncludeLocation(boolean includeLocation) {
124         this.includeLocation = includeLocation;
125     }
126 
127     // @Override
128     @Override
129     public String getLoggerName() {
130         return loggerName;
131     }
132 
133     // @Override
134     @Override
135     public Marker getMarker() {
136         return marker;
137     }
138 
139     // @Override
140     @Override
141     public String getFQCN() {
142         return fqcn;
143     }
144 
145     // @Override
146     @Override
147     public Level getLevel() {
148         return level;
149     }
150 
151     // @Override
152     @Override
153     public Message getMessage() {
154         if (message == null) {
155             message = new SimpleMessage("");
156         }
157         return message;
158     }
159 
160     // @Override
161     @Override
162     public Throwable getThrown() {
163         return thrown;
164     }
165 
166     // @Override
167     @Override
168     public Map<String, String> getContextMap() {
169         return contextMap;
170     }
171 
172     // @Override
173     @Override
174     public ContextStack getContextStack() {
175         return contextStack;
176     }
177 
178     // @Override
179     @Override
180     public String getThreadName() {
181         return threadName;
182     }
183 
184     // @Override
185     @Override
186     public StackTraceElement getSource() {
187         return location;
188     }
189 
190     // @Override
191     @Override
192     public long getMillis() {
193         return currentTimeMillis;
194     }
195 
196     /**
197      * Merges the contents of the specified map into the contextMap, after
198      * replacing any variables in the property values with the
199      * StrSubstitutor-supplied actual values.
200      * 
201      * @param properties configured properties
202      * @param strSubstitutor used to lookup values of variables in properties
203      */
204     public void mergePropertiesIntoContextMap(
205             Map<Property, Boolean> properties, StrSubstitutor strSubstitutor) {
206         if (properties == null) {
207             return; // nothing to do
208         }
209 
210         Map<String, String> map = (contextMap == null) ? new HashMap<String, String>()
211                 : new HashMap<String, String>(contextMap);
212 
213         for (Map.Entry<Property, Boolean> entry : properties.entrySet()) {
214             Property prop = entry.getKey();
215             if (map.containsKey(prop.getName())) {
216                 continue; // contextMap overrides config properties
217             }
218             String value = entry.getValue() ? strSubstitutor.replace(prop
219                     .getValue()) : prop.getValue();
220             map.put(prop.getName(), value);
221         }
222         contextMap = map;
223     }
224 }