IBM Support

How to create a custom logback filter to filter users printed to the audit.log

Troubleshooting


Problem

Summary

How to configure audit logging for only a subset of users in a DSE cluster. It is possible to create a custom filter to avoid filling the audit log with activity for all users. This guide will cover how to implement a custom filter.

 

Installation of DSE and a supported JDK are prerequisites for this article.

Applies to

  • DataStax Enterprise

Instructions

This article assumes DSE is running with audit logging already enabled, but for our purposes, we'll enable just the AUTH events for simplicity.

 

This requires the following change to the dse.yaml followed by a restart:

audit_logging_options:
    enabled: true
    logger: SLF4JAuditWriter   
    included_categories: AUTH


Next, we'll create a class called UserFilter that will match only usernames containing the string 'admin'.

Create the following at: /src/filter/package/UserFilter.java

package user.filter;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;

public class UserFilter extends Filter<ILoggingEvent> {

    @Override
    public FilterReply decide(ILoggingEvent event) {
        String message = event.getFormattedMessage();

        // Match messages containing 'user:' followed by a username containing 'admin'
        if (message.contains("user:") && message.contains("admin")) {
            return FilterReply.ACCEPT; // Log this message
        }

        return FilterReply.DENY; // Ignore other messages
    }
}

This should be customized to fit your needs. For example, if you had specific usernames to match that didn't contain a common string, you could instead create a class that used the following logic:

package user.filter;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;

public class UserFilter extends Filter<ILoggingEvent> {

    @Override
    public FilterReply decide(ILoggingEvent event) {
        String message = event.getFormattedMessage();

        // Match messages containing 'user:' with usernames 'cassandra' 'dseadmin' and 'starlord'
        if (message.contains("user:cassandra") || message.contains("user:dseadmin") || message.contains("user:starlord")) {
            return FilterReply.ACCEPT; // Log this message
        }

        return FilterReply.DENY; // Ignore other messages
    }
}

After creation, we'll use the logback-core-* and logback-classic-* jars that come with the DSE install for the classpath when compiling UserFilter.java.

For me, those jars are installed in /usr/share/dse/cassandra/lib, but verify this location for your DSE install as it can differ.
I compiled with the following command executed inside /src/filter/package:

sudo javac -cp /usr/share/dse/cassandra/lib/logback-core-1.2.11.jar:/usr/share/dse/cassandra/lib/logback-classic-1.2.11.jar -d out /src/filter/package/UserFilter.java

Still inside /src/filter/package, now create a jar from the compiled class:

jar cf UserFilter.jar -C out .

Next, copy the created UserFilter.jar to the same location as the logback jar files:

sudo cp UserFilter.jar /usr/share/dse/cassandra/lib/

Then give it the same ownership as the other jar files and the same permissions, I'm using user cassandra for my example:

sudo chown cassandra:cassandra /usr/share/dse/cassandra/lib/UserFilter.jar
sudo chmod 777 /usr/share/dse/cassandra/lib/UserFilter.jar

Now navigate to the logback.xml file that came with your DSE install, typically found in the same directory as the cassandra.yaml, for me, the file is '/etc/dse/cassandra/logback.xml'.

Open this file for editing and navigate to the audit log section of the file.

We'll be adding the newly created filter class via the following entry into the appender section of the file:

<filter class="user.filter.UserFilter" />

My full audit log appender XML is now:

<!--audit log-->
  <appender name="SLF4JAuditWriterAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${cassandra.logdir}/audit/audit.log</file>
    <encoder>
      <pattern>%-5level [%thread] %date{ISO8601} %X{service} %F:%L - %msg%n</pattern>
      <immediateFlush>true</immediateFlush>
    </encoder>
    <filter class="user.filter.UserFilter" />
    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
      <fileNamePattern>${cassandra.logdir}/audit/audit.log.%i.zip</fileNamePattern>
      <minIndex>1</minIndex>
      <maxIndex>5</maxIndex>
    </rollingPolicy>
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <maxFileSize>200MB</maxFileSize>
    </triggeringPolicy>
  </appender>

Once in place, restart DSE and test to ensure only the desired users are logged to the audit.log.

This can be customized to fit a variety of use case needs for applying custom filters.

Document Location

Worldwide

[{"Type":"MASTER","Line of Business":{"code":"LOB76","label":"Data Platform"},"Business Unit":{"code":"BU048","label":"IBM Software"},"Product":{"code":"SSCR56","label":"IBM DataStax Enterprise"},"ARM Category":[{"code":"","label":""}],"ARM Case Number":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"All Version(s)"}]

Historical Number

ka0Ui0000003rJ7IAI

Document Information

Modified date:
30 January 2026

UID

ibm17258477