001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2008 Sun Microsystems, Inc. 015 * Portions Copyright 2013-2015 ForgeRock AS. 016 */ 017package org.opends.server.loggers; 018 019import static org.opends.messages.ConfigMessages.*; 020 021import java.util.Collection; 022 023import org.forgerock.i18n.LocalizableMessage; 024import org.opends.messages.Severity; 025import org.opends.server.admin.ClassPropertyDefinition; 026import org.opends.server.admin.std.meta.ErrorLogPublisherCfgDefn; 027import org.opends.server.admin.std.server.ErrorLogPublisherCfg; 028import org.opends.server.api.DirectoryThread; 029import org.opends.server.backends.task.Task; 030import org.opends.server.core.ServerContext; 031 032/** 033 * This class defines the wrapper that will invoke all registered error loggers 034 * for each type of request received or response sent. If no error log 035 * publishers are registered, messages will be directed to standard out. 036 */ 037public class ErrorLogger extends AbstractLogger 038 <ErrorLogPublisher<ErrorLogPublisherCfg>, ErrorLogPublisherCfg> 039{ 040 041 private static LoggerStorage 042 <ErrorLogPublisher<ErrorLogPublisherCfg>, ErrorLogPublisherCfg> 043 loggerStorage = new LoggerStorage<>(); 044 045 /** The singleton instance of this class for configuration purposes. */ 046 private static final ErrorLogger instance = new ErrorLogger(); 047 048 /** 049 * Retrieve the singleton instance of this class. 050 * 051 * @return The singleton instance of this logger. 052 */ 053 public static ErrorLogger getInstance() 054 { 055 return instance; 056 } 057 058 /** 059 * The constructor for this class. 060 */ 061 private ErrorLogger() 062 { 063 super((Class) ErrorLogPublisher.class, 064 ERR_CONFIG_LOGGER_INVALID_ERROR_LOGGER_CLASS); 065 } 066 067 /** {@inheritDoc} */ 068 @Override 069 protected ClassPropertyDefinition getJavaClassPropertyDefinition() 070 { 071 return ErrorLogPublisherCfgDefn.getInstance() 072 .getJavaClassPropertyDefinition(); 073 } 074 075 /** {@inheritDoc} */ 076 @Override 077 protected Collection<ErrorLogPublisher<ErrorLogPublisherCfg>> getLogPublishers() 078 { 079 return loggerStorage.getLogPublishers(); 080 } 081 082 /** 083 * Writes a message to the error log using the provided information. 084 * <p> 085 * Category is defined using either short name (used for classes in well 086 * defined packages) or fully qualified classname. Conversion to short name is 087 * done automatically when loggers are created, see 088 * {@code LoggingCategoryNames} for list of existing short names. 089 * 090 * @param category 091 * The category of the message, which is either a classname or a 092 * simple category name defined in {@code LoggingCategoryNames} 093 * class. 094 * @param severity 095 * The severity of the message. 096 * @param message 097 * The message to be logged. 098 * @param exception 099 * The exception to be logged. May be {@code null}. 100 */ 101 public static void log(String category, Severity severity, LocalizableMessage message, Throwable exception) 102 { 103 for (ErrorLogPublisher<?> publisher : loggerStorage.getLogPublishers()) 104 { 105 publisher.log(category, severity, message, exception); 106 } 107 108 if (Thread.currentThread() instanceof DirectoryThread) 109 { 110 DirectoryThread thread = (DirectoryThread) Thread.currentThread(); 111 Task task = thread.getAssociatedTask(); 112 if (task != null) 113 { 114 task.addLogMessage(severity, message, exception); 115 } 116 } 117 } 118 119 /** 120 * Check if logging is enabled for the provided category and severity. 121 * 122 * @param category 123 * The category of the logging event, which is either a classname or 124 * a simple category name defined in {@code LoggingCategoryNames} 125 * class. 126 * @param severity 127 * The severity of logging event. 128 * @return {@code true} if logger is enabled 129 */ 130 public static boolean isEnabledFor(String category, Severity severity) 131 { 132 if (Thread.currentThread() instanceof DirectoryThread) 133 { 134 DirectoryThread thread = (DirectoryThread) Thread.currentThread(); 135 Task task = thread.getAssociatedTask(); 136 if (task != null) 137 { 138 return true; 139 } 140 } 141 for (ErrorLogPublisher<ErrorLogPublisherCfg> publisher : loggerStorage.getLogPublishers()) 142 { 143 if (publisher.isEnabledFor(category, severity)) 144 { 145 return true; 146 } 147 } 148 return false; 149 } 150 151 @Override 152 public final synchronized void addLogPublisher(final ErrorLogPublisher<ErrorLogPublisherCfg> publisher) 153 { 154 loggerStorage.addLogPublisher(publisher); 155 adjustJulLevel(); 156 } 157 158 @Override 159 public final synchronized boolean removeLogPublisher(final ErrorLogPublisher<ErrorLogPublisherCfg> publisher) 160 { 161 final boolean removed = loggerStorage.removeLogPublisher(publisher); 162 adjustJulLevel(); 163 return removed; 164 } 165 166 @Override 167 public final synchronized void removeAllLogPublishers() 168 { 169 loggerStorage.removeAllLogPublishers(); 170 adjustJulLevel(); 171 } 172 173 private void adjustJulLevel() 174 { 175 final ServerContext serverContext = getServerContext(); 176 if (serverContext != null) 177 { 178 serverContext.getLoggerConfigManager().adjustJulLevel(); 179 } 180 } 181}