2024-07-12 17:50:43 +00:00
|
|
|
import typing
|
|
|
|
from systemd import journal
|
|
|
|
|
|
|
|
|
|
|
|
def get_events_from_journal(
|
|
|
|
j: journal.Reader, limit: int, next: typing.Callable[[journal.Reader], typing.Dict]
|
|
|
|
):
|
|
|
|
events = []
|
|
|
|
i = 0
|
|
|
|
while i < limit:
|
|
|
|
entry = next(j)
|
|
|
|
if entry is None or entry == dict():
|
|
|
|
break
|
|
|
|
if entry["MESSAGE"] != "":
|
|
|
|
events.append(entry)
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
return events
|
|
|
|
|
|
|
|
|
|
|
|
def get_paginated_logs(
|
|
|
|
limit: int = 20,
|
2024-07-15 13:01:33 +00:00
|
|
|
# All entries returned will be lesser than this cursor. Sets upper bound on results.
|
|
|
|
up_cursor: str | None = None,
|
|
|
|
# All entries returned will be greater than this cursor. Sets lower bound on results.
|
|
|
|
down_cursor: str | None = None,
|
2024-07-25 17:34:28 +00:00
|
|
|
# All entries will be from a specific systemd slice
|
|
|
|
filterBySlice: str | None = None,
|
|
|
|
# All entries will be from a specific systemd unit
|
|
|
|
filterByUnit: str | None = None,
|
2024-07-12 17:50:43 +00:00
|
|
|
):
|
|
|
|
j = journal.Reader()
|
|
|
|
|
2024-07-25 17:34:28 +00:00
|
|
|
if filterBySlice:
|
|
|
|
j.add_match("_SYSTEMD_SLICE=" + filterBySlice)
|
|
|
|
if filterByUnit:
|
|
|
|
j.add_match("_SYSTEMD_UNIT=" + filterByUnit)
|
|
|
|
|
2024-07-12 17:50:43 +00:00
|
|
|
if up_cursor is None and down_cursor is None:
|
|
|
|
j.seek_tail()
|
|
|
|
|
|
|
|
events = get_events_from_journal(j, limit, lambda j: j.get_previous())
|
|
|
|
events.reverse()
|
|
|
|
|
2024-11-11 17:09:54 +00:00
|
|
|
j.close()
|
2024-11-11 17:04:00 +00:00
|
|
|
|
2024-07-12 17:50:43 +00:00
|
|
|
return events
|
|
|
|
elif up_cursor is None and down_cursor is not None:
|
|
|
|
j.seek_cursor(down_cursor)
|
|
|
|
j.get_previous() # pagination is exclusive
|
|
|
|
|
|
|
|
events = get_events_from_journal(j, limit, lambda j: j.get_previous())
|
|
|
|
events.reverse()
|
|
|
|
|
2024-11-11 17:04:00 +00:00
|
|
|
j.close()
|
|
|
|
|
2024-07-12 17:50:43 +00:00
|
|
|
return events
|
|
|
|
elif up_cursor is not None and down_cursor is None:
|
|
|
|
j.seek_cursor(up_cursor)
|
|
|
|
j.get_next() # pagination is exclusive
|
|
|
|
|
|
|
|
events = get_events_from_journal(j, limit, lambda j: j.get_next())
|
|
|
|
|
2024-11-11 17:09:54 +00:00
|
|
|
j.close()
|
2024-11-11 17:04:00 +00:00
|
|
|
|
2024-07-12 17:50:43 +00:00
|
|
|
return events
|
|
|
|
else:
|
2024-11-11 17:12:41 +00:00
|
|
|
j.close()
|
2024-11-11 17:04:00 +00:00
|
|
|
|
2024-07-12 17:50:43 +00:00
|
|
|
raise NotImplementedError(
|
|
|
|
"Pagination by both up_cursor and down_cursor is not implemented"
|
|
|
|
)
|