Journald log do not show details

Issue Description

When setting the log to use journald, there is no details displayed, so the logs are not very useful to debug anything. Logging to a file work fine.

Expected Behavior

It should show display more information, eg the details that I can see if I log in a file, or the one that can be seen on /admin/Management/x:Log.

Actual Behavior

See the logs. There is no details, just the message “JMAP method call”.

Reproduction Steps

  1. Configure Stalwart to log using journald ( on https://mail.example.org/admin/Settings/x:Tracer , create a Tracer of type Systemd journal, keep all default options)
  2. Make sure the journald socket is accessible
  3. Read the log with journalctl -u stalwart -f

Relevant Log Output

Jul 31 14:54:03 mail.example.org stalwart[673]: JMAP method call
Jul 31 14:56:03 mail.example.org stalwart[673]: HTTP connection ended
Jul 31 14:56:03 mail.example.org stalwart[673]: HTTP connection ended

Stalwart Version

v0.16.x

Installation Method

Built from source

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

Internal

Additional Context

I am running stalwart in a container on Fedora 44 with a statically built binary (all options turned off, but rocksdb).

Using strace, I can see that stalwart do not write the details to the socket, just SPANID:

[pid   676] sendto(71, "PRIORITY\n\1\0\0\0\0\0\0\0006\nSYSLOG_IDENTIFIER\n\10\0\0\0\0\0\0\0stalwart\nMESSAGE\n\22\0\0\0\0\0\0\0Resource not found\nSPANID\n\22\0\0\0\0\0\0\000321350216473144832\n", 123, MSG_NOSIGNAL, {sa_family=AF_UNIX, sun_path="/run/systemd/journal/socket"}, 30 <unfinished ...>

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

Journald tracing is working as designed: Stalwart sends each log event to systemd-journal as a structured record where the human-readable summary goes into the standard MESSAGE field, and all the additional context (span ID, error details, method info, etc.) is sent as extra structured journal fields alongside it, not appended into MESSAGE itself.

journalctl -u stalwart -f (the default “short” output format) only prints MESSAGE, so you’re seeing just the short description (“JMAP method call”, “Resource not found”, etc.) with none of the extra fields. To see the full details, query journald in verbose mode, e.g.:

journalctl -u stalwart -f -o verbose

or export/JSON output (-o json-pretty) to see all the extra fields (SPANID and whatever event-specific keys were attached), which is the equivalent of what you see when logging to a file or in the WebUI’s Tracer log.

The Journal tracer variant itself has no configuration knobs beyond the common tracer fields (enable, level, lossy, events, eventsPolicy); there’s no setting to force extra details into MESSAGE.

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

No, this seems wrong:

# journalctl -u stalwart -f -o verbose -n 1
Fri 2026-07-31 15:43:49.868263 UTC [s=2dc34a02bde7440da41cc96bc29e425e;i=24a774;b=33cf4d5175f64261869a971787f97e7a;m=1a25ab1d5;t=657ea0e0b9993;x=e7128add44330b03]
    PRIORITY=6
    _TRANSPORT=journal
    _SYSTEMD_SLICE=system.slice
    _BOOT_ID=33cf4d5175f64261869a971787f97e7a
    _MACHINE_ID=ad588906328a423e8cbb96578f76ff32
    _HOSTNAME=mail.example.org
    _RUNTIME_SCOPE=system
    _UID=0
    _GID=0
    SYSLOG_IDENTIFIER=stalwart
    _PID=673
    _COMM=stalwart
    _EXE=/srv/stalwart
    _CMDLINE=/srv/stalwart --config /etc/stalwart/config.json
    _CAP_EFFECTIVE=400
    _SELINUX_CONTEXT=system_u:system_r:container_t:s0:c298,c710
    _SYSTEMD_CGROUP=/system.slice/stalwart.service/libpod-payload-498e762852f091aa3074078318285c334190a6def0eebe3ae9041d171bf4ebb1
    _SYSTEMD_UNIT=stalwart.service
    _SYSTEMD_INVOCATION_ID=05113d39070c4e8b9a5384bde757e045
    MESSAGE=HTTP connection ended
    ELAPSED=120002
    SPANID=321351864526337536
    _SOURCE_REALTIME_TIMESTAMP=1785512629868263

It was my first verification. As I said, strace show that the data is not sent.

Looking more closely, I see some fields are present, but not others (for example, there is URL for “HTTP request URL”, but no “remoteIp” while this appear in the log file or in the admin interface). I also see that the events at the TRACE level are not appearing in the output of journalctl.

So 1) seems systemd (and syslog) level just go up to DEBUG. I assume that’s why TRACE is not visible.

  1. it seems that some events are fully displayed and not some others. For example, I see that in the log file:
2026-07-31T16:04:57Z DEBUG Resource not found (resource.not-found) listenerId = "http", localPort = 8080, remoteIp = 10.88.0.1, remotePort = 59962

And that with -o json-pretty:

{
	"_SELINUX_CONTEXT" : "system_u:system_r:container_t:s0:c298,c710",
	"__MONOTONIC_TIMESTAMP" : "8412817311",
	"__SEQNUM" : "2403252",
	"__SEQNUM_ID" : "2dc34a02bde7440da41cc96bc29e425e",
	"_COMM" : "stalwart",
	"_SYSTEMD_UNIT" : "stalwart.service",
	"_GID" : "0",
	"_CMDLINE" : "/srv/stalwart --config /etc/stalwart/config.json",
	"_RUNTIME_SCOPE" : "system",
	"_SYSTEMD_CGROUP" : "/system.slice/stalwart.service/libpod-payload-498e762852f091aa3074078318285c334190a6def0eebe3ae9041d171bf4ebb1",
	"_SOURCE_REALTIME_TIMESTAMP" : "1785514023866010",
	"_BOOT_ID" : "33cf4d5175f64261869a971787f97e7a",
	"_CAP_EFFECTIVE" : "400",
	"_UID" : "0",
	"_TRANSPORT" : "journal",
	"_PID" : "673",
	"_SYSTEMD_INVOCATION_ID" : "05113d39070c4e8b9a5384bde757e045",
	"_EXE" : "/srv/stalwart",
	"__REALTIME_TIMESTAMP" : "1785514023866205",
	"_SYSTEMD_SLICE" : "system.slice",
	"ELAPSED" : "3",
	"_HOSTNAME" : "mail.example.org",
	"MESSAGE" : "Metrics collected",
	"SYSLOG_IDENTIFIER" : "stalwart",
	"PRIORITY" : "5",
	"__CURSOR" : "s=2dc34a02bde7440da41cc96bc29e425e;i=24abb4;b=33cf4d5175f64261869a971787f97e7a;m=1f571679f;t=657ea61224f5d;x=101632f32e0a5918",
	"_MACHINE_ID" : "aa588906328a423e8cbb96578f76ff32"
}

But for some others types of events, this is working as expected, for example, for smtp.connection-end, I can see REMOTEIP and REMOTEPORT. I also tested locally from the server, in case the tracing system removed RFC 1918 IP, and no, it work the same.

Fixed in v0.16.16 (yet to be released).