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