1 /*
2 * Copyright 2012 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16
17 package io.netty.util.internal.logging;
18
19 import io.netty.util.internal.ObjectUtil;
20
21 /**
22 * Creates an {@link InternalLogger} or changes the default factory
23 * implementation. This factory allows you to choose what logging framework
24 * Netty should use. The default factory is {@link Slf4JLoggerFactory}. If SLF4J
25 * is not available, {@link Log4JLoggerFactory} is used. If Log4J is not available,
26 * {@link JdkLoggerFactory} is used. You can change it to your preferred
27 * logging framework before other Netty classes are loaded:
28 * <pre>
29 * {@link InternalLoggerFactory}.setDefaultFactory({@link Log4JLoggerFactory}.INSTANCE);
30 * </pre>
31 * Please note that the new default factory is effective only for the classes
32 * which were loaded after the default factory is changed. Therefore,
33 * {@link #setDefaultFactory(InternalLoggerFactory)} should be called as early
34 * as possible and shouldn't be called more than once.
35 */
36 public abstract class InternalLoggerFactory {
37
38 private static volatile InternalLoggerFactory defaultFactory;
39
40 @SuppressWarnings("UnusedCatchParameter")
41 private static InternalLoggerFactory newDefaultFactory(String name) {
42 InternalLoggerFactory f = useSlf4JLoggerFactory(name);
43 if (f != null) {
44 return f;
45 }
46
47 f = useLog4J2LoggerFactory(name);
48 if (f != null) {
49 return f;
50 }
51
52 f = useLog4JLoggerFactory(name);
53 if (f != null) {
54 return f;
55 }
56
57 return useJdkLoggerFactory(name);
58 }
59
60 private static InternalLoggerFactory useSlf4JLoggerFactory(String name) {
61 try {
62 InternalLoggerFactory f = Slf4JLoggerFactory.getInstanceWithNopCheck();
63 f.newInstance(name).debug("Using SLF4J as the default logging framework");
64 return f;
65 } catch (LinkageError ignore) {
66 return null;
67 } catch (Exception ignore) {
68 // We catch Exception and not ReflectiveOperationException as we still support java 6
69 return null;
70 }
71 }
72
73 private static InternalLoggerFactory useLog4J2LoggerFactory(String name) {
74 try {
75 InternalLoggerFactory f = Log4J2LoggerFactory.INSTANCE;
76 f.newInstance(name).debug("Using Log4J2 as the default logging framework");
77 return f;
78 } catch (LinkageError ignore) {
79 return null;
80 } catch (Exception ignore) {
81 // We catch Exception and not ReflectiveOperationException as we still support java 6
82 return null;
83 }
84 }
85
86 private static InternalLoggerFactory useLog4JLoggerFactory(String name) {
87 try {
88 InternalLoggerFactory f = Log4JLoggerFactory.INSTANCE;
89 f.newInstance(name).debug("Using Log4J as the default logging framework");
90 return f;
91 } catch (LinkageError ignore) {
92 return null;
93 } catch (Exception ignore) {
94 // We catch Exception and not ReflectiveOperationException as we still support java 6
95 return null;
96 }
97 }
98
99 private static InternalLoggerFactory useJdkLoggerFactory(String name) {
100 InternalLoggerFactory f = JdkLoggerFactory.INSTANCE;
101 f.newInstance(name).debug("Using java.util.logging as the default logging framework");
102 return f;
103 }
104
105 /**
106 * Returns the default factory. The initial default factory is
107 * {@link JdkLoggerFactory}.
108 */
109 public static InternalLoggerFactory getDefaultFactory() {
110 if (defaultFactory == null) {
111 defaultFactory = newDefaultFactory(InternalLoggerFactory.class.getName());
112 }
113 return defaultFactory;
114 }
115
116 /**
117 * Changes the default factory.
118 */
119 public static void setDefaultFactory(InternalLoggerFactory defaultFactory) {
120 InternalLoggerFactory.defaultFactory = ObjectUtil.checkNotNull(defaultFactory, "defaultFactory");
121 }
122
123 /**
124 * Creates a new logger instance with the name of the specified class.
125 */
126 public static InternalLogger getInstance(Class<?> clazz) {
127 return getInstance(clazz.getName());
128 }
129
130 /**
131 * Creates a new logger instance with the specified name.
132 */
133 public static InternalLogger getInstance(String name) {
134 return getDefaultFactory().newInstance(name);
135 }
136
137 /**
138 * Creates a new logger instance with the specified name.
139 */
140 protected abstract InternalLogger newInstance(String name);
141
142 }