|
|||||||||||||||||||
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
LogManagementMBean.java | 75% | 75.6% | 80% | 76.5% |
|
1 |
// Copyright 2005 The Apache Software Foundation
|
|
2 |
//
|
|
3 |
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4 |
// you may not use this file except in compliance with the License.
|
|
5 |
// You may obtain a copy of the License at
|
|
6 |
//
|
|
7 |
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8 |
//
|
|
9 |
// Unless required by applicable law or agreed to in writing, software
|
|
10 |
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11 |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12 |
// See the License for the specific language governing permissions and
|
|
13 |
// limitations under the License.
|
|
14 |
|
|
15 |
package org.apache.hivemind.management.log4j;
|
|
16 |
|
|
17 |
import java.util.Enumeration;
|
|
18 |
import java.util.Iterator;
|
|
19 |
import java.util.List;
|
|
20 |
|
|
21 |
import javax.management.InstanceAlreadyExistsException;
|
|
22 |
import javax.management.JMException;
|
|
23 |
import javax.management.MBeanAttributeInfo;
|
|
24 |
import javax.management.MBeanOperationInfo;
|
|
25 |
import javax.management.MBeanParameterInfo;
|
|
26 |
import javax.management.MBeanRegistration;
|
|
27 |
import javax.management.MBeanServer;
|
|
28 |
import javax.management.ObjectName;
|
|
29 |
|
|
30 |
import mx4j.AbstractDynamicMBean;
|
|
31 |
|
|
32 |
import org.apache.hivemind.ApplicationRuntimeException;
|
|
33 |
import org.apache.hivemind.management.ObjectNameBuilder;
|
|
34 |
import org.apache.hivemind.util.StringUtils;
|
|
35 |
import org.apache.log4j.Level;
|
|
36 |
import org.apache.log4j.LogManager;
|
|
37 |
import org.apache.log4j.Logger;
|
|
38 |
import org.apache.log4j.helpers.OptionConverter;
|
|
39 |
import org.apache.log4j.jmx.LoggerDynamicMBean;
|
|
40 |
import org.apache.log4j.spi.LoggerRepository;
|
|
41 |
import org.apache.oro.text.regex.MalformedPatternException;
|
|
42 |
import org.apache.oro.text.regex.Pattern;
|
|
43 |
import org.apache.oro.text.regex.Perl5Compiler;
|
|
44 |
import org.apache.oro.text.regex.Perl5Matcher;
|
|
45 |
|
|
46 |
/**
|
|
47 |
* MBean that manages MBeans for Log4j Loggers. New MBeans can be added by specifying the Logger
|
|
48 |
* name or a logger pattern. Each MBean allows managing level and appenders of a single logger. Uses
|
|
49 |
* the LoggerDynamicMBean from the log4j library. Similar to
|
|
50 |
* {@link org.apache.log4j.jmx.HierarchyDynamicMBean}but implements the hivemind ObjectName scheme
|
|
51 |
* by using ObjectNameBuilder service. *
|
|
52 |
*
|
|
53 |
* @author Achim Huegen
|
|
54 |
* @since 1.1
|
|
55 |
*/
|
|
56 |
public class LogManagementMBean extends AbstractDynamicMBean implements MBeanRegistration, |
|
57 |
LogManagement |
|
58 |
{ |
|
59 |
private static final String OBJECT_NAME_TYPE = "logger"; |
|
60 |
|
|
61 |
private static final char WILDCARD = '*'; |
|
62 |
|
|
63 |
private static Logger logger = Logger.getLogger(LogManagementMBean.class); |
|
64 |
|
|
65 |
private ObjectNameBuilder _objectNameBuilder;
|
|
66 |
|
|
67 |
private LoggerRepository _loggerRepository;
|
|
68 |
|
|
69 |
private MBeanServer _mbeanserver;
|
|
70 |
|
|
71 |
private List _loggerContributions;
|
|
72 |
|
|
73 | 2 |
public LogManagementMBean(ObjectNameBuilder objectNameBuilder, List loggerContributions)
|
74 |
{ |
|
75 | 2 |
_objectNameBuilder = objectNameBuilder; |
76 | 2 |
_loggerRepository = LogManager.getLoggerRepository(); |
77 | 2 |
_loggerContributions = loggerContributions; |
78 |
} |
|
79 |
|
|
80 | 1 |
protected MBeanAttributeInfo[] createMBeanAttributeInfo()
|
81 |
{ |
|
82 | 1 |
return new MBeanAttributeInfo[] |
83 |
{ new MBeanAttributeInfo("Threshold", String.class.getName(), |
|
84 |
"The \"threshold\" state of the logger hierarchy.", true, true, false) }; |
|
85 |
} |
|
86 |
|
|
87 | 1 |
protected MBeanOperationInfo[] createMBeanOperationInfo()
|
88 |
{ |
|
89 | 1 |
MBeanParameterInfo parameterInfo[] = new MBeanParameterInfo[1];
|
90 | 1 |
parameterInfo[0] = new MBeanParameterInfo("loggerPattern", "java.lang.String", |
91 |
"Name of the Logger. Use * as wildcard");
|
|
92 | 1 |
return new MBeanOperationInfo[] |
93 |
{ new MBeanOperationInfo("addLoggerMBean", "Adds a MBean for a single Logger or " |
|
94 |
+ "a group of Loggers", parameterInfo, "void", 1) }; |
|
95 |
} |
|
96 |
|
|
97 | 2 |
public ObjectName preRegister(MBeanServer mbeanserver, ObjectName objectname)
|
98 |
{ |
|
99 | 2 |
_mbeanserver = mbeanserver; |
100 | 2 |
return objectname;
|
101 |
} |
|
102 |
|
|
103 | 2 |
public void postRegister(Boolean registrationDone) |
104 |
{ |
|
105 | 2 |
addConfiguredLoggerMBeans(); |
106 |
} |
|
107 |
|
|
108 | 1 |
public void preDeregister() throws Exception |
109 |
{ |
|
110 |
} |
|
111 |
|
|
112 | 1 |
public void postDeregister() |
113 |
{ |
|
114 |
} |
|
115 |
|
|
116 | 0 |
public String getThreshold()
|
117 |
{ |
|
118 | 0 |
return _loggerRepository.getThreshold().toString();
|
119 |
} |
|
120 |
|
|
121 | 0 |
public void setThreshold(String threshold) |
122 |
{ |
|
123 | 0 |
OptionConverter.toLevel(threshold, _loggerRepository.getThreshold()); |
124 |
|
|
125 | 0 |
_loggerRepository.setThreshold(threshold); |
126 |
} |
|
127 |
|
|
128 |
/**
|
|
129 |
* @see org.apache.hivemind.management.log4j.LogManagement#addLoggerMBean(java.lang.String)
|
|
130 |
*/
|
|
131 | 0 |
public void addLoggerMBean(String loggerPattern) |
132 |
{ |
|
133 | 0 |
boolean hasWildcard = loggerPattern.indexOf(WILDCARD) >= 0;
|
134 | 0 |
if (hasWildcard)
|
135 |
{ |
|
136 | 0 |
addLoggerMBeansForPattern(loggerPattern); |
137 |
} |
|
138 |
else
|
|
139 |
{ |
|
140 | 0 |
Logger logger = LogManager.getLogger(loggerPattern); |
141 | 0 |
addLoggerMBean(logger); |
142 |
} |
|
143 |
} |
|
144 |
|
|
145 |
/**
|
|
146 |
* Adds a MBean for a logger.
|
|
147 |
*
|
|
148 |
* @param logger
|
|
149 |
* the logger
|
|
150 |
* @return ObjectName of created MBean
|
|
151 |
*/
|
|
152 | 9 |
protected ObjectName addLoggerMBean(Logger logger)
|
153 |
{ |
|
154 | 9 |
String name = logger.getName(); |
155 | 9 |
ObjectName objectname = null;
|
156 | 9 |
try
|
157 |
{ |
|
158 | 9 |
LoggerDynamicMBean loggerMBean = new LoggerDynamicMBean(logger);
|
159 | 9 |
objectname = getObjectNameBuilder().createObjectName(name, OBJECT_NAME_TYPE); |
160 | 9 |
_mbeanserver.registerMBean(loggerMBean, objectname); |
161 |
} |
|
162 |
catch (InstanceAlreadyExistsException exception)
|
|
163 |
{ |
|
164 |
// just warn
|
|
165 | 0 |
logger.warn("MBean for Logger " + logger.getName() + " already exists"); |
166 |
} |
|
167 |
catch (JMException exception)
|
|
168 |
{ |
|
169 | 0 |
throw new ApplicationRuntimeException(exception); |
170 |
} |
|
171 | 9 |
return objectname;
|
172 |
} |
|
173 |
|
|
174 |
/**
|
|
175 |
* Adds MBeans for all Loggers that are defined in the service configuration
|
|
176 |
*/
|
|
177 | 2 |
protected void addConfiguredLoggerMBeans() |
178 |
{ |
|
179 | 2 |
for (Iterator iterContributions = _loggerContributions.iterator(); iterContributions
|
180 |
.hasNext();) |
|
181 |
{ |
|
182 | 4 |
LoggerContribution contribution = (LoggerContribution) iterContributions.next(); |
183 | 4 |
String loggerPattern = contribution.getLoggerPattern(); |
184 |
|
|
185 | 4 |
addLoggerMBeansForPattern(loggerPattern); |
186 |
} |
|
187 |
} |
|
188 |
|
|
189 |
/**
|
|
190 |
* Adds MBeans for all existing Loggers, that match the loggerPattern
|
|
191 |
*
|
|
192 |
* @param loggerPattern
|
|
193 |
*/
|
|
194 | 4 |
protected void addLoggerMBeansForPattern(String loggerPattern) |
195 |
{ |
|
196 |
// Add MBeans for all loggers that match the pattern
|
|
197 | 4 |
Enumeration loggers = LogManager.getCurrentLoggers(); |
198 | 4 |
while (loggers.hasMoreElements())
|
199 |
{ |
|
200 | 233 |
Logger logger = (Logger) loggers.nextElement(); |
201 | 233 |
if (isMatch(logger.getName(), loggerPattern))
|
202 | 9 |
addLoggerMBean(logger); |
203 |
} |
|
204 |
} |
|
205 |
|
|
206 |
/**
|
|
207 |
* @return Returns the _objectNameBuilder.
|
|
208 |
*/
|
|
209 | 9 |
public ObjectNameBuilder getObjectNameBuilder()
|
210 |
{ |
|
211 | 9 |
return _objectNameBuilder;
|
212 |
} |
|
213 |
|
|
214 |
/**
|
|
215 |
* Returns true if loggerName matches a loggerPattern The pattern kann contain '*' as wildcard
|
|
216 |
* character. This gets translated to '.*' and is used for a regex match using jakarta oro
|
|
217 |
*/
|
|
218 | 233 |
protected boolean isMatch(String loggerName, String loggerPattern) |
219 |
{ |
|
220 |
// Adapt loggerPattern for oro
|
|
221 | 233 |
String realLoggerPattern = StringUtils |
222 |
.replace(loggerPattern, "" + WILDCARD, "." + WILDCARD); |
|
223 |
|
|
224 | 233 |
Perl5Compiler compiler = new Perl5Compiler();
|
225 | 233 |
Perl5Matcher matcher = new Perl5Matcher();
|
226 | 233 |
Pattern compiled; |
227 | 233 |
try
|
228 |
{ |
|
229 | 233 |
compiled = compiler.compile(realLoggerPattern); |
230 |
} |
|
231 |
catch (MalformedPatternException e)
|
|
232 |
{ |
|
233 | 0 |
throw new ApplicationRuntimeException("Malformed Logger Pattern:" + realLoggerPattern); |
234 |
} |
|
235 | 233 |
return matcher.matches(loggerName, compiled);
|
236 |
|
|
237 |
} |
|
238 |
|
|
239 |
} |
|