001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/util/tags/sakai_2-4-1/util-impl/impl/src/java/org/sakaiproject/log/impl/Log4jConfigurationManager.java $
003: * $Id: Log4jConfigurationManager.java 9662 2006-05-18 15:52:33Z ggolden@umich.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.log.impl;
021:
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.Map;
025: import java.util.Set;
026:
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.apache.log4j.Appender;
030: import org.apache.log4j.Layout;
031: import org.apache.log4j.Level;
032: import org.apache.log4j.Logger;
033: import org.apache.log4j.spi.ErrorHandler;
034: import org.apache.log4j.spi.Filter;
035: import org.apache.log4j.spi.LoggingEvent;
036: import org.sakaiproject.authz.api.SecurityService;
037: import org.sakaiproject.component.api.ServerConfigurationService;
038: import org.sakaiproject.log.api.LogConfigurationManager;
039: import org.sakaiproject.log.api.LogPermissionException;
040: import org.sakaiproject.util.StringUtil;
041:
042: /**
043: * <p>
044: * Log4jConfigurationManager lets us configure the log4j system with overrides from sakai.properties. Someday it might even have a service API for other fun things!
045: * </p>
046: */
047: public abstract class Log4jConfigurationManager implements
048: LogConfigurationManager {
049: /** Our log (commons). */
050: private static Log M_log = LogFactory
051: .getLog(Log4jConfigurationManager.class);
052:
053: /**********************************************************************************************************************************************************************************************************************************************************
054: * Dependencies
055: *********************************************************************************************************************************************************************************************************************************************************/
056:
057: /**
058: * @return the UsageSessionService collaborator.
059: */
060: protected abstract ServerConfigurationService serverConfigurationService();
061:
062: /**
063: * @return the SecurityService collaborator.
064: */
065: protected abstract SecurityService securityService();
066:
067: /**********************************************************************************************************************************************************************************************************************************************************
068: * Configuration
069: *********************************************************************************************************************************************************************************************************************************************************/
070:
071: /** Configuration: enable special log handling or not. */
072: protected boolean m_enabled = true;
073:
074: /**
075: * Configuration: enable special log handling or not.
076: *
077: * @param value
078: * the setting (true of false) for enabled.
079: */
080: public void setEnabled(String value) {
081: m_enabled = new Boolean(value).booleanValue();
082: }
083:
084: /** Map by logger name of set of message string starts to ignore. */
085: protected Map m_ignore = new HashMap();
086:
087: public void setIgnore(Map ignore) {
088: m_ignore = ignore;
089: }
090:
091: /**********************************************************************************************************************************************************************************************************************************************************
092: * Init and Destroy
093: *********************************************************************************************************************************************************************************************************************************************************/
094:
095: /**
096: * Final initialization, once all dependencies are set.
097: */
098: public void init() {
099: if (m_enabled) {
100: // slip in our appender
101: Appender a = Logger.getRootLogger().getAppender("Sakai");
102: if (a != null) {
103: Logger.getRootLogger().removeAppender(a);
104: Logger.getRootLogger()
105: .addAppender(new SakaiAppender(a));
106: }
107:
108: // set the log4j logging system with some overrides from sakai.properties
109: // each in the form LEVEL.NAME where LEVEL is OFF | TRACE | DEBUG | INFO | WARN | ERROR | FATAL | ALL, name is the logger name (such as org.sakaiproject)
110: // example:
111: // log.config.count=3
112: // log.config.1 = ALL.org.sakaiproject.log.impl
113: // log.config.2 = OFF.org.sakaiproject
114: // log.config.3 = DEBUG.org.sakaiproject.db.impl
115: String configs[] = serverConfigurationService().getStrings(
116: "log.config");
117: if (configs != null) {
118: for (int i = 0; i < configs.length; i++) {
119: String parts[] = StringUtil.splitFirst(configs[i],
120: ".");
121: if ((parts != null) && (parts.length == 2)) {
122: doSetLogLevel(parts[0], parts[1]);
123: } else {
124: M_log
125: .warn("invalid log.config entry: ignoring: "
126: + configs[i]);
127: }
128: }
129: }
130: }
131:
132: M_log.info("init(): enabled: " + m_enabled);
133: }
134:
135: /**
136: * Final cleanup.
137: */
138: public void destroy() {
139: M_log.info("destroy()");
140: }
141:
142: /**
143: * Set the log level
144: *
145: * @param level
146: * The log level string - one of OFF | TRACE | DEBUG | INFO | WARN | ERROR | FATAL | ALL
147: * @param loggerName
148: * The logger name.
149: */
150: protected boolean doSetLogLevel(String level, String loggerName) {
151: if (level.equals("OFF")) {
152: Logger logger = Logger.getLogger(loggerName);
153: if (logger != null) {
154: logger.setLevel(org.apache.log4j.Level.OFF);
155: M_log.info("OFF logging for: " + loggerName);
156: } else {
157: M_log.warn("no logger found: ignoring: " + loggerName);
158: }
159: } else if (level.equals("TRACE")) {
160: // Note: log4j has nothing below debug
161: Logger logger = Logger.getLogger(loggerName);
162: if (logger != null) {
163: logger.setLevel(org.apache.log4j.Level.DEBUG);
164: M_log.info("TRACE (DEBUG) logging for: " + loggerName);
165: } else {
166: M_log.warn("no logger found: ignoring: " + loggerName);
167: }
168: } else if (level.equals("DEBUG")) {
169: Logger logger = Logger.getLogger(loggerName);
170: if (logger != null) {
171: logger.setLevel(org.apache.log4j.Level.DEBUG);
172: M_log.info("DEBUG logging for: " + loggerName);
173: } else {
174: M_log.warn("no logger found: ignoring: " + loggerName);
175: }
176: } else if (level.equals("INFO")) {
177: Logger logger = Logger.getLogger(loggerName);
178: if (logger != null) {
179: logger.setLevel(org.apache.log4j.Level.INFO);
180: M_log.info("INFO logging for: " + loggerName);
181: } else {
182: M_log.warn("no logger found: ignoring: " + loggerName);
183: }
184: } else if (level.equals("WARN")) {
185: Logger logger = Logger.getLogger(loggerName);
186: if (logger != null) {
187: logger.setLevel(org.apache.log4j.Level.WARN);
188: M_log.info("WARN logging for: " + loggerName);
189: } else {
190: M_log.warn("no logger found: ignoring: " + loggerName);
191: }
192: } else if (level.equals("ERROR")) {
193: Logger logger = Logger.getLogger(loggerName);
194: if (logger != null) {
195: logger.setLevel(org.apache.log4j.Level.ERROR);
196: M_log.info("ERROR logging for: " + loggerName);
197: } else {
198: M_log.warn("no logger found: ignoring: " + loggerName);
199: }
200: } else if (level.equals("FATAL")) {
201: Logger logger = Logger.getLogger(loggerName);
202: if (logger != null) {
203: logger.setLevel(org.apache.log4j.Level.FATAL);
204: M_log.info("FATAL logging for: " + loggerName);
205: } else {
206: M_log.warn("no logger found: ignoring: " + loggerName);
207: }
208: } else if (level.equals("ALL")) {
209: Logger logger = Logger.getLogger(loggerName);
210: if (logger != null) {
211: logger.setLevel(org.apache.log4j.Level.ALL);
212: M_log.info("ALL logging for: " + loggerName);
213: } else {
214: M_log.warn("no logger found: ignoring: " + loggerName);
215: }
216: } else {
217: M_log.warn("invalid log level: ignorning: " + level);
218: return false;
219: }
220:
221: return true;
222: }
223:
224: /**********************************************************************************************************************************************************************************************************************************************************
225: * Work interface methods: LogConfigurationManager
226: *********************************************************************************************************************************************************************************************************************************************************/
227:
228: /**
229: * {@inheritDoc}
230: */
231: public boolean setLogLevel(String level, String loggerName)
232: throws LogPermissionException {
233: // check that this is a "super" user with the security service
234: if (!securityService().isSuperUser()) {
235: throw new LogPermissionException();
236: }
237:
238: return doSetLogLevel(level, loggerName);
239: }
240:
241: /**********************************************************************************************************************************************************************************************************************************************************
242: * Our special Appender
243: *********************************************************************************************************************************************************************************************************************************************************/
244:
245: class SakaiAppender implements org.apache.log4j.Appender {
246: protected Appender m_other = null;
247:
248: public SakaiAppender(Appender other) {
249: m_other = other;
250: }
251:
252: public void addFilter(Filter arg0) {
253: m_other.addFilter(arg0);
254: }
255:
256: public void clearFilters() {
257: m_other.clearFilters();
258: }
259:
260: public void close() {
261: m_other.close();
262: }
263:
264: public void doAppend(LoggingEvent arg0) {
265: String logger = arg0.getLoggerName();
266: String message = arg0.getRenderedMessage();
267: Level level = arg0.getLevel();
268:
269: Set toIgnore = (Set) m_ignore.get(logger);
270: if (toIgnore != null) {
271: // if any of the strings in the set start our message, skip it
272: for (Iterator i = toIgnore.iterator(); i.hasNext();) {
273: String start = (String) i.next();
274: if (message.startsWith(start))
275: return;
276: }
277: }
278:
279: m_other.doAppend(arg0);
280: }
281:
282: public ErrorHandler getErrorHandler() {
283: return m_other.getErrorHandler();
284: }
285:
286: public Filter getFilter() {
287: return m_other.getFilter();
288: }
289:
290: public Layout getLayout() {
291: return m_other.getLayout();
292: }
293:
294: public String getName() {
295: return m_other.getName();
296: }
297:
298: public boolean requiresLayout() {
299: return m_other.requiresLayout();
300: }
301:
302: public void setErrorHandler(ErrorHandler arg0) {
303: m_other.setErrorHandler(arg0);
304: }
305:
306: public void setLayout(Layout arg0) {
307: m_other.setLayout(arg0);
308: }
309:
310: public void setName(String arg0) {
311: m_other.setName(arg0);
312: }
313: }
314: }
|