Skip to content

traced_probes: Add linux.journald data source (1/3)#5796

Open
staticfloat wants to merge 1 commit into
google:mainfrom
staticfloat:sf/journald-part-1
Open

traced_probes: Add linux.journald data source (1/3)#5796
staticfloat wants to merge 1 commit into
google:mainfrom
staticfloat:sf/journald-part-1

Conversation

@staticfloat
Copy link
Copy Markdown

@staticfloat staticfloat commented May 10, 2026

Add a new linux.journald data source to traced_probes that reads log entries from the systemd journal via libsystemd. The library is loaded at runtime via dlopen("libsystemd.so.0") so there is no compile-time dependency on libsystemd.

This adds a few new protos to configure and store the journald events. It creates a data source registered under the name 'linux.journald', opens the journal with sd_journal_open(), and emits one JournaldEventPacket per entry containing: timestamp, pid, priority, tag (SYSLOG_IDENTIFIER), message (MESSAGE), uid, comm (_COMM), systemd_unit (_SYSTEMD_UNIT), hostname (_HOSTNAME), and transport (_TRANSPORT). It by default captures from every journal it has access to, so it will include both system and user journals if running as root, for instance.

This is part 1 of a split-up version of #5331 and will close #3288.

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.

@staticfloat staticfloat requested a review from a team as a code owner May 10, 2026 00:00
Copy link
Copy Markdown
Member

@LalitMaganti LalitMaganti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some intuial comments.

Comment thread protos/perfetto/config/perfetto_config.proto
Comment thread protos/perfetto/trace/perfetto_trace.proto
Comment thread protos/perfetto/trace/linux/journald_event.proto Outdated
Comment thread protos/perfetto/trace/linux/journald_event.proto Outdated
Comment thread protos/perfetto/trace/linux/journald_event.proto Outdated
Comment thread src/traced/probes/journald/journald_data_source.cc Outdated
Comment thread src/traced/probes/journald/journald_data_source.cc Outdated
Comment thread src/traced/probes/journald/journald_data_source.cc Outdated
Comment thread src/traced/probes/journald/journald_data_source.cc Outdated
@staticfloat staticfloat force-pushed the sf/journald-part-1 branch 2 times, most recently from ebf663a to aaf3540 Compare May 13, 2026 05:00
Comment thread protos/perfetto/trace/linux/journald_event.proto Outdated
@staticfloat
Copy link
Copy Markdown
Author

I also see that CI is unhappy with me because I added this builtin_clock.pbzero.h include. Is there a better way for me to specify that this packet's timestamp comes from CLOCK_MONOTONIC than packet->set_timestamp_clock_id(protos::pbzero::BUILTIN_CLOCK_MONOTONIC);?

@staticfloat staticfloat force-pushed the sf/journald-part-1 branch 2 times, most recently from ea67497 to ad3b71d Compare May 13, 2026 14:28
@LalitMaganti
Copy link
Copy Markdown
Member

Is there a better way for me to specify that this packet's timestamp comes from CLOCK_MONOTONIC than packet->set_timestamp_clock_id(protos::pbzero::BUILTIN_CLOCK_MONOTONIC);?

You just need to update the BUILD.gn to add a reference to the protos targbet. You're missing that right now.

@staticfloat staticfloat force-pushed the sf/journald-part-1 branch from ad3b71d to 8c81e6f Compare May 13, 2026 16:09
@staticfloat
Copy link
Copy Markdown
Author

Hmmm, the anonymous namespace is fighting the fact that I have a persistent sd_ member, despite the fact that it is private. I could make that member an opaque pointer (e.g. void * sd_, then auto* sd = static_cast<SdJournalApi*>(sd_);), but it's a little ugly. Do you have a preference on how to deal with this?

Comment thread protos/perfetto/trace/linux/journald_event.proto Outdated
Comment thread src/traced/probes/journald/journald_data_source.h Outdated
@staticfloat staticfloat force-pushed the sf/journald-part-1 branch from 8c81e6f to 560fc30 Compare May 13, 2026 20:09
Comment thread protos/perfetto/config/linux/journald_config.proto Outdated
Comment thread src/traced/probes/journald/journald_data_source.cc Outdated
Comment thread protos/perfetto/config/data_source_config.proto Outdated
@staticfloat staticfloat force-pushed the sf/journald-part-1 branch from 560fc30 to e93f2b9 Compare May 13, 2026 23:46
Comment thread src/traced/probes/journald/journald_data_source_unittest.cc Outdated
Comment thread src/traced/probes/journald/journald_data_source.cc
Comment thread src/traced/probes/journald/journald_data_source.cc Outdated
Add a new `linux.journald` data source to `traced_probes` that reads log
entries from the systemd journal via `libsystemd`. The library is loaded
at runtime via dlopen("libsystemd.so.0") so there is no compile-time
dependency on libsystemd.

New protos:
- `JournaldConfig` in `protos/perfetto/config/linux/journald_config.proto`
- `JournaldEventPacket` in `protos/perfetto/trace/linux/journald_event.proto`

The data source opens the journal with sd_journal_open(), and emits one
JournaldEventPacket per entry containing: timestamp, pid, priority,
tag, message, uid, comm, systemd_unit, hostname and transport.
@staticfloat staticfloat force-pushed the sf/journald-part-1 branch from e93f2b9 to c13bac7 Compare May 15, 2026 05:22
@LalitMaganti
Copy link
Copy Markdown
Member

Still LGTM

Copy link
Copy Markdown
Member

@sashwinbalaji sashwinbalaji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not that familiar with journald, so please use your best judgement on these.

Also feel free to resolve anything that doesn't make sense as just flagging things that looked a bit off to me.

}
}

std::string JournaldDataSource::GetField(const char* field) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe need to benchmark would a single sd_journal_enumerate_data be better than these many separate sd_journal_get_data calls ?

https://man7.org/linux/man-pages/man3/sd_journal_enumerate_data.3.html

Comment thread src/traced/probes/journald/journald_data_source.cc
Comment thread src/traced/probes/journald/journald_data_source.cc
Comment thread src/traced/probes/journald/journald_data_source.cc
Comment thread src/traced/probes/journald/journald_data_source.cc

JournaldDataSource::~JournaldDataSource() {
if (journal_ && sd_) {
task_runner_->RemoveFileDescriptorWatch(sd_->get_fd(journal_));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's possibe AddFileDescriptotWatch was never invoked due to early return by SD_CHECKs which can on a debug build might result in crash as we have PERFETTO_DCHECK(watch_tasks_.count(fd));

weak->OnJournalReadable();
});

// Drain once after seek_tail(). sd_journal_next() returns 0 immediately
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a small race here worth a look.

If journald writes a new entry between previous() above and this loop, next() returns 1, the cursor moves onto that entry, and the empty loop body drops it.

OnJournalReadable can only run after this function is completed, so when it runs next() returns 0 because we're already past it, so that entry never makes it into the trace.

Probably rare but I dont have much info on journald so would ask you to consider once.

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.

Linux journald logs datasource

3 participants