| File was renamed from opends/src/server/org/opends/server/loggers/DirectoryAccessLogger.java |
| | |
| | | |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.Iterator; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.concurrent.CopyOnWriteArrayList; |
| | | import java.util.logging.Level; |
| | | import java.util.logging.Logger; |
| | | import java.util.*; |
| | | |
| | | import org.opends.server.api.AccessLogger; |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.api.ConfigurableComponent; |
| | | import org.opends.server.config.BooleanConfigAttribute; |
| | | import org.opends.server.config.ConfigAttribute; |
| | | import org.opends.server.config.ConfigEntry; |
| | | import org.opends.server.api.*; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.config.StringConfigAttribute; |
| | | import org.opends.server.core.AbandonOperation; |
| | | import org.opends.server.core.AddOperation; |
| | | import org.opends.server.core.BindOperation; |
| | |
| | | import org.opends.server.core.ModifyDNOperation; |
| | | import org.opends.server.core.SearchOperation; |
| | | import org.opends.server.core.UnbindOperation; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ConfigChangeResult; |
| | | import org.opends.server.types.DisconnectReason; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.SearchResultEntry; |
| | | import org.opends.server.types.SearchResultReference; |
| | | import org.opends.server.types.*; |
| | | |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.messages.LoggerMessages.*; |
| | | import static org.opends.server.messages.ConfigMessages.*; |
| | | import static org.opends.server.messages.MessageHandler.*; |
| | | |
| | | import static org.opends.server.messages.MessageHandler.getMessage; |
| | | import org.opends.server.admin.std.server.FileBasedAccessLogPublisherCfg; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import static org.opends.server.util.StaticUtils.getFileForPath; |
| | | import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; |
| | | import org.opends.server.util.TimeThread; |
| | | |
| | | |
| | | /** |
| | | * This class provides the implementation of the access logger used by |
| | | * the directory server. |
| | | */ |
| | | public class DirectoryAccessLogger extends AccessLogger |
| | | implements ConfigurableComponent |
| | | public class TextAccessLogPublisher |
| | | extends AccessLogPublisher<FileBasedAccessLogPublisherCfg> |
| | | implements ConfigurationChangeListener<FileBasedAccessLogPublisherCfg> |
| | | { |
| | | private static final int DEFAULT_TIME_INTERVAL = 30000; |
| | | private static final int DEFAULT_BUFFER_SIZE = 65536; |
| | | private boolean suppressInternalOps = true; |
| | | private Logger accessLogger = null; |
| | | private String changedLogFileName = null; |
| | | private DirectoryFileHandler fileHandler = null; |
| | | private TextWriter writer; |
| | | |
| | | // The DN of the config entry this component is associated with. |
| | | private DN configDN; |
| | | |
| | | private FileBasedAccessLogPublisherCfg currentConfig; |
| | | |
| | | /** |
| | | * Initializes this access logger based on the information in the provided |
| | | * configuration entry. |
| | | * Returns an instance of the text access log publisher that will print |
| | | * all messages to the provided writer. This is used to print the messages |
| | | * to the console when the server starts up. |
| | | * |
| | | * @param configEntry The configuration entry that contains the information |
| | | * to use to initialize this access logger. |
| | | * |
| | | * @throws ConfigException If an unrecoverable problem arises in the |
| | | * process of performing the initialization. |
| | | */ |
| | | public void initializeAccessLogger(ConfigEntry configEntry) |
| | | throws ConfigException |
| | | * @param writer The text writer where the message will be written to. |
| | | * @return The instance of the text error log publisher that will print |
| | | * all messages to standard out. |
| | | */ |
| | | public static TextAccessLogPublisher |
| | | getStartupTextAccessPublisher(TextWriter writer) |
| | | { |
| | | configDN = configEntry.getDN(); |
| | | TextAccessLogPublisher startupPublisher = new TextAccessLogPublisher(); |
| | | startupPublisher.writer = writer; |
| | | |
| | | // FIXME - read the logger name from the config |
| | | StringConfigAttribute logFileStub = |
| | | new StringConfigAttribute(ATTR_LOGGER_FILE, |
| | | getMessage(MSGID_CONFIG_LOGGER_DESCRIPTION_CLASS_NAME), |
| | | true, false, true); |
| | | StringConfigAttribute logFileNameAttr = (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(logFileStub); |
| | | |
| | | if(logFileNameAttr == null) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_NO_FILE_NAME; |
| | | String message = getMessage(msgID, configEntry.getDN().toString()); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | initializeAccessLogger(logFileNameAttr.activeValue(), configEntry); |
| | | |
| | | return startupPublisher; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void initializeAccessLogPublisher( |
| | | FileBasedAccessLogPublisherCfg config) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | File logFile = getFileForPath(config.getLogFile()); |
| | | FileNamingPolicy fnPolicy = new TimeStampNaming(logFile); |
| | | |
| | | try |
| | | { |
| | | FilePermission perm = |
| | | FilePermission.decodeUNIXMode(config.getLogFileMode()); |
| | | |
| | | LogPublisherErrorHandler errorHandler = |
| | | new LogPublisherErrorHandler(config.dn()); |
| | | |
| | | boolean writerAutoFlush = |
| | | config.isAutoFlush() && !config.isAsynchronous(); |
| | | |
| | | MultifileTextWriter writer = |
| | | new MultifileTextWriter("Multifile Text Writer for " + |
| | | config.dn().toNormalizedString(), |
| | | config.getTimeInterval(), |
| | | fnPolicy, |
| | | perm, |
| | | errorHandler, |
| | | "UTF-8", |
| | | writerAutoFlush, |
| | | config.isAppend(), |
| | | (int)config.getBufferSize()); |
| | | |
| | | // Validate retention and rotation policies. |
| | | for(DN dn : config.getRotationPolicyDN()) |
| | | { |
| | | RotationPolicy policy = DirectoryServer.getRotationPolicy(dn); |
| | | if(policy != null) |
| | | { |
| | | writer.addRotationPolicy(policy); |
| | | } |
| | | else |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_INVALID_ROTATION_POLICY; |
| | | String message = getMessage(msgID, dn.toString(), |
| | | config.dn().toString()); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | for(DN dn: config.getRetentionPolicyDN()) |
| | | { |
| | | RetentionPolicy policy = DirectoryServer.getRetentionPolicy(dn); |
| | | if(policy != null) |
| | | { |
| | | writer.addRetentionPolicy(policy); |
| | | } |
| | | else |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_INVALID_RETENTION_POLICY; |
| | | String message = getMessage(msgID, dn.toString(), |
| | | config.dn().toString()); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | |
| | | if(config.isAsynchronous()) |
| | | { |
| | | this.writer = new AsyncronousTextWriter("Asyncronous Text Writer for " + |
| | | config.dn().toNormalizedString(), config.getQueueSize(), |
| | | config.isAutoFlush(), |
| | | writer); |
| | | } |
| | | else |
| | | { |
| | | this.writer = writer; |
| | | } |
| | | } |
| | | catch(DirectoryException e) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGING_CANNOT_CREATE_WRITER; |
| | | String message = getMessage(msgID, config.dn().toString(), |
| | | String.valueOf(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | |
| | | } |
| | | catch(IOException e) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGING_CANNOT_CREATE_WRITER; |
| | | String message = getMessage(msgID, config.dn().toString(), |
| | | String.valueOf(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | |
| | | } |
| | | |
| | | suppressInternalOperations = config.isSuppressInternalOperations(); |
| | | |
| | | currentConfig = config; |
| | | |
| | | config.addFileBasedAccessChangeListener(this); |
| | | } |
| | | |
| | | /** |
| | | * Closes this access logger and releases any resources it might have held. |
| | | * {@inheritDoc} |
| | | */ |
| | | public void closeAccessLogger() |
| | | public boolean isConfigurationChangeAcceptable( |
| | | FileBasedAccessLogPublisherCfg config, List<String> unacceptableReasons) |
| | | { |
| | | // Make sure the permission is valid. |
| | | try |
| | | { |
| | | if(!currentConfig.getLogFileMode().equalsIgnoreCase( |
| | | config.getLogFileMode())) |
| | | { |
| | | FilePermission.decodeUNIXMode(config.getLogFileMode()); |
| | | } |
| | | if(!currentConfig.getLogFile().equalsIgnoreCase(config.getLogFile())) |
| | | { |
| | | File logFile = getFileForPath(config.getLogFile()); |
| | | if(logFile.createNewFile()) |
| | | { |
| | | logFile.delete(); |
| | | } |
| | | } |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGING_CANNOT_CREATE_WRITER; |
| | | String message = getMessage(msgID, config.dn().toString(), |
| | | stackTraceToSingleLineString(e)); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | |
| | | // Validate retention and rotation policies. |
| | | for(DN dn : config.getRotationPolicyDN()) |
| | | { |
| | | RotationPolicy policy = DirectoryServer.getRotationPolicy(dn); |
| | | if(policy == null) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_INVALID_ROTATION_POLICY; |
| | | String message = getMessage(msgID, dn.toString(), |
| | | config.dn().toString()); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | } |
| | | for(DN dn: config.getRetentionPolicyDN()) |
| | | { |
| | | RetentionPolicy policy = DirectoryServer.getRetentionPolicy(dn); |
| | | if(policy == null) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_INVALID_RETENTION_POLICY; |
| | | String message = getMessage(msgID, dn.toString(), |
| | | config.dn().toString()); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConfigChangeResult applyConfigurationChange( |
| | | FileBasedAccessLogPublisherCfg config) |
| | | { |
| | | // Default result code. |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<String> messages = new ArrayList<String>(); |
| | | |
| | | suppressInternalOperations = config.isSuppressInternalOperations(); |
| | | |
| | | File logFile = getFileForPath(config.getLogFile()); |
| | | FileNamingPolicy fnPolicy = new TimeStampNaming(logFile); |
| | | |
| | | try |
| | | { |
| | | FilePermission perm = |
| | | FilePermission.decodeUNIXMode(config.getLogFileMode()); |
| | | |
| | | boolean writerAutoFlush = |
| | | config.isAutoFlush() && !config.isAsynchronous(); |
| | | |
| | | TextWriter currentWriter; |
| | | // Determine the writer we are using. If we were writing asyncronously, |
| | | // we need to modify the underlaying writer. |
| | | if(writer instanceof AsyncronousTextWriter) |
| | | { |
| | | currentWriter = ((AsyncronousTextWriter)writer).getWrappedWriter(); |
| | | } |
| | | else |
| | | { |
| | | currentWriter = writer; |
| | | } |
| | | |
| | | if(currentWriter instanceof MultifileTextWriter) |
| | | { |
| | | MultifileTextWriter mfWriter = (MultifileTextWriter)currentWriter; |
| | | |
| | | mfWriter.setNamingPolicy(fnPolicy); |
| | | mfWriter.setFilePermissions(perm); |
| | | mfWriter.setAppend(config.isAppend()); |
| | | mfWriter.setAutoFlush(writerAutoFlush); |
| | | mfWriter.setBufferSize((int)config.getBufferSize()); |
| | | mfWriter.setInterval(config.getTimeInterval()); |
| | | |
| | | mfWriter.removeAllRetentionPolicies(); |
| | | mfWriter.removeAllRotationPolicies(); |
| | | |
| | | for(DN dn : config.getRotationPolicyDN()) |
| | | { |
| | | RotationPolicy policy = DirectoryServer.getRotationPolicy(dn); |
| | | if(policy != null) |
| | | { |
| | | mfWriter.addRotationPolicy(policy); |
| | | } |
| | | else |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_INVALID_ROTATION_POLICY; |
| | | String message = getMessage(msgID, dn.toString(), |
| | | config.dn().toString()); |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | messages.add(message); |
| | | } |
| | | } |
| | | for(DN dn: config.getRetentionPolicyDN()) |
| | | { |
| | | RetentionPolicy policy = DirectoryServer.getRetentionPolicy(dn); |
| | | if(policy != null) |
| | | { |
| | | mfWriter.addRetentionPolicy(policy); |
| | | } |
| | | else |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_INVALID_RETENTION_POLICY; |
| | | String message = getMessage(msgID, dn.toString(), |
| | | config.dn().toString()); |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | messages.add(message); |
| | | } |
| | | } |
| | | |
| | | |
| | | if(writer instanceof AsyncronousTextWriter && !config.isAsynchronous()) |
| | | { |
| | | // The asynronous setting is being turned off. |
| | | AsyncronousTextWriter asyncWriter = ((AsyncronousTextWriter)writer); |
| | | writer = mfWriter; |
| | | asyncWriter.shutdown(false); |
| | | } |
| | | |
| | | if(!(writer instanceof AsyncronousTextWriter) && |
| | | config.isAsynchronous()) |
| | | { |
| | | // The asynronous setting is being turned on. |
| | | AsyncronousTextWriter asyncWriter = |
| | | new AsyncronousTextWriter("Asyncronous Text Writer for " + |
| | | config.dn().toNormalizedString(), config.getQueueSize(), |
| | | config.isAutoFlush(), |
| | | mfWriter); |
| | | writer = asyncWriter; |
| | | } |
| | | |
| | | if((currentConfig.isAsynchronous() && config.isAsynchronous()) && |
| | | (currentConfig.getQueueSize() != config.getQueueSize())) |
| | | { |
| | | adminActionRequired = true; |
| | | } |
| | | |
| | | currentConfig = config; |
| | | } |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGING_CANNOT_CREATE_WRITER; |
| | | String message = getMessage(msgID, config.dn().toString(), |
| | | stackTraceToSingleLineString(e)); |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | messages.add(message); |
| | | |
| | | } |
| | | |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public void close() |
| | | { |
| | | fileHandler.close(); |
| | | writer.shutdown(); |
| | | |
| | | if(currentConfig != null) |
| | | { |
| | | currentConfig.removeFileBasedAccessChangeListener(this); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | public void logConnect(ClientConnection clientConnection) |
| | | { |
| | | long connectionID = clientConnection.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | buffer.append("CONNECT conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" CONNECT conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" from="); |
| | | buffer.append(clientConnection.getClientAddress()); |
| | |
| | | buffer.append(" protocol="); |
| | | buffer.append(clientConnection.getProtocol()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | |
| | | } |
| | | |
| | |
| | | String message) |
| | | { |
| | | long connectionID = clientConnection.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("DISCONNECT conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" DISCONNECT conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" reason=\""); |
| | | buffer.append(disconnectReason); |
| | |
| | | |
| | | buffer.append("\""); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logAbandonRequest(AbandonOperation abandonOperation) |
| | | { |
| | | long connectionID = abandonOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("ABANDON conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" ABANDON conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(abandonOperation.getOperationID()); |
| | |
| | | buffer.append(" idToAbandon="); |
| | | buffer.append(abandonOperation.getIDToAbandon()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | /** |
| | |
| | | public void logAbandonResult(AbandonOperation abandonOperation) |
| | | { |
| | | long connectionID = abandonOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("ABANDON conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" ABANDON conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(abandonOperation.getOperationID()); |
| | |
| | | buffer.append(" etime="); |
| | | buffer.append(abandonOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logAddRequest(AddOperation addOperation) |
| | | { |
| | | long connectionID = addOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("ADD conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" ADD conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(addOperation.getOperationID()); |
| | |
| | | addOperation.getRawEntryDN().toString(buffer); |
| | | buffer.append("\""); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logAddResponse(AddOperation addOperation) |
| | | { |
| | | long connectionID = addOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("ADD conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" ADD conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(addOperation.getOperationID()); |
| | |
| | | buffer.append("\" etime="); |
| | | buffer.append(addOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logBindRequest(BindOperation bindOperation) |
| | | { |
| | | long connectionID = bindOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("BIND conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" BIND conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(bindOperation.getOperationID()); |
| | |
| | | bindOperation.getRawBindDN().toString(buffer); |
| | | buffer.append("\""); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logBindResponse(BindOperation bindOperation) |
| | | { |
| | | long connectionID = bindOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("BIND conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" BIND conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(bindOperation.getOperationID()); |
| | |
| | | buffer.append("\" etime="); |
| | | buffer.append(bindOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logCompareRequest(CompareOperation compareOperation) |
| | | { |
| | | long connectionID = compareOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("COMPARE conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" COMPARE conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(compareOperation.getOperationID()); |
| | |
| | | buffer.append("\" attr="); |
| | | buffer.append(compareOperation.getAttributeType()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logCompareResponse(CompareOperation compareOperation) |
| | | { |
| | | long connectionID = compareOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("COMPARE conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" COMPARE conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(compareOperation.getOperationID()); |
| | |
| | | buffer.append("\" etime="); |
| | | buffer.append(compareOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logDeleteRequest(DeleteOperation deleteOperation) |
| | | { |
| | | long connectionID = deleteOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("DELETE conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" DELETE conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(deleteOperation.getOperationID()); |
| | |
| | | buffer.append("\""); |
| | | |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logDeleteResponse(DeleteOperation deleteOperation) |
| | | { |
| | | long connectionID = deleteOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("DELETE conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" DELETE conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(deleteOperation.getOperationID()); |
| | |
| | | buffer.append("\" etime="); |
| | | buffer.append(deleteOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logExtendedRequest(ExtendedOperation extendedOperation) |
| | | { |
| | | long connectionID = extendedOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("EXTENDED conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" EXTENDED conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(extendedOperation.getOperationID()); |
| | |
| | | buffer.append(extendedOperation.getRequestOID()); |
| | | buffer.append("\""); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logExtendedResponse(ExtendedOperation extendedOperation) |
| | | { |
| | | long connectionID = extendedOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("EXTENDED conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" EXTENDED conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(extendedOperation.getOperationID()); |
| | |
| | | buffer.append("\" etime="); |
| | | buffer.append(extendedOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logModifyRequest(ModifyOperation modifyOperation) |
| | | { |
| | | long connectionID = modifyOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("MODIFY conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" MODIFY conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(modifyOperation.getOperationID()); |
| | |
| | | modifyOperation.getRawEntryDN().toString(buffer); |
| | | buffer.append("\""); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logModifyResponse(ModifyOperation modifyOperation) |
| | | { |
| | | long connectionID = modifyOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("MODIFY conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" MODIFY conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(modifyOperation.getOperationID()); |
| | |
| | | buffer.append("\" etime="); |
| | | buffer.append(modifyOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logModifyDNRequest(ModifyDNOperation modifyDNOperation) |
| | | { |
| | | long connectionID = modifyDNOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("MODIFYDN conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" MODIFYDN conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(modifyDNOperation.getOperationID()); |
| | |
| | | newSuperior.toString(buffer); |
| | | } |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logModifyDNResponse(ModifyDNOperation modifyDNOperation) |
| | | { |
| | | long connectionID = modifyDNOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("MODIFYDN conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" MODIFYDN conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(modifyDNOperation.getOperationID()); |
| | |
| | | buffer.append("\" etime="); |
| | | buffer.append(modifyDNOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logSearchRequest(SearchOperation searchOperation) |
| | | { |
| | | long connectionID = searchOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("SEARCH conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" SEARCH conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(searchOperation.getOperationID()); |
| | |
| | | buffer.append("\""); |
| | | } |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logSearchResultDone(SearchOperation searchOperation) |
| | | { |
| | | long connectionID = searchOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("SEARCH conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" SEARCH conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(searchOperation.getOperationID()); |
| | |
| | | buffer.append(" etime="); |
| | | buffer.append(searchOperation.getProcessingTime()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | |
| | | |
| | |
| | | public void logUnbind(UnbindOperation unbindOperation) |
| | | { |
| | | long connectionID = unbindOperation.getConnectionID(); |
| | | if(connectionID < 0 && suppressInternalOps) |
| | | if (connectionID < 0 && suppressInternalOperations) |
| | | { |
| | | return; |
| | | } |
| | | StringBuilder buffer = new StringBuilder(50); |
| | | |
| | | buffer.append("UNBIND conn="); |
| | | buffer.append("["); |
| | | buffer.append(TimeThread.getLocalTime()); |
| | | buffer.append("]"); |
| | | buffer.append(" UNBIND conn="); |
| | | buffer.append(connectionID); |
| | | buffer.append(" op="); |
| | | buffer.append(unbindOperation.getOperationID()); |
| | | buffer.append(" msgID="); |
| | | buffer.append(unbindOperation.getMessageID()); |
| | | |
| | | accessLogger.log(DirectoryLogLevel.INFORMATIONAL, buffer.toString()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided object is equal to this access logger. |
| | | * |
| | | * @param obj The object for which to make the determination. |
| | | * |
| | | * @return <CODE>true</CODE> if the provided object is equal |
| | | * to this access logger, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean equals(Object obj) |
| | | { |
| | | if(this == obj) { |
| | | return true; |
| | | } |
| | | |
| | | if((obj == null) || (obj.getClass() != this.getClass())) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | return accessLogger.equals(obj); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the hash code for this access logger. |
| | | * |
| | | * @return The hash code for this access logger. |
| | | */ |
| | | public int hashCode() |
| | | { |
| | | return accessLogger.hashCode(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the configuration entry with which this component is |
| | | * associated. |
| | | * |
| | | * @return The DN of the configuration entry with which this component is |
| | | * associated. |
| | | */ |
| | | public DN getConfigurableComponentEntryDN() |
| | | { |
| | | return configDN; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of configuration attributes that are associated with this |
| | | * configurable component. |
| | | * |
| | | * @return The set of configuration attributes that are associated with this |
| | | * configurable component. |
| | | */ |
| | | public List<ConfigAttribute> getConfigurationAttributes() |
| | | { |
| | | // NYI |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the configuration entry that will result from a proposed |
| | | * modification is acceptable to this change listener. |
| | | * |
| | | * @param configEntry The configuration entry that will result from |
| | | * the requested update. |
| | | * @param unacceptableReasons A buffer to which this method can append a |
| | | * human-readable message explaining why the |
| | | * proposed change is not acceptable. |
| | | * |
| | | * @return <CODE>true</CODE> if the proposed entry contains an acceptable |
| | | * configuration, or <CODE>false</CODE> if it does not. |
| | | */ |
| | | public boolean hasAcceptableConfiguration(ConfigEntry configEntry, |
| | | List<String> unacceptableReasons) |
| | | { |
| | | try |
| | | { |
| | | StringConfigAttribute logFileStub = |
| | | new StringConfigAttribute(ATTR_LOGGER_FILE, |
| | | getMessage(MSGID_CONFIG_LOGGER_DESCRIPTION_CLASS_NAME), |
| | | true, false, true); |
| | | StringConfigAttribute logFileNameAttr = (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(logFileStub); |
| | | |
| | | if(logFileNameAttr == null) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_NO_FILE_NAME; |
| | | String message = getMessage(msgID, configEntry.getDN().toString()); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | changedLogFileName = logFileNameAttr.pendingValue(); |
| | | } catch (ConfigException ce) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_INVALID_ACCESS_LOGGER_CLASS; |
| | | String message = getMessage(msgID, this.getClass().getName(), |
| | | configEntry.getDN().toString(), |
| | | String.valueOf(ce)); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Attempts to apply a new configuration to this Directory Server component |
| | | * based on the provided changed entry. |
| | | * |
| | | * @param configEntry The configuration entry that containing the |
| | | * updated configuration for this component. |
| | | * @param detailedResults Indicates whether to provide detailed information |
| | | * about any actions performed. |
| | | * |
| | | * @return Information about the result of processing the configuration |
| | | * change. |
| | | */ |
| | | public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry, |
| | | boolean detailedResults) |
| | | { |
| | | fileHandler.close(); |
| | | // reinitialize the logger. |
| | | try |
| | | { |
| | | initializeAccessLogger(changedLogFileName, configEntry); |
| | | } catch(ConfigException ce) |
| | | { |
| | | // TODO - log the change failure. |
| | | return new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(), |
| | | false); |
| | | } |
| | | |
| | | return new ConfigChangeResult(ResultCode.SUCCESS, false); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Initialize the JDK logger an associate a file handler with the |
| | | * specified file name with it. |
| | | * |
| | | * @param logFileName The name of the log file to write to. |
| | | * @param configEntry The configuration entry with the information to use to |
| | | * initialize this logger. |
| | | * |
| | | * @throws ConfigException If an unrecoverable problem arises in the |
| | | * process of performing the initialization. |
| | | */ |
| | | private void initializeAccessLogger(String logFileName, |
| | | ConfigEntry configEntry) throws ConfigException |
| | | { |
| | | accessLogger = |
| | | Logger.getLogger("org.opends.server.loggers.DirectoryAccessLogger"); |
| | | accessLogger.setLevel(Level.ALL); |
| | | |
| | | File logFile = new File(logFileName); |
| | | if(!logFile.isAbsolute()) |
| | | { |
| | | logFile = new File (DirectoryServer.getServerRoot() + File.separator + |
| | | logFileName); |
| | | } |
| | | |
| | | BooleanConfigAttribute enabledAttr; |
| | | try |
| | | { |
| | | BooleanConfigAttribute enabledStub = |
| | | new BooleanConfigAttribute(ATTR_LOGGER_SUPPRESS_INTERNAL_OPERATIONS, |
| | | getMessage(MSGID_CONFIG_LOGGER_SUPPRESS_INTERNAL_OPERATIONS), |
| | | false); |
| | | enabledAttr = (BooleanConfigAttribute) |
| | | configEntry.getConfigAttribute(enabledStub); |
| | | |
| | | if (enabledAttr != null) |
| | | { |
| | | suppressInternalOps = enabledAttr.pendingValue(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | int msgID = MSGID_CONFIG_LOGGER_INVALID_SUPPRESS_INT_OPERATION_VALUE; |
| | | String message = getMessage(msgID, configEntry.getDN().toString(), |
| | | String.valueOf(e)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | |
| | | |
| | | try |
| | | { |
| | | int bufferSize = RotationConfigUtil.getIntegerAttribute(configEntry, |
| | | ATTR_LOGGER_BUFFER_SIZE, MSGID_LOGGER_BUFFER_SIZE); |
| | | if(bufferSize == -1) |
| | | { |
| | | bufferSize = DEFAULT_BUFFER_SIZE; |
| | | } |
| | | CopyOnWriteArrayList<RotationPolicy> rp = |
| | | RotationConfigUtil.getRotationPolicies(configEntry); |
| | | fileHandler = new DirectoryFileHandler(configEntry, |
| | | logFile.getAbsolutePath(), |
| | | bufferSize); |
| | | fileHandler.setFormatter(new DirectoryFileFormatter(false)); |
| | | accessLogger.addHandler(fileHandler); |
| | | |
| | | if(rp != null) |
| | | { |
| | | ArrayList<ActionType> actions = |
| | | RotationConfigUtil.getPostRotationActions(configEntry); |
| | | fileHandler.setPostRotationActions(actions); |
| | | for(RotationPolicy rotationPolicy : rp) |
| | | { |
| | | if(rotationPolicy instanceof SizeBasedRotationPolicy) |
| | | { |
| | | long fileSize = |
| | | ((SizeBasedRotationPolicy) rotationPolicy).getMaxFileSize(); |
| | | fileHandler.setFileSize(fileSize); |
| | | rp.remove(rotationPolicy); |
| | | } |
| | | } |
| | | } |
| | | |
| | | CopyOnWriteArrayList<RetentionPolicy> retentionPolicies = |
| | | RotationConfigUtil.getRetentionPolicies(configEntry); |
| | | |
| | | int threadTimeInterval = RotationConfigUtil.getIntegerAttribute( |
| | | configEntry, ATTR_LOGGER_THREAD_INTERVAL, |
| | | MSGID_LOGGER_THREAD_INTERVAL); |
| | | if(threadTimeInterval == -1) |
| | | { |
| | | threadTimeInterval = DEFAULT_TIME_INTERVAL; |
| | | } |
| | | |
| | | LoggerThread lt = new LoggerThread("AccessLogger Thread", |
| | | threadTimeInterval, fileHandler, rp, |
| | | retentionPolicies); |
| | | lt.start(); |
| | | |
| | | } catch(IOException ioe) { |
| | | int msgID = MSGID_LOG_ACCESS_CANNOT_ADD_FILE_HANDLER; |
| | | String message = getMessage(msgID, String.valueOf(ioe)); |
| | | throw new ConfigException(msgID, message, ioe); |
| | | } |
| | | writer.writeRecord(buffer.toString()); |
| | | } |
| | | } |
| | | |