systemd-journal 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/Gemfile +1 -0
- data/README.md +18 -7
- data/Rakefile +6 -0
- data/examples/ssh_watcher.rb +2 -4
- data/lib/systemd/ffi_size_t.rb +9 -13
- data/lib/systemd/id128.rb +13 -15
- data/lib/systemd/journal.rb +50 -52
- data/lib/systemd/journal/compat.rb +4 -7
- data/lib/systemd/journal/fields.rb +2 -2
- data/lib/systemd/journal/native.rb +3 -3
- data/lib/systemd/journal/version.rb +1 -1
- data/lib/systemd/journal_entry.rb +7 -2
- data/lib/systemd/journal_error.rb +2 -4
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f9a1f4583f555e4c8832ce277fc87d02eeabb2f
|
4
|
+
data.tar.gz: a4bc24e388cf2211574a5f138df8d05dc7f97505
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25274b48c5eba590dd4904f10142932fc4c6458170a49f93453c4d7e0cbb9822c6d045e2d9536f0d79244528081d2725fe99ab1aafacb3ebb4ae891a2076e05c
|
7
|
+
data.tar.gz: 2f863c1a90d35b999115eedd3b160b5d36db4cc273f80fdad5a91fca74dcc9f8c1189b9e1cd9c47dbc6e69df3b180d02ab15be8718ec46383539ebc1e22c14ce
|
data/.rubocop.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
Ruby bindings for reading from the systemd journal.
|
4
4
|
|
5
|
-
* [documentation](http://rubydoc.info/gems/systemd-journal)
|
5
|
+
* [gem documentation](http://rubydoc.info/gems/systemd-journal)
|
6
|
+
* [libsystemd-journal documentation](http://www.freedesktop.org/software/systemd/man/sd-journal.html)
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
@@ -14,6 +15,11 @@ And then execute:
|
|
14
15
|
|
15
16
|
bundle install
|
16
17
|
|
18
|
+
Obviously you will need to have [systemd](http://www.freedesktop.org/wiki/Software/systemd/)
|
19
|
+
installed on your system in order to use the gem. The two native library
|
20
|
+
dependencies are `libsystemd-journal` and `libsystemd-id128`.
|
21
|
+
|
22
|
+
|
17
23
|
## Usage
|
18
24
|
|
19
25
|
require 'systemd/journal'
|
@@ -30,17 +36,17 @@ Print all messages as they occur:
|
|
30
36
|
Filter events and iterate:
|
31
37
|
|
32
38
|
j = Systemd::Journal.new
|
33
|
-
|
39
|
+
|
34
40
|
# only display entries from SSHD with priority 6.
|
35
41
|
j.filter(priority: 6, _exe: '/usr/bin/sshd')
|
36
42
|
j.each do |entry|
|
37
43
|
puts entry.message
|
38
44
|
end
|
39
|
-
|
45
|
+
|
40
46
|
Moving around the journal:
|
41
47
|
|
42
48
|
j = Systemd::Journal.new
|
43
|
-
|
49
|
+
|
44
50
|
j.seek(:head) # move to the start of journal
|
45
51
|
j.move(10) # move forward by 10 entries
|
46
52
|
c = j.cursor # get a reference to this entry
|
@@ -50,15 +56,20 @@ Moving around the journal:
|
|
50
56
|
j.seek(:tail) # move to end of the journal
|
51
57
|
j.move_previous # move back
|
52
58
|
j.move_next # move forward
|
53
|
-
|
59
|
+
|
54
60
|
j.current_entry # get the entry we're currently positioned at
|
55
|
-
|
61
|
+
|
56
62
|
# seek the entry that occured closest to this time
|
57
63
|
j.seek(Time.parse("2013-10-31T12:00:00+04:00:00"))
|
58
64
|
|
59
|
-
|
65
|
+
|
60
66
|
See the documentation for more examples.
|
61
67
|
|
68
|
+
## Issues?
|
69
|
+
|
70
|
+
If you run into problems or have questions, please open an
|
71
|
+
[Issue](https://github.com/ledbettj/systemd-journal/issues).
|
72
|
+
|
62
73
|
## Contributing
|
63
74
|
|
64
75
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "yard"
|
3
3
|
require "rspec/core/rake_task"
|
4
|
+
require "rubocop/rake_task"
|
4
5
|
|
5
6
|
desc "open a console with systemd/journal required"
|
6
7
|
task :console do
|
7
8
|
exec 'pry -I./lib -r systemd/journal'
|
8
9
|
end
|
9
10
|
|
11
|
+
Rubocop::RakeTask.new(:rubocop) do |task|
|
12
|
+
task.patterns = ['lib/**/*.rb']
|
13
|
+
task.fail_on_error = false
|
14
|
+
end
|
15
|
+
|
10
16
|
YARD::Rake::YardocTask.new do |t|
|
11
17
|
t.files = ['lib/**/*.rb']
|
12
18
|
t.options = ['--no-private', '--markup=markdown']
|
data/examples/ssh_watcher.rb
CHANGED
@@ -8,10 +8,8 @@ class SSHWatcher
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def run
|
11
|
-
@journal.
|
12
|
-
|
13
|
-
while @journal.move_next ; end
|
14
|
-
|
11
|
+
@journal.filter(_exe: '/usr/bin/sshd')
|
12
|
+
@journal.seek(:tail)
|
15
13
|
@journal.watch{ |entry| process_event(entry) }
|
16
14
|
end
|
17
15
|
|
data/lib/systemd/ffi_size_t.rb
CHANGED
@@ -2,18 +2,14 @@ require 'ffi'
|
|
2
2
|
|
3
3
|
# @private
|
4
4
|
class FFI::MemoryPointer
|
5
|
+
# monkey patch a read_size_t and write_size_t method onto FFI::MemoryPointer
|
6
|
+
p = FFI::MemoryPointer.new(:size_t, 1)
|
7
|
+
w = case p.size
|
8
|
+
when 4 then :uint32
|
9
|
+
when 8 then :uint64
|
10
|
+
else raise RuntimeError.new("unsupported size_t width: #{p.size}")
|
11
|
+
end
|
5
12
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
case (p = FFI::MemoryPointer.new(:size_t, 1)).size
|
9
|
-
when 4
|
10
|
-
alias_method(:read_size_t, :read_uint32) unless p.respond_to?(:read_size_t)
|
11
|
-
alias_method(:write_size_t, :write_uint32) unless p.respond_to?(:write_size_t)
|
12
|
-
when 8
|
13
|
-
alias_method(:read_size_t, :read_uint64) unless p.respond_to?(:read_size_t)
|
14
|
-
alias_method(:write_size_t, :write_uint64) unless p.respond_to?(:write_size_t)
|
15
|
-
else
|
16
|
-
raise RuntimeError.new("unsupported size_t width: #{p.size}")
|
17
|
-
end
|
18
|
-
|
13
|
+
alias_method :read_size_t, :"read_#{w}" unless p.respond_to?(:read_size_t)
|
14
|
+
alias_method :write_size_t, :"write_#{w}" unless p.respond_to?(:write_size_t)
|
19
15
|
end
|
data/lib/systemd/id128.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'ffi'
|
2
2
|
|
3
3
|
module Systemd
|
4
|
+
# Provides access to the 128-bit IDs for various items in the systemd
|
5
|
+
# ecosystem, such as the machine id and boot id.
|
4
6
|
module Id128
|
5
|
-
|
6
7
|
# Get the 128-bit hex string identifying the current machine.
|
7
8
|
# Can be used to filter a journal to show only messages originating
|
8
9
|
# from this machine.
|
@@ -11,12 +12,7 @@ module Systemd
|
|
11
12
|
# j.add_match('_MACHINE_ID', Systemd::Id128.machine_id)
|
12
13
|
# @return [String] 128-bit hex string representing the current machine.
|
13
14
|
def self.machine_id
|
14
|
-
@machine_id ||=
|
15
|
-
ptr = FFI::MemoryPointer.new(Native::Id128, 1)
|
16
|
-
rc = Native.sd_id128_get_machine(ptr)
|
17
|
-
raise JournalError.new(rc) if rc < 0
|
18
|
-
Native::Id128.new(ptr).to_s
|
19
|
-
end
|
15
|
+
@machine_id ||= read_id128(:sd_id128_get_machine)
|
20
16
|
end
|
21
17
|
|
22
18
|
# Get the 128-bit hex string identifying the current system's current boot.
|
@@ -27,19 +23,20 @@ module Systemd
|
|
27
23
|
# j.add_match('_BOOT_ID', Systemd::Id128.boot_id)
|
28
24
|
# @return [String] 128-bit hex string representing the current boot.
|
29
25
|
def self.boot_id
|
30
|
-
@boot_id ||=
|
31
|
-
ptr = FFI::MemoryPointer.new(Native::Id128, 1)
|
32
|
-
rc = Native.sd_id128_get_boot(ptr)
|
33
|
-
raise JournalError.new(rc) if rc < 0
|
34
|
-
Native::Id128.new(ptr).to_s
|
35
|
-
end
|
26
|
+
@boot_id ||= read_id128(:sd_id128_get_boot)
|
36
27
|
end
|
37
28
|
|
38
29
|
# Get a random 128-bit hex string.
|
39
30
|
# @return [String] 128-bit random hex string.
|
40
31
|
def self.random
|
32
|
+
read_id128(:sd_id128_randomize)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def self.read_id128(func)
|
41
38
|
ptr = FFI::MemoryPointer.new(Native::Id128, 1)
|
42
|
-
rc = Native.
|
39
|
+
rc = Native.send(func, ptr)
|
43
40
|
raise JournalError.new(rc) if rc < 0
|
44
41
|
Native::Id128.new(ptr).to_s
|
45
42
|
end
|
@@ -56,13 +53,14 @@ module Systemd
|
|
56
53
|
attach_function :sd_id128_randomize, [:pointer], :int
|
57
54
|
end
|
58
55
|
|
56
|
+
# @private
|
59
57
|
class Id128 < FFI::Union
|
60
58
|
layout :bytes, [:uint8, 16],
|
61
59
|
:dwords, [:uint32, 4],
|
62
60
|
:qwords, [:uint64, 2]
|
63
61
|
|
64
62
|
def to_s
|
65
|
-
(
|
63
|
+
('%02x' * 16) % self[:bytes].to_a
|
66
64
|
end
|
67
65
|
end
|
68
66
|
end
|
data/lib/systemd/journal.rb
CHANGED
@@ -38,9 +38,9 @@ module Systemd
|
|
38
38
|
ptr = FFI::MemoryPointer.new(:pointer, 1)
|
39
39
|
|
40
40
|
rc = if path
|
41
|
-
Native
|
41
|
+
Native.sd_journal_open_directory(ptr, path, 0)
|
42
42
|
else
|
43
|
-
Native
|
43
|
+
Native.sd_journal_open(ptr, flags)
|
44
44
|
end
|
45
45
|
|
46
46
|
raise JournalError.new(rc) if rc < 0
|
@@ -101,9 +101,8 @@ module Systemd
|
|
101
101
|
# @return [Boolean] False if unable to move to the next entry, indicating
|
102
102
|
# that the pointer has reached the end of the journal.
|
103
103
|
def move_next
|
104
|
-
|
105
|
-
|
106
|
-
end
|
104
|
+
rc = Native.sd_journal_next(@ptr)
|
105
|
+
raise JournalError.new(rc) if rc < 0
|
107
106
|
rc > 0
|
108
107
|
end
|
109
108
|
|
@@ -112,7 +111,7 @@ module Systemd
|
|
112
111
|
# moved. If this number is less than the requested amount, the read
|
113
112
|
# pointer has reached the end of the journal.
|
114
113
|
def move_next_skip(amount)
|
115
|
-
rc = Native
|
114
|
+
rc = Native.sd_journal_next_skip(@ptr, amount)
|
116
115
|
raise JournalError.new(rc) if rc < 0
|
117
116
|
rc
|
118
117
|
end
|
@@ -122,9 +121,8 @@ module Systemd
|
|
122
121
|
# @return [Boolean] False if unable to move to the previous entry,
|
123
122
|
# indicating that the pointer has reached the beginning of the journal.
|
124
123
|
def move_previous
|
125
|
-
|
126
|
-
|
127
|
-
end
|
124
|
+
rc = Native.sd_journal_previous(@ptr)
|
125
|
+
raise JournalError.new(rc) if rc < 0
|
128
126
|
rc > 0
|
129
127
|
end
|
130
128
|
|
@@ -133,7 +131,7 @@ module Systemd
|
|
133
131
|
# was moved. If this number is less than the requested amount, the read
|
134
132
|
# pointer has reached the beginning of the journal.
|
135
133
|
def move_previous_skip(amount)
|
136
|
-
rc = Native
|
134
|
+
rc = Native.sd_journal_previous_skip(@ptr, amount)
|
137
135
|
raise JournalError.new(rc) if rc < 0
|
138
136
|
rc
|
139
137
|
end
|
@@ -152,15 +150,15 @@ module Systemd
|
|
152
150
|
def seek(whence)
|
153
151
|
rc = case whence
|
154
152
|
when :head, :start
|
155
|
-
Native
|
153
|
+
Native.sd_journal_seek_head(@ptr)
|
156
154
|
when :tail, :end
|
157
|
-
Native
|
155
|
+
Native.sd_journal_seek_tail(@ptr)
|
158
156
|
else
|
159
157
|
if whence.is_a?(Time)
|
160
158
|
# TODO: is this right? who knows.
|
161
|
-
Native
|
159
|
+
Native.sd_journal_seek_realtime_usec(@ptr, whence.to_i * 1_000_000)
|
162
160
|
elsif whence.is_a?(String)
|
163
|
-
Native
|
161
|
+
Native.sd_journal_seek_cursor(@ptr, whence)
|
164
162
|
else
|
165
163
|
raise ArgumentError.new("Unknown seek type: #{whence.class}")
|
166
164
|
end
|
@@ -183,13 +181,13 @@ module Systemd
|
|
183
181
|
def read_field(field)
|
184
182
|
len_ptr = FFI::MemoryPointer.new(:size_t, 1)
|
185
183
|
out_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
186
|
-
|
187
|
-
rc = Native
|
184
|
+
field = field.to_s.upcase
|
185
|
+
rc = Native.sd_journal_get_data(@ptr, field, out_ptr, len_ptr)
|
188
186
|
|
189
187
|
raise JournalError.new(rc) if rc < 0
|
190
188
|
|
191
189
|
len = len_ptr.read_size_t
|
192
|
-
out_ptr
|
190
|
+
string_from_out_ptr(out_ptr, len).split('=', 2).last
|
193
191
|
end
|
194
192
|
|
195
193
|
# Read the contents of all fields from the current journal entry.
|
@@ -205,22 +203,15 @@ module Systemd
|
|
205
203
|
# j.move_next
|
206
204
|
# j.current_entry{ |field, value| puts "#{field}: #{value}" }
|
207
205
|
def current_entry
|
208
|
-
Native
|
209
|
-
|
210
|
-
len_ptr = FFI::MemoryPointer.new(:size_t, 1)
|
211
|
-
out_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
206
|
+
Native.sd_journal_restart_data(@ptr)
|
212
207
|
results = {}
|
213
208
|
|
214
|
-
while (
|
215
|
-
|
216
|
-
key, value = out_ptr.read_pointer.read_string_length(len).split('=', 2)
|
209
|
+
while (kvpair = enumerate_helper(:sd_journal_enumerate_data))
|
210
|
+
key, value = kvpair
|
217
211
|
results[key] = value
|
218
|
-
|
219
212
|
yield(key, value) if block_given?
|
220
213
|
end
|
221
214
|
|
222
|
-
raise JournalError.new(rc) if rc < 0
|
223
|
-
|
224
215
|
JournalEntry.new(results)
|
225
216
|
end
|
226
217
|
|
@@ -237,24 +228,16 @@ module Systemd
|
|
237
228
|
# end
|
238
229
|
def query_unique(field)
|
239
230
|
results = []
|
240
|
-
out_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
241
|
-
len_ptr = FFI::MemoryPointer.new(:size_t, 1)
|
242
231
|
|
243
|
-
Native
|
244
|
-
|
245
|
-
if (rc = Native::sd_journal_query_unique(@ptr, field.to_s.upcase)) < 0
|
246
|
-
raise JournalError.new(rc)
|
247
|
-
end
|
232
|
+
Native.sd_journal_restart_unique(@ptr)
|
248
233
|
|
249
|
-
|
250
|
-
|
251
|
-
results << out_ptr.read_pointer.read_string_length(len).split('=', 2).last
|
234
|
+
rc = Native.sd_journal_query_unique(@ptr, field.to_s.upcase)
|
235
|
+
raise JournalError.new(rc) if rc < 0
|
252
236
|
|
253
|
-
|
237
|
+
while (kvpair = enumerate_helper(:sd_journal_enumerate_unique))
|
238
|
+
results << kvpair.last
|
254
239
|
end
|
255
240
|
|
256
|
-
raise JournalError.new(rc) if rc < 0
|
257
|
-
|
258
241
|
results
|
259
242
|
end
|
260
243
|
|
@@ -271,7 +254,7 @@ module Systemd
|
|
271
254
|
# @return [Symbol] :append if new entries were appened to the journal.
|
272
255
|
# @return [Symbol] :invalidate if journal files were added/removed/rotated.
|
273
256
|
def wait(timeout_usec = -1)
|
274
|
-
rc = Native
|
257
|
+
rc = Native.sd_journal_wait(@ptr, timeout_usec)
|
275
258
|
raise JournalError.new(rc) if rc.is_a?(Fixnum) && rc < 0
|
276
259
|
rc == :nop ? nil : rc
|
277
260
|
end
|
@@ -287,7 +270,7 @@ module Systemd
|
|
287
270
|
# puts event.message
|
288
271
|
# end
|
289
272
|
def watch
|
290
|
-
|
273
|
+
loop do
|
291
274
|
if wait
|
292
275
|
yield current_entry while move_next
|
293
276
|
end
|
@@ -303,7 +286,7 @@ module Systemd
|
|
303
286
|
# @return [nil]
|
304
287
|
def add_filter(field, value)
|
305
288
|
match = "#{field.to_s.upcase}=#{value}"
|
306
|
-
rc = Native
|
289
|
+
rc = Native.sd_journal_add_match(@ptr, match, match.length)
|
307
290
|
raise JournalError.new(rc) if rc < 0
|
308
291
|
end
|
309
292
|
|
@@ -336,7 +319,7 @@ module Systemd
|
|
336
319
|
# # has priority 5
|
337
320
|
# end
|
338
321
|
def add_disjunction
|
339
|
-
rc = Native
|
322
|
+
rc = Native.sd_journal_add_disjunction(@ptr)
|
340
323
|
raise JournalError.new(rc) if rc < 0
|
341
324
|
end
|
342
325
|
|
@@ -354,14 +337,14 @@ module Systemd
|
|
354
337
|
# # current_entry is an sshd event with priority 5
|
355
338
|
# end
|
356
339
|
def add_conjunction
|
357
|
-
rc = Native
|
340
|
+
rc = Native.sd_journal_add_conjunction(@ptr)
|
358
341
|
raise JournalError.new(rc) if rc < 0
|
359
342
|
end
|
360
343
|
|
361
344
|
# Remove all filters and conjunctions/disjunctions.
|
362
345
|
# @return [nil]
|
363
346
|
def clear_filters
|
364
|
-
Native
|
347
|
+
Native.sd_journal_flush_matches(@ptr)
|
365
348
|
end
|
366
349
|
|
367
350
|
# Get the number of bytes the Journal is currently using on disk.
|
@@ -371,7 +354,7 @@ module Systemd
|
|
371
354
|
# @return [Integer] size in bytes
|
372
355
|
def disk_usage
|
373
356
|
size_ptr = FFI::MemoryPointer.new(:uint64)
|
374
|
-
rc = Native
|
357
|
+
rc = Native.sd_journal_get_usage(@ptr, size_ptr)
|
375
358
|
|
376
359
|
raise JournalError.new(rc) if rc < 0
|
377
360
|
size_ptr.read_uint64
|
@@ -382,7 +365,7 @@ module Systemd
|
|
382
365
|
# @return [Integer] size in bytes.
|
383
366
|
def data_threshold
|
384
367
|
size_ptr = FFI::MemoryPointer.new(:size_t, 1)
|
385
|
-
if (rc = Native
|
368
|
+
if (rc = Native.sd_journal_get_data_threshold(@ptr, size_ptr)) < 0
|
386
369
|
raise JournalError.new(rc)
|
387
370
|
end
|
388
371
|
|
@@ -392,7 +375,7 @@ module Systemd
|
|
392
375
|
# Set the maximum length of a data field that will be returned.
|
393
376
|
# Fields longer than this will be truncated.
|
394
377
|
def data_threshold=(threshold)
|
395
|
-
if (rc = Native
|
378
|
+
if (rc = Native.sd_journal_set_data_threshold(@ptr, threshold)) < 0
|
396
379
|
raise JournalError.new(rc)
|
397
380
|
end
|
398
381
|
end
|
@@ -425,17 +408,32 @@ module Systemd
|
|
425
408
|
private
|
426
409
|
|
427
410
|
def self.finalize(ptr)
|
428
|
-
proc{ Native
|
411
|
+
proc{ Native.sd_journal_close(ptr) unless ptr.nil? }
|
412
|
+
end
|
413
|
+
|
414
|
+
def enumerate_helper(enum_function)
|
415
|
+
len_ptr = FFI::MemoryPointer.new(:size_t, 1)
|
416
|
+
out_ptr = FFI::MemoryPointer.new(:pointer, 1)
|
417
|
+
|
418
|
+
rc = Native.send(enum_function, @ptr, out_ptr, len_ptr)
|
419
|
+
raise JournalError.new(rc) if rc < 0
|
420
|
+
return nil if rc == 0
|
421
|
+
|
422
|
+
len = len_ptr.read_size_t
|
423
|
+
string_from_out_ptr(out_ptr, len).split('=', 2)
|
424
|
+
end
|
425
|
+
|
426
|
+
def string_from_out_ptr(p, len)
|
427
|
+
p.read_pointer.read_string_length(len)
|
429
428
|
end
|
430
429
|
|
431
430
|
# some sd_journal_* functions return strings that we're expected to free
|
432
|
-
# ourselves.
|
431
|
+
# ourselves. This function copies the string from a char* to a ruby string,
|
433
432
|
# frees the char*, and returns the ruby string.
|
434
433
|
def read_and_free_outstr(ptr)
|
435
434
|
str = ptr.read_string
|
436
435
|
LibC.free(ptr)
|
437
436
|
str
|
438
437
|
end
|
439
|
-
|
440
438
|
end
|
441
439
|
end
|
@@ -6,7 +6,6 @@ module Systemd
|
|
6
6
|
# This module provides compatibility with the systemd-journal.gem
|
7
7
|
# by Daniel Mack (https://github.com/zonque/systemd-journal.gem)
|
8
8
|
module Compat
|
9
|
-
|
10
9
|
# system is unusable
|
11
10
|
LOG_EMERG = 0
|
12
11
|
# action must be taken immediately
|
@@ -32,12 +31,11 @@ module Systemd
|
|
32
31
|
# methods in this module will be available as class methods on
|
33
32
|
# {Systemd::Journal}
|
34
33
|
module ClassMethods
|
35
|
-
|
36
34
|
# write the value of the c errno constant to the systemd journal in the
|
37
35
|
# style of the perror() function.
|
38
36
|
# @param [String] message the text to prefix the error message with.
|
39
37
|
def perror(message)
|
40
|
-
rc = Native
|
38
|
+
rc = Native.sd_journal_perror(message)
|
41
39
|
raise JournalError.new(rc) if rc < 0
|
42
40
|
end
|
43
41
|
|
@@ -46,23 +44,22 @@ module Systemd
|
|
46
44
|
# severity of the event.
|
47
45
|
# @param [String] message the content of the message to write.
|
48
46
|
def print(level, message)
|
49
|
-
rc = Native
|
47
|
+
rc = Native.sd_journal_print(level, message)
|
50
48
|
raise JournalError.new(rc) if rc < 0
|
51
49
|
end
|
52
50
|
|
53
51
|
# write an event to the systemd journal.
|
54
52
|
# @param [Hash] contents the set of key-value pairs defining the event.
|
55
53
|
def message(contents)
|
56
|
-
items = contents.flat_map do |k,v|
|
54
|
+
items = contents.flat_map do |k, v|
|
57
55
|
[:string, "#{k.to_s.upcase}=#{v}"]
|
58
56
|
end
|
59
57
|
# add a null pointer to terminate the varargs
|
60
58
|
items += [:string, nil]
|
61
|
-
rc = Native
|
59
|
+
rc = Native.sd_journal_send(*items)
|
62
60
|
raise JournalError.new(rc) if rc < 0
|
63
61
|
end
|
64
62
|
end
|
65
|
-
|
66
63
|
end
|
67
64
|
end
|
68
65
|
end
|
@@ -12,7 +12,7 @@ module Systemd
|
|
12
12
|
_MACHINE_ID _HOSTNAME _TRANSPORT }
|
13
13
|
|
14
14
|
# Fields used in messages originating from the kernel.
|
15
|
-
KERNEL_FIELDS = %w{ _KERNEL_DEVICE _KERNEL_SUBSYSTEM _UDEV_SYSNAME
|
16
|
-
|
15
|
+
KERNEL_FIELDS = %w{ _KERNEL_DEVICE _KERNEL_SUBSYSTEM _UDEV_SYSNAME
|
16
|
+
_UDEV_DEVNODE _UDEV_DEVLINK }
|
17
17
|
end
|
18
18
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module Systemd
|
2
2
|
class Journal
|
3
3
|
# Provides the FFI bindings to the native `libsystemd-journal` shared
|
4
|
-
#
|
4
|
+
# library.
|
5
5
|
module Native
|
6
|
+
# rubocop:disable LineLength
|
6
7
|
require 'ffi'
|
7
8
|
extend FFI::Library
|
8
9
|
ffi_lib %w[libsystemd-journal.so libsystemd-journal.so.0]
|
@@ -60,9 +61,9 @@ module Systemd
|
|
60
61
|
# misc
|
61
62
|
attach_function :sd_journal_get_usage, [:pointer, :pointer], :int
|
62
63
|
end
|
63
|
-
|
64
64
|
end unless $NO_FFI_SPEC
|
65
65
|
|
66
|
+
# @private
|
66
67
|
module LibC
|
67
68
|
require 'ffi'
|
68
69
|
extend FFI::Library
|
@@ -70,5 +71,4 @@ module Systemd
|
|
70
71
|
|
71
72
|
attach_function :free, [:pointer], :void
|
72
73
|
end
|
73
|
-
|
74
74
|
end
|
@@ -1,9 +1,15 @@
|
|
1
1
|
module Systemd
|
2
|
+
# Represents a single entry in the Journal.
|
2
3
|
class JournalEntry
|
3
4
|
include Enumerable
|
4
5
|
|
5
6
|
attr_reader :fields
|
6
7
|
|
8
|
+
# Create a new JournalEntry from the given entry hash. You probably don't
|
9
|
+
# need to construct this yourself; instead instances are returned from
|
10
|
+
# {Systemd::Journal} methods such as {Systemd::Journal#current_entry}.
|
11
|
+
# @param [Hash] entry a hash containing all the key-value pairs associated
|
12
|
+
# with a given journal entry.
|
7
13
|
def initialize(entry)
|
8
14
|
@entry = entry
|
9
15
|
@fields = entry.map do |key, value|
|
@@ -14,15 +20,14 @@ module Systemd
|
|
14
20
|
|
15
21
|
end
|
16
22
|
|
23
|
+
# Get the value of a given field in the entry, or nil if it doesn't exist
|
17
24
|
def [](key)
|
18
25
|
@entry[key] || @entry[key.to_s.upcase]
|
19
26
|
end
|
20
27
|
|
21
28
|
def each
|
22
29
|
return to_enum(:each) unless block_given?
|
23
|
-
|
24
30
|
@entry.each{ |key, value| yield [key, value] }
|
25
31
|
end
|
26
|
-
|
27
32
|
end
|
28
33
|
end
|
@@ -3,8 +3,7 @@ require 'ffi'
|
|
3
3
|
module Systemd
|
4
4
|
# This execption is raised whenever a sd_journal_* call returns an error.
|
5
5
|
class JournalError < StandardError
|
6
|
-
|
7
|
-
# Returns the (negated) error number.
|
6
|
+
# Returns the (positive) error number.
|
8
7
|
attr_reader :code
|
9
8
|
|
10
9
|
# Instantiate a new JournalError based on the specified return code.
|
@@ -12,7 +11,7 @@ module Systemd
|
|
12
11
|
# return code.
|
13
12
|
def initialize(code)
|
14
13
|
@code = -code
|
15
|
-
super(LIBC
|
14
|
+
super(LIBC.strerror(@code))
|
16
15
|
end
|
17
16
|
|
18
17
|
private
|
@@ -25,6 +24,5 @@ module Systemd
|
|
25
24
|
|
26
25
|
attach_function :strerror, [:int], :string
|
27
26
|
end
|
28
|
-
|
29
27
|
end
|
30
28
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: systemd-journal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Ledbetter
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
@@ -62,6 +62,7 @@ extensions: []
|
|
62
62
|
extra_rdoc_files: []
|
63
63
|
files:
|
64
64
|
- .gitignore
|
65
|
+
- .rubocop.yml
|
65
66
|
- Gemfile
|
66
67
|
- LICENSE.txt
|
67
68
|
- README.md
|