Cassandra Logging Configuration (logback.xml)
Cassandra uses Logback for logging, configured via logback.xml. This file controls log levels, output destinations, formats, and rotation policies.
Configuration File
Section titled “Configuration File”| File | Location |
|---|---|
logback.xml | /etc/cassandra/ |
Changes to logback.xml are detected automatically within 60 seconds—no restart required.
Log Files
Section titled “Log Files”Cassandra produces several log files by default:
| Log File | Purpose | Default Location |
|---|---|---|
system.log | Main operational log | /var/log/cassandra/ |
debug.log | Detailed debug output | /var/log/cassandra/ |
gc.log | Garbage collection (JVM-configured) | /var/log/cassandra/ |
Basic Structure
Section titled “Basic Structure”<configuration scan="true" scanPeriod="60 seconds">
<!-- Appenders define where logs go --> <appender name="..." class="..."> <!-- appender configuration --> </appender>
<!-- Loggers define what gets logged --> <logger name="..." level="..."/>
<!-- Root logger catches everything not matched by specific loggers --> <root level="INFO"> <appender-ref ref="..."/> </root>
</configuration>Appenders
Section titled “Appenders”Console Appender
Section titled “Console Appender”Output to stdout (useful for containers):
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern> </encoder></appender>Rolling File Appender (system.log)
Section titled “Rolling File Appender (system.log)”Standard file appender with rotation:
<appender name="SYSTEMLOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${cassandra.logdir}/system.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- Roll daily --> <fileNamePattern>${cassandra.logdir}/system.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern> <!-- Max 50MB per file --> <maxFileSize>50MB</maxFileSize> <!-- Keep 7 days of history --> <maxHistory>7</maxHistory> <!-- Cap total size at 5GB --> <totalSizeCap>5GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern> </encoder></appender>Debug Log Appender
Section titled “Debug Log Appender”Separate file for DEBUG level messages:
<appender name="DEBUGLOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${cassandra.logdir}/debug.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${cassandra.logdir}/debug.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>7</maxHistory> <totalSizeCap>5GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern> </encoder></appender>Async Appender
Section titled “Async Appender”Wrap appenders for non-blocking logging:
<appender name="ASYNCSYSTEMLOG" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1024</queueSize> <discardingThreshold>0</discardingThreshold> <includeCallerData>true</includeCallerData> <appender-ref ref="SYSTEMLOG"/></appender>Log Levels
Section titled “Log Levels”| Level | Description | Use Case |
|---|---|---|
TRACE | Most detailed | Deep debugging |
DEBUG | Detailed information | Development, troubleshooting |
INFO | Normal operations | Production default |
WARN | Potential issues | Production monitoring |
ERROR | Errors requiring attention | Always enabled |
OFF | Disable logging | Specific loggers only |
Logger Configuration
Section titled “Logger Configuration”Root Logger
Section titled “Root Logger”Catches all log messages not matched by specific loggers:
<root level="INFO"> <appender-ref ref="SYSTEMLOG"/> <appender-ref ref="STDOUT"/></root>Package-Specific Loggers
Section titled “Package-Specific Loggers”Control verbosity for specific components:
<!-- Reduce noisy components --><logger name="org.apache.cassandra.db.compaction" level="INFO"/><logger name="org.apache.cassandra.service.StorageService" level="INFO"/>
<!-- Increase verbosity for troubleshooting --><logger name="org.apache.cassandra.db.commitlog" level="DEBUG"/><logger name="org.apache.cassandra.streaming" level="DEBUG"/>Common Logger Configurations
Section titled “Common Logger Configurations”| Logger | Level | Purpose |
|---|---|---|
org.apache.cassandra | INFO | All Cassandra components |
org.apache.cassandra.db.compaction | INFO | Compaction operations |
org.apache.cassandra.db.commitlog | INFO | Commit log operations |
org.apache.cassandra.streaming | INFO | Streaming operations |
org.apache.cassandra.hints | INFO | Hinted handoff |
org.apache.cassandra.repair | INFO | Repair operations |
org.apache.cassandra.gms | INFO | Gossip protocol |
org.apache.cassandra.net | INFO | Internode messaging |
org.apache.cassandra.cql3 | INFO | CQL processing |
org.apache.cassandra.auth | INFO | Authentication/authorization |
Log Pattern Format
Section titled “Log Pattern Format”Pattern Elements
Section titled “Pattern Elements”| Element | Description | Example Output |
|---|---|---|
%level | Log level | INFO |
%-5level | Log level, left-padded to 5 chars | INFO |
%thread | Thread name | main |
%date{ISO8601} | ISO timestamp | 2024-01-15 10:30:45,123 |
%logger | Logger name | org.apache.cassandra.db.Memtable |
%F | Source file name | Memtable.java |
%L | Line number | 234 |
%M | Method name | flush |
%msg | Log message | Flushing memtable |
%n | Newline | |
%X{key} | MDC value | Custom context |
Standard Pattern
Section titled “Standard Pattern”<pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern>Output:
INFO [main] 2024-01-15 10:30:45,123 StorageService.java:1234 - Starting listening for CQL clientsJSON Pattern (for log aggregation)
Section titled “JSON Pattern (for log aggregation)”<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="ch.qos.logback.contrib.json.classic.JsonLayout"> <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter"/> <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSS'Z'</timestampFormat> <appendLineSeparator>true</appendLineSeparator> </layout></encoder>Rolling Policies
Section titled “Rolling Policies”Size and Time Based
Section titled “Size and Time Based”Roll logs based on both size and time:
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${cassandra.logdir}/system.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>7</maxHistory> <totalSizeCap>5GB</totalSizeCap></rollingPolicy>Time Based Only
Section titled “Time Based Only”Roll logs daily without size limit:
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${cassandra.logdir}/system.log.%d{yyyy-MM-dd}.zip</fileNamePattern> <maxHistory>30</maxHistory></rollingPolicy>Size Based Only
Section titled “Size Based Only”Roll logs based on size only:
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <fileNamePattern>${cassandra.logdir}/system.log.%i.zip</fileNamePattern> <minIndex>1</minIndex> <maxIndex>10</maxIndex></rollingPolicy><triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>100MB</maxFileSize></triggeringPolicy>Complete Examples
Section titled “Complete Examples”Production Configuration
Section titled “Production Configuration”<configuration scan="true" scanPeriod="60 seconds">
<!-- JMX configuration --> <jmxConfigurator/>
<!-- System log --> <appender name="SYSTEMLOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${cassandra.logdir}/system.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${cassandra.logdir}/system.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>7</maxHistory> <totalSizeCap>5GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern> </encoder> </appender>
<!-- Debug log --> <appender name="DEBUGLOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${cassandra.logdir}/debug.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${cassandra.logdir}/debug.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>7</maxHistory> <totalSizeCap>5GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern> </encoder> <!-- Only DEBUG level --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>DEBUG</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender>
<!-- Async wrappers --> <appender name="ASYNCSYSTEMLOG" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1024</queueSize> <discardingThreshold>0</discardingThreshold> <includeCallerData>true</includeCallerData> <appender-ref ref="SYSTEMLOG"/> </appender>
<appender name="ASYNCDEBUGLOG" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1024</queueSize> <discardingThreshold>0</discardingThreshold> <includeCallerData>true</includeCallerData> <appender-ref ref="DEBUGLOG"/> </appender>
<!-- Reduce noisy loggers --> <logger name="org.apache.cassandra.db.compaction.CompactionTask" level="INFO"/> <logger name="org.apache.cassandra.service.StorageProxy" level="INFO"/>
<!-- Root logger --> <root level="INFO"> <appender-ref ref="ASYNCSYSTEMLOG"/> <appender-ref ref="ASYNCDEBUGLOG"/> </root>
</configuration>Container/Kubernetes Configuration
Section titled “Container/Kubernetes Configuration”<configuration scan="true" scanPeriod="60 seconds">
<!-- Console output for container logs --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%-5level [%thread] %date{ISO8601} %logger{36} - %msg%n</pattern> </encoder> </appender>
<!-- Async wrapper --> <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1024</queueSize> <discardingThreshold>0</discardingThreshold> <appender-ref ref="STDOUT"/> </appender>
<!-- Reduce verbosity --> <logger name="org.apache.cassandra.db.compaction" level="WARN"/> <logger name="org.apache.cassandra.gms.Gossiper" level="WARN"/>
<root level="INFO"> <appender-ref ref="ASYNCSTDOUT"/> </root>
</configuration>Debug/Troubleshooting Configuration
Section titled “Debug/Troubleshooting Configuration”<configuration scan="true" scanPeriod="60 seconds">
<appender name="SYSTEMLOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${cassandra.logdir}/system.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${cassandra.logdir}/system.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>3</maxHistory> <totalSizeCap>10GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%-5level [%thread] %date{ISO8601} %logger{36}:%L - %msg%n</pattern> </encoder> </appender>
<!-- Enable debug for specific subsystems --> <logger name="org.apache.cassandra.db.compaction" level="DEBUG"/> <logger name="org.apache.cassandra.streaming" level="DEBUG"/> <logger name="org.apache.cassandra.repair" level="DEBUG"/> <logger name="org.apache.cassandra.hints" level="DEBUG"/> <logger name="org.apache.cassandra.net" level="DEBUG"/> <logger name="org.apache.cassandra.gms" level="DEBUG"/>
<root level="DEBUG"> <appender-ref ref="SYSTEMLOG"/> </root>
</configuration>Runtime Log Level Changes
Section titled “Runtime Log Level Changes”Modify log levels without restart using nodetool:
# View current levelsnodetool getlogginglevels
# Set level for specific loggernodetool setlogginglevel org.apache.cassandra.db.compaction DEBUG
# Reset to configuration file settingsnodetool setlogginglevel org.apache.cassandra.db.compaction RESETRuntime vs Persistent Changes
Changes via nodetool are temporary and reset on restart. For persistent changes, modify logback.xml.
Audit Logging
Section titled “Audit Logging”Cassandra 4.0+ includes built-in audit logging:
<!-- Audit log appender --><appender name="AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${cassandra.logdir}/audit/audit.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${cassandra.logdir}/audit/audit.log.%d{yyyy-MM-dd}.%i.zip</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>10GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%-5level [%thread] %date{ISO8601} - %msg%n</pattern> </encoder></appender>
<logger name="org.apache.cassandra.audit" level="INFO" additivity="false"> <appender-ref ref="AUDIT"/></logger>Enable in cassandra.yaml:
audit_logging_options: enabled: true logger: - class_name: BinAuditLogger included_keyspaces: my_keyspace included_categories: QUERY,DML,DDL,AUTHFull Query Logging
Section titled “Full Query Logging”Log all CQL queries for debugging:
# Enable via nodetoolnodetool enablefullquerylog --path /var/log/cassandra/fql
# Disablenodetool disablefullquerylog
# Read logsfqltool dump /var/log/cassandra/fqlSlow Query Logging
Section titled “Slow Query Logging”Log queries exceeding threshold:
slow_query_log_timeout_in_ms: 500Slow queries appear in system.log at WARN level.
Troubleshooting
Section titled “Troubleshooting”Log File Not Created
Section titled “Log File Not Created”-
Check directory permissions:
Terminal window ls -la /var/log/cassandra/ -
Verify
cassandra.logdirproperty:Terminal window grep logdir /etc/cassandra/cassandra-env.sh -
Check for XML syntax errors:
Terminal window xmllint --noout /etc/cassandra/logback.xml
Disk Space Issues
Section titled “Disk Space Issues”Configure aggressive rotation:
<maxFileSize>25MB</maxFileSize><maxHistory>3</maxHistory><totalSizeCap>1GB</totalSizeCap>Performance Impact
Section titled “Performance Impact”Use async appenders to minimize logging overhead:
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1024</queueSize> <discardingThreshold>0</discardingThreshold> <neverBlock>true</neverBlock> <appender-ref ref="SYSTEMLOG"/></appender>Missing Stack Traces
Section titled “Missing Stack Traces”Ensure includeCallerData is enabled for async appenders:
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> <includeCallerData>true</includeCallerData> <appender-ref ref="SYSTEMLOG"/></appender>Best Practices
Section titled “Best Practices”| Practice | Recommendation |
|---|---|
| Production log level | INFO for root, WARN for noisy components |
| Async appenders | Always use for production |
| Rotation | Size + time based with totalSizeCap |
| Debug logs | Separate file, enable only when needed |
| Container deployments | Console output, let orchestrator handle rotation |
| Disk monitoring | Alert when log partition exceeds 80% |
| Retention | 7-30 days depending on compliance requirements |
Related Documentation
Section titled “Related Documentation”- cassandra.yaml - Main configuration
- JVM Options - GC logging configuration
- Monitoring - Log aggregation and alerting