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