Documentation
¶
Index ¶
- func SipHash24(key [16]byte, data []byte) uint64
- type Entry
- func (e *Entry) Get(key string) string
- func (e *Entry) Hostname() string
- func (e *Entry) Message() string
- func (e *Entry) Realtime() uint64
- func (e *Entry) Seqnum() uint64
- func (e *Entry) String() string
- func (e *Entry) SyslogFacility() string
- func (e *Entry) SyslogIdentifier() string
- func (e *Entry) Unit() string
- type File
- func (f *File) ArenaSize() uint64
- func (f *File) Close() error
- func (f *File) Entry() *Entry
- func (f *File) Exists() bool
- func (f *File) FieldValues(name string, limit int) ([]string, bool, error)
- func (f *File) Fields() ([]string, error)
- func (f *File) HeadEntryRealtime() uint64
- func (f *File) HeadEntrySeqnum() uint64
- func (f *File) HeaderSize() uint64
- func (f *File) NEntries() uint64
- func (f *File) NObjects() uint64
- func (f *File) Next() bool
- func (f *File) NextEntry() (*Entry, bool)
- func (f *File) Path() string
- func (f *File) Previous() bool
- func (f *File) ReloadHeader() error
- func (f *File) Seek(seqnum uint64) bool
- func (f *File) SeekHead()
- func (f *File) SeekRealtime(t time.Time) bool
- func (f *File) SeekTail()
- func (f *File) Signature() string
- func (f *File) State() uint8
- func (f *File) TailEntryRealtime() uint64
- func (f *File) TailEntrySeqnum() uint64
- func (f *File) TailObjectOffset() uint64
- type FileHeader
- type Journal
- func (j *Journal) Close() error
- func (j *Journal) Entry() *Entry
- func (j *Journal) FieldValues(name string, limit int) ([]string, bool, error)
- func (j *Journal) Fields() ([]string, error)
- func (j *Journal) Files() []*File
- func (j *Journal) Follow(ctx context.Context, pollInterval time.Duration, fn func(*Entry) bool) error
- func (j *Journal) NFiles() int
- func (j *Journal) Next() bool
- func (j *Journal) NextEntry() (e *Entry, ok bool)
- func (j *Journal) Previous() bool
- func (j *Journal) Seek(seqnum uint64) bool
- func (j *Journal) SeekHead()
- func (j *Journal) SeekRealtime(t time.Time)
- func (j *Journal) SeekTail()
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Entry ¶
type Entry struct {
Timestamp time.Time
Fields map[string]string
BootID string
MessageID string
Priority int
UID uint32
GID uint32
PID uint32
Transport string
// contains filtered or unexported fields
}
Entry represents a single journald log record. Fields contains all key-value pairs from the entry (MESSAGE, _SYSTEMD_UNIT, etc.). Timestamp is derived from the entry's realtime clock value. Seqnum and Realtime provide raw access to the on-disk values for use in cursor-based navigation.
func (*Entry) Get ¶
Get returns the value for an arbitrary field key. For well-known fields, prefer the typed accessors (Message, Unit, etc.) which are self-documenting.
func (*Entry) Realtime ¶
Realtime returns the entry's wall-clock timestamp as microseconds since the Unix epoch. Use for SeekRealtime comparisons. For human-readable time, use the Timestamp field instead.
func (*Entry) Seqnum ¶
Seqnum returns the entry's monotonic sequence number. Seqnums are unique within a journal file and increase with each entry. Use for cursor-based iteration — a File's containsSeqnum checks whether a seqnum falls within a file's range.
func (*Entry) SyslogFacility ¶
SyslogFacility returns the SYSLOG_FACILITY field value (e.g. "4" for cron).
func (*Entry) SyslogIdentifier ¶
SyslogIdentifier returns the SYSLOG_IDENTIFIER field value (e.g. "sshd").
type File ¶
type File struct {
// contains filtered or unexported fields
}
File reads a single journald journal file. It holds one entry at a time in memory (streaming iteration, not eager load). For multi-file journals, use Journal instead — File is strictly single-file.
File is not safe for concurrent use. Each goroutine should open its own.
func Open ¶
Open opens a journald journal file for reading. Returns error if the file doesn't exist, isn't a valid journal file, or can't be read. The File starts positioned at the first entry (after the header).
func (*File) ArenaSize ¶
ArenaSize returns the total byte size of the data arena (all objects after the header).
func (*File) Close ¶
Close releases the underlying file descriptor. After Close, all methods return zero values or errors.
func (*File) Exists ¶
Exists reports whether the file still exists on disk. Used by Journal to detect deleted files during cleanup.
func (*File) FieldValues ¶
FieldValues returns all distinct values for the named field (label) in this journal file, up to limit values. If truncated is true, the limit was reached and the result is not cached — the caller may retry with a higher limit. For archived (non-rotating) files, complete (non-truncated) results are cached after the first call.
func (*File) Fields ¶
Fields returns all distinct field names (label names) present in this journal file. For archived (non-rotating) files, results are cached after the first call.
func (*File) HeadEntryRealtime ¶
HeadEntryRealtime returns the wall-clock timestamp (microseconds since Unix epoch) of the oldest entry in this file. Used by Journal.SeekRealtime to pick the best file.
func (*File) HeadEntrySeqnum ¶
HeadEntrySeqnum returns the smallest sequence number in this file (the oldest entry). Files are sorted by this value in Journal. Used for seqnum-based file lookup.
func (*File) HeaderSize ¶
HeaderSize returns the byte size of the file header. Entries begin at this offset.
func (*File) NEntries ¶
NEntries returns the total number of log entries recorded in this file's header. This is the count at file open time — use Next() to iterate and count actual entries reachable from the current offset.
func (*File) NObjects ¶
NObjects returns the total number of objects (entries, data fields, hash tables, etc.) in the file's arena.
func (*File) Next ¶
Next advances to the next entry in the file, skipping non-entry objects (data fields, hash tables, etc.). Returns true and stores the entry if found. Returns false at EOF or on read error. Call after Open or SeekHead/SeekRealtime to read the first entry.
func (*File) NextEntry ¶
NextEntry is a convenience wrapper: calls Next() then returns (Entry(), true) on success, or (nil, false) if no more entries.
func (*File) Path ¶
Path returns the filesystem path of the underlying file, or empty string if the File was constructed from an in-memory source.
func (*File) Previous ¶
Previous moves the cursor to the entry just before the current one by sequence number. Uses the file header to check if the previous seqnum is in range, then calls Seek(target). If there is a gap (Seek lands past the target), decrements and retries until a match is found or the head seqnum is reached.
Returns false if there is no previous entry (already at head) or if no entry has been read yet. O(n) per Seek call — acceptable for bounded backward iteration but not for repeated random access.
func (*File) ReloadHeader ¶
ReloadHeader re-reads the file header from disk and updates the cached size. Use after the active journal file may have grown or been rotated to an archived state. Calls readHeader internally, so header fields (HeadEntrySeqnum, TailEntrySeqnum, State, etc.) are refreshed on success.
func (*File) Seek ¶
Seek positions the reader at the entry with the given seqnum and reads it into Entry(). If seqnum < HeadEntrySeqnum, loads the first entry (may be after the target). If seqnum >= TailEntrySeqnum, loads the last entry. Returns true if the loaded entry's seqnum is >= seqnum.
func (*File) SeekHead ¶
func (f *File) SeekHead()
SeekHead resets the read position to the first entry in the file. The next call to Next() will return the oldest entry.
func (*File) SeekRealtime ¶
SeekRealtime positions the reader at the first entry whose realtime timestamp is >= t and reads it into Entry(). If t is before the head realtime, loads the first entry (may be after t). If t is after the tail realtime, loads the last entry. Returns true if the loaded entry's timestamp is >= t.
func (*File) SeekTail ¶
func (f *File) SeekTail()
SeekTail positions the reader at the last entry in the file and reads it into Entry(). Equivalent to Seek(tailSeqnum).
func (*File) Signature ¶
Signature returns the 8-byte magic string that identifies valid journald files.
func (*File) State ¶
State returns the file's lifecycle state from its header: 0=offline, 1=online (active, receiving new entries), 2=archived (rotated, no new entries).
func (*File) TailEntryRealtime ¶
TailEntryRealtime returns the wall-clock timestamp (microseconds since Unix epoch) of the newest entry in this file. Used by Journal.SeekRealtime to skip files entirely before the target time.
func (*File) TailEntrySeqnum ¶
TailEntrySeqnum returns the largest sequence number in this file (the newest entry). Used for rotation detection and gap detection in Journal.Next().
func (*File) TailObjectOffset ¶
TailObjectOffset returns the byte offset of the tail object (most recently written).
type FileHeader ¶
type FileHeader struct {
Signature [8]byte
CompatibleFlags uint32
IncompatibleFlags uint32
State uint8
Reserved [7]byte
FileID [16]byte
MachineID [16]byte
TailEntryBootID [16]byte
SeqnumID [16]byte
HeaderSize uint64
ArenaSize uint64
DataTableOffset uint64
DataTableSize uint64
FieldTableOffset uint64
FieldTableSize uint64
TailObjectOffset uint64
NObjects uint64
NEntries uint64
TailEntrySeqnum uint64
HeadEntrySeqnum uint64
EntryArrayOffset uint64
HeadEntryRealtime uint64
TailEntryRealtime uint64
TailEntryMonotonic uint64
NData uint64
NFields uint64
NTags uint64
NEntryArrays uint64
DataHashChainDepth uint64
FieldHashChainDepth uint64
TailEntryArrayOffset uint32
TailEntryArrayNEnts uint32
TailEntryOffset uint64
}
FileHeader holds the binary header of a journald journal file. HeadEntrySeqnum is the oldest (smallest) sequence number in the file; TailEntrySeqnum is the newest (largest). Head/TailRealtime are the corresponding wall-clock timestamps as microseconds since the Unix epoch. State indicates file lifecycle: 0=offline, 1=online (active), 2=archived (rotated).
type Journal ¶
type Journal struct {
// contains filtered or unexported fields
}
Journal reads a journald log across multiple journal files (active + archived). Files are sorted by HeadEntrySeqnum (smallest = oldest). The last file in the list is the active file receiving new entries. Handles file rotation, gap detection across files, and header reload when the active file grows.
Not safe for concurrent use. Each goroutine should acquire a dedicated Journal from a Pool.
func OpenJournal ¶
OpenJournal opens all journal files matching name in dir. Files are opened as name.journal (active) and name@*.journal (archived), sorted by HeadEntrySeqnum.
If name.journal is not found directly in dir, OpenJournal searches one level of subdirectories (e.g. the machine-id directory used by journald). If exactly one subdirectory contains name.journal, it is used automatically. Returns error if no matching files exist, multiple subdirectories match, or any file fails to open.
func (*Journal) Close ¶
Close closes all underlying Files. Returns the first error encountered; remaining files are still closed.
func (*Journal) FieldValues ¶
FieldValues returns all distinct values for the named field across all files in the journal, up to limit values. If truncated is true, the limit was reached.
func (*Journal) Fields ¶
Fields returns all distinct field names (label names) across all files in the journal.
func (*Journal) Files ¶
Files returns the open Readers sorted by HeadEntrySeqnum (index 0 = oldest). Useful for diagnostics (e.g. printing seqnum ranges with cmd/inspect).
func (*Journal) Follow ¶
func (j *Journal) Follow(ctx context.Context, pollInterval time.Duration, fn func(*Entry) bool) error
Follow polls for new entries at the given interval and calls fn for each entry. Returns nil if fn returns false (stopped early). Returns the context cause if ctx is cancelled. Useful for tailing live journals:
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
err := j.Follow(ctx, 10*time.Millisecond, func(e *Entry) bool {
fmt.Println(e)
return true // keep following
})
func (*Journal) Next ¶
Next advances to the next entry in sequence-number order across all files. On first call (Entry() == nil), reads the first entry from the file with the smallest HeadEntrySeqnum. On subsequent calls, advances within the current file or jumps to the next file. Handles gaps between files by finding the file with the smallest HeadEntrySeqnum greater than the current seqnum. When caught up, reloads the active file's header to detect rotation or new entries. Returns false when no more entries are available.
func (*Journal) NextEntry ¶
NextEntry is a convenience wrapper: calls Next() then returns (Entry(), true) on success, or (nil, false) if no more entries.
func (*Journal) Previous ¶
Previous moves to the entry just before the current one in sequence-number order. Uses containsSeqnum to check if the previous seqnum is in a file, then delegates to File.Previous (which uses Seek). Handles cross-file gaps by falling back to the file with the largest tail before the current seqnum.
Returns false if there is no previous entry (at head of first file) or no entry has been read yet. O(n) per call — see File.Previous for details.
func (*Journal) Seek ¶
Seek positions the journal at the entry with the given seqnum and reads it into Entry(). Refreshes if seqnum is beyond the tail. Returns true if the resulting Entry()'s seqnum is >= seqnum.
func (*Journal) SeekHead ¶
func (j *Journal) SeekHead()
SeekHead resets all files to their first entry and clears the current Entry. The next Next() call reads from the oldest entry across all files.
func (*Journal) SeekRealtime ¶
SeekRealtime positions the journal at the first entry whose timestamp is >= t. Files entirely before t are skipped. The best file (smallest HeadEntryRealtime that covers t) is SeekRealtime'd and its first entry is read into Entry(). Returns true if the resulting Entry()'s timestamp is >= t. Call Next() after SeekRealtime to continue iteration.