View Javadoc
1   /*
2    * Copyright 2016 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  package io.netty5.util.internal.logging;
17  
18  
19  import org.apache.logging.log4j.Level;
20  import org.apache.logging.log4j.Logger;
21  import org.apache.logging.log4j.spi.ExtendedLogger;
22  import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;
23  
24  import java.security.AccessController;
25  import java.security.PrivilegedAction;
26  
27  import static io.netty5.util.internal.logging.AbstractInternalLogger.EXCEPTION_MESSAGE;
28  
29  class Log4J2Logger extends ExtendedLoggerWrapper implements InternalLogger {
30  
31      private static final long serialVersionUID = 5485418394879791397L;
32      private static final boolean VARARGS_ONLY;
33  
34      static {
35          // Older Log4J2 versions have only log methods that takes the format + varargs. So we should not use
36          // Log4J2 if the version is too old.
37          // See https://github.com/netty/netty/issues/8217
38          VARARGS_ONLY = AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
39              try {
40                  Logger.class.getMethod("debug", String.class, Object.class);
41                  return false;
42              } catch (NoSuchMethodException ignore) {
43                  // Log4J2 version too old.
44                  return true;
45              } catch (SecurityException ignore) {
46                  // We could not detect the version so we will use Log4J2 if its on the classpath.
47                  return false;
48              }
49          });
50      }
51  
52      Log4J2Logger(Logger logger) {
53          super((ExtendedLogger) logger, logger.getName(), logger.getMessageFactory());
54          if (VARARGS_ONLY) {
55              throw new UnsupportedOperationException("Log4J2 version mismatch");
56          }
57      }
58  
59      @Override
60      public String name() {
61          return getName();
62      }
63  
64      @Override
65      public void trace(Throwable t) {
66          log(Level.TRACE, EXCEPTION_MESSAGE, t);
67      }
68  
69      @Override
70      public void debug(Throwable t) {
71          log(Level.DEBUG, EXCEPTION_MESSAGE, t);
72      }
73  
74      @Override
75      public void info(Throwable t) {
76          log(Level.INFO, EXCEPTION_MESSAGE, t);
77      }
78  
79      @Override
80      public void warn(Throwable t) {
81          log(Level.WARN, EXCEPTION_MESSAGE, t);
82      }
83  
84      @Override
85      public void error(Throwable t) {
86          log(Level.ERROR, EXCEPTION_MESSAGE, t);
87      }
88  
89      @Override
90      public boolean isEnabled(InternalLogLevel level) {
91          return isEnabled(toLevel(level));
92      }
93  
94      @Override
95      public void log(InternalLogLevel level, String msg) {
96          log(toLevel(level), msg);
97      }
98  
99      @Override
100     public void log(InternalLogLevel level, String format, Object arg) {
101         log(toLevel(level), format, arg);
102     }
103 
104     @Override
105     public void log(InternalLogLevel level, String format, Object argA, Object argB) {
106         log(toLevel(level), format, argA, argB);
107     }
108 
109     @Override
110     public void log(InternalLogLevel level, String format, Object... arguments) {
111         log(toLevel(level), format, arguments);
112     }
113 
114     @Override
115     public void log(InternalLogLevel level, String msg, Throwable t) {
116         log(toLevel(level), msg, t);
117     }
118 
119     @Override
120     public void log(InternalLogLevel level, Throwable t) {
121         log(toLevel(level), EXCEPTION_MESSAGE, t);
122     }
123 
124     private static Level toLevel(InternalLogLevel level) {
125         switch (level) {
126             case INFO:
127                 return Level.INFO;
128             case DEBUG:
129                 return Level.DEBUG;
130             case WARN:
131                 return Level.WARN;
132             case ERROR:
133                 return Level.ERROR;
134             case TRACE:
135                 return Level.TRACE;
136             default:
137                 throw new Error();
138         }
139     }
140 }