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.logback13;
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 Logback logger.
27   */
28  public class Logback13LoggerAccessor extends DefaultAccessor {
29  
30    /**
31     * Returns all appenders of this logger.
32     *
33     * @return a list of {@link Logback13AppenderAccessor}s
34     */
35    @SuppressWarnings("unchecked")
36    public List<Logback13AppenderAccessor> getAppenders() {
37      List<Logback13AppenderAccessor> appenders = new ArrayList<>();
38      try {
39        for (Object appender : Collections.list(Iterators.asEnumeration(
40            (Iterator<Object>) MethodUtils.invokeMethod(getTarget(), "iteratorForAppenders")))) {
41          List<Object> siftedAppenders = getSiftedAppenders(appender);
42          if (!siftedAppenders.isEmpty()) {
43            for (Object siftedAppender : siftedAppenders) {
44              wrapAndAddAppender(siftedAppender, appenders);
45            }
46          } else {
47            wrapAndAddAppender(appender, appenders);
48          }
49        }
50      } catch (Exception e) {
51        logger.error("{}#getAppenders() failed", getTarget().getClass().getName(), e);
52      }
53      return appenders;
54    }
55  
56    /**
57     * Returns the appender of this logger with the given name.
58     *
59     * @param name the name of the appender to return
60     *
61     * @return the appender with the given name, or null if no such appender exists for this logger
62     */
63    public Logback13AppenderAccessor getAppender(String name) {
64      try {
65        Object appender = MethodUtils.invokeMethod(getTarget(), "getAppender", name);
66        if (appender == null) {
67          List<Logback13AppenderAccessor> appenders = getAppenders();
68          for (Logback13AppenderAccessor wrappedAppender : appenders) {
69            if (wrappedAppender.getIndex().equals(name)) {
70              return wrappedAppender;
71            }
72          }
73        }
74        return wrapAppender(appender);
75      } catch (Exception e) {
76        logger.error("{}#getAppender() failed", getTarget().getClass().getName(), e);
77      }
78      return null;
79    }
80  
81    /**
82     * Checks if is context.
83     *
84     * @return true, if is context
85     */
86    public boolean isContext() {
87      return false;
88    }
89  
90    /**
91     * Checks if is root.
92     *
93     * @return true, if is root
94     */
95    public boolean isRoot() {
96      return "ROOT".equals(getName());
97    }
98  
99    /**
100    * Gets the name.
101    *
102    * @return the name
103    */
104   public String getName() {
105     return (String) getProperty(getTarget(), "name", null);
106   }
107 
108   /**
109    * Gets the log level of this logger.
110    *
111    * @return the level of this logger
112    */
113   public String getLevel() {
114     try {
115       Object level = MethodUtils.invokeMethod(getTarget(), "getLevel");
116       return (String) MethodUtils.invokeMethod(level, "toString");
117     } catch (Exception e) {
118       logger.error("{}#getLevel() failed", getTarget().getClass().getName(), e);
119     }
120     return null;
121   }
122 
123   /**
124    * Sets the log level of this logger.
125    *
126    * @param newLevelStr the name of the new level
127    */
128   public void setLevel(String newLevelStr) {
129     try {
130       Object level = MethodUtils.invokeMethod(getTarget(), "getLevel");
131       Object newLevel = MethodUtils.invokeMethod(level, "toLevel", newLevelStr);
132       MethodUtils.invokeMethod(getTarget(), "setLevel", newLevel);
133     } catch (Exception e) {
134       logger.error("{}#setLevel('{}') failed", getTarget().getClass().getName(), newLevelStr, e);
135     }
136   }
137 
138   /**
139    * Gets the sifted appenders.
140    *
141    * @param appender the appender
142    *
143    * @return the sifted appenders
144    *
145    * @throws Exception the exception
146    */
147   @SuppressWarnings("unchecked")
148   private List<Object> getSiftedAppenders(Object appender) throws Exception {
149     if ("ch.qos.logback.classic.sift.SiftingAppender".equals(appender.getClass().getName())) {
150       Object tracker = MethodUtils.invokeMethod(appender, "getAppenderTracker");
151       if (tracker != null) {
152         return (List<Object>) MethodUtils.invokeMethod(tracker, "allComponents");
153       }
154     }
155     return Collections.emptyList();
156   }
157 
158   /**
159    * Wrap and add appender.
160    *
161    * @param appender the appender
162    * @param appenders the appenders
163    */
164   private void wrapAndAddAppender(Object appender,
165       Collection<Logback13AppenderAccessor> appenders) {
166     Logback13AppenderAccessor appenderAccessor = wrapAppender(appender);
167     if (appenderAccessor != null) {
168       appenders.add(appenderAccessor);
169     }
170   }
171 
172   /**
173    * Wrap appender.
174    *
175    * @param appender the appender
176    *
177    * @return the logback appender accessor
178    */
179   private Logback13AppenderAccessor wrapAppender(Object appender) {
180     try {
181       if (appender == null) {
182         throw new IllegalArgumentException("appender is null");
183       }
184       Logback13AppenderAccessor appenderAccessor = new Logback13AppenderAccessor();
185       appenderAccessor.setTarget(appender);
186       appenderAccessor.setLoggerAccessor(this);
187       appenderAccessor.setApplication(getApplication());
188       return appenderAccessor;
189     } catch (Exception e) {
190       logger.error("Could not wrap appender: '{}'", appender, e);
191     }
192     return null;
193   }
194 
195 }