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.internal;
18  
19  import org.apache.logging.log4j.Level;
20  import org.apache.logging.log4j.LogBuilder;
21  import org.apache.logging.log4j.Logger;
22  import org.apache.logging.log4j.Marker;
23  import org.apache.logging.log4j.message.Message;
24  import org.apache.logging.log4j.message.SimpleMessage;
25  import org.apache.logging.log4j.status.StatusLogger;
26  import org.apache.logging.log4j.util.LambdaUtil;
27  import org.apache.logging.log4j.util.StackLocatorUtil;
28  import org.apache.logging.log4j.util.Supplier;
29  
30  
31  /**
32   * Collects data for a log event and then logs it. This class should be considered private.
33   */
34  public class DefaultLogBuilder implements LogBuilder {
35  
36      private static Message EMPTY_MESSAGE = new SimpleMessage("");
37      private static final String FQCN = DefaultLogBuilder.class.getName();
38      private static final Logger LOGGER = StatusLogger.getLogger();
39  
40      private final Logger logger;
41      private Level level;
42      private Marker marker;
43      private Throwable throwable;
44      private StackTraceElement location;
45      private volatile boolean inUse;
46      private long threadId;
47  
48      public DefaultLogBuilder(Logger logger, Level level) {
49          this.logger = logger;
50          this.level = level;
51          this.threadId = Thread.currentThread().getId();
52          this.inUse = true;
53      }
54  
55      public DefaultLogBuilder(Logger logger) {
56          this.logger = logger;
57          this.inUse = false;
58          this.threadId = Thread.currentThread().getId();
59      }
60  
61      /**
62       * This method should be considered internal. It is used to reset the LogBuilder for a new log message.
63       * @param level The logging level for this event.
64       * @return This LogBuilder instance.
65       */
66      public LogBuilder reset(Level level) {
67          this.inUse = true;
68          this.level = level;
69          this.marker = null;
70          this.throwable = null;
71          this.location = null;
72          return this;
73      }
74  
75      @Override
76      public LogBuilder withMarker(Marker marker) {
77          this.marker = marker;
78          return this;
79      }
80  
81      @Override
82      public LogBuilder withThrowable(Throwable throwable) {
83          this.throwable = throwable;
84          return this;
85      }
86  
87      @Override
88      public LogBuilder withLocation() {
89          location = StackLocatorUtil.getStackTraceElement(2);
90          return this;
91      }
92  
93      @Override
94      public LogBuilder withLocation(StackTraceElement location) {
95          this.location = location;
96          return this;
97      }
98  
99      public boolean isInUse() {
100         return inUse;
101     }
102 
103     @Override
104     public void log(Message message) {
105         if (isValid()) {
106             logMessage(message);
107         }
108     }
109 
110     @Override
111     public void log(CharSequence message) {
112         if (isValid()) {
113             logMessage(logger.getMessageFactory().newMessage(message));
114         }
115     }
116 
117     @Override
118     public void log(String message) {
119         if (isValid()) {
120             logMessage(logger.getMessageFactory().newMessage(message));
121         }
122     }
123 
124     @Override
125     public void log(String message, Object... params) {
126         if (isValid()) {
127             logMessage(logger.getMessageFactory().newMessage(message, params));
128         }
129     }
130 
131     @Override
132     public void log(String message, Supplier<?>... params) {
133         if (isValid()) {
134             logMessage(logger.getMessageFactory().newMessage(message, LambdaUtil.getAll(params)));
135         }
136     }
137 
138     @Override
139     public void log(Supplier<Message> messageSupplier) {
140         if (isValid()) {
141             logMessage(messageSupplier.get());
142         }
143     }
144 
145     @Override
146     public void log(Object message) {
147         if (isValid()) {
148             logMessage(logger.getMessageFactory().newMessage(message));
149         }
150     }
151 
152     @Override
153     public void log(String message, Object p0) {
154         if (isValid()) {
155             logMessage(logger.getMessageFactory().newMessage(message, p0));
156         }
157     }
158 
159     @Override
160     public void log(String message, Object p0, Object p1) {
161         if (isValid()) {
162             logMessage(logger.getMessageFactory().newMessage(message, p0, p1));
163         }
164     }
165 
166     @Override
167     public void log(String message, Object p0, Object p1, Object p2) {
168         if (isValid()) {
169             logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2));
170         }
171     }
172 
173     @Override
174     public void log(String message, Object p0, Object p1, Object p2, Object p3) {
175         if (isValid()) {
176             logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3));
177         }
178     }
179 
180     @Override
181     public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4) {
182         if (isValid()) {
183             logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4));
184         }
185     }
186 
187     @Override
188     public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) {
189         if (isValid()) {
190             logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5));
191         }
192     }
193 
194     @Override
195     public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) {
196         if (isValid()) {
197             logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5, p6));
198         }
199     }
200 
201     @Override
202     public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6,
203             Object p7) {
204         if (isValid()) {
205             logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7));
206         }
207     }
208 
209     @Override
210     public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6,
211             Object p7, Object p8) {
212         if (isValid()) {
213             logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7, p8));
214         }
215     }
216 
217     @Override
218     public void log(String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6,
219             Object p7, Object p8, Object p9) {
220         if (isValid()) {
221             logMessage(logger.getMessageFactory().newMessage(message, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));
222         }
223     }
224 
225     @Override
226     public void log() {
227         if (isValid()) {
228             logMessage(EMPTY_MESSAGE);
229         }
230     }
231 
232     private void logMessage(Message message) {
233         try {
234             logger.logMessage(level, marker, FQCN, location, message, throwable);
235         } finally {
236             inUse = false;
237         }
238     }
239 
240     private boolean isValid() {
241         if (!inUse) {
242             LOGGER.warn("Attempt to reuse LogBuilder was ignored. {}",
243                     StackLocatorUtil.getCallerClass(2));
244             return false ;
245         }
246         if (this.threadId != Thread.currentThread().getId()) {
247             LOGGER.warn("LogBuilder can only be used on the owning thread. {}",
248                     StackLocatorUtil.getCallerClass(2));
249             return false;
250         }
251         return true;
252     }
253 }