View Javadoc
1   /*
2    * Licensed under the GPL License. You may not use this file except in compliance with the License.
3    * You may obtain a copy of the License at
4    *
5    *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6    *
7    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8    * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9    * PURPOSE.
10   */
11  package psiprobe.tools.logging.slf4jlogback;
12  
13  import com.google.common.collect.Iterators;
14  
15  import java.util.ArrayList;
16  import java.util.Collection;
17  import java.util.Collections;
18  import java.util.Iterator;
19  import java.util.List;
20  
21  import org.apache.commons.lang3.reflect.MethodUtils;
22  
23  import psiprobe.tools.logging.DefaultAccessor;
24  
25  /**
26   * A wrapper for a TomcatSlf4jLogback logger.
27   */
28  public class TomcatSlf4jLogbackLoggerAccessor extends DefaultAccessor {
29  
30    /**
31     * Returns all appenders of this logger.
32     *
33     * @return a list of {@link TomcatSlf4jLogbackAppenderAccessor}s
34     */
35    @SuppressWarnings("unchecked")
36    public List<TomcatSlf4jLogbackAppenderAccessor> getAppenders() {
37      List<TomcatSlf4jLogbackAppenderAccessor> appenders = new ArrayList<>();
38  
39      try {
40        for (Object appender : Collections.list(Iterators.asEnumeration(
41            (Iterator<Object>) MethodUtils.invokeMethod(getTarget(), "iteratorForAppenders")))) {
42          List<Object> siftedAppenders = getSiftedAppenders(appender);
43          if (!siftedAppenders.isEmpty()) {
44            for (Object siftedAppender : siftedAppenders) {
45              wrapAndAddAppender(siftedAppender, appenders);
46            }
47          } else {
48            wrapAndAddAppender(appender, appenders);
49          }
50        }
51      } catch (NoClassDefFoundError e) {
52        logger.error("{}#getAppenders() failed", getTarget().getClass().getName(), e);
53        logger.error("To see this logger, upgrade slf4j to 1.7.21+");
54      } catch (Exception e) {
55        logger.error("{}#getAppenders() failed", getTarget().getClass().getName(), e);
56      }
57      return appenders;
58    }
59  
60    /**
61     * Returns the appender of this logger with the given name.
62     *
63     * @param name the name of the appender to return
64     *
65     * @return the appender with the given name, or null if no such appender exists for this logger
66     */
67    public TomcatSlf4jLogbackAppenderAccessor getAppender(String name) {
68      try {
69        Object appender = MethodUtils.invokeMethod(getTarget(), "getAppender", name);
70        if (appender == null) {
71          List<TomcatSlf4jLogbackAppenderAccessor> appenders = getAppenders();
72          for (TomcatSlf4jLogbackAppenderAccessor wrappedAppender : appenders) {
73            if (wrappedAppender.getIndex().equals(name)) {
74              return wrappedAppender;
75            }
76          }
77        }
78        return wrapAppender(appender);
79      } catch (Exception e) {
80        logger.error("{}#getAppender() failed", getTarget().getClass().getName(), e);
81      }
82      return null;
83    }
84  
85    /**
86     * Checks if is context.
87     *
88     * @return true, if is context
89     */
90    public boolean isContext() {
91      return false;
92    }
93  
94    /**
95     * Checks if is root.
96     *
97     * @return true, if is root
98     */
99    public boolean isRoot() {
100     return "ROOT".equals(getName());
101   }
102 
103   /**
104    * Gets the name.
105    *
106    * @return the name
107    */
108   public String getName() {
109     return (String) getProperty(getTarget(), "name", null);
110   }
111 
112   /**
113    * Gets the log level of this logger.
114    *
115    * @return the level of this logger
116    */
117   public String getLevel() {
118     try {
119       Object level = MethodUtils.invokeMethod(getTarget(), "getLevel");
120       return (String) MethodUtils.invokeMethod(level, "toString");
121     } catch (Exception e) {
122       logger.error("{}#getLevel() failed", getTarget().getClass().getName(), e);
123     }
124     return null;
125   }
126 
127   /**
128    * Sets the log level of this logger.
129    *
130    * @param newLevelStr the name of the new level
131    */
132   public void setLevel(String newLevelStr) {
133     try {
134       Object level = MethodUtils.invokeMethod(getTarget(), "getLevel");
135       Object newLevel = MethodUtils.invokeMethod(level, "toLevel", newLevelStr);
136       MethodUtils.invokeMethod(getTarget(), "setLevel", newLevel);
137     } catch (Exception e) {
138       logger.error("{}#setLevel('{}') failed", getTarget().getClass().getName(), newLevelStr, e);
139     }
140   }
141 
142   /**
143    * Gets the sifted appenders.
144    *
145    * @param appender the appender
146    *
147    * @return the sifted appenders
148    *
149    * @throws Exception the exception
150    */
151   @SuppressWarnings("unchecked")
152   private List<Object> getSiftedAppenders(Object appender) throws Exception {
153     if ("org.apache.juli.logging.ch.qos.logback.classic.sift.SiftingAppender"
154         .equals(appender.getClass().getName())) {
155 
156       Object tracker = MethodUtils.invokeMethod(appender, "getAppenderTracker");
157       if (tracker != null) {
158         return (List<Object>) MethodUtils.invokeMethod(tracker, "allComponents");
159       }
160     }
161     return Collections.emptyList();
162   }
163 
164   /**
165    * Wrap and add appender.
166    *
167    * @param appender the appender
168    * @param appenders the appenders
169    */
170   private void wrapAndAddAppender(Object appender,
171       Collection<TomcatSlf4jLogbackAppenderAccessor> appenders) {
172 
173     TomcatSlf4jLogbackAppenderAccessor appenderAccessor = wrapAppender(appender);
174     if (appenderAccessor != null) {
175       appenders.add(appenderAccessor);
176     }
177   }
178 
179   /**
180    * Wrap appender.
181    *
182    * @param appender the appender
183    *
184    * @return the tomcat slf4j logback appender accessor
185    */
186   private TomcatSlf4jLogbackAppenderAccessor wrapAppender(Object appender) {
187     try {
188       if (appender == null) {
189         throw new IllegalArgumentException("appender is null");
190       }
191       TomcatSlf4jLogbackAppenderAccessor appenderAccessor =
192           new TomcatSlf4jLogbackAppenderAccessor();
193 
194       appenderAccessor.setTarget(appender);
195       appenderAccessor.setLoggerAccessor(this);
196       appenderAccessor.setApplication(getApplication());
197       return appenderAccessor;
198     } catch (IllegalArgumentException e) {
199       logger.error("Could not wrap appender: '{}'", appender, e);
200     }
201     return null;
202   }
203 
204 }