From 33092f68b1dfc3b9dae653b8b0b95cbab5381d5c Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 11 Oct 2011 16:34:58 +0000
Subject: [PATCH] Fix OPENDJ-308: Implement access log filtering and configurable message format
---
opends/resource/schema/02-config.ldif | 34 +
opends/src/server/org/opends/server/loggers/TextAuditLogPublisher.java | 23
opends/src/admin/defn/org/opends/server/admin/std/AccessLogFilteringCriteriaConfiguration.xml | 98 ++++
opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java | 885 ++++++++++++++++++++++++++----------
opends/src/admin/defn/org/opends/server/admin/std/FileBasedAccessLogPublisherConfiguration.xml | 46 +
opends/src/admin/defn/org/opends/server/admin/std/FileBasedAuditLogPublisherConfiguration.xml | 288 ++++++++++++
opends/src/admin/messages/FileBasedAuditLogPublisherCfgDefn.properties | 26 +
opends/src/admin/messages/FileBasedAccessLogPublisherCfgDefn.properties | 7
opends/resource/config/config.ldif | 2
opends/src/admin/messages/AccessLogFilteringCriteriaCfgDefn.properties | 17
10 files changed, 1,165 insertions(+), 261 deletions(-)
diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index 6a52c56..836689e 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -706,7 +706,7 @@
objectClass: top
objectClass: ds-cfg-log-publisher
objectClass: ds-cfg-access-log-publisher
-objectClass: ds-cfg-file-based-access-log-publisher
+objectClass: ds-cfg-file-based-audit-log-publisher
cn: File-Based Audit Logger
ds-cfg-java-class: org.opends.server.loggers.TextAuditLogPublisher
ds-cfg-enabled: false
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index 06b6ad4..9887e52 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -2668,6 +2668,14 @@
NAME 'ds-cfg-rename-inbound-attributes'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
X-ORIGIN 'OpenDJ Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.30
+ NAME 'ds-cfg-filtering-policy'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'OpenDJ Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.31
+ NAME 'ds-cfg-log-record-type'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
NAME 'ds-cfg-access-control-handler'
SUP top
@@ -2932,7 +2940,8 @@
ds-cfg-buffer-size $
ds-cfg-auto-flush $
ds-cfg-append $
- ds-cfg-queue-size )
+ ds-cfg-queue-size $
+ ds-cfg-filtering-policy )
X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.26
NAME 'ds-cfg-file-based-debug-log-publisher'
@@ -4442,3 +4451,26 @@
MAY ( ds-cfg-remove-inbound-attributes $
ds-cfg-rename-inbound-attributes )
X-ORIGIN 'OpenDJ Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.6
+ NAME 'ds-cfg-file-based-audit-log-publisher'
+ SUP ds-cfg-access-log-publisher
+ STRUCTURAL
+ MUST ( ds-cfg-log-file $
+ ds-cfg-asynchronous $
+ ds-cfg-log-file-permissions )
+ MAY ( ds-cfg-rotation-policy $
+ ds-cfg-rotation-action $
+ ds-cfg-retention-policy $
+ ds-cfg-time-interval $
+ ds-cfg-buffer-size $
+ ds-cfg-auto-flush $
+ ds-cfg-append $
+ ds-cfg-queue-size )
+ X-ORIGIN 'OpenDJ Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.7
+ NAME 'ds-cfg-access-log-filtering-criteria'
+ SUP top
+ STRUCTURAL
+ MUST ( cn )
+ MAY ( ds-cfg-log-record-type )
+ X-ORIGIN 'OpenDJ Directory Server' )
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/AccessLogFilteringCriteriaConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/AccessLogFilteringCriteriaConfiguration.xml
new file mode 100644
index 0000000..ede1982
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/AccessLogFilteringCriteriaConfiguration.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ! CDDL HEADER START
+ !
+ ! The contents of this file are subject to the terms of the
+ ! Common Development and Distribution License, Version 1.0 only
+ ! (the "License"). You may not use this file except in compliance
+ ! with the License.
+ !
+ ! You can obtain a copy of the license at
+ ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ ! See the License for the specific language governing permissions
+ ! and limitations under the License.
+ !
+ ! When distributing Covered Code, include this CDDL HEADER in each
+ ! file and include the License file at
+ ! trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ ! add the following below this CDDL HEADER, with the fields enclosed
+ ! by brackets "[]" replaced with your own identifying information:
+ ! Portions Copyright [yyyy] [name of copyright owner]
+ !
+ ! CDDL HEADER END
+ !
+ !
+ ! Copyright 2011 ForgeRock AS.
+ ! -->
+<adm:managed-object name="access-log-filtering-criteria"
+ plural-name="access-log-filtering-criteria"
+ package="org.opends.server.admin.std"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+ <adm:synopsis>
+ A set of rules which together determine whether a log record should be
+ logged or not.
+ </adm:synopsis>
+ <adm:tag name="core-server"/>
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:name>ds-cfg-access-log-filtering-criteria</ldap:name>
+ <ldap:superior>top</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+ <adm:property name="log-record-type" multi-valued="true">
+ <adm:synopsis>
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:alias>
+ <adm:synopsis>All records</adm:synopsis>
+ </adm:alias>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:enumeration>
+ <adm:value name="abandon">
+ <adm:synopsis>Abandon operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="add">
+ <adm:synopsis>Add operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="bind">
+ <adm:synopsis>Bind operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="compare">
+ <adm:synopsis>Compare operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="delete">
+ <adm:synopsis>Delete operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="extended">
+ <adm:synopsis>Extended operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="modify">
+ <adm:synopsis>Modify operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="rename">
+ <adm:synopsis>Rename operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="search">
+ <adm:synopsis>Search operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="unbind">
+ <adm:synopsis>Unbind operations</adm:synopsis>
+ </adm:value>
+ <adm:value name="connect">
+ <adm:synopsis>Client connections</adm:synopsis>
+ </adm:value>
+ <adm:value name="disconnect">
+ <adm:synopsis>Client disconnections</adm:synopsis>
+ </adm:value>
+ </adm:enumeration>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-log-record-type</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/FileBasedAccessLogPublisherConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/FileBasedAccessLogPublisherConfiguration.xml
index f18115d..3249731 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/FileBasedAccessLogPublisherConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/FileBasedAccessLogPublisherConfiguration.xml
@@ -24,6 +24,7 @@
!
!
! Copyright 2007-2009 Sun Microsystems, Inc.
+ ! Portions copyright 2011 ForgeRock AS.
! -->
<adm:managed-object name="file-based-access-log-publisher"
plural-name="file-based-access-log-publishers"
@@ -40,6 +41,15 @@
<ldap:superior>ds-cfg-access-log-publisher</ldap:superior>
</ldap:object-class>
</adm:profile>
+ <adm:relation name="access-log-filtering-criteria">
+ <adm:synopsis>
+ The set of criteria which will be used to filter log records.
+ </adm:synopsis>
+ <adm:one-to-many/>
+ <adm:profile name="ldap">
+ <ldap:rdn-sequence>cn=Filtering Criteria</ldap:rdn-sequence>
+ </adm:profile>
+ </adm:relation>
<adm:property-override name="java-class" advanced="true">
<adm:default-behavior>
<adm:defined>
@@ -285,4 +295,40 @@
</ldap:attribute>
</adm:profile>
</adm:property>
+ <adm:property name="filtering-policy">
+ <adm:synopsis>
+ Specifies how filtering criteria should be applied to log records.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>no-filtering</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:enumeration>
+ <adm:value name="no-filtering">
+ <adm:synopsis>
+ No filtering will be performed, and all records will be logged.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="inclusive">
+ <adm:synopsis>
+ Records must match at least one of the filtering criteria in order
+ to be logged.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="exclusive">
+ <adm:synopsis>
+ Records must not match any of the filtering criteria in order to be
+ logged.
+ </adm:synopsis>
+ </adm:value>
+ </adm:enumeration>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-filtering-policy</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
</adm:managed-object>
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/FileBasedAuditLogPublisherConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/FileBasedAuditLogPublisherConfiguration.xml
new file mode 100644
index 0000000..23b82c2
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/FileBasedAuditLogPublisherConfiguration.xml
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ! CDDL HEADER START
+ !
+ ! The contents of this file are subject to the terms of the
+ ! Common Development and Distribution License, Version 1.0 only
+ ! (the "License"). You may not use this file except in compliance
+ ! with the License.
+ !
+ ! You can obtain a copy of the license at
+ ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ ! See the License for the specific language governing permissions
+ ! and limitations under the License.
+ !
+ ! When distributing Covered Code, include this CDDL HEADER in each
+ ! file and include the License file at
+ ! trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ ! add the following below this CDDL HEADER, with the fields enclosed
+ ! by brackets "[]" replaced with your own identifying information:
+ ! Portions Copyright [yyyy] [name of copyright owner]
+ !
+ ! CDDL HEADER END
+ !
+ !
+ ! Copyright 2011 ForgeRock AS.
+ ! -->
+<adm:managed-object name="file-based-audit-log-publisher"
+ plural-name="file-based-audit-log-publishers"
+ package="org.opends.server.admin.std" extends="access-log-publisher"
+ xmlns:adm="http://www.opends.org/admin"
+ xmlns:ldap="http://www.opends.org/admin-ldap">
+ <adm:synopsis>
+ <adm:user-friendly-plural-name />
+ publish access messages to the file system.
+ </adm:synopsis>
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:name>ds-cfg-file-based-audit-log-publisher</ldap:name>
+ <ldap:superior>ds-cfg-access-log-publisher</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+ <adm:property-override name="java-class" advanced="true">
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>
+ org.opends.server.loggers.TextAuditLogPublisher
+ </adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ </adm:property-override>
+ <adm:property name="asynchronous" mandatory="true" advanced="true">
+ <adm:synopsis>
+ Indicates whether the
+ <adm:user-friendly-name />
+ will publish records asynchronously.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>true</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:boolean />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-asynchronous</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="queue-size" advanced="true">
+ <adm:synopsis>
+ The maximum number of log records that can be stored in the
+ asynchronous queue.
+ </adm:synopsis>
+ <adm:description>
+ Setting the queue size to zero activates parallel log writer
+ implementation which has no queue size limit and as such the
+ parallel log writer should only be used on a very well tuned
+ server configuration to avoid potential out of memory errors.
+ </adm:description>
+ <adm:requires-admin-action>
+ <adm:other>
+ <adm:synopsis>
+ The <adm:user-friendly-name /> must be restarted if this property
+ is changed and the asynchronous property is set to true.
+ </adm:synopsis>
+ </adm:other>
+ </adm:requires-admin-action>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>5000</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:integer lower-limit="0" />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-queue-size</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="log-file" mandatory="true">
+ <adm:synopsis>
+ The file name to use for the log files generated by the
+ <adm:user-friendly-name />.
+ The path to the file is relative to the server root.
+ </adm:synopsis>
+ <adm:requires-admin-action>
+ <adm:component-restart />
+ </adm:requires-admin-action>
+ <adm:syntax>
+ <adm:string>
+ <adm:pattern>
+ <adm:regex>.*</adm:regex>
+ <adm:usage>FILE</adm:usage>
+ <adm:synopsis>
+ A path to an existing file that is readable by the server.
+ </adm:synopsis>
+ </adm:pattern>
+ </adm:string>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-log-file</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="log-file-permissions" mandatory="true">
+ <adm:synopsis>
+ The UNIX permissions of the log files created by this
+ <adm:user-friendly-name />.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>640</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:string>
+ <adm:pattern>
+ <adm:regex>^([0-7][0-7][0-7])$</adm:regex>
+ <adm:usage>MODE</adm:usage>
+ <adm:synopsis>
+ A valid UNIX mode string. The mode string must contain
+ three digits between zero and seven.
+ </adm:synopsis>
+ </adm:pattern>
+ </adm:string>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-log-file-permissions</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="time-interval" advanced="true">
+ <adm:synopsis>
+ Specifies the interval at which to check whether the log files
+ need to be rotated.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>5s</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:duration base-unit="ms" lower-limit="1" />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-time-interval</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="buffer-size" advanced="true">
+ <adm:synopsis>Specifies the log file buffer size.</adm:synopsis>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>64kb</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:size lower-limit="1" />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-buffer-size</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="auto-flush" advanced="true">
+ <adm:synopsis>
+ Specifies whether to flush the writer after every log record.
+ </adm:synopsis>
+ <adm:description>
+ If the asynchronous writes option is used, the writer is
+ flushed after all the log records in the queue are written.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>true</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:boolean />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-auto-flush</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="append">
+ <adm:synopsis>
+ Specifies whether to append to existing log files.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:defined>
+ <adm:value>true</adm:value>
+ </adm:defined>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:boolean />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-append</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="rotation-policy" multi-valued="true">
+ <adm:synopsis>
+ The rotation policy to use for the
+ <adm:user-friendly-name />
+ .
+ </adm:synopsis>
+ <adm:description>
+ When multiple policies are used, rotation will occur if any
+ policy's conditions are met.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:alias>
+ <adm:synopsis>
+ No rotation policy is used and log rotation will not occur.
+ </adm:synopsis>
+ </adm:alias>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:aggregation parent-path="/"
+ relation-name="log-rotation-policy" />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-rotation-policy</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+ <adm:property name="retention-policy" multi-valued="true">
+ <adm:synopsis>
+ The retention policy to use for the
+ <adm:user-friendly-name />
+ .
+ </adm:synopsis>
+ <adm:description>
+ When multiple policies are used, log files are cleaned when
+ any of the policy's conditions are met.
+ </adm:description>
+ <adm:default-behavior>
+ <adm:alias>
+ <adm:synopsis>
+ No retention policy is used and log files are never cleaned.
+ </adm:synopsis>
+ </adm:alias>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:aggregation parent-path="/"
+ relation-name="log-retention-policy" />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:name>ds-cfg-retention-policy</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+</adm:managed-object>
diff --git a/opends/src/admin/messages/AccessLogFilteringCriteriaCfgDefn.properties b/opends/src/admin/messages/AccessLogFilteringCriteriaCfgDefn.properties
new file mode 100644
index 0000000..00038dc
--- /dev/null
+++ b/opends/src/admin/messages/AccessLogFilteringCriteriaCfgDefn.properties
@@ -0,0 +1,17 @@
+user-friendly-name=Access Log Filtering Criteria
+user-friendly-plural-name=Access Log Filtering Criteria
+synopsis=A set of rules which together determine whether a log record should be logged or not.
+property.log-record-type.synopsis=
+property.log-record-type.default-behavior.alias.synopsis=All records
+property.log-record-type.syntax.enumeration.value.abandon.synopsis=Abandon operations
+property.log-record-type.syntax.enumeration.value.add.synopsis=Add operations
+property.log-record-type.syntax.enumeration.value.bind.synopsis=Bind operations
+property.log-record-type.syntax.enumeration.value.compare.synopsis=Compare operations
+property.log-record-type.syntax.enumeration.value.connect.synopsis=Client connections
+property.log-record-type.syntax.enumeration.value.delete.synopsis=Delete operations
+property.log-record-type.syntax.enumeration.value.disconnect.synopsis=Client disconnections
+property.log-record-type.syntax.enumeration.value.extended.synopsis=Extended operations
+property.log-record-type.syntax.enumeration.value.modify.synopsis=Modify operations
+property.log-record-type.syntax.enumeration.value.rename.synopsis=Rename operations
+property.log-record-type.syntax.enumeration.value.search.synopsis=Search operations
+property.log-record-type.syntax.enumeration.value.unbind.synopsis=Unbind operations
diff --git a/opends/src/admin/messages/FileBasedAccessLogPublisherCfgDefn.properties b/opends/src/admin/messages/FileBasedAccessLogPublisherCfgDefn.properties
index 30cd2fe..b71b4c3 100644
--- a/opends/src/admin/messages/FileBasedAccessLogPublisherCfgDefn.properties
+++ b/opends/src/admin/messages/FileBasedAccessLogPublisherCfgDefn.properties
@@ -7,6 +7,10 @@
property.auto-flush.description=If the asynchronous writes option is used, the writer is flushed after all the log records in the queue are written.
property.buffer-size.synopsis=Specifies the log file buffer size.
property.enabled.synopsis=Indicates whether the File Based Access Log Publisher is enabled for use.
+property.filtering-policy.synopsis=Specifies how filtering criteria should be applied to log records.
+property.filtering-policy.syntax.enumeration.value.exclusive.synopsis=Records must not match any of the filtering criteria in order to be logged.
+property.filtering-policy.syntax.enumeration.value.inclusive.synopsis=Records must match at least one of the filtering criteria in order to be logged.
+property.filtering-policy.syntax.enumeration.value.no-filtering.synopsis=No filtering will be performed, and all records will be logged.
property.java-class.synopsis=The fully-qualified name of the Java class that provides the File Based Access Log Publisher implementation.
property.log-file.synopsis=The file name to use for the log files generated by the File Based Access Log Publisher. The path to the file is relative to the server root.
property.log-file.syntax.string.pattern.synopsis=A path to an existing file that is readable by the server.
@@ -24,3 +28,6 @@
property.suppress-internal-operations.synopsis=Indicates whether internal operations (for example, operations that are initiated by plugins) should be logged along with the operations that are requested by users.
property.suppress-synchronization-operations.synopsis=Indicates whether access messages that are generated by synchronization operations should be suppressed.
property.time-interval.synopsis=Specifies the interval at which to check whether the log files need to be rotated.
+relation.access-log-filtering-criteria.user-friendly-name=Access Log Filtering Criteria
+relation.access-log-filtering-criteria.user-friendly-plural-name=Access Log Filtering Criteria
+relation.access-log-filtering-criteria.synopsis=The set of criteria which will be used to filter log records.
diff --git a/opends/src/admin/messages/FileBasedAuditLogPublisherCfgDefn.properties b/opends/src/admin/messages/FileBasedAuditLogPublisherCfgDefn.properties
new file mode 100644
index 0000000..c684c21
--- /dev/null
+++ b/opends/src/admin/messages/FileBasedAuditLogPublisherCfgDefn.properties
@@ -0,0 +1,26 @@
+user-friendly-name=File Based Audit Log Publisher
+user-friendly-plural-name=File Based Audit Log Publishers
+synopsis=File Based Audit Log Publishers publish access messages to the file system.
+property.append.synopsis=Specifies whether to append to existing log files.
+property.asynchronous.synopsis=Indicates whether the File Based Audit Log Publisher will publish records asynchronously.
+property.auto-flush.synopsis=Specifies whether to flush the writer after every log record.
+property.auto-flush.description=If the asynchronous writes option is used, the writer is flushed after all the log records in the queue are written.
+property.buffer-size.synopsis=Specifies the log file buffer size.
+property.enabled.synopsis=Indicates whether the File Based Audit Log Publisher is enabled for use.
+property.java-class.synopsis=The fully-qualified name of the Java class that provides the File Based Audit Log Publisher implementation.
+property.log-file.synopsis=The file name to use for the log files generated by the File Based Audit Log Publisher. The path to the file is relative to the server root.
+property.log-file.syntax.string.pattern.synopsis=A path to an existing file that is readable by the server.
+property.log-file-permissions.synopsis=The UNIX permissions of the log files created by this File Based Audit Log Publisher.
+property.log-file-permissions.syntax.string.pattern.synopsis=A valid UNIX mode string. The mode string must contain three digits between zero and seven.
+property.queue-size.synopsis=The maximum number of log records that can be stored in the asynchronous queue.
+property.queue-size.description=Setting the queue size to zero activates parallel log writer implementation which has no queue size limit and as such the parallel log writer should only be used on a very well tuned server configuration to avoid potential out of memory errors.
+property.queue-size.requires-admin-action.synopsis=The File Based Audit Log Publisher must be restarted if this property is changed and the asynchronous property is set to true.
+property.retention-policy.synopsis=The retention policy to use for the File Based Audit Log Publisher .
+property.retention-policy.description=When multiple policies are used, log files are cleaned when any of the policy's conditions are met.
+property.retention-policy.default-behavior.alias.synopsis=No retention policy is used and log files are never cleaned.
+property.rotation-policy.synopsis=The rotation policy to use for the File Based Audit Log Publisher .
+property.rotation-policy.description=When multiple policies are used, rotation will occur if any policy's conditions are met.
+property.rotation-policy.default-behavior.alias.synopsis=No rotation policy is used and log rotation will not occur.
+property.suppress-internal-operations.synopsis=Indicates whether internal operations (for example, operations that are initiated by plugins) should be logged along with the operations that are requested by users.
+property.suppress-synchronization-operations.synopsis=Indicates whether access messages that are generated by synchronization operations should be suppressed.
+property.time-interval.synopsis=Specifies the interval at which to check whether the log files need to be rotated.
diff --git a/opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java b/opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java
index 22806ee..6a0e94b 100644
--- a/opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java
+++ b/opends/src/server/org/opends/server/loggers/TextAccessLogPublisher.java
@@ -30,35 +30,28 @@
import static org.opends.messages.ConfigMessages.*;
-import static org.opends.server.util.StaticUtils.*;
+import static org.opends.server.util.StaticUtils.getFileForPath;
+import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
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.*;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
+import org.opends.server.admin.server.ConfigurationAddListener;
import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.server.ConfigurationDeleteListener;
+import org.opends.server.admin.std.meta.AccessLogFilteringCriteriaCfgDefn.*;
+import org.opends.server.admin.std.meta.FileBasedAccessLogPublisherCfgDefn.*;
+import org.opends.server.admin.std.server.AccessLogFilteringCriteriaCfg;
import org.opends.server.admin.std.server.AccessLogPublisherCfg;
import org.opends.server.admin.std.server.FileBasedAccessLogPublisherCfg;
import org.opends.server.api.AccessLogPublisher;
import org.opends.server.api.ClientConnection;
import org.opends.server.api.ExtendedOperationHandler;
import org.opends.server.config.ConfigException;
-import org.opends.server.core.AbandonOperation;
-import org.opends.server.core.AddOperation;
-import org.opends.server.core.BindOperation;
-import org.opends.server.core.CompareOperation;
-import org.opends.server.core.DeleteOperation;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.ExtendedOperation;
-import org.opends.server.core.ModifyDNOperation;
-import org.opends.server.core.ModifyOperation;
-import org.opends.server.core.SearchOperation;
-import org.opends.server.core.UnbindOperation;
+import org.opends.server.core.*;
import org.opends.server.types.*;
import org.opends.server.util.TimeThread;
@@ -74,11 +67,184 @@
{
/**
+ * Criteria based filter.
+ */
+ static final class CriteriaFilter implements Filter
+ {
+ private final AccessLogFilteringCriteriaCfg cfg;
+ private final boolean logConnectRecords;
+ private final boolean logDisconnectRecords;
+ private final EnumSet<OperationType> logOperationRecords;
+
+
+
+ /**
+ * Creates a new criteria based filter.
+ *
+ * @param cfg
+ * The access log filter criteria.
+ */
+ CriteriaFilter(final AccessLogFilteringCriteriaCfg cfg)
+ {
+ this.cfg = cfg;
+
+ // Pre-parse the log record types for more efficient queries.
+ if (cfg.getLogRecordType().isEmpty())
+ {
+ logConnectRecords = true;
+ logDisconnectRecords = true;
+
+ logOperationRecords = EnumSet.allOf(OperationType.class);
+ }
+ else
+ {
+ logConnectRecords =
+ cfg.getLogRecordType().contains(LogRecordType.CONNECT);
+ logDisconnectRecords =
+ cfg.getLogRecordType().contains(LogRecordType.DISCONNECT);
+
+ logOperationRecords = EnumSet.noneOf(OperationType.class);
+ for (final LogRecordType type : cfg.getLogRecordType())
+ {
+ switch (type)
+ {
+ case ABANDON:
+ logOperationRecords.add(OperationType.ABANDON);
+ break;
+ case ADD:
+ logOperationRecords.add(OperationType.ADD);
+ break;
+ case BIND:
+ logOperationRecords.add(OperationType.BIND);
+ break;
+ case COMPARE:
+ logOperationRecords.add(OperationType.COMPARE);
+ break;
+ case DELETE:
+ logOperationRecords.add(OperationType.DELETE);
+ break;
+ case EXTENDED:
+ logOperationRecords.add(OperationType.EXTENDED);
+ break;
+ case MODIFY:
+ logOperationRecords.add(OperationType.MODIFY);
+ break;
+ case RENAME:
+ logOperationRecords.add(OperationType.MODIFY_DN);
+ break;
+ case SEARCH:
+ logOperationRecords.add(OperationType.SEARCH);
+ break;
+ case UNBIND:
+ logOperationRecords.add(OperationType.UNBIND);
+ break;
+ default: // Ignore CONNECT/DISCONNECT
+ break;
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConnectLoggable(final ClientConnection connection)
+ {
+ if (!logConnectRecords)
+ {
+ return false;
+ }
+
+ // TODO: other checks.
+
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isDisconnectLoggable(final ClientConnection connection)
+ {
+ if (!logDisconnectRecords)
+ {
+ return false;
+ }
+
+ // TODO: other checks.
+
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isRequestLoggable(final Operation operation)
+ {
+ if (!logOperationRecords.contains(operation.getOperationType()))
+ {
+ return false;
+ }
+
+ // TODO: other checks.
+
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isResponseLoggable(final Operation operation)
+ {
+ if (!logOperationRecords.contains(operation.getOperationType()))
+ {
+ return false;
+ }
+
+ // TODO: other checks.
+
+ return true;
+ }
+
+ }
+
+
+
+ /**
* Log message filter predicate.
*/
static interface Filter
{
/**
+ * Returns {@code true} if the provided client connect should be logged.
+ *
+ * @param connection
+ * The client connection.
+ * @return {@code true} if the provided client connect should be logged.
+ */
+ boolean isConnectLoggable(ClientConnection connection);
+
+
+
+ /**
+ * Returns {@code true} if the provided client disconnect should be logged.
+ *
+ * @param connection
+ * The client connection.
+ * @return {@code true} if the provided client disconnect should be logged.
+ */
+ boolean isDisconnectLoggable(ClientConnection connection);
+
+
+
+ /**
* Returns {@code true} if the provided request should be logged.
*
* @param operation
@@ -102,66 +268,6 @@
/**
- * A filter which performs a logical AND over a set of sub-filters.
- */
- static final class AndFilter implements Filter
- {
- private final Filter[] subFilters;
-
-
-
- /**
- * Creates a new AND filter.
- *
- * @param subFilters
- * The sub-filters.
- */
- AndFilter(Filter[] subFilters)
- {
- this.subFilters = subFilters;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isRequestLoggable(Operation operation)
- {
- for (Filter filter : subFilters)
- {
- if (!filter.isRequestLoggable(operation))
- {
- // Fail fast.
- return false;
- }
- }
- return true;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isResponseLoggable(Operation operation)
- {
- for (Filter filter : subFilters)
- {
- if (!filter.isResponseLoggable(operation))
- {
- // Fail fast.
- return false;
- }
- }
- return true;
- }
-
- }
-
-
-
- /**
* A filter which performs a logical OR over a set of sub-filters.
*/
static final class OrFilter implements Filter
@@ -176,7 +282,7 @@
* @param subFilters
* The sub-filters.
*/
- OrFilter(Filter[] subFilters)
+ OrFilter(final Filter[] subFilters)
{
this.subFilters = subFilters;
}
@@ -186,9 +292,45 @@
/**
* {@inheritDoc}
*/
- public boolean isRequestLoggable(Operation operation)
+ public boolean isConnectLoggable(final ClientConnection connection)
{
- for (Filter filter : subFilters)
+ for (final Filter filter : subFilters)
+ {
+ if (filter.isConnectLoggable(connection))
+ {
+ // Succeed fast.
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isDisconnectLoggable(final ClientConnection connection)
+ {
+ for (final Filter filter : subFilters)
+ {
+ if (filter.isDisconnectLoggable(connection))
+ {
+ // Succeed fast.
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isRequestLoggable(final Operation operation)
+ {
+ for (final Filter filter : subFilters)
{
if (filter.isRequestLoggable(operation))
{
@@ -204,9 +346,9 @@
/**
* {@inheritDoc}
*/
- public boolean isResponseLoggable(Operation operation)
+ public boolean isResponseLoggable(final Operation operation)
{
- for (Filter filter : subFilters)
+ for (final Filter filter : subFilters)
{
if (filter.isResponseLoggable(operation))
{
@@ -225,20 +367,34 @@
* The root filter which first checks the logger configuration, delegating to
* a sub-filter if needed.
*/
- final class RootFilter implements Filter
+ static final class RootFilter implements Filter
{
private final Filter subFilter;
+ private final boolean suppressInternalOperations;
+ private final boolean suppressSynchronizationOperations;
+ private final FilteringPolicy policy;
/**
* Creates a new root filter.
*
+ * @param suppressInternal
+ * Indicates whether internal operations should be suppressed.
+ * @param suppressSynchronization
+ * Indicates whether sync operations should be suppressed.
+ * @param policy
+ * The filtering policy.
* @param subFilter
- * The sub-filter.
+ * The sub-filters.
*/
- RootFilter(Filter subFilter)
+ RootFilter(final boolean suppressInternal,
+ final boolean suppressSynchronization, final FilteringPolicy policy,
+ final Filter subFilter)
{
+ this.suppressInternalOperations = suppressInternal;
+ this.suppressSynchronizationOperations = suppressSynchronization;
+ this.policy = policy;
this.subFilter = subFilter;
}
@@ -247,12 +403,20 @@
/**
* {@inheritDoc}
*/
- public boolean isRequestLoggable(Operation operation)
+ public boolean isConnectLoggable(final ClientConnection connection)
{
- if (isLoggable(operation))
+ final long connectionID = connection.getConnectionID();
+ if (connectionID >= 0 || !suppressInternalOperations)
{
- // FIXME: actual behavior determined by default filter policy.
- return subFilter.isRequestLoggable(operation);
+ switch (policy)
+ {
+ case INCLUSIVE:
+ return subFilter.isConnectLoggable(connection);
+ case EXCLUSIVE:
+ return !subFilter.isConnectLoggable(connection);
+ default: // NO_FILTERING:
+ return true;
+ }
}
else
{
@@ -265,12 +429,70 @@
/**
* {@inheritDoc}
*/
- public boolean isResponseLoggable(Operation operation)
+ public boolean isDisconnectLoggable(final ClientConnection connection)
+ {
+ final long connectionID = connection.getConnectionID();
+ if (connectionID >= 0 || !suppressInternalOperations)
+ {
+ switch (policy)
+ {
+ case INCLUSIVE:
+ return subFilter.isDisconnectLoggable(connection);
+ case EXCLUSIVE:
+ return !subFilter.isDisconnectLoggable(connection);
+ default: // NO_FILTERING:
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isRequestLoggable(final Operation operation)
{
if (isLoggable(operation))
{
- // FIXME: actual behavior determined by default filter policy.
- return subFilter.isResponseLoggable(operation);
+ switch (policy)
+ {
+ case INCLUSIVE:
+ return subFilter.isRequestLoggable(operation);
+ case EXCLUSIVE:
+ return !subFilter.isRequestLoggable(operation);
+ default: // NO_FILTERING:
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isResponseLoggable(final Operation operation)
+ {
+ if (isLoggable(operation))
+ {
+ switch (policy)
+ {
+ case INCLUSIVE:
+ return subFilter.isResponseLoggable(operation);
+ case EXCLUSIVE:
+ return !subFilter.isResponseLoggable(operation);
+ default: // NO_FILTERING:
+ return true;
+ }
}
else
{
@@ -281,9 +503,9 @@
// Determines whether the provided operation should be logged.
- private boolean isLoggable(Operation operation)
+ private boolean isLoggable(final Operation operation)
{
- long connectionID = operation.getConnectionID();
+ final long connectionID = operation.getConnectionID();
if (connectionID < 0)
{
// This is an internal operation.
@@ -304,6 +526,92 @@
/**
+ * Filter criteria configuration listener.
+ */
+ private final class FilterChangeListener implements
+ ConfigurationChangeListener<AccessLogFilteringCriteriaCfg>,
+ ConfigurationAddListener<AccessLogFilteringCriteriaCfg>,
+ ConfigurationDeleteListener<AccessLogFilteringCriteriaCfg>
+ {
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationAdd(
+ final AccessLogFilteringCriteriaCfg configuration)
+ {
+ // Rebuild the filter using the new configuration and criteria.
+ buildFilters();
+ configuration.addChangeListener(this);
+ return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ final AccessLogFilteringCriteriaCfg configuration)
+ {
+ // Rebuild the filter using the new configuration and criteria.
+ buildFilters();
+ return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationDelete(
+ final AccessLogFilteringCriteriaCfg configuration)
+ {
+ // Rebuild the filter using the new configuration and criteria.
+ buildFilters();
+ return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationAddAcceptable(
+ final AccessLogFilteringCriteriaCfg configuration,
+ final List<Message> unacceptableReasons)
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ final AccessLogFilteringCriteriaCfg configuration,
+ final List<Message> unacceptableReasons)
+ {
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationDeleteAcceptable(
+ final AccessLogFilteringCriteriaCfg configuration,
+ final List<Message> unacceptableReasons)
+ {
+ return true;
+ }
+ }
+
+
+
+ /**
* The category to use when logging responses.
*/
private static final String CATEGORY_RESPONSE = "RES";
@@ -328,26 +636,22 @@
* messages to standard out.
*/
public static TextAccessLogPublisher getStartupTextAccessPublisher(
- TextWriter writer, boolean suppressInternal)
+ final TextWriter writer, final boolean suppressInternal)
{
- TextAccessLogPublisher startupPublisher = new TextAccessLogPublisher();
+ final TextAccessLogPublisher startupPublisher =
+ new TextAccessLogPublisher();
startupPublisher.writer = writer;
- startupPublisher.suppressInternalOperations = suppressInternal;
- startupPublisher.setSubFilter(new AndFilter(new Filter[0])); // Always true.
+ startupPublisher.buildFilters(suppressInternal, false,
+ FilteringPolicy.NO_FILTERING);
return startupPublisher;
}
- private FileBasedAccessLogPublisherCfg currentConfig;
-
- private boolean suppressInternalOperations = true;
-
- private boolean suppressSynchronizationOperations = false;
-
- private TextWriter writer;
-
- private Filter filter;
+ private FileBasedAccessLogPublisherCfg currentConfig = null;
+ private TextWriter writer = null;
+ private Filter filter = null;
+ private FilterChangeListener filterChangeListener = null;
@@ -355,26 +659,21 @@
* {@inheritDoc}
*/
public ConfigChangeResult applyConfigurationChange(
- FileBasedAccessLogPublisherCfg config)
+ final FileBasedAccessLogPublisherCfg config)
{
// Default result code.
ResultCode resultCode = ResultCode.SUCCESS;
boolean adminActionRequired = false;
- ArrayList<Message> messages = new ArrayList<Message>();
+ final ArrayList<Message> messages = new ArrayList<Message>();
- suppressInternalOperations = config.isSuppressInternalOperations();
- suppressSynchronizationOperations = config
- .isSuppressSynchronizationOperations();
-
- File logFile = getFileForPath(config.getLogFile());
- FileNamingPolicy fnPolicy = new TimeStampNaming(logFile);
-
+ final File logFile = getFileForPath(config.getLogFile());
+ final FileNamingPolicy fnPolicy = new TimeStampNaming(logFile);
try
{
- FilePermission perm = FilePermission.decodeUNIXMode(config
+ final FilePermission perm = FilePermission.decodeUNIXMode(config
.getLogFilePermissions());
- boolean writerAutoFlush = config.isAutoFlush()
+ final boolean writerAutoFlush = config.isAutoFlush()
&& !config.isAsynchronous();
TextWriter currentWriter;
@@ -395,7 +694,8 @@
if (currentWriter instanceof MultifileTextWriter)
{
- MultifileTextWriter mfWriter = (MultifileTextWriter) currentWriter;
+ final MultifileTextWriter mfWriter =
+ (MultifileTextWriter) currentWriter;
mfWriter.setNamingPolicy(fnPolicy);
mfWriter.setFilePermissions(perm);
@@ -407,12 +707,12 @@
mfWriter.removeAllRetentionPolicies();
mfWriter.removeAllRotationPolicies();
- for (DN dn : config.getRotationPolicyDNs())
+ for (final DN dn : config.getRotationPolicyDNs())
{
mfWriter.addRotationPolicy(DirectoryServer.getRotationPolicy(dn));
}
- for (DN dn : config.getRetentionPolicyDNs())
+ for (final DN dn : config.getRetentionPolicyDNs())
{
mfWriter.addRetentionPolicy(DirectoryServer.getRetentionPolicy(dn));
}
@@ -420,7 +720,8 @@
if (writer instanceof AsyncronousTextWriter && !config.isAsynchronous())
{
// The asynchronous setting is being turned off.
- AsyncronousTextWriter asyncWriter = ((AsyncronousTextWriter) writer);
+ final AsyncronousTextWriter asyncWriter =
+ ((AsyncronousTextWriter) writer);
writer = mfWriter;
asyncWriter.shutdown(false);
}
@@ -428,7 +729,7 @@
if (writer instanceof ParallelTextWriter && !config.isAsynchronous())
{
// The asynchronous setting is being turned off.
- ParallelTextWriter asyncWriter = ((ParallelTextWriter) writer);
+ final ParallelTextWriter asyncWriter = ((ParallelTextWriter) writer);
writer = mfWriter;
asyncWriter.shutdown(false);
}
@@ -437,7 +738,7 @@
&& config.isAsynchronous())
{
// The asynchronous setting is being turned on.
- AsyncronousTextWriter asyncWriter = new AsyncronousTextWriter(
+ final AsyncronousTextWriter asyncWriter = new AsyncronousTextWriter(
"Asyncronous Text Writer for " + config.dn().toNormalizedString(),
config.getQueueSize(), config.isAutoFlush(), mfWriter);
writer = asyncWriter;
@@ -446,7 +747,7 @@
if (!(writer instanceof ParallelTextWriter) && config.isAsynchronous())
{
// The asynchronous setting is being turned on.
- ParallelTextWriter asyncWriter = new ParallelTextWriter(
+ final ParallelTextWriter asyncWriter = new ParallelTextWriter(
"Parallel Text Writer for " + config.dn().toNormalizedString(),
config.isAutoFlush(), mfWriter);
writer = asyncWriter;
@@ -458,16 +759,16 @@
adminActionRequired = true;
}
- // FIXME: use a dummy set of sub-filters for now.
- setSubFilter(new AndFilter(new Filter[0])); // Always true.
-
currentConfig = config;
+
+ // Rebuild the filter using the new configuration and criteria.
+ buildFilters();
}
}
- catch (Exception e)
+ catch (final Exception e)
{
- Message message = ERR_CONFIG_LOGGING_CANNOT_CREATE_WRITER.get(config.dn()
- .toString(), stackTraceToSingleLineString(e));
+ final Message message = ERR_CONFIG_LOGGING_CANNOT_CREATE_WRITER.get(
+ config.dn().toString(), stackTraceToSingleLineString(e));
resultCode = DirectoryServer.getServerErrorResultCode();
messages.add(message);
@@ -489,6 +790,24 @@
if (currentConfig != null)
{
currentConfig.removeFileBasedAccessChangeListener(this);
+
+ for (final String criteriaName : currentConfig
+ .listAccessLogFilteringCriteria())
+ {
+ try
+ {
+ currentConfig.getAccessLogFilteringCriteria(criteriaName)
+ .removeChangeListener(filterChangeListener);
+ }
+ catch (final ConfigException e)
+ {
+ // Ignore.
+ }
+ }
+ currentConfig
+ .removeAccessLogFilteringCriteriaAddListener(filterChangeListener);
+ currentConfig
+ .removeAccessLogFilteringCriteriaDeleteListener(filterChangeListener);
}
}
@@ -516,35 +835,36 @@
* {@inheritDoc}
*/
@Override
- public void initializeAccessLogPublisher(FileBasedAccessLogPublisherCfg cfg)
- throws ConfigException, InitializationException
+ public void initializeAccessLogPublisher(
+ final FileBasedAccessLogPublisherCfg cfg) throws ConfigException,
+ InitializationException
{
- File logFile = getFileForPath(cfg.getLogFile());
- FileNamingPolicy fnPolicy = new TimeStampNaming(logFile);
+ final File logFile = getFileForPath(cfg.getLogFile());
+ final FileNamingPolicy fnPolicy = new TimeStampNaming(logFile);
try
{
- FilePermission perm = FilePermission.decodeUNIXMode(cfg
+ final FilePermission perm = FilePermission.decodeUNIXMode(cfg
.getLogFilePermissions());
- LogPublisherErrorHandler errorHandler = new LogPublisherErrorHandler(
- cfg.dn());
+ final LogPublisherErrorHandler errorHandler =
+ new LogPublisherErrorHandler(cfg.dn());
- boolean writerAutoFlush = cfg.isAutoFlush()
+ final boolean writerAutoFlush = cfg.isAutoFlush()
&& !cfg.isAsynchronous();
- MultifileTextWriter writer = new MultifileTextWriter(
+ final MultifileTextWriter writer = new MultifileTextWriter(
"Multifile Text Writer for " + cfg.dn().toNormalizedString(),
cfg.getTimeInterval(), fnPolicy, perm, errorHandler, "UTF-8",
writerAutoFlush, cfg.isAppend(), (int) cfg.getBufferSize());
// Validate retention and rotation policies.
- for (DN dn : cfg.getRotationPolicyDNs())
+ for (final DN dn : cfg.getRotationPolicyDNs())
{
writer.addRotationPolicy(DirectoryServer.getRotationPolicy(dn));
}
- for (DN dn : cfg.getRetentionPolicyDNs())
+ for (final DN dn : cfg.getRetentionPolicyDNs())
{
writer.addRetentionPolicy(DirectoryServer.getRetentionPolicy(dn));
}
@@ -568,30 +888,47 @@
this.writer = writer;
}
}
- catch (DirectoryException e)
+ catch (final DirectoryException e)
{
- Message message = ERR_CONFIG_LOGGING_CANNOT_CREATE_WRITER.get(cfg.dn()
- .toString(), String.valueOf(e));
+ final Message message = ERR_CONFIG_LOGGING_CANNOT_CREATE_WRITER.get(cfg
+ .dn().toString(), String.valueOf(e));
throw new InitializationException(message, e);
}
- catch (IOException e)
+ catch (final IOException e)
{
- Message message = ERR_CONFIG_LOGGING_CANNOT_OPEN_FILE.get(
+ final Message message = ERR_CONFIG_LOGGING_CANNOT_OPEN_FILE.get(
logFile.toString(), cfg.dn().toString(), String.valueOf(e));
throw new InitializationException(message, e);
}
- suppressInternalOperations = cfg.isSuppressInternalOperations();
- suppressSynchronizationOperations = cfg
- .isSuppressSynchronizationOperations();
currentConfig = cfg;
- // FIXME: use a dummy set of sub-filters for now.
- setSubFilter(new AndFilter(new Filter[0])); // Always true.
+ // Rebuild the filter using the new configuration and criteria.
+ buildFilters();
- cfg.addFileBasedAccessChangeListener(this);
+ // Add change listeners.
+ filterChangeListener = new FilterChangeListener();
+ for (final String criteriaName : currentConfig
+ .listAccessLogFilteringCriteria())
+ {
+ try
+ {
+ currentConfig.getAccessLogFilteringCriteria(criteriaName)
+ .addChangeListener(filterChangeListener);
+ }
+ catch (final ConfigException e)
+ {
+ // Ignore.
+ }
+ }
+ currentConfig
+ .addAccessLogFilteringCriteriaAddListener(filterChangeListener);
+ currentConfig
+ .addAccessLogFilteringCriteriaDeleteListener(filterChangeListener);
+
+ currentConfig.addFileBasedAccessChangeListener(this);
}
@@ -600,10 +937,11 @@
* {@inheritDoc}
*/
@Override
- public boolean isConfigurationAcceptable(AccessLogPublisherCfg configuration,
- List<Message> unacceptableReasons)
+ public boolean isConfigurationAcceptable(
+ final AccessLogPublisherCfg configuration,
+ final List<Message> unacceptableReasons)
{
- FileBasedAccessLogPublisherCfg config =
+ final FileBasedAccessLogPublisherCfg config =
(FileBasedAccessLogPublisherCfg) configuration;
return isConfigurationChangeAcceptable(config, unacceptableReasons);
}
@@ -614,24 +952,25 @@
* {@inheritDoc}
*/
public boolean isConfigurationChangeAcceptable(
- FileBasedAccessLogPublisherCfg config, List<Message> unacceptableReasons)
+ final FileBasedAccessLogPublisherCfg config,
+ final List<Message> unacceptableReasons)
{
// Make sure the permission is valid.
try
{
- FilePermission filePerm = FilePermission.decodeUNIXMode(config
+ final FilePermission filePerm = FilePermission.decodeUNIXMode(config
.getLogFilePermissions());
if (!filePerm.isOwnerWritable())
{
- Message message = ERR_CONFIG_LOGGING_INSANE_MODE.get(config
+ final Message message = ERR_CONFIG_LOGGING_INSANE_MODE.get(config
.getLogFilePermissions());
unacceptableReasons.add(message);
return false;
}
}
- catch (DirectoryException e)
+ catch (final DirectoryException e)
{
- Message message = ERR_CONFIG_LOGGING_MODE_INVALID.get(
+ final Message message = ERR_CONFIG_LOGGING_MODE_INVALID.get(
config.getLogFilePermissions(), String.valueOf(e));
unacceptableReasons.add(message);
return false;
@@ -651,19 +990,21 @@
* abandon request.
*/
@Override
- public void logAbandonRequest(AbandonOperation abandonOperation)
+ public void logAbandonRequest(final AbandonOperation abandonOperation)
{
if (!filter.isRequestLoggable(abandonOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(abandonOperation, "ABANDON", CATEGORY_REQUEST, buffer);
buffer.append(" idToAbandon=");
buffer.append(abandonOperation.getIDToAbandon());
if (abandonOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -679,18 +1020,18 @@
* abandon request.
*/
@Override
- public void logAbandonResult(AbandonOperation abandonOperation)
+ public void logAbandonResult(final AbandonOperation abandonOperation)
{
if (!filter.isResponseLoggable(abandonOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(abandonOperation, "ABANDON", CATEGORY_RESPONSE, buffer);
buffer.append(" result=");
buffer.append(abandonOperation.getResultCode().getIntValue());
- MessageBuilder msg = abandonOperation.getErrorMessage();
+ final MessageBuilder msg = abandonOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -717,20 +1058,22 @@
* request.
*/
@Override
- public void logAddRequest(AddOperation addOperation)
+ public void logAddRequest(final AddOperation addOperation)
{
if (!filter.isRequestLoggable(addOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(addOperation, "ADD", CATEGORY_REQUEST, buffer);
buffer.append(" dn=\"");
buffer.append(addOperation.getRawEntryDN().toString());
buffer.append("\"");
if (addOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -746,19 +1089,19 @@
* response.
*/
@Override
- public void logAddResponse(AddOperation addOperation)
+ public void logAddResponse(final AddOperation addOperation)
{
if (!filter.isResponseLoggable(addOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(addOperation, "ADD", CATEGORY_RESPONSE, buffer);
buffer.append(" result=");
buffer.append(addOperation.getResultCode().getIntValue());
- MessageBuilder msg = addOperation.getErrorMessage();
+ final MessageBuilder msg = addOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -768,7 +1111,7 @@
logAdditionalLogItems(addOperation, buffer);
- DN proxiedAuthDN = addOperation.getProxiedAuthorizationDN();
+ final DN proxiedAuthDN = addOperation.getProxiedAuthorizationDN();
if (proxiedAuthDN != null)
{
buffer.append(" authzDN=\"");
@@ -798,14 +1141,14 @@
* request.
*/
@Override
- public void logBindRequest(BindOperation bindOperation)
+ public void logBindRequest(final BindOperation bindOperation)
{
if (!filter.isRequestLoggable(bindOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(bindOperation, "BIND", CATEGORY_REQUEST, buffer);
final String protocolVersion = bindOperation.getProtocolVersion();
@@ -834,7 +1177,9 @@
buffer.append(bindOperation.getRawBindDN().toString());
buffer.append("\"");
if (bindOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -850,19 +1195,19 @@
* bind response.
*/
@Override
- public void logBindResponse(BindOperation bindOperation)
+ public void logBindResponse(final BindOperation bindOperation)
{
if (!filter.isResponseLoggable(bindOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(bindOperation, "BIND", CATEGORY_RESPONSE, buffer);
buffer.append(" result=");
buffer.append(bindOperation.getResultCode().getIntValue());
- MessageBuilder msg = bindOperation.getErrorMessage();
+ final MessageBuilder msg = bindOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -870,7 +1215,7 @@
buffer.append('\"');
}
- Message failureMessage = bindOperation.getAuthFailureReason();
+ final Message failureMessage = bindOperation.getAuthFailureReason();
if (failureMessage != null)
{
buffer.append(" authFailureID=");
@@ -884,17 +1229,17 @@
if (bindOperation.getResultCode() == ResultCode.SUCCESS)
{
- AuthenticationInfo authInfo = bindOperation.getAuthenticationInfo();
+ final AuthenticationInfo authInfo = bindOperation.getAuthenticationInfo();
if (authInfo != null)
{
- DN authDN = authInfo.getAuthenticationDN();
+ final DN authDN = authInfo.getAuthenticationDN();
if (authDN != null)
{
buffer.append(" authDN=\"");
authDN.toString(buffer);
buffer.append('\"');
- DN authzDN = authInfo.getAuthorizationDN();
+ final DN authzDN = authInfo.getAuthorizationDN();
if (!authDN.equals(authzDN))
{
buffer.append(" authzDN=\"");
@@ -934,21 +1279,23 @@
* compare request.
*/
@Override
- public void logCompareRequest(CompareOperation compareOperation)
+ public void logCompareRequest(final CompareOperation compareOperation)
{
if (!filter.isRequestLoggable(compareOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(compareOperation, "COMPARE", CATEGORY_REQUEST, buffer);
buffer.append(" dn=\"");
buffer.append(compareOperation.getRawEntryDN().toString());
buffer.append("\" attr=");
buffer.append(compareOperation.getAttributeType().getNameOrOID());
if (compareOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -964,19 +1311,19 @@
* compare response.
*/
@Override
- public void logCompareResponse(CompareOperation compareOperation)
+ public void logCompareResponse(final CompareOperation compareOperation)
{
if (!filter.isResponseLoggable(compareOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(compareOperation, "COMPARE", CATEGORY_RESPONSE, buffer);
buffer.append(" result=");
buffer.append(compareOperation.getResultCode().getIntValue());
- MessageBuilder msg = compareOperation.getErrorMessage();
+ final MessageBuilder msg = compareOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -986,7 +1333,7 @@
logAdditionalLogItems(compareOperation, buffer);
- DN proxiedAuthDN = compareOperation.getProxiedAuthorizationDN();
+ final DN proxiedAuthDN = compareOperation.getProxiedAuthorizationDN();
if (proxiedAuthDN != null)
{
buffer.append(" authzDN=\"");
@@ -1016,16 +1363,15 @@
* The client connection that has been established.
*/
@Override
- public void logConnect(ClientConnection clientConnection)
+ public void logConnect(final ClientConnection clientConnection)
{
- // FIXME: implement filtering.
- long connectionID = clientConnection.getConnectionID();
-
- if (connectionID < 0 && suppressInternalOperations)
+ if (!filter.isConnectLoggable(clientConnection))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+
+ final long connectionID = clientConnection.getConnectionID();
+ final StringBuilder buffer = new StringBuilder(100);
buffer.append("[");
buffer.append(TimeThread.getLocalTime());
buffer.append("]");
@@ -1053,20 +1399,22 @@
* request.
*/
@Override
- public void logDeleteRequest(DeleteOperation deleteOperation)
+ public void logDeleteRequest(final DeleteOperation deleteOperation)
{
if (!filter.isRequestLoggable(deleteOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(deleteOperation, "DELETE", CATEGORY_REQUEST, buffer);
buffer.append(" dn=\"");
buffer.append(deleteOperation.getRawEntryDN().toString());
buffer.append("\"");
if (deleteOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -1082,19 +1430,19 @@
* delete response.
*/
@Override
- public void logDeleteResponse(DeleteOperation deleteOperation)
+ public void logDeleteResponse(final DeleteOperation deleteOperation)
{
if (!filter.isResponseLoggable(deleteOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(deleteOperation, "DELETE", CATEGORY_RESPONSE, buffer);
buffer.append(" result=");
buffer.append(deleteOperation.getResultCode().getIntValue());
- MessageBuilder msg = deleteOperation.getErrorMessage();
+ final MessageBuilder msg = deleteOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -1104,7 +1452,7 @@
logAdditionalLogItems(deleteOperation, buffer);
- DN proxiedAuthDN = deleteOperation.getProxiedAuthorizationDN();
+ final DN proxiedAuthDN = deleteOperation.getProxiedAuthorizationDN();
if (proxiedAuthDN != null)
{
buffer.append(" authzDN=\"");
@@ -1138,16 +1486,16 @@
* about the disconnect.
*/
@Override
- public void logDisconnect(ClientConnection clientConnection,
- DisconnectReason disconnectReason, Message message)
+ public void logDisconnect(final ClientConnection clientConnection,
+ final DisconnectReason disconnectReason, final Message message)
{
- // FIXME: implement filtering.
- long connectionID = clientConnection.getConnectionID();
- if (connectionID < 0 && suppressInternalOperations)
+ if (!filter.isDisconnectLoggable(clientConnection))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+
+ final long connectionID = clientConnection.getConnectionID();
+ final StringBuilder buffer = new StringBuilder(100);
buffer.append("[");
buffer.append(TimeThread.getLocalTime());
buffer.append("]");
@@ -1178,7 +1526,7 @@
* the extended request.
*/
@Override
- public void logExtendedRequest(ExtendedOperation extendedOperation)
+ public void logExtendedRequest(final ExtendedOperation extendedOperation)
{
if (!filter.isRequestLoggable(extendedOperation))
{
@@ -1186,10 +1534,10 @@
}
String name = null;
- String oid = extendedOperation.getRequestOID();
- StringBuilder buffer = new StringBuilder(100);
+ final String oid = extendedOperation.getRequestOID();
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(extendedOperation, "EXTENDED", CATEGORY_REQUEST, buffer);
- ExtendedOperationHandler<?> extOpHandler = DirectoryServer
+ final ExtendedOperationHandler<?> extOpHandler = DirectoryServer
.getExtendedOperationHandler(oid);
if (extOpHandler != null)
{
@@ -1223,21 +1571,21 @@
* extended response.
*/
@Override
- public void logExtendedResponse(ExtendedOperation extendedOperation)
+ public void logExtendedResponse(final ExtendedOperation extendedOperation)
{
if (!filter.isResponseLoggable(extendedOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(extendedOperation, "EXTENDED", CATEGORY_RESPONSE, buffer);
String name = null;
- String oid = extendedOperation.getResponseOID();
+ final String oid = extendedOperation.getResponseOID();
if (oid != null)
{
- ExtendedOperationHandler<?> extOpHandler = DirectoryServer
+ final ExtendedOperationHandler<?> extOpHandler = DirectoryServer
.getExtendedOperationHandler(oid);
if (extOpHandler != null)
{
@@ -1257,7 +1605,7 @@
buffer.append(" result=");
buffer.append(extendedOperation.getResultCode().getIntValue());
- MessageBuilder msg = extendedOperation.getErrorMessage();
+ final MessageBuilder msg = extendedOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -1289,14 +1637,14 @@
* modify DN request.
*/
@Override
- public void logModifyDNRequest(ModifyDNOperation modifyDNOperation)
+ public void logModifyDNRequest(final ModifyDNOperation modifyDNOperation)
{
if (!filter.isRequestLoggable(modifyDNOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(modifyDNOperation, "MODIFYDN", CATEGORY_REQUEST, buffer);
buffer.append(" dn=\"");
buffer.append(modifyDNOperation.getRawEntryDN().toString());
@@ -1305,14 +1653,16 @@
buffer.append("\" deleteOldRDN=");
buffer.append(modifyDNOperation.deleteOldRDN());
- ByteString newSuperior = modifyDNOperation.getRawNewSuperior();
+ final ByteString newSuperior = modifyDNOperation.getRawNewSuperior();
if (newSuperior != null)
{
buffer.append(" newSuperior=\"");
buffer.append(newSuperior.toString());
}
if (modifyDNOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -1328,19 +1678,19 @@
* the modify DN response.
*/
@Override
- public void logModifyDNResponse(ModifyDNOperation modifyDNOperation)
+ public void logModifyDNResponse(final ModifyDNOperation modifyDNOperation)
{
if (!filter.isResponseLoggable(modifyDNOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(modifyDNOperation, "MODIFYDN", CATEGORY_RESPONSE, buffer);
buffer.append(" result=");
buffer.append(modifyDNOperation.getResultCode().getIntValue());
- MessageBuilder msg = modifyDNOperation.getErrorMessage();
+ final MessageBuilder msg = modifyDNOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -1350,7 +1700,7 @@
logAdditionalLogItems(modifyDNOperation, buffer);
- DN proxiedAuthDN = modifyDNOperation.getProxiedAuthorizationDN();
+ final DN proxiedAuthDN = modifyDNOperation.getProxiedAuthorizationDN();
if (proxiedAuthDN != null)
{
buffer.append(" authzDN=\"");
@@ -1380,20 +1730,22 @@
* modify request.
*/
@Override
- public void logModifyRequest(ModifyOperation modifyOperation)
+ public void logModifyRequest(final ModifyOperation modifyOperation)
{
if (!filter.isRequestLoggable(modifyOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(modifyOperation, "MODIFY", CATEGORY_REQUEST, buffer);
buffer.append(" dn=\"");
buffer.append(modifyOperation.getRawEntryDN().toString());
buffer.append("\"");
if (modifyOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -1409,19 +1761,19 @@
* modify response.
*/
@Override
- public void logModifyResponse(ModifyOperation modifyOperation)
+ public void logModifyResponse(final ModifyOperation modifyOperation)
{
if (!filter.isResponseLoggable(modifyOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(modifyOperation, "MODIFY", CATEGORY_RESPONSE, buffer);
buffer.append(" result=");
buffer.append(modifyOperation.getResultCode().getIntValue());
- MessageBuilder msg = modifyOperation.getErrorMessage();
+ final MessageBuilder msg = modifyOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -1431,7 +1783,7 @@
logAdditionalLogItems(modifyOperation, buffer);
- DN proxiedAuthDN = modifyOperation.getProxiedAuthorizationDN();
+ final DN proxiedAuthDN = modifyOperation.getProxiedAuthorizationDN();
if (proxiedAuthDN != null)
{
buffer.append(" authzDN=\"");
@@ -1461,14 +1813,14 @@
* request.
*/
@Override
- public void logSearchRequest(SearchOperation searchOperation)
+ public void logSearchRequest(final SearchOperation searchOperation)
{
if (!filter.isRequestLoggable(searchOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(192);
+ final StringBuilder buffer = new StringBuilder(192);
appendHeader(searchOperation, "SEARCH", CATEGORY_REQUEST, buffer);
buffer.append(" base=\"");
buffer.append(searchOperation.getRawBaseDN().toString());
@@ -1477,7 +1829,7 @@
buffer.append(" filter=\"");
searchOperation.getRawFilter().toString(buffer);
- LinkedHashSet<String> attrs = searchOperation.getAttributes();
+ final LinkedHashSet<String> attrs = searchOperation.getAttributes();
if ((attrs == null) || attrs.isEmpty())
{
buffer.append("\" attrs=\"ALL\"");
@@ -1486,7 +1838,7 @@
{
buffer.append("\" attrs=\"");
- Iterator<String> iterator = attrs.iterator();
+ final Iterator<String> iterator = attrs.iterator();
buffer.append(iterator.next());
while (iterator.hasNext())
{
@@ -1497,7 +1849,9 @@
buffer.append("\"");
}
if (searchOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -1513,19 +1867,19 @@
* search result done message.
*/
@Override
- public void logSearchResultDone(SearchOperation searchOperation)
+ public void logSearchResultDone(final SearchOperation searchOperation)
{
if (!filter.isResponseLoggable(searchOperation))
{
return;
}
- StringBuilder buffer = new StringBuilder(128);
+ final StringBuilder buffer = new StringBuilder(128);
appendHeader(searchOperation, "SEARCH", CATEGORY_RESPONSE, buffer);
buffer.append(" result=");
buffer.append(searchOperation.getResultCode().getIntValue());
- MessageBuilder msg = searchOperation.getErrorMessage();
+ final MessageBuilder msg = searchOperation.getErrorMessage();
if ((msg != null) && (msg.length() > 0))
{
buffer.append(" message=\"");
@@ -1538,7 +1892,7 @@
logAdditionalLogItems(searchOperation, buffer);
- DN proxiedAuthDN = searchOperation.getProxiedAuthorizationDN();
+ final DN proxiedAuthDN = searchOperation.getProxiedAuthorizationDN();
if (proxiedAuthDN != null)
{
buffer.append(" authzDN=\"");
@@ -1568,7 +1922,7 @@
* request.
*/
@Override
- public void logUnbind(UnbindOperation unbindOperation)
+ public void logUnbind(final UnbindOperation unbindOperation)
{
// FIXME: ensure that these are logged in combined mode.
if (!filter.isRequestLoggable(unbindOperation))
@@ -1576,10 +1930,12 @@
return;
}
- StringBuilder buffer = new StringBuilder(100);
+ final StringBuilder buffer = new StringBuilder(100);
appendHeader(unbindOperation, "UNBIND", CATEGORY_REQUEST, buffer);
if (unbindOperation.isSynchronizationOperation())
+ {
buffer.append(" type=synchronization");
+ }
writer.writeRecord(buffer.toString());
}
@@ -1587,8 +1943,8 @@
// Appends the common log header information to the provided buffer.
- private void appendHeader(Operation operation, String opType,
- String category, StringBuilder buffer)
+ private void appendHeader(final Operation operation, final String opType,
+ final String category, final StringBuilder buffer)
{
buffer.append('[');
buffer.append(TimeThread.getLocalTime());
@@ -1606,21 +1962,54 @@
- // Appends additional log items to the provided builder.
- private void logAdditionalLogItems(Operation operation, StringBuilder builder)
+ // Build an appropriate set of filters based on the configuration.
+ private void buildFilters()
{
- for (AdditionalLogItem item : operation.getAdditionalLogItems())
+ buildFilters(currentConfig.isSuppressInternalOperations(),
+ currentConfig.isSuppressSynchronizationOperations(),
+ currentConfig.getFilteringPolicy());
+ }
+
+
+
+ private void buildFilters(final boolean suppressInternal,
+ final boolean suppressSynchronization, final FilteringPolicy policy)
+ {
+ final ArrayList<Filter> subFilters = new ArrayList<Filter>();
+ if (currentConfig != null)
+ {
+ for (final String criteriaName : currentConfig
+ .listAccessLogFilteringCriteria())
+ {
+ try
+ {
+ final AccessLogFilteringCriteriaCfg cfg = currentConfig
+ .getAccessLogFilteringCriteria(criteriaName);
+ subFilters.add(new CriteriaFilter(cfg));
+ }
+ catch (final ConfigException e)
+ {
+ // TODO: Unable to decode this access log criteria, so log a warning
+ // and continue.
+ }
+ }
+ }
+ final Filter orFilter = new OrFilter(subFilters.toArray(new Filter[0]));
+ filter = new RootFilter(suppressInternal, suppressSynchronization, policy,
+ orFilter);
+ }
+
+
+
+ // Appends additional log items to the provided builder.
+ private void logAdditionalLogItems(final Operation operation,
+ final StringBuilder builder)
+ {
+ for (final AdditionalLogItem item : operation.getAdditionalLogItems())
{
builder.append(' ');
item.toString(builder);
}
}
-
-
- // Sets the sub-filter.
- private void setSubFilter(Filter subFilter)
- {
- this.filter = new RootFilter(subFilter);
- }
}
diff --git a/opends/src/server/org/opends/server/loggers/TextAuditLogPublisher.java b/opends/src/server/org/opends/server/loggers/TextAuditLogPublisher.java
index f059641..2e639f7 100644
--- a/opends/src/server/org/opends/server/loggers/TextAuditLogPublisher.java
+++ b/opends/src/server/org/opends/server/loggers/TextAuditLogPublisher.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS.
*/
package org.opends.server.loggers;
@@ -41,7 +42,7 @@
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.AccessLogPublisherCfg;
-import org.opends.server.admin.std.server.FileBasedAccessLogPublisherCfg;
+import org.opends.server.admin.std.server.FileBasedAuditLogPublisherCfg;
import org.opends.server.api.AccessLogPublisher;
import org.opends.server.config.ConfigException;
import org.opends.server.core.AddOperation;
@@ -61,8 +62,8 @@
* the directory server.
*/
public class TextAuditLogPublisher extends
- AccessLogPublisher<FileBasedAccessLogPublisherCfg> implements
- ConfigurationChangeListener<FileBasedAccessLogPublisherCfg>
+ AccessLogPublisher<FileBasedAuditLogPublisherCfg> implements
+ ConfigurationChangeListener<FileBasedAuditLogPublisherCfg>
{
private boolean suppressInternalOperations = true;
@@ -71,7 +72,7 @@
private TextWriter writer;
- private FileBasedAccessLogPublisherCfg currentConfig;
+ private FileBasedAuditLogPublisherCfg currentConfig;
@@ -79,7 +80,7 @@
* {@inheritDoc}
*/
public ConfigChangeResult applyConfigurationChange(
- FileBasedAccessLogPublisherCfg config)
+ FileBasedAuditLogPublisherCfg config)
{
// Default result code.
ResultCode resultCode = ResultCode.SUCCESS;
@@ -186,7 +187,7 @@
public void close()
{
writer.shutdown();
- currentConfig.removeFileBasedAccessChangeListener(this);
+ currentConfig.removeFileBasedAuditChangeListener(this);
}
@@ -214,7 +215,7 @@
*/
@Override()
public void initializeAccessLogPublisher(
- FileBasedAccessLogPublisherCfg config)
+ FileBasedAuditLogPublisherCfg config)
throws ConfigException, InitializationException
{
File logFile = getFileForPath(config.getLogFile());
@@ -279,7 +280,7 @@
currentConfig = config;
- config.addFileBasedAccessChangeListener(this);
+ config.addFileBasedAuditChangeListener(this);
}
@@ -291,8 +292,8 @@
public boolean isConfigurationAcceptable(AccessLogPublisherCfg configuration,
List<Message> unacceptableReasons)
{
- FileBasedAccessLogPublisherCfg config =
- (FileBasedAccessLogPublisherCfg) configuration;
+ FileBasedAuditLogPublisherCfg config =
+ (FileBasedAuditLogPublisherCfg) configuration;
return isConfigurationChangeAcceptable(config, unacceptableReasons);
}
@@ -302,7 +303,7 @@
* {@inheritDoc}
*/
public boolean isConfigurationChangeAcceptable(
- FileBasedAccessLogPublisherCfg config, List<Message> unacceptableReasons)
+ FileBasedAuditLogPublisherCfg config, List<Message> unacceptableReasons)
{
// Make sure the permission is valid.
try
--
Gitblit v1.10.0