/*
* Copyright (c)2005-2010 Mark Logic Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* The use of the Apache License does not indicate that this project is
* affiliated with the Apache Software Foundation.
*/
package com.marklogic.ps;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Hashtable;
import java.util.Properties;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
/**
* @author Michael Blakeley michael.blakeley@marklogic.com
*
* wrapper for java logging
*/
public class SimpleLogger extends Logger implements
PropertyClientInterface {
/**
*
*/
static public final String LOG_FILEHANDLER_LIMIT = "LOG_FILEHANDLER_LIMIT";
/**
*
*/
static public final String LOG_FILEHANDLER_COUNT = "LOG_FILEHANDLER_COUNT";
/**
*
*/
static public final String LOG_FILEHANDLER_APPEND = "LOG_FILEHANDLER_APPEND";
/**
*
*/
static public final String LOG_FILEHANDLER_PATH = "LOG_FILEHANDLER_PATH";
/**
*
*/
static public final String DEFAULT_LOG_HANDLER = "CONSOLE,FILE";
/**
*
*/
static public final String DEFAULT_LOG_LEVEL = "INFO";
/**
*
*/
static public final String LOG_HANDLER = "LOG_HANDLER";
/**
*
*/
static public final String LOG_LEVEL = "LOG_LEVEL";
/**
*
*/
static public final String DEFAULT_FILEHANDLER_PATH = "simplelogger-%u-%g.log";
static public final String LOGGER_NAME = "com.marklogic.ps";
private static Hashtable<String, SimpleLogger> loggers = new Hashtable<String, SimpleLogger>();
SimpleLogger(String name) {
super(name, null);
loggers.put(name, this);
this.setParent(Logger.getLogger(""));
}
SimpleLogger(String name, String resBundle) {
super(name, resBundle);
loggers.put(name, this);
this.setParent(Logger.getLogger(""));
}
public static SimpleLogger getSimpleLogger() {
return getSimpleLogger(LOGGER_NAME);
}
public static synchronized SimpleLogger getSimpleLogger(String name) {
SimpleLogger obj = loggers.get(name);
if (obj == null)
obj = new SimpleLogger(name);
return obj;
}
public static synchronized SimpleLogger getSimpleLogger(String name,
String resBundle) {
SimpleLogger obj = loggers.get(name);
if (obj == null)
obj = new SimpleLogger(name, resBundle);
return obj;
}
public void configureLogger(Properties _prop) {
if (_prop == null) {
System.err
.println("WARNING: null properties. Cannot configure logger");
return;
}
/*
* set up logging: we want to use the properties to set up all logging
* thus, we need to use "com.marklogic.ps" as our logger. Note that
* getParent() appears to fetch the first non-null ancestor, usually
* root! So we take a cruder approach.
*/
// don't use the root settings
setUseParentHandlers(false);
// now set the user's properties, if available
String logLevel = _prop.getProperty(LOG_LEVEL, DEFAULT_LOG_LEVEL);
// support multiple handlers: comma-separated
String[] logHandler = _prop.getProperty(LOG_HANDLER,
DEFAULT_LOG_HANDLER).split(",");
String logFilePath = _prop.getProperty(LOG_FILEHANDLER_PATH,
DEFAULT_FILEHANDLER_PATH);
boolean logFileAppend = Boolean.parseBoolean(_prop.getProperty(
LOG_FILEHANDLER_APPEND, "true"));
int logFileCount = Integer.parseInt(_prop.getProperty(
LOG_FILEHANDLER_COUNT, "1"));
int logFileLimit = Integer.parseInt(_prop.getProperty(
LOG_FILEHANDLER_LIMIT, "0"));
Handler h = null;
if (logHandler != null && logHandler.length > 0) {
// remove any old handlers
Handler[] v = getHandlers();
for (int i = 0; i < v.length; i++) {
removeHandler(v[i]);
}
// can't use the logger here: all the handlers are gone!
severe("this should not happen");
for (int i = 0; i < logHandler.length; i++) {
if (logHandler[i] == null)
continue;
// allow the user to specify the file
if (logHandler[i].equals("FILE")) {
System.err.println("logging to file " + logFilePath);
try {
h = new FileHandler(logFilePath, logFileLimit,
logFileCount, logFileAppend);
} catch (SecurityException e) {
e.printStackTrace();
// fatal error
System.err
.println("cannot configure logging: exiting");
Runtime.getRuntime().exit(-1);
} catch (IOException e) {
e.printStackTrace();
// fatal error
System.err
.println("cannot configure logging: exiting");
Runtime.getRuntime().exit(-1);
}
h.setFormatter(new SimpleFormatter());
} else if (logHandler[i].equals("CONSOLE")) {
System.err.println("logging to " + logHandler[i]);
h = new ConsoleHandler();
h.setFormatter(new SimpleFormatter());
} else {
// try to load the string as a classname
try {
Class<? extends Handler> lhc = Class.forName(
logHandler[i], true,
RecordLoader.getClassLoader())
.asSubclass(Handler.class);
System.err.println("logging to class "
+ logHandler[i]);
Constructor<? extends Handler> con = lhc
.getConstructor(new Class[] {});
h = con.newInstance(new Object[] {});
} catch (Exception e) {
System.err.println("unrecognized LOG_HANDLER: "
+ logHandler[i]);
e.printStackTrace();
System.err
.println("cannot configure logging: exiting");
Runtime.getRuntime().exit(-1);
}
}
if (h != null)
addHandler(h);
} // for handler properties
} else {
// default to ConsoleHandler
h = new ConsoleHandler();
h.setFormatter(new SimpleFormatter());
addHandler(h);
}
if (logLevel != null) {
/*
* Logger.setLevel() isn't sufficient, unless the Handler.level is
* set equal or lower
*/
Level lvl = Level.parse(logLevel);
if (lvl != null) {
setLevel(lvl);
Handler[] v = getHandlers();
for (int i = 0; i < v.length; i++) {
v[i].setLevel(lvl);
}
}
fine("logging set to " + getLevel());
}
info("setting up logging for: " + getName());
}
public void logException(String message, Throwable exception) {
super.log(Level.SEVERE,
(null != message) ? message : "EXCEPTION", exception);
}
/*
* (non-Javadoc)
*
* @see
* com.marklogic.ps.PropertyClientInterface#setProperties(java.util.Properties
* )
*/
public void setProperties(Properties _properties) {
configureLogger(_properties);
}
/**
* @param t
*/
public void logException(Throwable t) {
logException(null, t);
}
}