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 io.netty.util.internal.logging.InternalLoggerFactory;
36  import io.netty.util.internal.logging.JdkLoggerFactory;
37  import io.netty.util.internal.logging.Slf4JLoggerFactory;
38  import org.waarp.common.utility.SystemPropertyUtil;
39  
40  /**
41   * Creates an {@link WaarpLogger} or changes the default factory
42   * implementation.
43   * This factory allows you to
44   * choose what logging framework Waarp should use. The default factory is
45   * {@link
46   * WaarpSlf4JLoggerFactory}. If
47   * SLF4J is not available, {@link WaarpSlf4JLoggerFactory} is used. If Log4J is
48   * not available,
49   * {@link WaarpJdkLoggerFactory} is used. You can change it to your preferred
50   * logging framework before other
51   * Waarp classes are loaded:
52   *
53   * <pre>
54   * {@link WaarpLoggerFactory}.setDefaultFactory(new {@link WaarpSlf4JLoggerFactory}());
55   * </pre>
56   * <p>
57   * Please note that the new default factory is effective only for the classes
58   * which were loaded after the
59   * default factory is changed. Therefore, {@link #setDefaultFactory(WaarpLoggerFactory)}
60   * should be called as
61   * early as possible and shouldn't be called more than once.
62   */
63  public abstract class WaarpLoggerFactory {
64    private static volatile WaarpLoggerFactory defaultFactory;
65    protected static WaarpLogLevel currentLevel;
66    static String localName = null;
67  
68    static {
69      SystemPropertyUtil.isFileEncodingCorrect();
70      final String name = WaarpLoggerFactory.class.getName();
71      WaarpLoggerFactory f;
72      try {
73        f = new WaarpSlf4JLoggerFactory(true);//NOSONAR
74        f.newInstance(name)
75         .debug("Using Logback (SLF4J) as the default logging framework");
76        defaultFactory = f;
77      } catch (final Throwable t1) {
78        f = new WaarpJdkLoggerFactory(null);//NOSONAR
79        f.newInstance(name)
80         .debug("Using java.util.logging as the default logging framework", t1);
81      }
82  
83      defaultFactory = f;
84    }
85  
86    /**
87     * Returns the default factory. The initial default factory is {@link
88     * WaarpJdkLoggerFactory}.
89     *
90     * @return the current default Factory
91     */
92    public static WaarpLoggerFactory getDefaultFactory() {
93      return defaultFactory;
94    }
95  
96    /**
97     * Changes the default factory if not already the same type, or just change
98     * the level
99     *
100    * @param factory
101    */
102   public static void setDefaultFactoryIfNotSame(
103       final WaarpLoggerFactory factory) {
104     final WaarpLoggerFactory current = getDefaultFactory();
105     if (current != null && current.getClass() == factory.getClass()) {
106       current.seLevelSpecific(factory.getLevelSpecific());
107     } else {
108       setDefaultFactory(factory);
109     }
110   }
111 
112   /**
113    * Changes the default factory.
114    *
115    * @param factory
116    */
117   public static void setDefaultFactory(final WaarpLoggerFactory factory) {
118     if (factory == null) {
119       throw new IllegalArgumentException("defaultFactory");
120     }
121     WaarpLoggerFactory.defaultFactory = factory;
122     if (factory instanceof WaarpJdkLoggerFactory) {
123       InternalLoggerFactory.setDefaultFactory(JdkLoggerFactory.INSTANCE);
124     } else if (factory instanceof WaarpSlf4JLoggerFactory) {
125       InternalLoggerFactory.setDefaultFactory(Slf4JLoggerFactory.INSTANCE);
126     }
127     factory.seLevelSpecific(factory.getLevelSpecific());
128   }
129 
130   /**
131    * Creates a new logger instance with the name of the specified class.
132    *
133    * @param clazz
134    *
135    * @return the logger instance
136    */
137   public static WaarpLogger getInstance(final Class<?> clazz) {
138     return getInstance(clazz.getName());
139   }
140 
141   /**
142    * Creates a new logger instance with the specified name.
143    *
144    * @param name
145    *
146    * @return the logger instance
147    */
148   public static WaarpLogger getInstance(final String name) {
149     return getDefaultFactory().newInstance(name);
150   }
151 
152   /**
153    * Creates a new logger instance with the name of the specified class.
154    *
155    * @param clazz
156    *
157    * @return the logger instance
158    */
159   public static WaarpLogger getLogger(final Class<?> clazz) {
160     return getInstance(clazz.getName());
161   }
162 
163   /**
164    * Creates a new logger instance with the specified name.
165    *
166    * @param name
167    *
168    * @return the logger instance
169    */
170   public static WaarpLogger getLogger(final String name) {
171     return getDefaultFactory().newInstance(name);
172   }
173 
174   /**
175    * @param level
176    */
177   public static void setLogLevel(final WaarpLogLevel level) {
178     setInternalLogLevel(level);
179     if (currentLevel != null) {
180       getDefaultFactory().seLevelSpecific(currentLevel);
181     }
182   }
183 
184   public static WaarpLogLevel getLogLevel() {
185     return currentLevel;
186   }
187 
188   protected static synchronized void setInternalLogLevel(
189       final WaarpLogLevel level) {
190     if (level != null) {
191       currentLevel = level;
192     }
193   }
194 
195   /**
196    * @param level
197    */
198   protected WaarpLoggerFactory(final WaarpLogLevel level) {
199     setInternalLogLevel(level);
200     if (currentLevel == null) {
201       setInternalLogLevel(getLevelSpecific());
202     }
203   }
204 
205   /**
206    * @param localNameNew if set, will be added to each line of log
207    */
208   public static void setLocalName(final String localNameNew) {
209     localName = localNameNew;
210   }
211 
212   /**
213    * @return should return the current Level for the specific implementation
214    */
215   protected abstract WaarpLogLevel getLevelSpecific();
216 
217   /**
218    * Set the level for the specific implementation
219    *
220    * @param level
221    */
222   protected abstract void seLevelSpecific(WaarpLogLevel level);
223 
224   /**
225    * Creates a new logger instance with the specified name.
226    */
227   protected abstract WaarpLogger newInstance(String name);
228 }