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          public RingBufferLogEvent newInstance() {
46              return new RingBufferLogEvent();
47          }
48      }
49  
50      /** The {@code EventFactory} for {@code RingBufferLogEvent}s. */
51      public static final Factory FACTORY = new Factory();
52  
53      private AsyncLogger asyncLogger;
54      private String loggerName;
55      private Marker marker;
56      private String fqcn;
57      private Level level;
58      private Message message;
59      private Throwable thrown;
60      private Map<String, String> contextMap;
61      private ContextStack contextStack;
62      private String threadName;
63      private StackTraceElement location;
64      private long currentTimeMillis;
65      private boolean endOfBatch;
66      private boolean includeLocation;
67  
68      public void setValues(AsyncLogger asyncLogger, String loggerName,
69              Marker marker, String fqcn, Level level, Message data, Throwable t,
70              Map<String, String> map, ContextStack contextStack,
71              String threadName, StackTraceElement location,
72              long currentTimeMillis) {
73          this.asyncLogger = asyncLogger;
74          this.loggerName = loggerName;
75          this.marker = marker;
76          this.fqcn = fqcn;
77          this.level = level;
78          this.message = data;
79          this.thrown = t;
80          this.contextMap = map;
81          this.contextStack = contextStack;
82          this.threadName = threadName;
83          this.location = location;
84          this.currentTimeMillis = currentTimeMillis;
85      }
86  
87      /**
88       * Event processor that reads the event from the ringbuffer can call this
89       * method.
90       * 
91       * @param endOfBatch flag to indicate if this is the last event in a batch
92       *            from the RingBuffer
93       */
94      public void execute(boolean endOfBatch) {
95          this.endOfBatch = endOfBatch;
96          asyncLogger.actualAsyncLog(this);
97      }
98  
99      /**
100      * Returns {@code true} if this event is the end of a batch, {@code false}
101      * otherwise.
102      * 
103      * @return {@code true} if this event is the end of a batch, {@code false}
104      *         otherwise
105      */
106     public boolean isEndOfBatch() {
107         return endOfBatch;
108     }
109 
110     public void setEndOfBatch(boolean endOfBatch) {
111         this.endOfBatch = endOfBatch;
112     }
113 
114     public boolean isIncludeLocation() {
115         return includeLocation;
116     }
117 
118     public void setIncludeLocation(boolean includeLocation) {
119         this.includeLocation = includeLocation;
120     }
121 
122     // @Override
123     public String getLoggerName() {
124         return loggerName;
125     }
126 
127     // @Override
128     public Marker getMarker() {
129         return marker;
130     }
131 
132     // @Override
133     public String getFQCN() {
134         return fqcn;
135     }
136 
137     // @Override
138     public Level getLevel() {
139         return level;
140     }
141 
142     // @Override
143     public Message getMessage() {
144         if (message == null) {
145             message = new SimpleMessage("");
146         }
147         return message;
148     }
149 
150     // @Override
151     public Throwable getThrown() {
152         return thrown;
153     }
154 
155     // @Override
156     public Map<String, String> getContextMap() {
157         return contextMap;
158     }
159 
160     // @Override
161     public ContextStack getContextStack() {
162         return contextStack;
163     }
164 
165     // @Override
166     public String getThreadName() {
167         return threadName;
168     }
169 
170     // @Override
171     public StackTraceElement getSource() {
172         return location;
173     }
174 
175     // @Override
176     public long getMillis() {
177         return currentTimeMillis;
178     }
179 
180     /**
181      * Merges the contents of the specified map into the contextMap, after
182      * replacing any variables in the property values with the
183      * StrSubstitutor-supplied actual values.
184      * 
185      * @param properties configured properties
186      * @param strSubstitutor used to lookup values of variables in properties
187      */
188     public void mergePropertiesIntoContextMap(
189             Map<Property, Boolean> properties, StrSubstitutor strSubstitutor) {
190         if (properties == null) {
191             return; // nothing to do
192         }
193 
194         Map<String, String> map = (contextMap == null) ? new HashMap<String, String>()
195                 : new HashMap<String, String>(contextMap);
196 
197         for (Map.Entry<Property, Boolean> entry : properties.entrySet()) {
198             Property prop = entry.getKey();
199             if (map.containsKey(prop.getName())) {
200                 continue; // contextMap overrides config properties
201             }
202             String value = entry.getValue() ? strSubstitutor.replace(prop
203                     .getValue()) : prop.getValue();
204             map.put(prop.getName(), value);
205         }
206         contextMap = map;
207     }
208 }