View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5    *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    *
8    *  All Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  
21  /*
22   * Copyright 2012 The Netty Project
23   * The Netty Project licenses this file to you under the Apache License,
24   * version 2.0 (the "License"); you may not use this file except in compliance
25   * with the License. You may obtain a copy of the License at:
26   * http://www.apache.org/licenses/LICENSE-2.0
27   * Unless required by applicable law or agreed to in writing, software
28   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
29   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
30   * License for the specific language governing permissions and limitations
31   * under the License.
32   */
33  package org.waarp.common.logging;
34  
35  import java.io.Serializable;
36  
37  /**
38   * A skeletal implementation of {@link WaarpLogger}. This class implements all
39   * methods that have a
40   * {@link WaarpLogLevel} parameter by default to call specific logger methods
41   * such as {@link #info(String)} or
42   * {@link #isInfoEnabled()}.
43   */
44  public abstract class AbstractWaarpLogger implements WaarpLogger, Serializable {
45  
46    private static final long serialVersionUID = -6382972526573193470L;
47  
48    private static final String EXCEPTION_MESSAGE = "Unexpected exception:";
49  
50    private final String name;
51  
52    /**
53     * Creates a new instance.
54     */
55    protected AbstractWaarpLogger(final String name) {
56      if (name == null) {
57        throw new IllegalArgumentException("name");
58      }
59      this.name = name;
60    }
61  
62    @Override
63    public final String name() {
64      return name;
65    }
66  
67    @Override
68    public final boolean isEnabled(final WaarpLogLevel level) {
69      switch (level) {
70        case TRACE:
71          return isTraceEnabled();
72        case DEBUG:
73          return isDebugEnabled();
74        case INFO:
75          return isInfoEnabled();
76        case WARN:
77          return isWarnEnabled();
78        case ERROR:
79          return isErrorEnabled();
80        default:
81          return false;
82      }
83    }
84  
85    @Override
86    public final void trace(final Throwable t) {
87      trace(EXCEPTION_MESSAGE, t);
88    }
89  
90    @Override
91    public final void debug(final Throwable t) {
92      debug(EXCEPTION_MESSAGE, t);
93    }
94  
95    @Override
96    public final void info(final Throwable t) {
97      info(EXCEPTION_MESSAGE, t);
98    }
99  
100   @Override
101   public final void warn(final Throwable t) {
102     warn(EXCEPTION_MESSAGE, t);
103   }
104 
105   @Override
106   public final void error(final Throwable t) {
107     error(EXCEPTION_MESSAGE, t);
108   }
109 
110   @Override
111   public final void log(final WaarpLogLevel level, final String msg,
112                         final Throwable cause) {
113     switch (level) {
114       case TRACE:
115         trace(msg, cause);
116         break;
117       case DEBUG:
118         debug(msg, cause);
119         break;
120       case INFO:
121         info(msg, cause);
122         break;
123       case WARN:
124         warn(msg, cause);
125         break;
126       case ERROR:
127         error(msg, cause);
128         break;
129       default:
130     }
131   }
132 
133   @Override
134   public final void log(final WaarpLogLevel level, final Throwable cause) {
135     switch (level) {
136       case TRACE:
137         trace(cause);
138         break;
139       case DEBUG:
140         debug(cause);
141         break;
142       case INFO:
143         info(cause);
144         break;
145       case WARN:
146         warn(cause);
147         break;
148       case ERROR:
149         error(cause);
150         break;
151       default:
152     }
153   }
154 
155   @Override
156   public final void log(final WaarpLogLevel level, final String msg) {
157     switch (level) {
158       case TRACE:
159         trace(msg);
160         break;
161       case DEBUG:
162         debug(msg);
163         break;
164       case INFO:
165         info(msg);
166         break;
167       case WARN:
168         warn(msg);
169         break;
170       case ERROR:
171         error(msg);
172         break;
173       default:
174     }
175   }
176 
177   @Override
178   public final void log(final WaarpLogLevel level, final String format,
179                         final Object arg) {
180     switch (level) {
181       case TRACE:
182         trace(format, arg);
183         break;
184       case DEBUG:
185         debug(format, arg);
186         break;
187       case INFO:
188         info(format, arg);
189         break;
190       case WARN:
191         warn(format, arg);
192         break;
193       case ERROR:
194         error(format, arg);
195         break;
196       default:
197     }
198   }
199 
200   @Override
201   public final void log(final WaarpLogLevel level, final String format,
202                         final Object argA, final Object argB) {
203     switch (level) {
204       case TRACE:
205         trace(format, argA, argB);
206         break;
207       case DEBUG:
208         debug(format, argA, argB);
209         break;
210       case INFO:
211         info(format, argA, argB);
212         break;
213       case WARN:
214         warn(format, argA, argB);
215         break;
216       case ERROR:
217         error(format, argA, argB);
218         break;
219       default:
220     }
221   }
222 
223   @Override
224   public final void log(final WaarpLogLevel level, final String format,
225                         final Object... arguments) {
226     switch (level) {
227       case TRACE:
228         trace(format, arguments);
229         break;
230       case DEBUG:
231         debug(format, arguments);
232         break;
233       case INFO:
234         info(format, arguments);
235         break;
236       case WARN:
237         warn(format, arguments);
238         break;
239       case ERROR:
240         error(format, arguments);
241         break;
242       default:
243     }
244   }
245 
246   protected final Object readResolve() {
247     return WaarpLoggerFactory.getInstance(name());
248   }
249 
250   /**
251    * @param o
252    *
253    * @return the simple Class Name
254    */
255   public static String simpleClassName(final Object o) {
256     if (o == null) {
257       return "null_object";
258     } else {
259       return simpleClassName(o.getClass());
260     }
261   }
262 
263   /**
264    * @param clazz
265    *
266    * @return the simple Class Name
267    */
268   public static String simpleClassName(final Class<?> clazz) {
269     if (clazz == null) {
270       return "null_class";
271     }
272     final Package pkg = clazz.getPackage();
273     if (pkg != null) {
274       return clazz.getName().substring(pkg.getName().length() + 1);
275     } else {
276       return clazz.getName();
277     }
278   }
279 
280   @Override
281   public String toString() {
282     return simpleClassName(this) + '(' + name() + ')';
283   }
284 
285   private static final int BASELEVEL;
286   private static final int LOGLEVEL;
287 
288   /**
289    * Determine the good level
290    *
291    * @return the default base level
292    */
293   private static int detectLoggingBaseLevel() {
294     final StackTraceElement[] elt = Thread.currentThread().getStackTrace();
295     int i;
296     for (i = 0; i < elt.length; i++) {
297       if ("detectLoggingBaseLevel".equalsIgnoreCase(elt[i].getMethodName())) {
298         break;
299       }
300     }
301     return i;
302   }
303 
304   static {
305     BASELEVEL = detectLoggingBaseLevel();
306     LOGLEVEL = BASELEVEL + 2;
307   }
308 
309   /**
310    * To be used in message for logger (rank 2) like
311    * logger.warn(code,"message:"+getImmediateMethodAndLine(),null);
312    *
313    * @return "ClassAndMethodName(FileName:LineNumber)"
314    */
315   public static String getImmediateMethodAndLine() {
316     final StackTraceElement elt =
317         Thread.currentThread().getStackTrace()[BASELEVEL + 1];
318     return getMethodAndLine(elt);
319   }
320 
321   // FIXME TODO for JDK6 IBM add 1 (2->3 and 3->4)
322 
323   /**
324    * To be used only by Logger (rank 5)
325    *
326    * @return "MethodName(FileName:LineNumber)"
327    */
328   public static String getLoggerMethodAndLine() {
329     final StackTraceElement elt =
330         Thread.currentThread().getStackTrace()[LOGLEVEL];
331     return getMethodAndLine(elt);
332   }
333 
334   /**
335    * To be used only by Logger (rank 5)
336    *
337    * @return "MethodName(FileName:LineNumber)"
338    */
339   public static String getLoggerMethodAndLineCallee(final int deep) {
340     final StackTraceElement elt =
341         Thread.currentThread().getStackTrace()[LOGLEVEL + deep];
342     return getMethodAndLine(elt);
343   }
344 
345   /**
346    * @param rank is the current depth of call+1 (immediate = 1+1=2)
347    *
348    * @return "ClassAndMethodName(FileName:LineNumber)"
349    */
350   protected static String getRankMethodAndLine(final int rank) {
351     final StackTraceElement elt = Thread.currentThread().getStackTrace()[rank];
352     return getMethodAndLine(elt);
353   }
354 
355 
356   /**
357    * @param elt
358    *
359    * @return "MethodName(FileName:LineNumber) " from elt
360    */
361   private static String getMethodAndLine(final StackTraceElement elt) {
362     final StringBuilder builder =
363         new StringBuilder(elt.getClassName()).append('.')
364                                              .append(elt.getMethodName())
365                                              .append('(')
366                                              .append(elt.getFileName())
367                                              .append(':')
368                                              .append(elt.getLineNumber())
369                                              .append(") : ");
370     if (WaarpLoggerFactory.localName != null) {
371       builder.append('[').append(WaarpLoggerFactory.localName).append("] ");
372     }
373     return builder.toString();
374   }
375 
376 }