Class Journal
- All Implemented Interfaces:
AutoCloseable
Instantiate with the appropriate set of access flags, then use its member functions to select, read, iterate, filter etc. systemd journal entries.
This library reflects the concepts used in systemd journals, especially way they designed cursor and filters.
- Version:
- $Id: $Id
-
Field Summary
FieldsModifier and TypeFieldDescriptionConstantACCEPTABLE_FLAGS_FOR_DIRECTORY_OPENprivate jnr.ffi.Addressprivate boolean(package private) static final Patternprivate Charsetprivate jnr.ffi.byref.AddressByReferenceprivate ZoneOffsetstatic final StringConstantLIB_NAME="systemd"private static NativeJournal(package private) static final intprivate ByteBufferprivate final jnr.ffi.byref.LongLongByReferenceprivate final jnr.ffi.byref.PointerByReferenceprotected static jnr.ffi.RuntimeConstantruntime -
Constructor Summary
ConstructorsConstructorDescriptionconstructor, opening journal access within a namespace.constructor, opening journal access within a namespace.Deprecated.open a journal *directory*.open one or multiple journal files.open journal accesss with flags.constructor with varargs. -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()close after use.voidadd an "AND" to the filter expression list.voidadd an "OR" to the filter expression list.voidfilteringAddFilterExpressionExactMatch(String fieldName, byte[] valueToMatch) add a filter for a field name outside the predefined ones.voidfilteringAddFilterExpressionExactMatch(String journalField, String valueToMatch) add a filter for a field to match a StringvoidfilteringAddFilterExpressionExactMatch(JournalField journalField, byte[] valueToMatch) add a filter for a field to match a byte sequencevoidfilteringAddFilterExpressionExactMatch(JournalField journalField, String valueToMatch) add a filter for a field to match a Stringprivate voidfilteringAddFilterExpressionExactMatchUnchecked(String fieldName, byte[] valueToMatch) voidreset the filter list.intforeachInTimerange(Instant startTime, Instant endTime, int limitCount, JournalConsumer<Journal, JJournalException> toBeCalledOnEachEntry) loop over journal entries within a given timeframe.list all available fields in current journal, insofar defined in the fields enum.list all available fields in current journal, as Strings.longas the function name says: getBytesUsedByJournalFilesget current cursor value as String.intgetDataSize(String fieldName) how long is that field anyhow?get the timeframe the current journal is covering - its earliest, and its latest entry, specified in microseconds.Getter for the fieldjournalTimeZoneOffset.get current journal entry timestamp as Java8 instantlongget raw microseconds value of the current journal entry.booleanhasActiveFilters.booleancheck if persistent journal files have been found.booleancheck if runtime journal files have been found.private voidinit()(package private) static voidloadLib()booleanmoveBackwardUntilEarliestTime move to the firstbooleanmove backward in the journal until a given time is matched.booleanmoveForwardUntilTime(Instant time) move forward in the journal until a given time is matched.voidmove to first valid entry.voidmove to last valid entry.booleanmove to next entry.booleanmove back one entry.voidreadDataToBuffer(String fieldName, ByteBuffer buffer) read field data to buffer.byte[]readFieldAsByteArray(String fieldname) read a field as byte[].byte[]readFieldAsByteArray(JournalField field) read a field as byte[].readFieldAsString(String fieldname) read a field as StringreadFieldAsString(JournalField field) read a field as StringreadFieldAsStringRaw(JournalField field) read a field as Stringprivate StringreadFieldAsStringReturnNullOnEmpty(String fieldname) voidread a complete set of fields.voidreadFieldsAsStrings(Set<JournalField> fields, Map<JournalField, String> targetMap) read a complete set of fields, using the JournalField enum.voidreadFieldToByteArray(String fieldname, ByteBuffer destinationBuffer) read a field into existing byte[].convenience function to read MESSAGE field of current journal entry.booleanseekCursor(String cursorValue) move journal access to a provided cursor; going to the first valid entry on that cursor.voidseekCursorRaw(String cursorValue) journal cursor seek function, wrapped for Java.voidsetJournalTimeZoneOffset(ZoneOffset journalTimeZoneOffset) Setter for the fieldjournalTimeZoneOffset.longskip(long numEntriesToSkip) skip a number of entriesbooleantestCursorRaw(String cursorValue) test whether current position matches supplied cursor.private UUIDturnTwoLongsIntoUUID(long high, long low) static voidvalidateFieldName(String journalField) validate field names.
-
Field Details
-
ACCEPTABLE_FLAGS_FOR_DIRECTORY_OPEN
ConstantACCEPTABLE_FLAGS_FOR_DIRECTORY_OPEN -
LIB_NAME
ConstantLIB_NAME="systemd"- See Also:
-
MILLION
static final int MILLION- See Also:
-
JOURNAL_FIELD_NAME_REGEXP
-
libJournal
-
runtime
protected static jnr.ffi.Runtime runtimeConstantruntime -
journalHandle
private jnr.ffi.byref.AddressByReference journalHandle -
actualJournalHandle
private jnr.ffi.Address actualJournalHandle -
filtersActiveFlag
private boolean filtersActiveFlag -
reusableByteBuffer
-
reusableLongLongByReference
private final jnr.ffi.byref.LongLongByReference reusableLongLongByReference -
reusablePointerByReference
private final jnr.ffi.byref.PointerByReference reusablePointerByReference -
journalCharset
-
journalTimeZoneOffset
-
-
Constructor Details
-
Journal
constructor with varargs.- Parameters:
openFlags- flags to use when opening the Journal access. See OpenFlags enum for details.- Throws:
JJournalException- on severe errors
-
Journal
open journal accesss with flags.- Parameters:
openFlags- an EnumSet of flags.- Throws:
JJournalException- example for specifying a single flag: EnumSet.of(OpenFlags.LOCAL_ONLY)
-
Journal
constructor, opening journal access within a namespace.sd_journal_open_namespace() is similar to sd_journal_open() but takes an additional namespace parameter that specifies which journal namespace to operate on. If specified as NULL the call is identical to sd_journal_open(). If non-NULL only data from the namespace identified by the specified parameter is accessed. This call understands two additional flags: if SD_JOURNAL_ALL_NAMESPACES is specified the namespace parameter is ignored and all defined namespaces are accessed simultaneously; if SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE the specified namespace and the default namespace are accessed but no others (this flag has no effect when namespace is passed as NULL). For details about journal namespaces see systemd-journald.service(8).
- Parameters:
namespace- namespace to operate onopenFlags- flags for opening journal access- Throws:
JJournalException- on failure
-
Journal
constructor, opening journal access within a namespace.sd_journal_open_namespace() is similar to sd_journal_open() but takes an additional namespace parameter that specifies which journal namespace to operate on. If specified as NULL the call is identical to sd_journal_open(). If non-NULL only data from the namespace identified by the specified parameter is accessed. This call understands two additional flags: if SD_JOURNAL_ALL_NAMESPACES is specified the namespace parameter is ignored and all defined namespaces are accessed simultaneously; if SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE the specified namespace and the default namespace are accessed but no others (this flag has no effect when namespace is passed as NULL). For details about journal namespaces see systemd-journald.service(8).
- Parameters:
namespace- namespace to operate onopenFlags- flags for opening journal access- Throws:
JJournalException- on failure NB: if you provide a String parameter, you'll get this - the namespace constructor, which is the one used most often. If you are looking to use the file-based constructor, make sure to provide an List of String objects.
-
Journal
open one or multiple journal files. "All files will be opened and interleaved automatically. Please note that in the case of a live journal, this function is only useful for debugging, because individual journal files can be rotated at any moment, and the opening of specific files is inherently racy." As per documentation, there are no flags available or used here.- Parameters:
filenames- the files to use, with paths. (no special order, it might as well be a set).- Throws:
JJournalException- exception on severe errors
-
Journal
Deprecated.open a journal *directory*. to differentiate from the open-files signature, this is intentionally using a single Path, instead of a String.- Parameters:
directory- pathopenFlags- This accepts OS_ROOT, SYSTEM, and CURRENT_USER flags. for OS_ROOT, the specified path is taken as root from where the relative subdirectories /var/log/journal and /run/log/journal are searched. SYSTEM and CURRENT_USER filter/limit the available files to system, and current user, respectively.- Throws:
JJournalException- exception on severe errors
-
Journal
open a journal *directory*. to differentiate from the open-files signature, this is intentionally using a single Path, instead of a String.- Parameters:
directory- pathopenFlags- This accepts OS_ROOT, SYSTEM, and CURRENT_USER flags. for OS_ROOT, the specified path is taken as root from where the relative subdirectories /var/log/journal and /run/log/journal are searched. SYSTEM and CURRENT_USER filter/limit the available files to system, and current user, respectively.- Throws:
JJournalException- exception on severe errors
-
-
Method Details
-
init
private void init() -
close
public void close()close after use. Also used for AutoCloseable.- Specified by:
closein interfaceAutoCloseable
-
moveToEarliest
move to first valid entry. (log is ordered chronologically)- Throws:
JJournalException- on failure
-
moveToNext
move to next entry.- Returns:
- true if successful, false if not.
- Throws:
JJournalException- if the movement fails altogether in a bad way. useful for loops like this: `while(journal.moveToNext()) {...} `
-
moveToPrevious
move back one entry.- Returns:
- true if successful, false if not.
- Throws:
JJournalException- if this goes really wrong
-
skip
skip a number of entries- Parameters:
numEntriesToSkip- positive to skip forward, negative to skip backwards.- Returns:
- difference between requested skip steps, and actual ones. if the move was performed as asked, this is 0. if the move was only partially performed, because the cursor hit the end, this is >0 and the number of "missing skips"
- Throws:
JJournalException- if the movement failed entirely usage e.g. while (journal.skip(SKIPAHEADVALUE) == 0) ...
-
moveToLatest
move to last valid entry. (log is ordered chronologically)- Throws:
JJournalException- on failure
-
getCursorRaw
get current cursor value as String.- Returns:
- current journal cursor as String.
- Throws:
JJournalException- on severe failures. "The cursor identifies a journal entry globally and in a stable way" Debugging hint: if you get no cursor on a journal, you may have opened something empty or nonexistent. (e.g. accessing a file as namespace)
-
testCursorRaw
test whether current position matches supplied cursor.- Parameters:
cursorValue- the cursor to use- Returns:
- true if valid, false if invalid
- Throws:
JJournalException- on severe failures.
-
seekCursorRaw
journal cursor seek function, wrapped for Java.- Parameters:
cursorValue- the string value containing the opaque cursor- Throws:
JJournalException- if things go seriously wrong
-
seekCursor
move journal access to a provided cursor; going to the first valid entry on that cursor.- Parameters:
cursorValue- the cursor to seek=move to- Returns:
- true if successful, false if not.
- Throws:
JJournalException- if things go seriously wrong
-
getAvailableFields
list all available fields in current journal, insofar defined in the fields enum. additional fields are ignored - see getAvailableFieldsAsString() for the alternative encompassing these.- Returns:
- the set of fields defined in this journal
- Throws:
JJournalException- if things go seriously wrong
-
getAvailableFieldsAsStrings
list all available fields in current journal, as Strings.- Returns:
- the set of field names in this journal
- Throws:
JJournalException- if things go seriously wrong
-
getTimestampAsInstant
get current journal entry timestamp as Java8 instant- Returns:
- Instant of the current journal entry
- Throws:
JJournalException- if things go wrong (e.g. no valid current entry)
-
getTimestampAsMicrosecondsLong
get raw microseconds value of the current journal entry.- Returns:
- a java Long containing the microseconds of the current journal entry.
- Throws:
JJournalException- if things go wrong (e.g. no valid current entry)
-
getFirstAndLastInstant
get the timeframe the current journal is covering - its earliest, and its latest entry, specified in microseconds. it's a pity java doesn't have a tuple, nor a proper "Period" class representing an start-to-end value. java.time.Period instead is just a distance vector, just like Duration. I'd call that a naming failure.- Returns:
- a library class containing the "since" and "until" time
- Throws:
JJournalException- if things go wrong
-
moveForwardUntilTime
move forward in the journal until a given time is matched.- Parameters:
time- the earliest instance the move may stop at.- Returns:
- true if we arrived at a match, false if we did not (e.g. too late).
- Throws:
JJournalException- on severe problems. UNTESTED -- TODO: use seek instead, sd_journal_seek_realtime_usec
-
moveBackwardUntilLatestTime
move backward in the journal until a given time is matched.- Parameters:
time- the latest instance the move may stop at. consider moveBackwardUntilEarliestTime if you want the earliest entry- Returns:
- true if we arrived at a match, false if we did not (e.g. too late).
- Throws:
JJournalException- on severe problems. UNTESTED -- TODO: use seek instead, sd_journal_seek_realtime_usec
-
moveBackwardUntilEarliestTime
moveBackwardUntilEarliestTime move to the first- Parameters:
time- the earliest time acceptable- Returns:
- true if this function could achieve its goal, false if not.
- Throws:
JJournalException- if there was an error, e.g. journal access failing. UNTESTED
-
foreachInTimerange
public int foreachInTimerange(Instant startTime, Instant endTime, int limitCount, JournalConsumer<Journal, JJournalException> toBeCalledOnEachEntry) throws JJournalExceptionloop over journal entries within a given timeframe. note this does not do a moveToEarliest() by itself (anymore). It starts from current position.- Parameters:
startTime- the time of the first entry to operate on, from current position onward. "null" for: do not move. use moveToEarliest(); before calling this function if you want to start from the earliest entry.endTime- the time of the first entry the range ended (that is, not processed anymore - one past last) "null" for tail of journal.limitCount- abort after this many entries having been processed.toBeCalledOnEachEntry- Consumer to be called on each entry.If you need to abort the loop, suggested way is to throw a RuntimeException, or an JJournalException. There is also JJournalException(CONSUMER_ENDING_LOOP) for the specific purpose of identifying this.
- Returns:
- number of entries processed in this range. 0 if empty/none found matching.
- Throws:
JJournalException- on errors, or on Consumer function aborting the loop.
-
hasActiveFilters
public boolean hasActiveFilters()hasActiveFilters.
- Returns:
- a boolean
-
filteringAddFilterExpressionExactMatch
public void filteringAddFilterExpressionExactMatch(String journalField, String valueToMatch) throws JJournalException add a filter for a field to match a String- Parameters:
journalField- field to matchvalueToMatch- value to match exactly with- Throws:
IllegalArgumentException- if the field name string provided doesn't match an actual field.JJournalException- if any.
-
filteringAddFilterExpressionExactMatch
public void filteringAddFilterExpressionExactMatch(JournalField journalField, String valueToMatch) throws JJournalException add a filter for a field to match a String- Parameters:
journalField- field to matchvalueToMatch- value to match exactly with- Throws:
JJournalException- if any.
-
filteringAddFilterExpressionExactMatch
public void filteringAddFilterExpressionExactMatch(JournalField journalField, byte[] valueToMatch) throws JJournalException add a filter for a field to match a byte sequence- Parameters:
journalField- field to matchvalueToMatch- value to match exactly with- Throws:
JJournalException- on severe errors
-
filteringAddFilterExpressionExactMatch
public void filteringAddFilterExpressionExactMatch(String fieldName, byte[] valueToMatch) throws JJournalException add a filter for a field name outside the predefined ones.- Parameters:
fieldName- field to match. may contain 0-9, A-Z and _ only.valueToMatch- value to match exactly with- Throws:
JJournalException- if the field name is invalid, or something else went wrong.
-
filteringAddFilterExpressionExactMatchUnchecked
private void filteringAddFilterExpressionExactMatchUnchecked(String fieldName, byte[] valueToMatch) throws JJournalException - Throws:
JJournalException
-
filteringAddDisjunctionOperator
add an "OR" to the filter expression list. It connects all filteringAddFilter* entries added since (a) most recent OR, (b) most recent AND; (c) the start of the filter expression list, whichever comes first, in an logical OR with all matches added afterwards, until (a) next OR (b) next AND (c) the end of filter expression list whichever comes next.- Throws:
JJournalException- if this fails, or if it is invoked without and filters defined.
-
filteringAddConjunctionOperator
add an "AND" to the filter expression list. It connects all filteringAddFilter* entries added since (a) most recent AND; (b) the start of the filter expression list, whichever comes first, in an logical OR with all matches added afterwards, until (a) next AND (b) the end of filter expression list whichever comes next. This AND operator takes precedence over the OR operator.- Throws:
JJournalException- if this fails, or if it is invoked without and filters defined.
-
filteringReset
public void filteringReset()reset the filter list. -
readFieldAsString
public String readFieldAsString(String fieldname) throws JJournalException, IllegalArgumentException read a field as String- Parameters:
fieldname- ID of the field to be read- Returns:
- field contents (without field name or separating :)
- Throws:
JJournalException- on failure - e.g. if the field does not existIllegalArgumentException- if the fieldname contains invalid characters note: this reuses the internal buffer, so it is even less thread-safe than other calls.
-
readFieldAsByteArray
public byte[] readFieldAsByteArray(String fieldname) throws JJournalException, IllegalArgumentException read a field as byte[]. The byte array is, as is wasteful Java tradition, allocated for this purpose only.- Parameters:
fieldname- ID of the field to be read- Returns:
- a newly allocated byte array containing the field contents.
- Throws:
JJournalException- on failure - e.g. if the field does not existIllegalArgumentException- if the fieldname contains invalid characters
-
readFieldToByteArray
public void readFieldToByteArray(String fieldname, ByteBuffer destinationBuffer) throws JJournalException, IllegalArgumentException read a field into existing byte[]. This call retains the fieldname and separator!- Parameters:
fieldname- ID of the field to be readdestinationBuffer- ByteBuffer for storing the result in. caller needs to take care of position, mark, limit etc.- Throws:
JJournalException- on failure - e.g. if the field does not existIllegalArgumentException- if the fieldname contains invalid characters
-
readFieldAsString
read a field as String- Parameters:
field- ID of the field to be read- Returns:
- a newly allocated byte array containing the field contents.
- Throws:
JJournalException- on failure - e.g. if the field does not exist
-
readFieldAsByteArray
read a field as byte[]. The byte array is, as is wasteful Java tradition, allocated for this purpose only.- Parameters:
field- ID of the field to be read- Returns:
- a newly allocated byte array containing the field contents.
- Throws:
JJournalException- on failure - e.g. if the field does not exist
-
readFieldAsStringRaw
read a field as String- Parameters:
field- aJournalFieldobject- Returns:
- full contents of the field, including the FIELDNAME header.
- Throws:
JJournalException- on failure - e.g. if the field does not exist note: this reuses the internal buffer, so it is even less thread-safe than other calls.
-
readFieldsAsStrings
public void readFieldsAsStrings(List<String> fieldnames, Map<String, String> targetMap) throws JJournalExceptionread a complete set of fields.- Parameters:
fieldnames- a collection of fields to read. illegal fieldnames cause an exception; non-existing fields will appear, with the value to be set (overwritten) to null.targetMap- collection to place the findings in.- Throws:
JJournalException- on severe errors.
-
readFieldsAsStrings
public void readFieldsAsStrings(Set<JournalField> fields, Map<JournalField, String> targetMap) throws JJournalExceptionread a complete set of fields, using the JournalField enum.- Parameters:
fields- a collection of fields to read. empty fields will get their corresponding values set to null.targetMap- collection to place the findings in.- Throws:
JJournalException- on severe errors.
-
readFieldAsStringReturnNullOnEmpty
- Throws:
JJournalException
-
readDataToBuffer
read field data to buffer. Lower level access; you have to take care of the buffer, conversion etc. yourself. This is suitable for accessing binary data. The easier way in most cases is to use readFieldAsString().- Parameters:
fieldName- the name of the field to be read, as Stringbuffer- the ByteBuffer to read the data into. You have to allocate and prepare (e.g. clear, flip etc) the buffer yourself.- Throws:
JJournalException- when things go wrong. org.metabit.platform.interfacing.jjournal.JJournalException BUFFER_TOO_SMALL exception when the message doesn't fit in.
-
getDataSize
how long is that field anyhow?- Parameters:
fieldName- field to check for its length- Returns:
- the size of the field, in bytes.
- Throws:
JJournalException- on errors, especially invalid field names (and being on an invalid position).
-
readMessageField
convenience function to read MESSAGE field of current journal entry. not threadsafe.- Returns:
- String containing the journal entry message
- Throws:
JJournalException- exception on severe errors
-
getBytesUsedByJournalFiles
as the function name says: getBytesUsedByJournalFiles- Returns:
- long containing the bytes used by journal files
- Throws:
JJournalException- when things go wrong.
-
hasRuntimeFiles
check if runtime journal files have been found.- Returns:
- true if runtime journal files have been found.
- Throws:
JJournalException- when things go wrong. see directory /run/systemd/journal/
-
hasPersistentFiles
check if persistent journal files have been found.- Returns:
- true if persistent journal files have been found.
- Throws:
JJournalException- when things go wrong. see directory /var/log/journal/
-
getJournalTimeZoneOffset
Getter for the field
journalTimeZoneOffset.- Returns:
- a
ZoneOffsetobject
-
setJournalTimeZoneOffset
Setter for the field
journalTimeZoneOffset.- Parameters:
journalTimeZoneOffset- aZoneOffsetobject
-
validateFieldName
validate field names. returns quietly if everything is ok.- Parameters:
journalField- string to be used as a journal field name. Use Uppercase ASCII characters, digits, and underscores only.- Throws:
IllegalArgumentException- if the string is refused man sd_journal_send: ...The variable name must be in uppercase and consist only of characters, numbers and underscores, and may not begin with an underscore.[...] A number of well-known fields are defined, see systemd.journal-fields(7) for details, but additional application defined fields may be used. This omits specifying which charset this refers to; so "ÖRTLICHKEIT" would be valid too. But judging from all examples, and the source code, interpretation of this library is that this is *meaning* ASCII uppercase.JJournalException
-
turnTwoLongsIntoUUID
-
loadLib
static void loadLib()
-