View Javadoc
1   /*
2    * Copyright (c) 2001-2017, Zoltan Farkas All Rights Reserved.
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this program; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17   *
18   * Additionally licensed with:
19   *
20   * Licensed under the Apache License, Version 2.0 (the "License");
21   * you may not use this file except in compliance with the License.
22   * You may obtain a copy of the License at
23   *
24   *      http://www.apache.org/licenses/LICENSE-2.0
25   *
26   * Unless required by applicable law or agreed to in writing, software
27   * distributed under the License is distributed on an "AS IS" BASIS,
28   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29   * See the License for the specific language governing permissions and
30   * limitations under the License.
31   */
32  package org.spf4j.log;
33  
34  import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
35  import javax.annotation.Nullable;
36  import org.slf4j.Logger;
37  import org.slf4j.Marker;
38  import org.spf4j.base.Arrays;
39  import org.spf4j.base.ExecutionContext;
40  import org.spf4j.base.ExecutionContexts;
41  import org.spf4j.base.Wrapper;
42  import org.spf4j.base.avro.LogRecord;
43  
44  /**
45   * A Execution context aware logger.
46   *
47   * does the following:
48   *
49   * <li>
50   * 1) if Execution context is present, it logs the context id. (relies on Logging back-ends supporting overflow args)
51   * </li>
52   * <li>
53   * 2) if Execution context is present, it allows for context aware log level, and upgrades log messages to be logged by
54   * backend.
55   * </li>
56   *
57   * @author Zoltan Farkas
58   */
59  @SuppressFBWarnings("LO_SUSPECT_LOG_PARAMETER")
60  public final class ExecContextLogger implements Logger, Wrapper<Logger> {
61  
62    private final XLog logger;
63  
64    public static ExecContextLogger from(final Logger wrapped) {
65      if (wrapped instanceof ExecContextLogger) {
66        return (ExecContextLogger) wrapped;
67      } else {
68        return new ExecContextLogger(wrapped);
69      }
70    }
71  
72    public ExecContextLogger(final Logger wrapped) {
73      this(new SLf4jXLogAdapter(wrapped));
74    }
75  
76    public ExecContextLogger(final XLog traceLogger) {
77      this.logger = traceLogger;
78    }
79  
80    @Override
81    public Logger getWrapped() {
82      return this.logger.getWrapped();
83    }
84  
85    @Override
86    public String getName() {
87      return this.logger.getWrapped().getName();
88    }
89  
90    public boolean isEnabled(final Level level, @Nullable final Marker marker) {
91      ExecutionContext ctx = ExecutionContexts.current();
92      if (ctx == null) {
93        return logger.isEnabled(level, marker);
94      }
95      String name = getName();
96      Level backendOverwrite = ctx.getBackendMinLogLevel(name);
97      if (backendOverwrite == null) {
98        return logger.isEnabled(level, marker) || level.ordinal() >= ctx.getContextMinLogLevel(name).ordinal();
99      } else {
100       return logger.isEnabled(level, marker)
101               || level.ordinal()
102               >= Math.min(ctx.getContextMinLogLevel(name).ordinal(), backendOverwrite.ordinal());
103     }
104   }
105 
106 
107   public void log(final ExecutionContext ctx, final Level level, final LogRecord log) {
108     if (ctx == null) {
109       logger.log(null, level, "RemoteLog", log);
110       return;
111     }
112     String name = getName();
113     boolean logged = false;
114     if (logger.isEnabled(level, null)) {
115       logger.log(null, level, "RemoteLog", LogAttribute.traceId(ctx.getId()), log);
116       logged = true;
117     } else {
118       Level backendOverwrite = ctx.getBackendMinLogLevel(name);
119       if (backendOverwrite != null && backendOverwrite.ordinal() <= level.ordinal()) {
120        logger.logUpgrade(null, level, "RemoteLog", LogAttribute.traceId(ctx.getId()), log);
121        logged = true;
122       }
123     }
124     if (ctx.getContextMinLogLevel(name).ordinal() <= level.ordinal()) {
125       ctx.addLog(new AvroLogRecordImpl(log, logged));
126     }
127   }
128 
129   public void log(@Nullable final Marker marker, final Level level, final String msg, final Object... args) {
130     log(ExecutionContexts.current(), marker, level, msg, args);
131   }
132 
133   public void log(final ExecutionContext ctx, @Nullable final Marker marker,
134           final Level level, final String msg, final Object... args) {
135     if (ctx == null) {
136       logger.log(marker, level, msg, args);
137       return;
138     }
139     String name = getName();
140     boolean logged;
141     if (logger.isEnabled(level, marker)) {
142       logger.log(null, level, msg, Arrays.append(args, LogAttribute.traceId(ctx.getId())));
143       logged = true;
144     } else {
145       Level backendOverwrite = ctx.getBackendMinLogLevel(name);
146       if (backendOverwrite == null) {
147         logged = false;
148       } else if (backendOverwrite.ordinal() <= level.ordinal()) {
149         logger.logUpgrade(null, level, msg, Arrays.append(args, LogAttribute.traceId(ctx.getId())));
150         logged = true;
151       } else {
152         logged = false;
153       }
154     }
155     if (ctx.getContextMinLogLevel(name).ordinal() <= level.ordinal()) {
156       ctx.addLog(new Slf4jLogRecordImpl(logged, name, level, marker, msg, args));
157     }
158   }
159 
160   @Override
161   public boolean isTraceEnabled() {
162     return isEnabled(Level.TRACE, null);
163   }
164 
165   @Override
166   public void trace(final String msg) {
167     log(null, Level.TRACE, msg);
168   }
169 
170   @Override
171   public void trace(final String format, final Object arg) {
172     log(null, Level.TRACE, format, arg);
173   }
174 
175   @Override
176   public void trace(final String format, final Object arg1, final Object arg2) {
177     log(null, Level.TRACE, format, arg1, arg2);
178   }
179 
180   @Override
181   public void trace(final String format, final Object... arguments) {
182     log(null, Level.TRACE, format, arguments);
183   }
184 
185   @Override
186   public void trace(final String msg, final Throwable t) {
187     log(null, Level.TRACE, msg, t);
188   }
189 
190   @Override
191   public boolean isTraceEnabled(final Marker marker) {
192     return isEnabled(Level.TRACE, marker);
193   }
194 
195   @Override
196   public void trace(final Marker marker, final String msg) {
197     log(marker, Level.TRACE, msg);
198   }
199 
200   @Override
201   public void trace(final Marker marker, final String format, final Object arg) {
202     log(marker, Level.TRACE, format, arg);
203   }
204 
205   @Override
206   public void trace(final Marker marker, final String format, final Object arg1, final Object arg2) {
207     log(marker, Level.TRACE, format, arg1, arg2);
208   }
209 
210   @Override
211   public void trace(final Marker marker, final String format, final Object... argArray) {
212     log(marker, Level.TRACE, format, argArray);
213   }
214 
215   @Override
216   public void trace(final Marker marker, final String msg, final Throwable t) {
217     log(marker, Level.TRACE, msg, t);
218   }
219 
220   @Override
221   public boolean isDebugEnabled() {
222     return isEnabled(Level.DEBUG, null);
223   }
224 
225   @Override
226   public void debug(final String msg) {
227     log(null, Level.DEBUG, msg);
228   }
229 
230   @Override
231   public void debug(final String format, final Object arg) {
232     log(null, Level.DEBUG, format, arg);
233   }
234 
235   @Override
236   public void debug(final String format, final Object arg1, final Object arg2) {
237     log(null, Level.DEBUG, format, arg1, arg2);
238   }
239 
240   @Override
241   public void debug(final String format, final Object... arguments) {
242     log(null, Level.DEBUG, format, arguments);
243   }
244 
245   @Override
246   public void debug(final String msg, final Throwable t) {
247     log(null, Level.DEBUG, msg, t);
248   }
249 
250   @Override
251   public boolean isDebugEnabled(final Marker marker) {
252     return isEnabled(Level.DEBUG, marker);
253   }
254 
255   @Override
256   public void debug(final Marker marker, final String msg) {
257     log(marker, Level.DEBUG, msg);
258   }
259 
260   @Override
261   public void debug(final Marker marker, final String format, final Object arg) {
262     log(marker, Level.DEBUG, format, arg);
263   }
264 
265   @Override
266   public void debug(final Marker marker, final String format, final Object arg1, final Object arg2) {
267     log(marker, Level.DEBUG, format, arg1, arg2);
268   }
269 
270   @Override
271   public void debug(final Marker marker, final String format, final Object... arguments) {
272     log(marker, Level.DEBUG, format, arguments);
273   }
274 
275   @Override
276   public void debug(final Marker marker, final String msg, final Throwable t) {
277     log(marker, Level.DEBUG, msg, t);
278   }
279 
280   @Override
281   public boolean isInfoEnabled() {
282     return isEnabled(Level.INFO, null);
283   }
284 
285   @Override
286   public void info(final String msg) {
287     log(null, Level.INFO, msg);
288   }
289 
290   @Override
291   public void info(final String format, final Object arg) {
292     log(null, Level.INFO, format, arg);
293   }
294 
295   @Override
296   public void info(final String format, final Object arg1, final Object arg2) {
297     log(null, Level.INFO, format, arg1, arg2);
298   }
299 
300   @Override
301   public void info(final String format, final Object... arguments) {
302     log(null, Level.INFO, format, arguments);
303   }
304 
305   @Override
306   public void info(final String msg, final Throwable t) {
307     log(null, Level.INFO, msg, t);
308   }
309 
310   @Override
311   public boolean isInfoEnabled(final Marker marker) {
312     return isEnabled(Level.INFO, marker);
313   }
314 
315   @Override
316   public void info(final Marker marker, final String msg) {
317     log(marker, Level.INFO, msg);
318   }
319 
320   @Override
321   public void info(final Marker marker, final String format, final Object arg) {
322     log(marker, Level.INFO, format, arg);
323   }
324 
325   @Override
326   public void info(final Marker marker, final String format, final Object arg1, final Object arg2) {
327     log(marker, Level.INFO, format, arg1, arg2);
328   }
329 
330   @Override
331   public void info(final Marker marker, final String format, final Object... arguments) {
332     log(marker, Level.INFO, format, arguments);
333   }
334 
335   @Override
336   public void info(final Marker marker, final String msg, final Throwable t) {
337     log(marker, Level.INFO, msg, t);
338   }
339 
340   @Override
341   public boolean isWarnEnabled() {
342     return isEnabled(Level.WARN, null);
343   }
344 
345   @Override
346   public void warn(final String msg) {
347     log(null, Level.WARN, msg);
348   }
349 
350   @Override
351   public void warn(final String format, final Object arg) {
352     log(null, Level.WARN, format, arg);
353   }
354 
355   @Override
356   public void warn(final String format, final Object... arguments) {
357     log(null, Level.WARN, format, arguments);
358   }
359 
360   @Override
361   public void warn(final String format, final Object arg1, final Object arg2) {
362     log(null, Level.WARN, format, arg1, arg2);
363   }
364 
365   @Override
366   public void warn(final String msg, final Throwable t) {
367     log(null, Level.WARN, msg, t);
368   }
369 
370   @Override
371   public boolean isWarnEnabled(final Marker marker) {
372     return isEnabled(Level.WARN, marker);
373   }
374 
375   @Override
376   public void warn(final Marker marker, final String msg) {
377     log(marker, Level.WARN, msg);
378   }
379 
380   @Override
381   public void warn(final Marker marker, final String format, final Object arg) {
382     log(marker, Level.WARN, format, arg);
383   }
384 
385   @Override
386   public void warn(final Marker marker, final String format, final Object arg1, final Object arg2) {
387     log(marker, Level.WARN, format, arg1, arg2);
388   }
389 
390   @Override
391   public void warn(final Marker marker, final String format, final Object... arguments) {
392     log(marker, Level.WARN, format, arguments);
393   }
394 
395   @Override
396   public void warn(final Marker marker, final String msg, final Throwable t) {
397     log(marker, Level.WARN, msg, t);
398   }
399 
400   @Override
401   public boolean isErrorEnabled() {
402     return isEnabled(Level.ERROR, null);
403   }
404 
405   @Override
406   public void error(final String msg) {
407     log(null, Level.ERROR, msg);
408   }
409 
410   @Override
411   public void error(final String format, final Object arg) {
412     log(null, Level.ERROR, format, arg);
413   }
414 
415   @Override
416   public void error(final String format, final Object arg1, final Object arg2) {
417     log(null, Level.ERROR, format, arg1, arg2);
418   }
419 
420   @Override
421   public void error(final String format, final Object... arguments) {
422     log(null, Level.ERROR, format, arguments);
423   }
424 
425   @Override
426   public void error(final String msg, final Throwable t) {
427     log(null, Level.ERROR, msg, t);
428   }
429 
430   @Override
431   public boolean isErrorEnabled(final Marker marker) {
432     return isEnabled(Level.ERROR, marker);
433   }
434 
435   @Override
436   public void error(final Marker marker, final String msg) {
437     log(marker, Level.ERROR, msg);
438   }
439 
440   @Override
441   public void error(final Marker marker, final String format, final Object arg) {
442     log(marker, Level.ERROR, format, arg);
443   }
444 
445   @Override
446   public void error(final Marker marker, final String format, final Object arg1, final Object arg2) {
447     log(marker, Level.ERROR, format, arg1, arg2);
448   }
449 
450   @Override
451   public void error(final Marker marker, final String format, final Object... arguments) {
452     log(marker, Level.ERROR, format, arguments);
453   }
454 
455   @Override
456   public void error(final Marker marker, final String msg, final Throwable t) {
457     log(marker, Level.ERROR, msg, t);
458   }
459 
460   @Override
461   public String toString() {
462     return "ExecContextLogger{" + "traceLogger=" + this.logger + '}';
463   }
464 
465 }