systemd-journal 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/README.md +25 -2
- data/Rakefile +6 -6
- data/lib/systemd/id128.rb +9 -0
- data/lib/systemd/journal.rb +33 -246
- data/lib/systemd/journal/filterable.rb +102 -0
- data/lib/systemd/journal/native.rb +9 -6
- data/lib/systemd/journal/navigable.rb +112 -0
- data/lib/systemd/journal/version.rb +1 -1
- data/lib/systemd/journal/waitable.rb +74 -0
- data/lib/systemd/journal/{compat.rb → writable.rb} +4 -3
- data/lib/systemd/journal_entry.rb +27 -2
- data/spec/no_ffi.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/systemd/id128_spec.rb +5 -5
- data/spec/systemd/journal_entry_spec.rb +69 -15
- data/spec/systemd/journal_spec.rb +206 -125
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df7fe5c76f75b85e1c6ae332b5dc4db8268956c9
|
4
|
+
data.tar.gz: ddb32ec9f34855f7fe8ae5bfef85f5c8606b9295
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1aa3dd8871ac3b44fe9e063a5fef7ed300f2580a76ebb0a122951dd1136fe86c99322f5342515fafcaf723c337b90ccc59a4a89c47cb02fe007912ba9e493b6f
|
7
|
+
data.tar.gz: 30018c03c4cc3178e2798c9f7edf60d290cdef165ee41bccc5a9256f0fe922b5f9473a6f6fb6d3fe8662f56111eef6878729874b05bc69b06729c4e521a1c6b5
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Systemd::Journal [](http://badge.fury.io/rb/systemd-journal) [](https://travis-ci.org/ledbettj/systemd-journal)
|
1
|
+
# Systemd::Journal [](http://badge.fury.io/rb/systemd-journal) [](https://travis-ci.org/ledbettj/systemd-journal) [](https://codeclimate.com/github/ledbettj/systemd-journal)
|
2
2
|
|
3
3
|
Ruby bindings for reading from the systemd journal.
|
4
4
|
|
@@ -9,7 +9,7 @@ Ruby bindings for reading from the systemd journal.
|
|
9
9
|
|
10
10
|
Add this line to your application's Gemfile:
|
11
11
|
|
12
|
-
gem 'systemd-journal', '~> 1.
|
12
|
+
gem 'systemd-journal', '~> 1.1.0'
|
13
13
|
|
14
14
|
And then execute:
|
15
15
|
|
@@ -62,6 +62,27 @@ Moving around the journal:
|
|
62
62
|
# seek the entry that occured closest to this time
|
63
63
|
j.seek(Time.parse("2013-10-31T12:00:00+04:00:00"))
|
64
64
|
|
65
|
+
Waiting for things to happen:
|
66
|
+
|
67
|
+
j = Systemd::Journal.new
|
68
|
+
j.seek(:tail)
|
69
|
+
# wait up to one second for something to happen
|
70
|
+
if j.wait(1_000_000)
|
71
|
+
puts 'something changed!'
|
72
|
+
# same as above, but can be interrupted with Control+C.
|
73
|
+
if j.wait(1_000_000, select: true)
|
74
|
+
puts 'something changed!'
|
75
|
+
|
76
|
+
Accessing the catalog:
|
77
|
+
|
78
|
+
j = Systemd::Journal.new
|
79
|
+
j.move_next
|
80
|
+
j.move_next while !j.current_entry.catalog?
|
81
|
+
|
82
|
+
puts j.current_entry.catalog
|
83
|
+
# or if you have a message id:
|
84
|
+
puts Systemd::Journal.catalog_for(j.current_entry.message_id)
|
85
|
+
|
65
86
|
|
66
87
|
See the documentation for more examples.
|
67
88
|
|
@@ -78,3 +99,5 @@ If you run into problems or have questions, please open an
|
|
78
99
|
4. Push to the branch (`git push origin my-new-feature`)
|
79
100
|
5. Create new Pull Request, targeting the __develop__ branch.
|
80
101
|
6. Wipe hands on pants, you're done.
|
102
|
+
|
103
|
+
[](https://bitdeli.com/free "Bitdeli Badge")
|
data/Rakefile
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'yard'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
require 'rubocop/rake_task'
|
5
5
|
|
6
|
-
desc
|
6
|
+
desc 'open a console with systemd/journal required'
|
7
7
|
task :console do
|
8
8
|
exec 'pry -I./lib -r systemd/journal'
|
9
9
|
end
|
10
10
|
|
11
11
|
Rubocop::RakeTask.new(:rubocop) do |task|
|
12
|
-
task.patterns = ['lib/**/*.rb']
|
12
|
+
task.patterns = ['lib/**/*.rb', 'spec/**/*.rb']
|
13
13
|
task.fail_on_error = false
|
14
14
|
end
|
15
15
|
|
data/lib/systemd/id128.rb
CHANGED
data/lib/systemd/journal.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'systemd/journal/native'
|
2
2
|
require 'systemd/journal/flags'
|
3
|
-
require 'systemd/journal/
|
3
|
+
require 'systemd/journal/writable'
|
4
4
|
require 'systemd/journal/fields'
|
5
|
+
require 'systemd/journal/navigable'
|
6
|
+
require 'systemd/journal/filterable'
|
7
|
+
require 'systemd/journal/waitable'
|
5
8
|
require 'systemd/journal_error'
|
6
9
|
require 'systemd/journal_entry'
|
7
10
|
require 'systemd/id128'
|
@@ -12,11 +15,14 @@ module Systemd
|
|
12
15
|
# Class to allow interacting with the systemd journal.
|
13
16
|
# To read from the journal, instantiate a new {Systemd::Journal}; to write to
|
14
17
|
# the journal, use
|
15
|
-
# {Systemd::Journal::
|
16
|
-
# {Systemd::Journal::
|
18
|
+
# {Systemd::Journal::Writable::ClassMethods#message Journal.message} or
|
19
|
+
# {Systemd::Journal::Writable::ClassMethods#print Journal.print}.
|
17
20
|
class Journal
|
18
21
|
include Enumerable
|
19
|
-
include Systemd::Journal::
|
22
|
+
include Systemd::Journal::Writable
|
23
|
+
include Systemd::Journal::Navigable
|
24
|
+
include Systemd::Journal::Filterable
|
25
|
+
include Systemd::Journal::Waitable
|
20
26
|
|
21
27
|
# Returns a new instance of a Journal, opened with the provided options.
|
22
28
|
# @param [Hash] opts optional initialization parameters.
|
@@ -60,115 +66,6 @@ module Systemd
|
|
60
66
|
yield current_entry while move_next
|
61
67
|
end
|
62
68
|
|
63
|
-
# Move the read pointer by `offset` entries.
|
64
|
-
# @param [Integer] offset how many entries to move the read pointer by. If
|
65
|
-
# this value is positive, the read pointer moves forward. Otherwise, it
|
66
|
-
# moves backwards.
|
67
|
-
# @return [Integer] the number of entries the read pointer actually moved.
|
68
|
-
def move(offset)
|
69
|
-
offset > 0 ? move_next_skip(offset) : move_previous_skip(-offset)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Filter the journal at a high level.
|
73
|
-
# Takes any number of arguments; each argument should be a hash representing
|
74
|
-
# a condition to filter based on. Fields inside the hash will be ANDed
|
75
|
-
# together. Each hash will be ORed with the others. Fields in hashes with
|
76
|
-
# Arrays as values are treated as an OR statement, since otherwise they
|
77
|
-
# would never match.
|
78
|
-
# @example
|
79
|
-
# j = Systemd::Journal.filter(
|
80
|
-
# {_systemd_unit: 'session-4.scope'},
|
81
|
-
# {priority: [4, 6]},
|
82
|
-
# {_exe: '/usr/bin/sshd', priority: 1}
|
83
|
-
# )
|
84
|
-
# # equivalent to
|
85
|
-
# (_systemd_unit == 'session-4.scope') ||
|
86
|
-
# (priority == 4 || priority == 6) ||
|
87
|
-
# (_exe == '/usr/bin/sshd' && priority == 1)
|
88
|
-
def filter(*conditions)
|
89
|
-
clear_filters
|
90
|
-
|
91
|
-
last_index = conditions.length - 1
|
92
|
-
|
93
|
-
conditions.each_with_index do |condition, index|
|
94
|
-
add_filters(condition)
|
95
|
-
add_disjunction unless index == last_index
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Move the read pointer to the next entry in the journal.
|
100
|
-
# @return [Boolean] True if moving to the next entry was successful.
|
101
|
-
# @return [Boolean] False if unable to move to the next entry, indicating
|
102
|
-
# that the pointer has reached the end of the journal.
|
103
|
-
def move_next
|
104
|
-
rc = Native.sd_journal_next(@ptr)
|
105
|
-
raise JournalError.new(rc) if rc < 0
|
106
|
-
rc > 0
|
107
|
-
end
|
108
|
-
|
109
|
-
# Move the read pointer forward by `amount` entries.
|
110
|
-
# @return [Integer] the actual number of entries by which the read pointer
|
111
|
-
# moved. If this number is less than the requested amount, the read
|
112
|
-
# pointer has reached the end of the journal.
|
113
|
-
def move_next_skip(amount)
|
114
|
-
rc = Native.sd_journal_next_skip(@ptr, amount)
|
115
|
-
raise JournalError.new(rc) if rc < 0
|
116
|
-
rc
|
117
|
-
end
|
118
|
-
|
119
|
-
# Move the read pointer to the previous entry in the journal.
|
120
|
-
# @return [Boolean] True if moving to the previous entry was successful.
|
121
|
-
# @return [Boolean] False if unable to move to the previous entry,
|
122
|
-
# indicating that the pointer has reached the beginning of the journal.
|
123
|
-
def move_previous
|
124
|
-
rc = Native.sd_journal_previous(@ptr)
|
125
|
-
raise JournalError.new(rc) if rc < 0
|
126
|
-
rc > 0
|
127
|
-
end
|
128
|
-
|
129
|
-
# Move the read pointer backwards by `amount` entries.
|
130
|
-
# @return [Integer] the actual number of entries by which the read pointer
|
131
|
-
# was moved. If this number is less than the requested amount, the read
|
132
|
-
# pointer has reached the beginning of the journal.
|
133
|
-
def move_previous_skip(amount)
|
134
|
-
rc = Native.sd_journal_previous_skip(@ptr, amount)
|
135
|
-
raise JournalError.new(rc) if rc < 0
|
136
|
-
rc
|
137
|
-
end
|
138
|
-
|
139
|
-
# Seek to a position in the journal.
|
140
|
-
# Note: after seeking, you must call {#move_next} or {#move_previous}
|
141
|
-
# before you can call {#read_field} or {#current_entry}.
|
142
|
-
#
|
143
|
-
# @param [Symbol, Time] whence one of :head, :tail, or a Time instance.
|
144
|
-
# `:head` (or `:start`) will seek to the beginning of the journal.
|
145
|
-
# `:tail` (or `:end`) will seek to the end of the journal. When a `Time`
|
146
|
-
# is provided, seek to the journal entry logged closest to that time. When
|
147
|
-
# a String is provided, assume it is a cursor from {#cursor} and seek to
|
148
|
-
# that entry.
|
149
|
-
# @return [True]
|
150
|
-
def seek(whence)
|
151
|
-
rc = case whence
|
152
|
-
when :head, :start
|
153
|
-
Native.sd_journal_seek_head(@ptr)
|
154
|
-
when :tail, :end
|
155
|
-
Native.sd_journal_seek_tail(@ptr)
|
156
|
-
else
|
157
|
-
if whence.is_a?(Time)
|
158
|
-
# TODO: is this right? who knows.
|
159
|
-
Native.sd_journal_seek_realtime_usec(@ptr, whence.to_i * 1_000_000)
|
160
|
-
elsif whence.is_a?(String)
|
161
|
-
Native.sd_journal_seek_cursor(@ptr, whence)
|
162
|
-
else
|
163
|
-
raise ArgumentError.new("Unknown seek type: #{whence.class}")
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
raise JournalErrornew(rc) if rc < 0
|
168
|
-
|
169
|
-
true
|
170
|
-
end
|
171
|
-
|
172
69
|
# Read the contents of the provided field from the current journal entry.
|
173
70
|
# {#move_next} or {#move_previous} must be called at least once after
|
174
71
|
# initialization or seeking prior to attempting to read data.
|
@@ -215,6 +112,27 @@ module Systemd
|
|
215
112
|
JournalEntry.new(results)
|
216
113
|
end
|
217
114
|
|
115
|
+
def current_catalog
|
116
|
+
out_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
117
|
+
|
118
|
+
rc = Native.sd_journal_get_catalog(@ptr, out_ptr)
|
119
|
+
raise JournalError.new(rc) if rc < 0
|
120
|
+
|
121
|
+
Journal.read_and_free_outstr(out_ptr.read_pointer)
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.catalog_for(message_id)
|
125
|
+
out_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
126
|
+
|
127
|
+
rc = Native.sd_journal_get_catalog_for_message_id(
|
128
|
+
Systemd::Id128::Native::Id128.from_s(message_id),
|
129
|
+
out_ptr
|
130
|
+
)
|
131
|
+
raise JournalError.new(rc) if rc < 0
|
132
|
+
|
133
|
+
read_and_free_outstr(out_ptr.read_pointer)
|
134
|
+
end
|
135
|
+
|
218
136
|
# Get the list of unique values stored in the journal for the given field.
|
219
137
|
# If passed a block, each possible value will be yielded.
|
220
138
|
# @return [Array] the list of possible values.
|
@@ -241,112 +159,6 @@ module Systemd
|
|
241
159
|
results
|
242
160
|
end
|
243
161
|
|
244
|
-
# Block until the journal is changed.
|
245
|
-
# @param timeout_usec [Integer] the maximum number of microseconds to wait
|
246
|
-
# or `-1` to wait indefinitely.
|
247
|
-
# @example Wait for an event for a maximum of 3 seconds
|
248
|
-
# j = Systemd::Journal.new
|
249
|
-
# j.seek(:tail)
|
250
|
-
# if j.wait(3 * 1_000_000)
|
251
|
-
# # event occurred
|
252
|
-
# end
|
253
|
-
# @return [Nil] if the wait time was reached (no events occured).
|
254
|
-
# @return [Symbol] :append if new entries were appened to the journal.
|
255
|
-
# @return [Symbol] :invalidate if journal files were added/removed/rotated.
|
256
|
-
def wait(timeout_usec = -1)
|
257
|
-
rc = Native.sd_journal_wait(@ptr, timeout_usec)
|
258
|
-
raise JournalError.new(rc) if rc.is_a?(Fixnum) && rc < 0
|
259
|
-
rc == :nop ? nil : rc
|
260
|
-
end
|
261
|
-
|
262
|
-
# Blocks and waits for new entries to be appended to the journal. When new
|
263
|
-
# entries are written, yields them in turn. Note that this function does
|
264
|
-
# not automatically seek to the end of the journal prior to waiting.
|
265
|
-
# This method Does not return.
|
266
|
-
# @example Print out events as they happen
|
267
|
-
# j = Systemd::Journal.new
|
268
|
-
# j.seek(:tail)
|
269
|
-
# j.watch do |event|
|
270
|
-
# puts event.message
|
271
|
-
# end
|
272
|
-
def watch
|
273
|
-
loop do
|
274
|
-
if wait
|
275
|
-
yield current_entry while move_next
|
276
|
-
end
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
# Add a filter to journal, such that only entries where the given filter
|
281
|
-
# matches are returned.
|
282
|
-
# {#move_next} or {#move_previous} must be invoked after adding a filter
|
283
|
-
# before attempting to read from the journal.
|
284
|
-
# @param [String] field the column to filter on, e.g. _PID, _EXE.
|
285
|
-
# @param [String] value the match to search for, e.g. '/usr/bin/sshd'
|
286
|
-
# @return [nil]
|
287
|
-
def add_filter(field, value)
|
288
|
-
match = "#{field.to_s.upcase}=#{value}"
|
289
|
-
rc = Native.sd_journal_add_match(@ptr, match, match.length)
|
290
|
-
raise JournalError.new(rc) if rc < 0
|
291
|
-
end
|
292
|
-
|
293
|
-
# Add a set of filters to the journal, such that only entries where the
|
294
|
-
# given filters match are returned.
|
295
|
-
# @param [Hash] filters a set of field/filter value pairs.
|
296
|
-
# If the filter value is an array, each value in the array is added
|
297
|
-
# and entries where the specified field matches any of the values is
|
298
|
-
# returned.
|
299
|
-
# @example Filter by PID and EXE
|
300
|
-
# j.add_filters(_pid: 6700, _exe: '/usr/bin/sshd')
|
301
|
-
def add_filters(filters)
|
302
|
-
filters.each do |field, value|
|
303
|
-
Array(value).each{ |v| add_filter(field, v) }
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
# Add an OR condition to the filter. All previously added matches
|
308
|
-
# will be ORed with the terms following the disjunction.
|
309
|
-
# {#move_next} or {#move_previous} must be invoked after adding a match
|
310
|
-
# before attempting to read from the journal.
|
311
|
-
# @return [nil]
|
312
|
-
# @example Filter entries returned using an OR condition
|
313
|
-
# j = Systemd::Journal.new
|
314
|
-
# j.add_filter('PRIORITY', 5)
|
315
|
-
# j.add_disjunction
|
316
|
-
# j.add_filter('_EXE', '/usr/bin/sshd')
|
317
|
-
# while j.move_next
|
318
|
-
# # current_entry is either an sshd event or
|
319
|
-
# # has priority 5
|
320
|
-
# end
|
321
|
-
def add_disjunction
|
322
|
-
rc = Native.sd_journal_add_disjunction(@ptr)
|
323
|
-
raise JournalError.new(rc) if rc < 0
|
324
|
-
end
|
325
|
-
|
326
|
-
# Add an AND condition to the filter. All previously added terms will be
|
327
|
-
# ANDed together with terms following the conjunction.
|
328
|
-
# {#move_next} or {#move_previous} must be invoked after adding a match
|
329
|
-
# before attempting to read from the journal.
|
330
|
-
# @return [nil]
|
331
|
-
# @example Filter entries returned using an AND condition
|
332
|
-
# j = Systemd::Journal.new
|
333
|
-
# j.add_filter('PRIORITY', 5)
|
334
|
-
# j.add_conjunction
|
335
|
-
# j.add_filter('_EXE', '/usr/bin/sshd')
|
336
|
-
# while j.move_next
|
337
|
-
# # current_entry is an sshd event with priority 5
|
338
|
-
# end
|
339
|
-
def add_conjunction
|
340
|
-
rc = Native.sd_journal_add_conjunction(@ptr)
|
341
|
-
raise JournalError.new(rc) if rc < 0
|
342
|
-
end
|
343
|
-
|
344
|
-
# Remove all filters and conjunctions/disjunctions.
|
345
|
-
# @return [nil]
|
346
|
-
def clear_filters
|
347
|
-
Native.sd_journal_flush_matches(@ptr)
|
348
|
-
end
|
349
|
-
|
350
162
|
# Get the number of bytes the Journal is currently using on disk.
|
351
163
|
# If {Systemd::Journal::Flags::LOCAL_ONLY} was passed when opening the
|
352
164
|
# journal, this value will only reflect the size of journal files of the
|
@@ -380,35 +192,10 @@ module Systemd
|
|
380
192
|
end
|
381
193
|
end
|
382
194
|
|
383
|
-
# returns a string representing the current read position.
|
384
|
-
# This string can be passed to {#seek} or {#cursor?}.
|
385
|
-
# @return [String] a cursor token.
|
386
|
-
def cursor
|
387
|
-
out_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
388
|
-
if (rc = Native.sd_journal_get_cursor(@ptr, out_ptr)) < 0
|
389
|
-
raise JournalError.new(rc)
|
390
|
-
end
|
391
|
-
|
392
|
-
read_and_free_outstr(out_ptr.read_pointer)
|
393
|
-
end
|
394
|
-
|
395
|
-
# Check if the read position is currently at the entry represented by the
|
396
|
-
# provided cursor value.
|
397
|
-
# @param c [String] a cursor token returned from {#cursor}.
|
398
|
-
# @return [Boolean] True if the current entry is the one represented by the
|
399
|
-
# provided cursor, False otherwise.
|
400
|
-
def cursor?(c)
|
401
|
-
if (rc = Native.sd_journal_test_cursor(@ptr, c)) < 0
|
402
|
-
raise JournalError.new(rc)
|
403
|
-
end
|
404
|
-
|
405
|
-
rc > 0
|
406
|
-
end
|
407
|
-
|
408
195
|
private
|
409
196
|
|
410
197
|
def self.finalize(ptr)
|
411
|
-
proc{ Native.sd_journal_close(ptr) unless ptr.nil? }
|
198
|
+
proc { Native.sd_journal_close(ptr) unless ptr.nil? }
|
412
199
|
end
|
413
200
|
|
414
201
|
def enumerate_helper(enum_function)
|
@@ -430,7 +217,7 @@ module Systemd
|
|
430
217
|
# some sd_journal_* functions return strings that we're expected to free
|
431
218
|
# ourselves. This function copies the string from a char* to a ruby string,
|
432
219
|
# frees the char*, and returns the ruby string.
|
433
|
-
def read_and_free_outstr(ptr)
|
220
|
+
def self.read_and_free_outstr(ptr)
|
434
221
|
str = ptr.read_string
|
435
222
|
LibC.free(ptr)
|
436
223
|
str
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Systemd
|
2
|
+
class Journal
|
3
|
+
module Filterable
|
4
|
+
# Filter the journal at a high level.
|
5
|
+
# Takes any number of arguments; each argument should be a hash
|
6
|
+
# representing a condition to filter based on. Fields inside the hash
|
7
|
+
# will be ANDed together. Each hash will be ORed with the others.
|
8
|
+
# Fields in hashes with Arrays as values are treated as an OR statement,
|
9
|
+
# since otherwise they would never match.
|
10
|
+
# @example
|
11
|
+
# j = Systemd::Journal.filter(
|
12
|
+
# {_systemd_unit: 'session-4.scope'},
|
13
|
+
# {priority: [4, 6]},
|
14
|
+
# {_exe: '/usr/bin/sshd', priority: 1}
|
15
|
+
# )
|
16
|
+
# # equivalent to
|
17
|
+
# (_systemd_unit == 'session-4.scope') ||
|
18
|
+
# (priority == 4 || priority == 6) ||
|
19
|
+
# (_exe == '/usr/bin/sshd' && priority == 1)
|
20
|
+
def filter(*conditions)
|
21
|
+
clear_filters
|
22
|
+
|
23
|
+
last_index = conditions.length - 1
|
24
|
+
|
25
|
+
conditions.each_with_index do |condition, index|
|
26
|
+
add_filters(condition)
|
27
|
+
add_disjunction unless index == last_index
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add a filter to journal, such that only entries where the given filter
|
32
|
+
# matches are returned.
|
33
|
+
# {#move_next} or {#move_previous} must be invoked after adding a filter
|
34
|
+
# before attempting to read from the journal.
|
35
|
+
# @param [String] field the column to filter on, e.g. _PID, _EXE.
|
36
|
+
# @param [String] value the match to search for, e.g. '/usr/bin/sshd'
|
37
|
+
# @return [nil]
|
38
|
+
def add_filter(field, value)
|
39
|
+
match = "#{field.to_s.upcase}=#{value}"
|
40
|
+
rc = Native.sd_journal_add_match(@ptr, match, match.length)
|
41
|
+
raise JournalError.new(rc) if rc < 0
|
42
|
+
end
|
43
|
+
|
44
|
+
# Add a set of filters to the journal, such that only entries where the
|
45
|
+
# given filters match are returned.
|
46
|
+
# @param [Hash] filters a set of field/filter value pairs.
|
47
|
+
# If the filter value is an array, each value in the array is added
|
48
|
+
# and entries where the specified field matches any of the values is
|
49
|
+
# returned.
|
50
|
+
# @example Filter by PID and EXE
|
51
|
+
# j.add_filters(_pid: 6700, _exe: '/usr/bin/sshd')
|
52
|
+
def add_filters(filters)
|
53
|
+
filters.each do |field, value|
|
54
|
+
Array(value).each { |v| add_filter(field, v) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Add an OR condition to the filter. All previously added matches
|
59
|
+
# will be ORed with the terms following the disjunction.
|
60
|
+
# {#move_next} or {#move_previous} must be invoked after adding a match
|
61
|
+
# before attempting to read from the journal.
|
62
|
+
# @return [nil]
|
63
|
+
# @example Filter entries returned using an OR condition
|
64
|
+
# j = Systemd::Journal.new
|
65
|
+
# j.add_filter('PRIORITY', 5)
|
66
|
+
# j.add_disjunction
|
67
|
+
# j.add_filter('_EXE', '/usr/bin/sshd')
|
68
|
+
# while j.move_next
|
69
|
+
# # current_entry is either an sshd event or
|
70
|
+
# # has priority 5
|
71
|
+
# end
|
72
|
+
def add_disjunction
|
73
|
+
rc = Native.sd_journal_add_disjunction(@ptr)
|
74
|
+
raise JournalError.new(rc) if rc < 0
|
75
|
+
end
|
76
|
+
|
77
|
+
# Add an AND condition to the filter. All previously added terms will be
|
78
|
+
# ANDed together with terms following the conjunction.
|
79
|
+
# {#move_next} or {#move_previous} must be invoked after adding a match
|
80
|
+
# before attempting to read from the journal.
|
81
|
+
# @return [nil]
|
82
|
+
# @example Filter entries returned using an AND condition
|
83
|
+
# j = Systemd::Journal.new
|
84
|
+
# j.add_filter('PRIORITY', 5)
|
85
|
+
# j.add_conjunction
|
86
|
+
# j.add_filter('_EXE', '/usr/bin/sshd')
|
87
|
+
# while j.move_next
|
88
|
+
# # current_entry is an sshd event with priority 5
|
89
|
+
# end
|
90
|
+
def add_conjunction
|
91
|
+
rc = Native.sd_journal_add_conjunction(@ptr)
|
92
|
+
raise JournalError.new(rc) if rc < 0
|
93
|
+
end
|
94
|
+
|
95
|
+
# Remove all filters and conjunctions/disjunctions.
|
96
|
+
# @return [nil]
|
97
|
+
def clear_filters
|
98
|
+
Native.sd_journal_flush_matches(@ptr)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|