blob: da19150e71ae5bf916d970e04bc988e5307a1a15 [file] [log] [blame]
/*
* Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.enterprise.server.logging;
import com.sun.common.util.logging.LoggingConfigImpl;
import com.sun.common.util.logging.LoggingOutputStream;
import com.sun.common.util.logging.LoggingXMLNames;
import com.sun.enterprise.admin.monitor.callflow.Agent;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.module.bootstrap.EarlyLogHandler;
import com.sun.enterprise.util.EarlyLogger;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.enterprise.v3.logging.AgentFormatterDelegate;
import org.glassfish.api.admin.FileMonitoring;
import org.glassfish.common.util.Constants;
import org.glassfish.hk2.api.PostConstruct;
import org.glassfish.hk2.api.PreDestroy;
import org.glassfish.hk2.api.Rank;
import org.glassfish.hk2.api.ServiceHandle;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.runlevel.RunLevel;
import org.glassfish.hk2.utilities.BuilderHelper;
import org.glassfish.internal.api.InitRunLevel;
import org.glassfish.internal.config.UnprocessedConfigListener;
import org.glassfish.server.ServerEnvironmentImpl;
import jakarta.inject.Inject;
import org.jvnet.hk2.annotations.Optional;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.config.UnprocessedChangeEvent;
import org.jvnet.hk2.config.UnprocessedChangeEvents;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.logging.*;
import java.util.logging.Formatter;
/**
* Reinitialzie the log manager using our logging.properties file.
*
* @author Jerome Dochez
* @author Carla Mott
* @author Naman Mehta
*/
@Service
@RunLevel(InitRunLevel.VAL)
@Rank(Constants.IMPORTANT_RUN_LEVEL_SERVICE)
public class LogManagerService implements PostConstruct, PreDestroy, org.glassfish.internal.api.LogManager {
@Inject
ServerEnvironmentImpl env;
@Inject
ServiceLocator habitat;
@Inject @Optional
Agent agent = null;
@Inject
FileMonitoring fileMonitoring;
@Inject
LoggingConfigImpl loggingConfig;
@Inject
UnprocessedConfigListener ucl;
@Inject
Domain domain;
final Map<String, Handler> gfHandlers = new HashMap<String, Handler>();
private static final Logger LOGGER = LogFacade.LOGGING_LOGGER;
PrintStream oStdOutBackup = System.out;
PrintStream oStdErrBackup = System.err;
String serverLogFileDetail = "";
String handlerDetail = "";
String handlerServices = "";
String consoleHandlerFormatterDetail = "";
String gffileHandlerFormatterDetail = "";
String rotationOnTimeLimitInMinutesDetail = "";
String flushFrequencyDetail = "";
String filterHandlerDetails = "";
String logToConsoleDetail = "";
String rotationInTimeLimitInBytesDetail = "";
String useSystemLoggingDetail = "";
String fileHandlerCountDetail = "";
String retainErrorsStaticticsDetail = "";
String log4jVersionDetail = "";
String maxHistoryFilesDetail = "";
String rotationOnDateChangeDetail = "";
String fileHandlerPatternDetail = "";
String fileHandlerFormatterDetail = "";
String logFormatDateFormatDetail = "";
private static final String SERVER_LOG_FILE_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.file";
private static final String HANDLER_PROPERTY = "handlers";
private static final String HANDLER_SERVICES_PROPERTY = "handlerServices";
private static final String CONSOLEHANDLER_FORMATTER_PROPERTY = "java.util.logging.ConsoleHandler.formatter";
private static final String GFFILEHANDLER_FORMATTER_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.formatter";
private static final String ROTATIONTIMELIMITINMINUTES_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.rotationTimelimitInMinutes";
private static final String FLUSHFREQUENCY_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.flushFrequency";
private static final String FILEHANDLER_LIMIT_PROPERTY = "java.util.logging.FileHandler.limit";
private static final String LOGTOCONSOLE_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.logtoConsole";
private static final String ROTATIONLIMITINBYTES_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.rotationLimitInBytes";
private static final String USESYSTEMLOGGING_PROPERTY = "com.sun.enterprise.server.logging.SyslogHandler.useSystemLogging";
private static final String FILEHANDLER_COUNT_PROPERTY = "java.util.logging.FileHandler.count";
private static final String RETAINERRORSSTATICTICS_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.retainErrorsStasticsForHours";
private static final String LOG4J_VERSION_PROPERTY = "log4j.logger.org.hibernate.validator.util.Version";
private static final String MAXHISTORY_FILES_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.maxHistoryFiles";
private static final String ROTATIONONDATECHANGE_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.rotationOnDateChange";
private static final String FILEHANDLER_PATTERN_PROPERTY = "java.util.logging.FileHandler.pattern";
private static final String FILEHANDLER_FORMATTER_PROPERTY = "java.util.logging.FileHandler.formatter";
private static final String LOGFORMAT_DATEFORMAT_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.logFormatDateFormat";
final static String EXCLUDE_FIELDS_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.excludeFields";
final static String MULTI_LINE_MODE_PROPERTY = "com.sun.enterprise.server.logging.GFFileHandler.multiLineMode";
private String RECORD_BEGIN_MARKER = "[#|";
private String RECORD_END_MARKER = "|#]";
private String RECORD_FIELD_SEPARATOR = "|";
private String RECORD_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
String recordBeginMarker;
String recordEndMarker;
String recordFieldSeparator;
String recordDateFormat;
Vector<Logger> loggerReference = new Vector<Logger>();
private String excludeFields;
private boolean multiLineMode = false;
private LoggingOutputStream stdoutOutputStream=null;
private LoggingOutputStream stderrOutputStream=null;
/*
Returns properties based on the DAS/Cluster/Instance
*/
public Map<String, String> getLoggingProperties() throws IOException {
Server targetServer = domain.getServerNamed(env.getInstanceName());
Map<String, String> props = null;
if (targetServer != null) {
if (targetServer.isDas()) {
props = loggingConfig.getLoggingProperties();
} else if (targetServer.getCluster() != null) {
props = loggingConfig.getLoggingProperties(targetServer.getCluster().getConfigRef());
} else if (targetServer.isInstance()) {
props = loggingConfig.getLoggingProperties(targetServer.getConfigRef());
} else {
props = loggingConfig.getLoggingProperties();
}
} else {
props = loggingConfig.getLoggingProperties();
}
return props;
}
/*
Returns logging file to be monitor during server is running.
*/
public File getLoggingFile() throws IOException {
File file = null;
Server targetServer = domain.getServerNamed(env.getInstanceName());
if (targetServer != null) {
if (targetServer.isDas()) {
file = new File(env.getConfigDirPath(), ServerEnvironmentImpl.kLoggingPropertiesFileName);
} else if (targetServer.getCluster() != null) {
String pathForLogging = env.getConfigDirPath() + File.separator + targetServer.getCluster().getConfigRef();
File dirForLogging = new File(pathForLogging);
file = new File(dirForLogging, ServerEnvironmentImpl.kLoggingPropertiesFileName);
} else if (targetServer.isInstance()) {
String pathForLogging = env.getConfigDirPath() + File.separator + targetServer.getConfigRef();
File dirForLogging = new File(pathForLogging);
file = new File(dirForLogging, ServerEnvironmentImpl.kLoggingPropertiesFileName);
} else {
file = new File(env.getConfigDirPath(), ServerEnvironmentImpl.kLoggingPropertiesFileName);
}
} else {
file = new File(env.getConfigDirPath(), ServerEnvironmentImpl.kLoggingPropertiesFileName);
}
return file;
}
/**
* Initialize the loggers
*/
public void postConstruct() {
// if the system property is already set, we don't need to do anything
if (System.getProperty("java.util.logging.config.file") != null) {
System.out.println("\n\n\n#!## LogManagerService.postConstruct : java.util.logging.config.file=" +System.getProperty("java.util.logging.config.file"));
return;
}
// logging.properties massaging.
final LogManager logMgr = LogManager.getLogManager();
File logging = null;
// reset settings
try {
logging = getLoggingFile();
System.setProperty("java.util.logging.config.file", logging.getAbsolutePath());
String rootFolder = env.getProps().get(com.sun.enterprise.util.SystemPropertyConstants.INSTALL_ROOT_PROPERTY);
String templateDir = rootFolder + File.separator + "lib" + File.separator + "templates";
File src = new File(templateDir, ServerEnvironmentImpl.kLoggingPropertiesFileName);
File dest = new File(env.getConfigDirPath(), ServerEnvironmentImpl.kLoggingPropertiesFileName);
System.out.println("\n\n\n#!## LogManagerService.postConstruct : rootFolder=" +rootFolder);
System.out.println("#!## LogManagerService.postConstruct : templateDir=" +templateDir);
System.out.println("#!## LogManagerService.postConstruct : src=" +src);
System.out.println("#!## LogManagerService.postConstruct : dest=" +dest);
if (!logging.exists()) {
LOGGER.log(Level.FINE, logging.getAbsolutePath() + " not found, creating new file from template.");
FileUtils.copy(src, dest);
logging = new File(env.getConfigDirPath(), ServerEnvironmentImpl.kLoggingPropertiesFileName);
}
logMgr.readConfiguration();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, LogFacade.ERROR_READING_CONF_FILE, e);
}
FormatterDelegate agentDelegate = null;
if (agent != null) {
agentDelegate = new AgentFormatterDelegate(agent);
}
// force the ConsoleHandler to use GF formatter
String formatterClassName = null;
try {
Map<String, String> props = getLoggingProperties();
formatterClassName = props.get(CONSOLEHANDLER_FORMATTER_PROPERTY);
if (formatterClassName == null || formatterClassName.isEmpty()) {
formatterClassName = UniformLogFormatter.class.getName();
}
consoleHandlerFormatterDetail = formatterClassName;
excludeFields = props.get(EXCLUDE_FIELDS_PROPERTY);
multiLineMode = Boolean.parseBoolean(props.get(MULTI_LINE_MODE_PROPERTY));
if (formatterClassName.equals(UniformLogFormatter.class.getName())) {
// used to support UFL formatter in GF.
UniformLogFormatter formatter = new UniformLogFormatter();
String cname = "com.sun.enterprise.server.logging.GFFileHandler";
recordBeginMarker = props.get(cname + ".logFormatBeginMarker");
if (recordBeginMarker == null || ("").equals(recordBeginMarker)) {
LOGGER.log(Level.FINE, "Record begin marker is not a proper value so using default.");
recordBeginMarker = RECORD_BEGIN_MARKER;
}
recordEndMarker = props.get(cname + ".logFormatEndMarker");
if (recordEndMarker == null || ("").equals(recordEndMarker)) {
LOGGER.log(Level.FINE, "Record end marker is not a proper value so using default.");
recordEndMarker = RECORD_END_MARKER;
}
recordFieldSeparator = props.get(cname + ".logFormatFieldSeparator");
if (recordFieldSeparator == null || ("").equals(recordFieldSeparator) || recordFieldSeparator.length() > 1) {
LOGGER.log(Level.FINE, "Log Format field separator is not a proper value so using default.");
recordFieldSeparator = RECORD_FIELD_SEPARATOR;
}
recordDateFormat = props.get(cname + ".logFormatDateFormat");
if (recordDateFormat != null && !("").equals(recordDateFormat)) {
SimpleDateFormat sdf = new SimpleDateFormat(recordDateFormat);
try {
sdf.format(new Date());
} catch (Exception e) {
LOGGER.log(Level.FINE, "Date Format specified is wrong so using default.");
recordDateFormat = RECORD_DATE_FORMAT;
}
} else {
LOGGER.log(Level.FINE, "Date Format specified is wrong so using default.");
recordDateFormat = RECORD_DATE_FORMAT;
}
formatter.setRecordBeginMarker(recordBeginMarker);
formatter.setRecordEndMarker(recordEndMarker);
formatter.setRecordDateFormat(recordDateFormat);
formatter.setRecordFieldSeparator(recordFieldSeparator);
formatter.setExcludeFields(excludeFields);
formatter.setMultiLineMode(multiLineMode);
for (Handler handler : logMgr.getLogger("").getHandlers()) {
// only get the ConsoleHandler
if (handler.getClass().equals(ConsoleHandler.class)) {
handler.setFormatter(formatter);
break;
}
}
} else if (formatterClassName.equals(ODLLogFormatter.class.getName())) {
// used to support ODL formatter in GF.
ODLLogFormatter formatter = new ODLLogFormatter();
formatter.setExcludeFields(excludeFields);
formatter.setMultiLineMode(multiLineMode);
for (Handler handler : logMgr.getLogger("").getHandlers()) {
// only get the ConsoleHandler
if (handler.getClass().equals(ConsoleHandler.class)) {
handler.setFormatter(formatter);
break;
}
}
}
//setting default attributes value for all properties
serverLogFileDetail = props.get(SERVER_LOG_FILE_PROPERTY);
handlerDetail = props.get(HANDLER_PROPERTY);
handlerServices = props.get(HANDLER_SERVICES_PROPERTY);
if (handlerServices == null) {
handlerServices = "";
}
consoleHandlerFormatterDetail = props.get(CONSOLEHANDLER_FORMATTER_PROPERTY);
gffileHandlerFormatterDetail = props.get(GFFILEHANDLER_FORMATTER_PROPERTY);
rotationOnTimeLimitInMinutesDetail = props.get(ROTATIONTIMELIMITINMINUTES_PROPERTY);
flushFrequencyDetail = props.get(FLUSHFREQUENCY_PROPERTY);
filterHandlerDetails = props.get(FILEHANDLER_LIMIT_PROPERTY);
logToConsoleDetail = props.get(LOGTOCONSOLE_PROPERTY);
rotationInTimeLimitInBytesDetail = props.get(ROTATIONLIMITINBYTES_PROPERTY);
useSystemLoggingDetail = props.get(USESYSTEMLOGGING_PROPERTY);
fileHandlerCountDetail = props.get(FILEHANDLER_COUNT_PROPERTY);
retainErrorsStaticticsDetail = props.get(RETAINERRORSSTATICTICS_PROPERTY);
log4jVersionDetail = props.get(LOG4J_VERSION_PROPERTY);
maxHistoryFilesDetail = props.get(MAXHISTORY_FILES_PROPERTY);
rotationOnDateChangeDetail = props.get(ROTATIONONDATECHANGE_PROPERTY);
fileHandlerPatternDetail = props.get(FILEHANDLER_PATTERN_PROPERTY);
fileHandlerFormatterDetail = props.get(FILEHANDLER_FORMATTER_PROPERTY);
logFormatDateFormatDetail = props.get(LOGFORMAT_DATEFORMAT_PROPERTY);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, LogFacade.ERROR_APPLYING_CONF, e);
}
Collection<Handler> handlers = getHandlerServices();
if (handlers != null && handlers.size() > 0) {
// add the new handlers to the root logger
for (Handler handler : handlers) {
addHandler(handler);
}
}
// Need to lock Logger.class first before locking LogManager to avoid deadlock.
// See GLASSFISH-7274 for more details.
// The synchronization in Logger class is addressed in JDK 1.7 but in JDK 1.6
// Logger.getLogger() is still synchronized.
synchronized (java.util.logging.Logger.class) {
synchronized (logMgr) {
Enumeration<String> loggerNames = logMgr.getLoggerNames();
while (loggerNames.hasMoreElements()) {
String loggerName = loggerNames.nextElement();
Logger logger = logMgr.getLogger(loggerName);
if (logger == null) {
continue;
}
for (Handler handler : logger.getHandlers()) {
Formatter formatter = handler.getFormatter();
if (formatter != null
&& formatter instanceof UniformLogFormatter) {
((UniformLogFormatter) formatter)
.setDelegate(agentDelegate);
}
}
}
}
}
// add the filter if there is one
try {
Map<String, String> map = getLoggingProperties();
String filterClassName = map.get(LoggingXMLNames.xmltoPropsMap.get("log-filter"));
if (filterClassName != null) {
Filter filterClass = habitat.getService(Filter.class, filterClassName);
Logger rootLogger = Logger.getLogger("");
if (rootLogger != null) {
rootLogger.setFilter(filterClass);
}
}
} catch (java.io.IOException ex) {
}
// redirect stderr and stdout, a better way to do this
//http://blogs.sun.com/nickstephen/entry/java_redirecting_system_out_and
Logger _ologger = LogFacade.STDOUT_LOGGER;
stdoutOutputStream = new LoggingOutputStream(_ologger, Level.INFO);
LoggingOutputStream.LoggingPrintStream pout = stdoutOutputStream.new LoggingPrintStream(stdoutOutputStream);
System.setOut(pout);
Logger _elogger = LogFacade.STDERR_LOGGER;
stderrOutputStream = new LoggingOutputStream(_elogger, Level.SEVERE);
LoggingOutputStream.LoggingPrintStream perr = stderrOutputStream.new LoggingPrintStream(stderrOutputStream);
System.setErr(perr);
// finally listen to changes to the logging.properties file
if (logging != null) {
fileMonitoring.monitors(logging, new FileMonitoring.FileChangeListener() {
public void changed(File changedFile) {
synchronized (gfHandlers) {
try {
Map<String, String> props = getLoggingProperties();
loggerReference = new Vector<Logger>();
if (props == null)
return;
// Set<String> keys = props.keySet();
for (Map.Entry<String,String> entry : props.entrySet()) {
String a = entry.getKey();
String val = entry.getValue();
if (a.endsWith(".level")) {
String n = a.substring(0, a.lastIndexOf(".level"));
Level l = Level.parse(val);
if (gfHandlers.containsKey(n)) {
// check if this is one of our handlers
Handler h = (Handler) gfHandlers.get(n);
h.setLevel(l);
} else if (n.equals("java.util.logging.ConsoleHandler")) {
Logger logger = Logger.getLogger("");
Handler[] h = logger.getHandlers();
for (int i = 0; i < h.length; i++) {
String name = h[i].toString();
if (name.contains("java.util.logging.ConsoleHandler"))
h[i].setLevel(l);
}
} else {
// Assume it is a logger
Logger appLogger = Logger.getLogger(n);
appLogger.setLevel(l);
loggerReference.add(appLogger);
}
} else if (a.equals(SERVER_LOG_FILE_PROPERTY)) {
//check if file name was changed and send notification
if (!val.equals(serverLogFileDetail)) {
PropertyChangeEvent pce = new PropertyChangeEvent(this, a, serverLogFileDetail, val);
UnprocessedChangeEvents ucel = new UnprocessedChangeEvents(new UnprocessedChangeEvent(pce, "server log filename changed."));
List<UnprocessedChangeEvents> b = new ArrayList();
b.add(ucel);
ucl.unprocessedTransactedEvents(b);
}
} else if (a.equals(HANDLER_PROPERTY)) {
if (!val.equals(handlerDetail)) {
generateAttributeChangeEvent(HANDLER_PROPERTY, handlerDetail, props);
}
} else if (a.equals(HANDLER_SERVICES_PROPERTY)) {
if (!val.equals(handlerServices)) {
generateAttributeChangeEvent(HANDLER_SERVICES_PROPERTY, handlerServices, props);
}
} else if (a.equals(CONSOLEHANDLER_FORMATTER_PROPERTY)) {
if (!val.equals(consoleHandlerFormatterDetail)) {
generateAttributeChangeEvent(CONSOLEHANDLER_FORMATTER_PROPERTY, consoleHandlerFormatterDetail, props);
}
} else if (a.equals(GFFILEHANDLER_FORMATTER_PROPERTY)) {
if (!val.equals(gffileHandlerFormatterDetail)) {
generateAttributeChangeEvent(GFFILEHANDLER_FORMATTER_PROPERTY, gffileHandlerFormatterDetail, props);
}
} else if (a.equals(ROTATIONTIMELIMITINMINUTES_PROPERTY)) {
if (!val.equals(rotationOnTimeLimitInMinutesDetail)) {
generateAttributeChangeEvent(ROTATIONTIMELIMITINMINUTES_PROPERTY, rotationOnTimeLimitInMinutesDetail, props);
}
} else if (a.equals(FLUSHFREQUENCY_PROPERTY)) {
if (!val.equals(flushFrequencyDetail)) {
generateAttributeChangeEvent(FLUSHFREQUENCY_PROPERTY, flushFrequencyDetail, props);
}
} else if (a.equals(FILEHANDLER_LIMIT_PROPERTY)) {
if (!val.equals(filterHandlerDetails)) {
generateAttributeChangeEvent(FILEHANDLER_LIMIT_PROPERTY, filterHandlerDetails, props);
}
} else if (a.equals(LOGTOCONSOLE_PROPERTY)) {
if (!val.equals(logToConsoleDetail)) {
generateAttributeChangeEvent(LOGTOCONSOLE_PROPERTY, logToConsoleDetail, props);
}
} else if (a.equals(ROTATIONLIMITINBYTES_PROPERTY)) {
if (!val.equals(rotationInTimeLimitInBytesDetail)) {
generateAttributeChangeEvent(ROTATIONLIMITINBYTES_PROPERTY, rotationInTimeLimitInBytesDetail, props);
}
} else if (a.equals(USESYSTEMLOGGING_PROPERTY)) {
if (!val.equals(useSystemLoggingDetail)) {
generateAttributeChangeEvent(USESYSTEMLOGGING_PROPERTY, useSystemLoggingDetail, props);
}
} else if (a.equals(FILEHANDLER_COUNT_PROPERTY)) {
if (!val.equals(fileHandlerCountDetail)) {
generateAttributeChangeEvent(FILEHANDLER_COUNT_PROPERTY, fileHandlerCountDetail, props);
}
} else if (a.equals(RETAINERRORSSTATICTICS_PROPERTY)) {
if (!val.equals(retainErrorsStaticticsDetail)) {
generateAttributeChangeEvent(RETAINERRORSSTATICTICS_PROPERTY, retainErrorsStaticticsDetail, props);
}
} else if (a.equals(LOG4J_VERSION_PROPERTY)) {
if (!val.equals(log4jVersionDetail)) {
generateAttributeChangeEvent(LOG4J_VERSION_PROPERTY, log4jVersionDetail, props);
}
} else if (a.equals(MAXHISTORY_FILES_PROPERTY)) {
if (!val.equals(maxHistoryFilesDetail)) {
generateAttributeChangeEvent(MAXHISTORY_FILES_PROPERTY, maxHistoryFilesDetail, props);
}
} else if (a.equals(ROTATIONONDATECHANGE_PROPERTY)) {
if (!val.equals(rotationOnDateChangeDetail)) {
generateAttributeChangeEvent(ROTATIONONDATECHANGE_PROPERTY, rotationOnDateChangeDetail, props);
}
} else if (a.equals(FILEHANDLER_PATTERN_PROPERTY)) {
if (!val.equals(fileHandlerPatternDetail)) {
generateAttributeChangeEvent(FILEHANDLER_PATTERN_PROPERTY, fileHandlerPatternDetail, props);
}
} else if (a.equals(FILEHANDLER_FORMATTER_PROPERTY)) {
if (!val.equals(fileHandlerFormatterDetail)) {
generateAttributeChangeEvent(FILEHANDLER_FORMATTER_PROPERTY, fileHandlerFormatterDetail, props);
}
} else if (a.equals(LOGFORMAT_DATEFORMAT_PROPERTY)) {
if (!val.equals(logFormatDateFormatDetail)) {
generateAttributeChangeEvent(LOGFORMAT_DATEFORMAT_PROPERTY, logFormatDateFormatDetail, props);
}
} else if (a.equals(EXCLUDE_FIELDS_PROPERTY)) {
val = (val == null) ? "" : val;
excludeFields = (excludeFields == null) ? "" : excludeFields;
if (!val.equals(excludeFields)) {
generateAttributeChangeEvent(EXCLUDE_FIELDS_PROPERTY, excludeFields, props);
}
} else if (a.equals(MULTI_LINE_MODE_PROPERTY)) {
String oldVal = Boolean.toString(multiLineMode);
if (!val.equalsIgnoreCase(oldVal)) {
generateAttributeChangeEvent(MULTI_LINE_MODE_PROPERTY, oldVal, props);
}
}
}
LOGGER.log(Level.INFO, LogFacade.UPDATED_LOG_LEVELS);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, LogFacade.ERROR_APPLYING_CONF, e);
}
}
}
public void deleted(File deletedFile) {
LOGGER.log(Level.WARNING, LogFacade.CONF_FILE_DELETED, deletedFile.getAbsolutePath());
}
});
}
// Log the messages that were generated very early before this Service
// started. Just use our own logger...
List<EarlyLogger.LevelAndMessage> catchUp = EarlyLogger.getEarlyMessages();
if (!catchUp.isEmpty()) {
for (EarlyLogger.LevelAndMessage levelAndMessage : catchUp) {
LOGGER.log(levelAndMessage.getLevel(), levelAndMessage.getMessage());
}
catchUp.clear();
}
ArrayBlockingQueue<LogRecord> catchEarlyMessage = EarlyLogHandler.earlyMessages;
while (!catchEarlyMessage.isEmpty()) {
LogRecord logRecord = catchEarlyMessage.poll();
if (logRecord != null) {
LOGGER.log(logRecord);
}
}
}
private Collection<Handler> getHandlerServices() {
Set<String> handlerServicesSet = new HashSet<String>();
handlerServicesSet.add(GFFileHandler.class.getName());
String[] handlerServicesArray = handlerServices.split(",");
for (String handlerService : handlerServicesArray) {
handlerServicesSet.add(handlerService);
}
List<Handler> handlers = habitat.getAllServices(Handler.class);
List<Handler> result = new ArrayList<Handler>();
List<Handler> customHandlers = new ArrayList<Handler>();
GFFileHandler gfFileHandler = null;
for (Handler handler: handlers) {
String handlerClassName = handler.getClass().getName();
if (handlerServicesSet.contains(handlerClassName )) {
result.add(handler);
}
if (handlerClassName.equals(GFFileHandler.class.getName())) {
gfFileHandler = (GFFileHandler) handler;
} else {
customHandlers.add(handler);
}
}
// Set formatter on custom handler service if configured
for (Handler handler : customHandlers) {
try {
Map<String, String> props = getLoggingProperties();
String handlerClassName = handler.getClass().getName();
String formatterClassName = props.get(handlerClassName+".formatter");
Formatter formatter = getCustomFormatter(formatterClassName, gfFileHandler);
if (formatter != null) {
handler.setFormatter(formatter);
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, LogFacade.ERROR_APPLYING_CONF, e);
}
}
return result;
}
private Formatter getCustomFormatter(String formatterClassName,
GFFileHandler gfFileHandler)
{
try {
Class customFormatterClass =
ClassLoader.getSystemClassLoader().loadClass(
formatterClassName);
return (Formatter) customFormatterClass.newInstance();
} catch (Exception e) {
return gfFileHandler.findFormatterService(formatterClassName);
}
}
public void generateAttributeChangeEvent(String property, String propertyDetail, Map props) {
PropertyChangeEvent pce = new PropertyChangeEvent(this, property, propertyDetail, props.get(property));
UnprocessedChangeEvents ucel = new UnprocessedChangeEvents(new UnprocessedChangeEvent(pce, "server log file attribute " + property + " changed."));
List<UnprocessedChangeEvents> b = new ArrayList();
b.add(ucel);
ucl.unprocessedTransactedEvents(b);
}
public void addHandler(Handler handler) {
Logger rootLogger = Logger.getLogger("");
if (rootLogger != null) {
synchronized (gfHandlers) {
rootLogger.addHandler(handler);
String handlerName = handler.toString();
gfHandlers.put(handlerName.substring(0, handlerName.indexOf("@")), handler);
}
}
}
public void preDestroy() {
//destroy the handlers
try {
for (ServiceHandle<?> i : habitat.getAllServiceHandles(BuilderHelper.createContractFilter(Handler.class.getName()))) {
i.destroy();
}
System.setOut(oStdOutBackup);
System.setErr(oStdErrBackup);
if (stdoutOutputStream != null) {
stdoutOutputStream.close();
}
if (stderrOutputStream != null) {
stderrOutputStream.close();
}
System.out.println("Completed shutdown of Log manager service");
} catch (Exception e) {
e.printStackTrace();
}
}
}