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.core; 028 029import static org.opends.messages.ConfigMessages.*; 030 031import java.util.ArrayList; 032import java.util.List; 033 034import org.forgerock.i18n.LocalizableMessage; 035import org.forgerock.i18n.slf4j.LocalizedLogger; 036import org.forgerock.opendj.config.server.ConfigException; 037import org.forgerock.opendj.ldap.ResultCode; 038import org.opends.server.admin.server.ConfigurationAddListener; 039import org.opends.server.admin.server.ConfigurationDeleteListener; 040import org.opends.server.admin.server.ServerManagementContext; 041import org.opends.server.admin.std.server.AccessLogPublisherCfg; 042import org.opends.server.admin.std.server.DebugLogPublisherCfg; 043import org.opends.server.admin.std.server.ErrorLogPublisherCfg; 044import org.opends.server.admin.std.server.HTTPAccessLogPublisherCfg; 045import org.opends.server.admin.std.server.LogPublisherCfg; 046import org.opends.server.admin.std.server.RootCfg; 047import org.opends.server.loggers.AbstractLogger; 048import org.opends.server.loggers.AccessLogger; 049import org.opends.server.loggers.DebugLogger; 050import org.opends.server.loggers.ErrorLogger; 051import org.opends.server.loggers.HTTPAccessLogger; 052import org.forgerock.opendj.config.server.ConfigChangeResult; 053import org.opends.server.types.InitializationException; 054 055/** 056 * This class defines a utility that will be used to manage the set of loggers 057 * used in the Directory Server. It will perform the logger initialization when 058 * the server is starting, and then will manage any additions, removals, or 059 * modifications of any loggers while the server is running. 060 */ 061public class LoggerConfigManager implements 062 ConfigurationAddListener<LogPublisherCfg>, 063 ConfigurationDeleteListener<LogPublisherCfg> 064{ 065 066 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 067 068 private final ServerContext serverContext; 069 070 /** 071 * Create the logger config manager with the provided 072 * server context. 073 * 074 * @param context 075 * The server context. 076 */ 077 public LoggerConfigManager(final ServerContext context) 078 { 079 this.serverContext = context; 080 } 081 082 /** 083 * Initializes all the log publishers. 084 * 085 * @throws ConfigException 086 * If an unrecoverable problem arises in the process of 087 * performing the initialization as a result of the server 088 * configuration. 089 * @throws InitializationException 090 * If a problem occurs during initialization that is not 091 * related to the server configuration. 092 */ 093 public void initializeLoggerConfig() 094 throws ConfigException, InitializationException 095 { 096 // Create an internal server management context and retrieve 097 // the root configuration which has the log publisher relation. 098 ServerManagementContext context = ServerManagementContext.getInstance(); 099 RootCfg root = context.getRootConfiguration(); 100 101 root.addLogPublisherAddListener(this); 102 root.addLogPublisherDeleteListener(this); 103 104 List<DebugLogPublisherCfg> debugPublisherCfgs = new ArrayList<>(); 105 List<AccessLogPublisherCfg> accessPublisherCfgs = new ArrayList<>(); 106 List<HTTPAccessLogPublisherCfg> httpAccessPublisherCfgs = new ArrayList<>(); 107 List<ErrorLogPublisherCfg> errorPublisherCfgs = new ArrayList<>(); 108 109 for (String name : root.listLogPublishers()) 110 { 111 LogPublisherCfg config = root.getLogPublisher(name); 112 113 if(config instanceof DebugLogPublisherCfg) 114 { 115 debugPublisherCfgs.add((DebugLogPublisherCfg)config); 116 } 117 else if(config instanceof AccessLogPublisherCfg) 118 { 119 accessPublisherCfgs.add((AccessLogPublisherCfg)config); 120 } 121 else if (config instanceof HTTPAccessLogPublisherCfg) 122 { 123 httpAccessPublisherCfgs.add((HTTPAccessLogPublisherCfg) config); 124 } 125 else if(config instanceof ErrorLogPublisherCfg) 126 { 127 errorPublisherCfgs.add((ErrorLogPublisherCfg)config); 128 } 129 else 130 { 131 throw new ConfigException(ERR_CONFIG_LOGGER_INVALID_OBJECTCLASS.get(config.dn())); 132 } 133 } 134 135 // See if there are active loggers in all categories. If not, then log a 136 // message. 137 // Do not output warn message for debug loggers because it is valid to fully 138 // disable all debug loggers. 139 if (accessPublisherCfgs.isEmpty()) 140 { 141 logger.warn(WARN_CONFIG_LOGGER_NO_ACTIVE_ACCESS_LOGGERS); 142 } 143 if (errorPublisherCfgs.isEmpty()) 144 { 145 logger.warn(WARN_CONFIG_LOGGER_NO_ACTIVE_ERROR_LOGGERS); 146 } 147 148 DebugLogger.getInstance().initializeLogger(debugPublisherCfgs, serverContext); 149 AccessLogger.getInstance().initializeLogger(accessPublisherCfgs, serverContext); 150 HTTPAccessLogger.getInstance().initializeLogger(httpAccessPublisherCfgs, serverContext); 151 ErrorLogger.getInstance().initializeLogger(errorPublisherCfgs, serverContext); 152 } 153 154 /** 155 * Returns the logger instance corresponding to the provided config. If no 156 * logger corresponds to it, null will be returned and a message will be added 157 * to the provided messages list. 158 * 159 * @param config 160 * the config for which to return the logger instance 161 * @param messages 162 * where the error message will be output if no logger correspond to 163 * the provided config. 164 * @return the logger corresponding to the provided config, null if no logger 165 * corresponds. 166 */ 167 private AbstractLogger getLoggerInstance(LogPublisherCfg config, 168 List<LocalizableMessage> messages) 169 { 170 if (config instanceof DebugLogPublisherCfg) 171 { 172 return DebugLogger.getInstance(); 173 } 174 else if (config instanceof AccessLogPublisherCfg) 175 { 176 return AccessLogger.getInstance(); 177 } 178 else if (config instanceof HTTPAccessLogPublisherCfg) 179 { 180 return HTTPAccessLogger.getInstance(); 181 } 182 else if (config instanceof ErrorLogPublisherCfg) 183 { 184 return ErrorLogger.getInstance(); 185 } 186 else 187 { 188 messages.add(ERR_CONFIG_LOGGER_INVALID_OBJECTCLASS.get(config.dn())); 189 return null; 190 } 191 } 192 193 /** {@inheritDoc} */ 194 @Override 195 public boolean isConfigurationAddAcceptable(LogPublisherCfg config, 196 List<LocalizableMessage> unacceptableReasons) 197 { 198 AbstractLogger instance = getLoggerInstance(config, unacceptableReasons); 199 return instance != null 200 && instance.isConfigurationAddAcceptable(config, unacceptableReasons); 201 } 202 203 /** {@inheritDoc} */ 204 @Override 205 public ConfigChangeResult applyConfigurationAdd(LogPublisherCfg config) 206 { 207 final ConfigChangeResult ccr = new ConfigChangeResult(); 208 AbstractLogger instance = getLoggerInstance(config, ccr.getMessages()); 209 if (instance != null) 210 { 211 return instance.applyConfigurationAdd(config); 212 } 213 else 214 { 215 ccr.setResultCode(ResultCode.UNWILLING_TO_PERFORM); 216 return ccr; 217 } 218 } 219 220 /** {@inheritDoc} */ 221 @Override 222 public boolean isConfigurationDeleteAcceptable(LogPublisherCfg config, 223 List<LocalizableMessage> unacceptableReasons) 224 { 225 AbstractLogger instance = getLoggerInstance(config, unacceptableReasons); 226 return instance != null 227 && instance.isConfigurationDeleteAcceptable(config, unacceptableReasons); 228 } 229 230 /** {@inheritDoc} */ 231 @Override 232 public ConfigChangeResult applyConfigurationDelete(LogPublisherCfg config) 233 { 234 final ConfigChangeResult ccr = new ConfigChangeResult(); 235 AbstractLogger instance = getLoggerInstance(config, ccr.getMessages()); 236 if (instance != null) 237 { 238 return instance.applyConfigurationDelete(config); 239 } 240 else 241 { 242 ccr.setResultCode(ResultCode.UNWILLING_TO_PERFORM); 243 return ccr; 244 } 245 } 246}