"""System logs""" from datetime import datetime import typing import strawberry from selfprivacy_api.utils.systemd_journal import get_paginated_logs @strawberry.type class LogEntry: message: str = strawberry.field() timestamp: datetime = strawberry.field() priority: typing.Optional[int] = strawberry.field() systemd_unit: typing.Optional[str] = strawberry.field() systemd_slice: typing.Optional[str] = strawberry.field() def __init__(self, journal_entry: typing.Dict): self.entry = journal_entry self.message = journal_entry["MESSAGE"] self.timestamp = journal_entry["__REALTIME_TIMESTAMP"] self.priority = journal_entry.get("PRIORITY") self.systemd_unit = journal_entry.get("_SYSTEMD_UNIT") self.systemd_slice = journal_entry.get("_SYSTEMD_SLICE") @strawberry.field() def cursor(self) -> str: return self.entry["__CURSOR"] @strawberry.type class LogsPageMeta: up_cursor: typing.Optional[str] = strawberry.field() down_cursor: typing.Optional[str] = strawberry.field() def __init__( self, up_cursor: typing.Optional[str], down_cursor: typing.Optional[str] ): self.up_cursor = up_cursor self.down_cursor = down_cursor @strawberry.type class PaginatedEntries: page_meta: LogsPageMeta = strawberry.field( description="Metadata to aid in pagination." ) entries: typing.List[LogEntry] = strawberry.field( description="The list of log entries." ) def __init__(self, meta: LogsPageMeta, entries: typing.List[LogEntry]): self.page_meta = meta self.entries = entries @staticmethod def from_entries(entries: typing.List[LogEntry]): if entries == []: return PaginatedEntries(LogsPageMeta(None, None), []) return PaginatedEntries( LogsPageMeta( entries[0].cursor(), entries[-1].cursor(), ), entries, ) @strawberry.type class Logs: @strawberry.field() def paginated( self, limit: int = 20, # 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, # 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, ) -> PaginatedEntries: if limit > 50: raise Exception("You can't fetch more than 50 entries via single request.") return PaginatedEntries.from_entries( list( map( lambda x: LogEntry(x), get_paginated_logs( limit, up_cursor, down_cursor, filterBySlice, filterByUnit, ), ) ) )