1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  package psiprobe.tools.logging.log4j2;
12  
13  import com.google.common.base.Strings;
14  
15  import java.util.ArrayList;
16  import java.util.Collection;
17  import java.util.Collections;
18  import java.util.List;
19  import java.util.Map;
20  
21  import org.apache.commons.lang3.reflect.MethodUtils;
22  
23  import psiprobe.tools.logging.DefaultAccessor;
24  
25  
26  
27  
28  public class Log4J2LoggerConfigAccessor extends DefaultAccessor {
29  
30    
31    private boolean context;
32  
33    
34    private Log4J2LoggerContextAccessor loggerContext;
35  
36    
37    private Map<String, Object> appenderMap;
38  
39    
40  
41  
42  
43  
44    @Override
45    @SuppressWarnings("unchecked")
46    public void setTarget(Object target) {
47      super.setTarget(target);
48  
49      try {
50        this.appenderMap = (Map<String, Object>) invokeMethod(target, "getAppenders", null, null);
51      } catch (Exception e) {
52        logger.error("{}#getAppenders() failed", target.getClass().getName(), e);
53      }
54    }
55  
56    
57  
58  
59  
60  
61    public List<Log4J2AppenderAccessor> getAppenders() {
62      List<Log4J2AppenderAccessor> appenders = new ArrayList<>();
63      if (appenderMap != null) {
64        try {
65          for (Object appender : appenderMap.values()) {
66            List<Object> asyncedAppenders = getAsyncedAppenders(appender);
67            if (!asyncedAppenders.isEmpty()) {
68              for (Object asyncedAppender : asyncedAppenders) {
69                wrapAndAddAppender(asyncedAppender, appenders);
70              }
71            } else {
72              wrapAndAddAppender(appender, appenders);
73            }
74          }
75        } catch (NoClassDefFoundError e) {
76          logger.error("{}#getAppenders() failed, To see this logger, upgrade slf4j to 1.7.21+",
77              getTarget().getClass().getName(), e);
78        } catch (Exception e) {
79          logger.error("{}#getAppenders() failed", getTarget().getClass().getName(), e);
80        }
81      }
82      return appenders;
83    }
84  
85    
86  
87  
88  
89  
90  
91  
92    public Log4J2AppenderAccessor getAppender(String name) {
93      if (this.appenderMap != null) {
94        try {
95          Object appender = appenderMap.get(name);
96          if (appender == null) {
97            List<Log4J2AppenderAccessor> appenders = getAppenders();
98            for (Log4J2AppenderAccessor wrappedAppender : appenders) {
99              if (wrappedAppender.getIndex().equals(name)) {
100               return wrappedAppender;
101             }
102           }
103         }
104         return wrapAppender(appender);
105       } catch (Exception e) {
106         logger.error("{}#getAppender() failed", getTarget().getClass().getName(), e);
107       }
108     }
109     return null;
110   }
111 
112   
113 
114 
115 
116 
117   public boolean isContext() {
118     return context;
119   }
120 
121   
122 
123 
124 
125 
126   public void setContext(boolean context) {
127     this.context = context;
128   }
129 
130   
131 
132 
133 
134 
135   public void setLoggerContext(Log4J2LoggerContextAccessor loggerContext) {
136     this.loggerContext = loggerContext;
137   }
138 
139   
140 
141 
142 
143 
144   public boolean isRoot() {
145     return Strings.isNullOrEmpty(getName());
146   }
147 
148   
149 
150 
151 
152 
153   public String getName() {
154     return (String) getProperty(getTarget(), "name", null);
155   }
156 
157   
158 
159 
160 
161 
162   public String getLevel() {
163     try {
164       Object level = MethodUtils.invokeMethod(getTarget(), "getLevel");
165       return (String) MethodUtils.invokeMethod(level, "toString");
166     } catch (Exception e) {
167       logger.error("{}#getLevel() failed", getTarget().getClass().getName(), e);
168     }
169     return null;
170   }
171 
172   
173 
174 
175 
176 
177   public void setLevel(String newLevelStr) {
178     try {
179       Object level = MethodUtils.invokeMethod(getTarget(), "getLevel");
180       Object newLevel = MethodUtils.invokeMethod(level, "toLevel", newLevelStr);
181       MethodUtils.invokeMethod(getTarget(), "setLevel", newLevel);
182       loggerContext.updateLoggers();
183     } catch (Exception e) {
184       logger.error("{}#setLevel('{}') failed", getTarget().getClass().getName(), newLevelStr, e);
185     }
186   }
187 
188 
189   
190 
191 
192 
193 
194 
195 
196 
197 
198   @SuppressWarnings("unchecked")
199   private List<Object> getAsyncedAppenders(Object appender) throws Exception {
200     if ("org.apache.logging.log4j.core.appender.AsyncAppender"
201         .equals(appender.getClass().getName())) {
202       Object appenders = MethodUtils.invokeMethod(appender, "getAppenders");
203       if (appenders != null) {
204         return (List<Object>) appenders;
205       }
206     }
207     return Collections.emptyList();
208   }
209 
210   
211 
212 
213 
214 
215 
216   private void wrapAndAddAppender(Object appender, Collection<Log4J2AppenderAccessor> appenders) {
217     Log4J2AppenderAccessor appenderAccessor = wrapAppender(appender);
218     if (appenderAccessor != null) {
219       appenders.add(appenderAccessor);
220     }
221   }
222 
223   
224 
225 
226 
227 
228 
229 
230   protected Log4J2AppenderAccessor wrapAppender(Object appender) {
231     try {
232       if (appender == null) {
233         throw new IllegalArgumentException("appender is null");
234       }
235       Log4J2AppenderAccessor appenderAccessor = new Log4J2AppenderAccessor();
236       appenderAccessor.setTarget(appender);
237       appenderAccessor.setLoggerAccessor(this);
238       appenderAccessor.setApplication(getApplication());
239       return appenderAccessor;
240     } catch (Exception e) {
241       logger.error("Could not wrap appender: {}", appender, e);
242     }
243     return null;
244   }
245 
246 }