The audit-log utility provides a lightweight, configurable logging system for recording driver communication events. It is primarily designed to capture communication traces that can be used for debugging and creating driver test suites.
The audit-log is split into two modules following an API/implementation separation pattern:
plc4j-utils-audit-log-api) - Contains the public API, configuration classes, and a no-op fallback implementationplc4j-utils-audit-log-impl) - Contains the actual file-based implementation using LogbackThis separation allows code to depend only on the API module at compile time while the implementation is optionally included at runtime.
AuditLog auditLog = AuditLog.builder() .withSource("connection-1") .withAuditLogFile("/path/to/audit-log.txt") .build(); // Log events auditLog.write(AuditLogEventType.CONNECT, "Connected to PLC at 192.168.1.100"); auditLog.write(AuditLogEventType.OUTGOING_BYTES, "Sent request", requestBytes); auditLog.write(AuditLogEventType.INCOMING_MESSAGE, "Received response", responseObject); // Close when done auditLog.close();
The audit log can be configured via the log.audit-log-file connection string parameter:
ads://192.168.1.100?log.audit-log-file=/tmp/ads-debug.log
Classes that need audit logging can implement the AuditLogProvider interface:
public class MyConnection implements AuditLogProvider { private final AuditLog auditLog; public MyConnection(AuditLogConfiguration config) { this.auditLog = AuditLog.builder() .withConfiguration(config) .withSource("my-connection") .build(); } @Override public AuditLog getAuditLog() { return auditLog; } }
The AuditLogEventType enum defines the following event types:
| Event Type | Description |
|---|---|
CONFIG | General configuration information |
SYSTEM | General system information |
CONNECT | Connection establishment events |
OUTGOING_BYTES | Raw bytes being sent |
OUTGOING_MESSAGE | Parsed messages being sent |
INCOMING_BYTES | Raw bytes received |
INCOMING_MESSAGE | Parsed messages received |
API_REQUEST | Incoming API requests |
API_RESPONSE | Outgoing API responses |
CLOSE | Connection close events |
ERROR | Error events |
Log entries follow this format:
[timestamp] [eventType] [source] message
Example:
[2025-01-28 14:30:45.123] [CONNECT] [connection-1] Connected to PLC at 192.168.1.100
[2025-01-28 14:30:45.234] [OUTGOING_MESSAGE] [connection-1] Sending read request: {"address":"DB1.DBD0","count":4}
When enabled, the implementation uses a size-and-time-based rolling policy:
{filename}.{date}.{index}.gz (e.g., audit.txt.2025-01-28.0.gz)plc4j-spi-config - Configuration annotationsslf4j-api - Logging facadeplc4j-utils-audit-log-api - The API modulelogback-classic / logback-core - File appender implementationjackson-core / jackson-databind - JSON serializationTo enable audit logging in your application:
<dependency> <groupId>org.apache.plc4x</groupId> <artifactId>plc4j-utils-audit-log-api</artifactId> <version>${project.version}</version> </dependency>
<dependency> <groupId>org.apache.plc4x</groupId> <artifactId>plc4j-utils-audit-log-impl</artifactId> <version>${project.version}</version> <scope>runtime</scope> </dependency>
audit-log-file parameter with a valid file pathIf the implementation module is not on the classpath or no file path is configured, audit logging silently falls back to a no-op implementation with zero overhead.