FileGator writes an append-only event log of security-relevant activity. It is plain JSON Lines: one JSON object per line, so it can be read with tail, jq or a log shipper without a custom parser.

What is recorded

EventWhen
auth.loginA successful sign-in
auth.login_failedAn unknown username or wrong password
auth.login_lockedAn attempt while the address is locked out
auth.logoutA sign-out
auth.password_changedA password was changed, or the change was refused
auth.sso_loginA single-sign-on hand-off opened a session
auth.sso_failedA hand-off was refused (bad signature, expired, reused nonce, unknown application)
security.csrf_failedA state-changing request without a valid CSRF token
security.ip_blockedA request refused by the IP allow/deny lists
security.permission_deniedA user tried an action they lack permission for
file.create, file.delete, file.rename, file.copyFile and folder changes
file.saveA file saved in the editor
file.uploadAn upload completed
file.zip, file.unzip, file.batch_downloadArchives and downloads
file.chmodPermission bits changed
admin.user_created, admin.user_updated, admin.user_deletedUser management
admin.settings_savedSettings changed
admin.storage_changed, admin.auth_changedA backend was switched
server.errorAn unexpected server-side failure

Plain folder listings and single-file downloads are not logged: they are the bulk of normal use and would bury the events that matter. file.batch_download, file.zip and file.unzip are logged because they take a whole selection at once.

Passwords never appear in the log, and neither does file content.

Record format

{
  "time": "2026-10-25T10:51:11.57245436Z",
  "level": "INFO",
  "msg": "user created",
  "event": "admin.user_created",
  "user": "admin",
  "target_user": "eve",
  "ip": "10.0.0.7",
  "method": "POST",
  "path": "/api/admin/users"
}

Enabling and configuring

The log is on by default and writes JSON Lines to standard output, so docker logs or journalctl collects it with no extra setup and no file to rotate. Point logging.file at a path to keep a file instead. Change it on Admin → Security:

SettingDefaultMeaning
Write an event logonTurn it off to log nothing
Log file- (stdout)- for standard output; a path (relative to the working directory) for a file
Log levelinfodebug, info, warn or error
Maximum log size0With a file: rotate past this size. The field takes megabytes and stores bytes, so 10 means 10 MB. 0 disables rotation, and must be 0 with -

Logging to stdout (the default)

{
  "logging": {
    "enabled": true,
    "file": "-",
    "level": "info",
    "max_size": 0
  }
}

Records go to standard output; startup messages stay on standard error, so docker logs shows both and either can be redirected separately:

./bin/filegator | jq -c '{time, event, user}'

Rotation is refused together with - because the supervisor (Docker, systemd, journald) owns that file and rotating it behind its back would lose records. A size above 0 with - is rejected at startup with that explanation.

An empty log file is different from -: it means standard error, the fallback used when the configured file cannot be opened.

To keep the event log in a file, set the log file to private/logs/app.log and the maximum size to 10 MB, matching the older layout.

When logging to a file, it is created with mode 0600. When it grows past the limit its contents move to <file>.1 and the live file starts empty, so disk use is bounded at roughly twice the limit. Exactly one previous file is kept.

The level applies immediately: switching to debug takes effect on the next request, with no restart.

If the file cannot be written

The server still starts. It prints a warning explaining that event logging is disabled and continues logging startup messages to stderr, which docker logs collects. This is deliberate: a read-only volume must not stop the server from serving files.

The server still runs in that case; set the log file to - to send events to standard output instead. There is no syslog or network sink.

Reading it

With the default stdout destination:

# Failed sign-ins this week, from journald
journalctl -u filegator | grep '"event":"auth.login_failed"'

# Everything one user did
docker logs filegator 2>&1 | grep '"user":"alice"' | jq -c '{time, event, path}'

# Who deleted something today
journalctl -u filegator --since today | grep '"event":"file.delete"'

With a log file, use the path instead of the service name.

Limitations