1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.jmx;
15
16 import java.io.File;
17 import java.io.FileNotFoundException;
18 import java.net.MalformedURLException;
19 import java.net.URL;
20 import java.util.ArrayList;
21 import java.util.Iterator;
22 import java.util.List;
23
24 import javax.management.InstanceNotFoundException;
25 import javax.management.MBeanRegistrationException;
26 import javax.management.MBeanServer;
27 import javax.management.ObjectName;
28
29 import ch.qos.logback.classic.Level;
30 import ch.qos.logback.classic.Logger;
31 import ch.qos.logback.classic.LoggerContext;
32 import ch.qos.logback.classic.joran.JoranConfigurator;
33 import ch.qos.logback.classic.spi.LoggerContextListener;
34 import ch.qos.logback.classic.util.ContextInitializer;
35 import ch.qos.logback.core.joran.spi.JoranException;
36 import ch.qos.logback.core.spi.ContextAwareBase;
37 import ch.qos.logback.core.status.Status;
38 import ch.qos.logback.core.status.StatusListener;
39 import ch.qos.logback.core.status.StatusListenerAsList;
40 import ch.qos.logback.core.status.StatusManager;
41 import ch.qos.logback.core.util.StatusPrinter;
42
43
44
45
46
47
48
49
50
51
52
53
54 public class JMXConfigurator extends ContextAwareBase implements
55 JMXConfiguratorMBean, LoggerContextListener {
56
57 private static String EMPTY = "";
58
59 LoggerContext loggerContext;
60 MBeanServer mbs;
61 ObjectName objectName;
62 String objectNameAsString;
63
64
65
66 boolean debug = true;
67
68 boolean started;
69
70 public JMXConfigurator(LoggerContext loggerContext, MBeanServer mbs,
71 ObjectName objectName) {
72 started = true;
73 this.context = loggerContext;
74 this.loggerContext = loggerContext;
75 this.mbs = mbs;
76 this.objectName = objectName;
77 this.objectNameAsString = objectName.toString();
78 if (previouslyRegisteredListenerWithSameObjectName()) {
79 addError("Previously registered JMXConfigurator named ["
80 + objectNameAsString + "] in the logger context named ["
81 + loggerContext.getName() + "]");
82 } else {
83
84 loggerContext.addListener(this);
85 }
86 }
87
88 private boolean previouslyRegisteredListenerWithSameObjectName() {
89 List<LoggerContextListener> lcll = loggerContext.getCopyOfListenerList();
90 for (LoggerContextListener lcl : lcll) {
91 if (lcl instanceof JMXConfigurator) {
92 JMXConfigurator jmxConfigurator = (JMXConfigurator) lcl;
93 if (objectName.equals(jmxConfigurator.objectName)) {
94 return true;
95 }
96 }
97 }
98 return false;
99 }
100
101 public void reloadDefaultConfiguration() throws JoranException {
102 ContextInitializer ci = new ContextInitializer(loggerContext);
103 URL url = ci.findURLOfDefaultConfigurationFile(true);
104 reloadByURL(url);
105 }
106
107 public void reloadByFileName(String fileName) throws JoranException,
108 FileNotFoundException {
109 File f = new File(fileName);
110 if (f.exists() && f.isFile()) {
111 URL url;
112 try {
113 url = f.toURI().toURL();
114 reloadByURL(url);
115 } catch (MalformedURLException e) {
116 throw new RuntimeException(
117 "Unexpected MalformedURLException occured. See nexted cause.", e);
118 }
119
120 } else {
121 String errMsg = "Could not find [" + fileName + "]";
122 addInfo(errMsg);
123 throw new FileNotFoundException(errMsg);
124 }
125 }
126
127 void addStatusListener(StatusListener statusListener) {
128 StatusManager sm = loggerContext.getStatusManager();
129 sm.add(statusListener);
130 }
131
132 void removeStatusListener(StatusListener statusListener) {
133 StatusManager sm = loggerContext.getStatusManager();
134 sm.remove(statusListener);
135 }
136
137 public void reloadByURL(URL url) throws JoranException {
138 StatusListenerAsList statusListenerAsList = new StatusListenerAsList();
139
140 addStatusListener(statusListenerAsList);
141 addInfo("Resetting context: " + loggerContext.getName());
142 loggerContext.reset();
143
144 addStatusListener(statusListenerAsList);
145
146 try {
147 JoranConfigurator configurator = new JoranConfigurator();
148 configurator.setContext(loggerContext);
149 configurator.doConfigure(url);
150 addInfo("Context: " + loggerContext.getName() + " reloaded.");
151 } finally {
152 removeStatusListener(statusListenerAsList);
153 if (debug) {
154 StatusPrinter.print(statusListenerAsList.getStatusList());
155 }
156 }
157 }
158
159 public void setLoggerLevel(String loggerName, String levelStr) {
160 if (loggerName == null) {
161 return;
162 }
163 if (levelStr == null) {
164 return;
165 }
166 loggerName = loggerName.trim();
167 levelStr = levelStr.trim();
168
169 addInfo("Trying to set level " + levelStr + " to logger " + loggerName);
170 LoggerContext lc = (LoggerContext) context;
171
172 Logger logger = lc.getLogger(loggerName);
173 if ("null".equalsIgnoreCase(levelStr)) {
174 logger.setLevel(null);
175 } else {
176 Level level = Level.toLevel(levelStr, null);
177 if (level != null) {
178 logger.setLevel(level);
179 }
180 }
181 }
182
183 public String getLoggerLevel(String loggerName) {
184 if (loggerName == null) {
185 return EMPTY;
186 }
187
188 loggerName = loggerName.trim();
189
190 LoggerContext lc = (LoggerContext) context;
191 Logger logger = lc.exists(loggerName);
192 if (logger != null && logger.getLevel() != null) {
193 return logger.getLevel().toString();
194 } else {
195 return EMPTY;
196 }
197 }
198
199 public String getLoggerEffectiveLevel(String loggerName) {
200 if (loggerName == null) {
201 return EMPTY;
202 }
203
204 loggerName = loggerName.trim();
205
206 LoggerContext lc = (LoggerContext) context;
207 Logger logger = lc.exists(loggerName);
208 if (logger != null) {
209 return logger.getEffectiveLevel().toString();
210 } else {
211 return EMPTY;
212 }
213 }
214
215 public List<String> getLoggerList() {
216 LoggerContext lc = (LoggerContext) context;
217 List<String> strList = new ArrayList<String>();
218 Iterator<Logger> it = lc.getLoggerList().iterator();
219 while (it.hasNext()) {
220 Logger log = it.next();
221 strList.add(log.getName());
222 }
223 return strList;
224 }
225
226 public List<String> getStatuses() {
227 List<String> list = new ArrayList<String>();
228 Iterator<Status> it = context.getStatusManager().getCopyOfStatusList()
229 .iterator();
230 while (it.hasNext()) {
231 list.add(it.next().toString());
232 }
233 return list;
234 }
235
236
237
238
239
240 public void onStop(LoggerContext context) {
241 if (!started) {
242 addInfo("onStop() method called on a stopped JMXActivator ["
243 + objectNameAsString + "]");
244 return;
245 }
246 if (mbs.isRegistered(objectName)) {
247 try {
248 addInfo("Unregistering mbean [" + objectNameAsString + "]");
249 mbs.unregisterMBean(objectName);
250 } catch (InstanceNotFoundException e) {
251
252 addError("Unable to find a verifiably registered mbean ["
253 + objectNameAsString + "]", e);
254 } catch (MBeanRegistrationException e) {
255 addError("Failed to unregister [" + objectNameAsString + "]", e);
256 }
257 } else {
258 addInfo("mbean [" + objectNameAsString
259 + "] was not in the mbean registry. This is OK.");
260 }
261 stop();
262 }
263
264 public void onLevelChange(Logger logger, Level level) {
265
266 }
267
268 public void onReset(LoggerContext context) {
269 addInfo("onReset() method called JMXActivator [" + objectNameAsString + "]");
270 }
271
272
273
274
275
276
277 public boolean isResetResistant() {
278 return true;
279 }
280
281 private void clearFields() {
282 mbs = null;
283 objectName = null;
284 loggerContext = null;
285 }
286
287 private void stop() {
288 started = false;
289 clearFields();
290 }
291
292 public void onStart(LoggerContext context) {
293
294 }
295
296 @Override
297 public String toString() {
298 return this.getClass().getName() + "(" + context.getName() + ")";
299 }
300 }