Skip to content

Add linux.journald data source#5331

Open
staticfloat wants to merge 5 commits intogoogle:mainfrom
staticfloat:sf/journald
Open

Add linux.journald data source#5331
staticfloat wants to merge 5 commits intogoogle:mainfrom
staticfloat:sf/journald

Conversation

@staticfloat
Copy link
Copy Markdown

This PR adds a linux.journald data source to capture journal messages on systemd systems, inspired by the Android logcat viewer. This PR satisfies #3288.

The design is fairly straightforward; libsystemd is added as an optional dependency, traced_probes is taught how to open a connection to the system journal, and messages are serialized in a new protobuf message and displayed in a new UI plugin that mimics that of the logcat messages.

This PR was co-written by AI; while I iterated on it until the look and feel felt correct, there may be context or use cases that I am unaware of. I am open to all review comments, and will do my best to address them.

Add wire-format protos for the linux.journald data source, modeled on
the Android logcat data source.

New files:
- protos/perfetto/config/linux/journald_config.proto: Config message
  with min_prio, filter_identifiers, and filter_units fields.
- protos/perfetto/config/linux/BUILD.gn: GN build target.
- protos/perfetto/trace/linux/journald_event.proto: JournaldEventPacket
  message with per-entry fields (timestamp, pid, tid, uid, gid, prio,
  tag, message, comm, exe, systemd_unit, hostname, transport,
  monotonic_ts) and a Stats submessage.
- protos/perfetto/trace/linux/BUILD.gn: GN build target.

Modified files:
- protos/perfetto/config/data_source_config.proto: Import journald
  config and add journald_config field (id 140).
- protos/perfetto/trace/trace_packet.proto: Import journald event and
  add journald_event field (id 126) to the oneof data block.
- protos/perfetto/config/BUILD.gn: Add linux:@type@ to deps.
- protos/perfetto/trace/BUILD.gn: Add linux:@type@ to non_minimal deps.
Add enable_perfetto_journald GN flag that gates the journald data source
in traced_probes. The flag is enabled on Linux non-Android standalone
builds that have enable_perfetto_traced_probes set.

Also add a pkg_config("pkgconfig_libsystemd") target to gn/BUILD.gn so
that targets building the journald data source can pull in the libsystemd
compile/link flags via pkg-config.

The flag is placed in a separate declare_args() block (after the block
containing enable_perfetto_traced_probes) so it can reference that
variable without triggering the GN "variable defined in same
declare_args() call" restriction.
Implement a new data source that reads log entries from the systemd
journal via libsystemd's sd-journal API. The data source:

- Opens both system and user journals (SD_JOURNAL_LOCAL_ONLY).
- Supports filtering by syslog priority, SYSLOG_IDENTIFIER, and
  _SYSTEMD_UNIT via sd_journal match/conjunction/disjunction filters.
- Seeks to the journal tail on start so only new entries are captured.
- Watches the journal file descriptor for new-entry notifications and
  drains entries in batches of up to 500.
- Extracts 14 fields per entry (timestamp, pid, tid, uid, gid, prio,
  tag, message, comm, exe, systemd_unit, hostname, transport,
  monotonic_ts) and writes them as JournaldEventPacket protos.
- Emits a Stats sub-message on Flush with counters for total, skipped,
  and failed entries.
- Gated behind the enable_perfetto_journald GN flag (Linux-only).
Adds full parsing and storage of JournaldEventPacket from the
linux.journald data source into Trace Processor.

Changes:
- src/trace_processor/tables/linux_tables.py: new JournaldLogTable
  with columns ts, utid, prio, tag, msg, uid, comm, systemd_unit,
  hostname, transport.
- src/trace_processor/tables/BUILD.gn: add linux_tables.py.
- src/trace_processor/importers/proto/linux_probes_parser.{h,cc}:
  parses JournaldEventPacket, resolves PIDs to utids, interns strings
  and inserts rows into JournaldLogTable.
- src/trace_processor/importers/proto/linux_probes_module.{h,cc}:
  registers for TracePacket field 126, tokenises each journald event
  into its own sorted packet (REALTIME → trace time conversion), then
  dispatches to the parser.
- src/trace_processor/importers/proto/BUILD.gn: adds the new sources
  and the linux:zero proto dep to the 'full' source_set.
- src/trace_processor/importers/proto/additional_modules.cc: registers
  LinuxProbesModule.
- src/trace_processor/storage/trace_storage.{h,cc}: adds
  journald_log_table() / mutable_journald_log_table() accessors and
  the linux_tables_py.h include.
- src/trace_processor/trace_processor_impl.cc: calls AddStaticTable
  for journald_log_table and adds linux_tables_py.h include.
- src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/views.sql:
  adds the public journald_logs SQL view.
- test/trace_processor/diff_tests/parser/linux/tests.py: new diff
  test Linux.journald_basic verifying end-to-end parsing.
- test/trace_processor/diff_tests/include_index.py: registers Linux
  test suite.
@staticfloat staticfloat requested a review from a team as a code owner March 29, 2026 00:34
Add a new Perfetto UI plugin for displaying journald logs from the
journald_logs SQL table exposed by trace processor.

The plugin mirrors the Android log plugin (com.android.AndroidLog)
in structure, with the following key differences:

- Table: journald_logs (vs android_logs)
- Priority scale: 0=EMERG...7=DEBUG (syslog convention, lower=worse)
  vs Android's 2=Verbose...7=Fatal (higher=worse)
- Priority filter SQL: prio <= minimumLevel (inverted vs Android)
- Default minimumLevel: 7 (show everything, DEBUG and above)
- Depth/color mapping inverted: 0→purple(EMERG/ALERT/CRIT),
  1→red(ERR), 2→orange(WARNING), 3→grey(NOTICE/INFO), 4→green(DEBUG)
- Extra columns: systemd_unit instead of machine_id
- No multi-machine filter

Files created/modified:
- ui/src/public/track_kinds.ts: Add JOURNALD_LOGS_TRACK_KIND
- ui/src/core/default_plugins.ts: Register dev.perfetto.JournaldLog
- ui/src/plugins/dev.perfetto.JournaldLog/logs_track.ts: Track renderer
- ui/src/plugins/dev.perfetto.JournaldLog/logs_panel.scss: Styles
- ui/src/plugins/dev.perfetto.JournaldLog/logs_panel.ts: Panel + filtering
- ui/src/plugins/dev.perfetto.JournaldLog/index.ts: Plugin entry point
@LalitMaganti
Copy link
Copy Markdown
Member

Hi. Thanks for the contribution! Really great to see this happening. However there are several concerns I have with this patch as it stands:

  1. this is a very large patch for us to review and increases the risk of reverts if one piece is wrong. It would be better if this split into at least 3 patches: on device, trace processor and UI. Even more is preferable if it's cleanly possible.
  2. On device, it seems like in the probes code, we're relying on a header installed on the system and linking against systemd directly.
    • This is something we don't do in Perfetto because it means you then cannot compile unless systemd is installed which it very well might not be, especially in docker containers or VMs where we compile code for distribution
    • The use of systemd functions directly instead of going through dlopen is also problematic because it means, at runtime we will need the library installed or the dynamic linker will fail to start traced_probes. That code needs to be rewritten to treat systemd purely as an optional dependency at runtime not compile time.
  3. I see you've added a new systemd logs table. I'm torn on this but on balance I think we should likely do the opposite refactor: create a common "logs" table and make Android logcat and systemd logs just views over the top of it. This should reduce unnecessary duplication while still allowing custom entries through the use of args.
  4. this also applies to the UI. You seem to have duplicated a lot of code at the UI level when really we should have figured out how to refactor and share that code instead. Specifically, we should probably have a common "logs" plugin which hosts all the shared code with the Android logs and systemd plugins depending on it.

This is my high level comments: I'm really excited to see this happen but I want to make sure this goes in while fitting in with the overall direction of the project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants