Class FileLogger

java.lang.Object
edu.cnu.mdi.log.FileLogger
All Implemented Interfaces:
ILogListener, Closeable, AutoCloseable, EventListener

public class FileLogger extends Object implements ILogListener, Closeable
An ILogListener that appends log messages to a file with automatic size-based rotation.

File format

Messages are written as UTF-8 text, one entry per line (or one entry per block of lines for multi-line messages such as stack traces). Each entry is prefixed with an ISO-8601 date-time stamp and a fixed-width level tag:

 2025-04-07T09:14:02 [INFO   ] Application started.
 2025-04-07T09:14:02 [CONFIG ] Loaded 195 countries from GeoJSON resource.
 2025-04-07T09:14:05 [WARNING] Configuration file not found; using defaults.
 

Unlike ConsoleLogger, the file logger uses a full date-time stamp (not just wall-clock time) so that entries from different days can be distinguished in a long-running application.

Rotation

When the log file exceeds getMaxFileSizeBytes() the current file is renamed to <name>.1 (overwriting any previous backup) and a fresh file is opened. This keeps exactly two files on disk at all times — the current log and one previous — which is sufficient for most desktop applications. More elaborate rotation strategies can be achieved by subclassing and overriding rotate().

The default maximum file size is 5 MB (5242880L bytes). An alternative limit can be supplied to the FileLogger(Path, long) constructor.

Flushing

The writer is flushed after every message. This is slightly less efficient than batched flushing but ensures that no messages are lost if the JVM terminates abnormally.

Registration

 Log.getInstance().addLogListener(new FileLogger(Path.of("app.log")));
 

Shutdown

FileLogger implements Closeable. In applications that want an orderly close of the underlying file, call close() during shutdown:

 FileLogger fileLogger = new FileLogger(Path.of("app.log"));
 Log.getInstance().addLogListener(fileLogger);
 // ... application runs ...
 Log.getInstance().removeLogListener(fileLogger);
 fileLogger.close();
 

If close() is not called the file is closed when the JVM exits via a shutdown hook registered in the constructor, so no messages are silently dropped.

Thread safety

All write operations are synchronized on the FileLogger instance, so it is safe to receive messages from multiple threads simultaneously.

  • Field Details

    • DEFAULT_MAX_BYTES

      public static final long DEFAULT_MAX_BYTES
      Default maximum log-file size before rotation: 5 MB.
      See Also:
  • Constructor Details

    • FileLogger

      public FileLogger(Path logPath)
      Construct a FileLogger that writes to logPath and rotates when the file exceeds DEFAULT_MAX_BYTES.
      Parameters:
      logPath - path of the log file to write; the file and any missing parent directories are created automatically
      Throws:
      IllegalArgumentException - if logPath is null
    • FileLogger

      public FileLogger(Path logPath, long maxFileSizeBytes)
      Construct a FileLogger that writes to logPath and rotates when the file exceeds maxFileSizeBytes.
      Parameters:
      logPath - path of the log file to write
      maxFileSizeBytes - maximum file size in bytes before rotation; must be positive
      Throws:
      IllegalArgumentException - if logPath is null or maxFileSizeBytes is not positive
  • Method Details

    • info

      public void info(String message)
      Appends an Log.Level.INFO message to the log file.
      Specified by:
      info in interface ILogListener
      Parameters:
      message - the message; never null
    • config

      public void config(String message)
      Appends a Log.Level.CONFIG message to the log file.
      Specified by:
      config in interface ILogListener
      Parameters:
      message - the message; never null
    • warning

      public void warning(String message)
      Appends a Log.Level.WARNING message to the log file.
      Specified by:
      warning in interface ILogListener
      Parameters:
      message - the message; never null
    • error

      public void error(String message)
      Appends a Log.Level.ERROR message to the log file.
      Specified by:
      error in interface ILogListener
      Parameters:
      message - the message; never null
    • exception

      public void exception(String message)
      Appends a Log.Level.EXCEPTION message (stack trace) to the log file.
      Specified by:
      exception in interface ILogListener
      Parameters:
      message - the formatted stack trace; never null
    • close

      public void close()
      Flush and close the underlying file writer.

      After this call the logger silently discards any further messages. The logger should also be unregistered from Log so it stops receiving messages:

       Log.getInstance().removeLogListener(fileLogger);
       fileLogger.close();
       
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
    • getLogPath

      public Path getLogPath()
      Returns the path of the active log file.
      Returns:
      the log file path; never null
    • getMaxFileSizeBytes

      public long getMaxFileSizeBytes()
      Returns the maximum file size in bytes before rotation is triggered.
      Returns:
      the rotation threshold in bytes
    • rotate

      protected void rotate()
      Rotate the log file.

      The current writer is closed, the active file is moved to the backup path (overwriting any previous backup), and a fresh writer is opened on the original path. Subclasses may override this method to implement more elaborate rotation strategies, such as date-stamped archives or more than one backup generation.