systemd-journal 2.1.0 → 2.1.1

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.
@@ -1,17 +1,17 @@
1
- require 'systemd/journal/version'
2
- require 'systemd/journal/native'
3
- require 'systemd/journal/flags'
4
- require 'systemd/journal/writable'
5
- require 'systemd/journal/fields'
6
- require 'systemd/journal/navigable'
7
- require 'systemd/journal/filterable'
8
- require 'systemd/journal/waitable'
9
- require 'systemd/journal/shim'
10
- require 'systemd/journal_error'
11
- require 'systemd/journal_entry'
12
- require 'systemd/id128'
13
- require 'systemd/ffi_size_t'
14
- require 'systemd'
1
+ require "systemd/journal/version"
2
+ require "systemd/journal/native"
3
+ require "systemd/journal/flags"
4
+ require "systemd/journal/writable"
5
+ require "systemd/journal/fields"
6
+ require "systemd/journal/navigable"
7
+ require "systemd/journal/filterable"
8
+ require "systemd/journal/waitable"
9
+ require "systemd/journal/shim"
10
+ require "systemd/journal_error"
11
+ require "systemd/journal_entry"
12
+ require "systemd/id128"
13
+ require "systemd/ffi_size_t"
14
+ require "systemd"
15
15
 
16
16
  module Systemd
17
17
  # Class to allow interacting with the systemd journal.
@@ -53,6 +53,7 @@ module Systemd
53
53
  open_type, flags = validate_options!(opts)
54
54
  ptr = FFI::MemoryPointer.new(:pointer, 1)
55
55
 
56
+ @reopen_filter_conditions = [] # retain the conditions for auto reopen
56
57
  @auto_reopen = (opts.key?(:auto_reopen) ? opts.delete(:auto_reopen) : false)
57
58
  if @auto_reopen
58
59
  @auto_reopen = @auto_reopen.is_a?(Integer) ? @auto_reopen : ITERATIONS_TO_AUTO_REOPEN
@@ -70,7 +71,7 @@ module Systemd
70
71
  j = new(opts.merge(finalize: false))
71
72
  yield j
72
73
  ensure
73
- j.close if j
74
+ j&.close
74
75
  end
75
76
 
76
77
  # Iterate over each entry in the journal, respecting the applied
@@ -96,13 +97,13 @@ module Systemd
96
97
  def read_field(field)
97
98
  len_ptr = FFI::MemoryPointer.new(:size_t, 1)
98
99
  out_ptr = FFI::MemoryPointer.new(:pointer, 1)
99
- field = field.to_s.upcase
100
+ field = field.to_s.upcase
100
101
  rc = Native.sd_journal_get_data(@ptr, field, out_ptr, len_ptr)
101
102
 
102
103
  raise JournalError, rc if rc < 0
103
104
 
104
105
  len = len_ptr.read_size_t
105
- string_from_out_ptr(out_ptr, len).split('=', 2).last
106
+ string_from_out_ptr(out_ptr, len).split("=", 2).last
106
107
  end
107
108
 
108
109
  # Read the contents of all fields from the current journal entry.
@@ -129,7 +130,7 @@ module Systemd
129
130
 
130
131
  JournalEntry.new(
131
132
  results,
132
- realtime_ts: read_realtime,
133
+ realtime_ts: read_realtime,
133
134
  monotonic_ts: read_monotonic
134
135
  )
135
136
  end
@@ -236,6 +237,21 @@ module Systemd
236
237
  )
237
238
  end
238
239
 
240
+ # @private
241
+ def self.finalize(ptr)
242
+ proc { Native.sd_journal_close(ptr) unless ptr.nil? }
243
+ end
244
+
245
+ # @private
246
+ # some sd_journal_* functions return strings that we're expected to free
247
+ # ourselves. This function copies the string from a char* to a ruby string,
248
+ # frees the char*, and returns the ruby string.
249
+ def self.read_and_free_outstr(ptr)
250
+ str = ptr.read_string
251
+ Shim.free(ptr)
252
+ str
253
+ end
254
+
239
255
  private
240
256
 
241
257
  def open_journal(type, ptr, opts, flags)
@@ -247,13 +263,13 @@ module Systemd
247
263
  Native.sd_journal_open_directory(ptr, opts[:path], 0)
248
264
  when :files, :file
249
265
  files = Array(opts[type])
250
- @open_target = "file#{files.one? ? '' : 's'}:#{files.join(',')}"
266
+ @open_target = "file#{files.one? ? "" : "s"}:#{files.join(",")}"
251
267
  Native.sd_journal_open_files(ptr, array_to_ptrs(files), 0)
252
268
  when :container
253
269
  @open_target = "container:#{opts[:container]}"
254
270
  Native.sd_journal_open_container(ptr, opts[:container], flags)
255
271
  when :local
256
- @open_target = 'journal:local'
272
+ @open_target = "journal:local"
257
273
  Native.sd_journal_open(ptr, flags)
258
274
  else
259
275
  raise ArgumentError, "Unknown open type: #{type}"
@@ -269,7 +285,7 @@ module Systemd
269
285
  end
270
286
 
271
287
  def read_monotonic
272
- out = FFI::MemoryPointer.new(:uint64, 1)
288
+ out = FFI::MemoryPointer.new(:uint64, 1)
273
289
  boot = FFI::MemoryPointer.new(Systemd::Id128::Native::Id128, 1)
274
290
 
275
291
  rc = Native.sd_journal_get_monotonic_usec(@ptr, out, boot)
@@ -297,7 +313,7 @@ module Systemd
297
313
 
298
314
  if type == :container && !Native.open_container?
299
315
  raise ArgumentError,
300
- 'This native library version does not support opening containers'
316
+ "This native library version does not support opening containers"
301
317
  end
302
318
 
303
319
  flags = opts[:flags] if [:local, :container].include?(type)
@@ -306,10 +322,6 @@ module Systemd
306
322
  [type, flags]
307
323
  end
308
324
 
309
- def self.finalize(ptr)
310
- proc { Native.sd_journal_close(ptr) unless ptr.nil? }
311
- end
312
-
313
325
  def enumerate_helper(enum_function)
314
326
  len_ptr = FFI::MemoryPointer.new(:size_t, 1)
315
327
  out_ptr = FFI::MemoryPointer.new(:pointer, 1)
@@ -319,20 +331,11 @@ module Systemd
319
331
  return nil if rc == 0
320
332
 
321
333
  len = len_ptr.read_size_t
322
- string_from_out_ptr(out_ptr, len).split('=', 2)
334
+ string_from_out_ptr(out_ptr, len).split("=", 2)
323
335
  end
324
336
 
325
337
  def string_from_out_ptr(p, len)
326
338
  p.read_pointer.read_string(len)
327
339
  end
328
-
329
- # some sd_journal_* functions return strings that we're expected to free
330
- # ourselves. This function copies the string from a char* to a ruby string,
331
- # frees the char*, and returns the ruby string.
332
- def self.read_and_free_outstr(ptr)
333
- str = ptr.read_string
334
- Shim.free(ptr)
335
- str
336
- end
337
340
  end
338
341
  end
@@ -12,8 +12,8 @@ module Systemd
12
12
  # with a given journal entry.
13
13
  def initialize(entry, context = {})
14
14
  inspect = []
15
- @entry = entry
16
- @ctx = context
15
+ @entry = entry
16
+ @ctx = context
17
17
  @fields = entry.map do |key, value|
18
18
  name = key.downcase.to_sym
19
19
  define_singleton_method(name) { value } unless respond_to?(name)
@@ -21,7 +21,7 @@ module Systemd
21
21
  inspect.push("#{name}: '#{value}'")
22
22
  name
23
23
  end
24
- @inspect = inspect.join(', ')
24
+ @inspect = inspect.join(", ")
25
25
  end
26
26
 
27
27
  # Returns the wall-clock time that this entry was received by the journal.
@@ -43,7 +43,12 @@ module Systemd
43
43
  def method_missing(m, *args)
44
44
  # not all journal entries will have all fields. don't raise an error
45
45
  # unless the user passed arguments.
46
- super(m, *args) unless args.empty?
46
+ super unless args.empty?
47
+ end
48
+
49
+ # @private
50
+ def respond_to_missing?(m, include_private = false)
51
+ fields&.include?(m) || super
47
52
  end
48
53
 
49
54
  # Get the value of a given field in the entry, or nil if it doesn't exist
@@ -94,7 +99,7 @@ module Systemd
94
99
 
95
100
  # @private
96
101
  def inspect
97
- format('#<%s:0x%016x %s>', self.class.name, object_id, @inspect)
102
+ format("#<%s:0x%016x %s>", self.class.name, object_id, @inspect)
98
103
  end
99
104
 
100
105
  private
@@ -1,4 +1,4 @@
1
- require 'ffi'
1
+ require "ffi"
2
2
 
3
3
  module Systemd
4
4
  # This exception is raised whenever a sd_journal_* call returns an error.
@@ -1,2 +1,2 @@
1
1
  # included for backwards compatibility with older versions
2
- require 'systemd/journal'
2
+ require "systemd/journal"
data/lib/systemd.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'systemd/id128'
1
+ require "systemd/id128"
2
2
 
3
3
  module Systemd
4
4
  # See {Systemd::Id128.machine_id}.
data/spec/spec_helper.rb CHANGED
@@ -1,18 +1,18 @@
1
- require 'rspec'
2
- require 'json'
3
- require 'simplecov'
1
+ require "rspec"
2
+ require "json"
3
+ require "simplecov"
4
4
 
5
5
  module SpecHelper
6
6
  def fixture_dir
7
- @path ||= File.join(File.expand_path('..', __FILE__), 'fixtures')
7
+ @path ||= File.join(File.expand_path("..", __FILE__), "fixtures")
8
8
  end
9
9
 
10
10
  def journal_file
11
- @file ||= File.join(fixture_dir, 'test.journal')
11
+ @file ||= File.join(fixture_dir, "test.journal")
12
12
  end
13
13
 
14
14
  def journal_json
15
- @json ||= JSON.parse(File.read(File.join(fixture_dir, 'test.json')))
15
+ @json ||= JSON.parse(File.read(File.join(fixture_dir, "test.json")))
16
16
  end
17
17
 
18
18
  def entry_field(index, name)
@@ -21,9 +21,9 @@ module SpecHelper
21
21
  end
22
22
 
23
23
  SimpleCov.start do
24
- add_filter '.bundle/'
24
+ add_filter ".bundle/"
25
25
  end
26
- require 'systemd/journal'
26
+ require "systemd/journal"
27
27
 
28
28
  RSpec.configure do |config|
29
29
  config.disable_monkey_patching!
@@ -1,14 +1,14 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  RSpec.describe Systemd::Id128 do
4
4
  subject(:id128) { Systemd::Id128 }
5
5
 
6
- describe 'machine_id' do
7
- it 'should be a 128 bit hexadecimal string' do
6
+ describe "machine_id" do
7
+ it "should be a 128 bit hexadecimal string" do
8
8
  expect(id128.machine_id).to match(/[0-9a-f]{16}/)
9
9
  end
10
10
 
11
- it 'should match when called twice' do
11
+ it "should match when called twice" do
12
12
  m1 = id128.machine_id
13
13
  m2 = id128.machine_id
14
14
  expect(m1).to eq(m2)
@@ -17,26 +17,28 @@ RSpec.describe Systemd::Id128 do
17
17
 
18
18
  # travis-ci does not boot with systemd so these cases
19
19
  # will raise exceptions.
20
- context 'when booted under systemd' do
21
- describe 'boot_id' do
22
- it 'should be a 128 bit hexadecimal string' do
23
- expect(id128.boot_id).to match(/[0-9a-f]{16}/)
24
- end
20
+ unless ENV["TRAVIS"]
21
+ context "when booted under systemd" do
22
+ describe "boot_id" do
23
+ it "should be a 128 bit hexadecimal string" do
24
+ expect(id128.boot_id).to match(/[0-9a-f]{16}/)
25
+ end
25
26
 
26
- it 'should match when called twice' do
27
- b1 = id128.boot_id
28
- b2 = id128.boot_id
29
- expect(b1).to eq(b2)
27
+ it "should match when called twice" do
28
+ b1 = id128.boot_id
29
+ b2 = id128.boot_id
30
+ expect(b1).to eq(b2)
31
+ end
30
32
  end
31
33
  end
32
- end unless ENV['TRAVIS']
34
+ end
33
35
 
34
- describe 'random' do
35
- it 'should be a 128 bit hexadecimal string' do
36
+ describe "random" do
37
+ it "should be a 128 bit hexadecimal string" do
36
38
  expect(id128.random).to match(/[0-9a-f]{16}/)
37
39
  end
38
40
 
39
- it 'should return a different value when called again' do
41
+ it "should return a different value when called again" do
40
42
  r1 = id128.random
41
43
  r2 = id128.random
42
44
  expect(r1).to_not eq(r2)
@@ -1,81 +1,81 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  RSpec.describe Systemd::JournalEntry do
4
- let(:msg) { 'test message' }
5
- let(:pid) { '123' }
6
- let(:hash) { { '_PID' => pid, 'MESSAGE' => msg } }
4
+ let(:msg) { "test message" }
5
+ let(:pid) { "123" }
6
+ let(:hash) { {"_PID" => pid, "MESSAGE" => msg} }
7
7
  subject(:entry) { Systemd::JournalEntry.new(hash) }
8
8
 
9
- describe 'initialize' do
10
- it 'takes a hash as an argument' do
9
+ describe "initialize" do
10
+ it "takes a hash as an argument" do
11
11
  expect { Systemd::JournalEntry.new(hash) }.to_not raise_error
12
12
  end
13
13
  end
14
14
 
15
- describe '[]' do
16
- it 'accepts symbols as a field name' do
15
+ describe "[]" do
16
+ it "accepts symbols as a field name" do
17
17
  expect(entry[:message]).to eq(msg)
18
18
  end
19
19
 
20
- it 'accepts strings as a field name' do
21
- expect(entry['message']).to eq(msg)
20
+ it "accepts strings as a field name" do
21
+ expect(entry["message"]).to eq(msg)
22
22
  end
23
23
 
24
- it 'doesnt care about case' do
25
- expect(entry['MeSSage']).to eq(msg)
24
+ it "doesnt care about case" do
25
+ expect(entry["MeSSage"]).to eq(msg)
26
26
  end
27
27
 
28
- it 'returns nil if not found' do
29
- expect(entry['missing']).to be nil
28
+ it "returns nil if not found" do
29
+ expect(entry["missing"]).to be nil
30
30
  end
31
31
  end
32
32
 
33
- describe 'each' do
34
- it 'is chainable as an enumerator' do
33
+ describe "each" do
34
+ it "is chainable as an enumerator" do
35
35
  expect(entry.each.class).to be(Enumerator)
36
36
  end
37
37
 
38
- it 'yields each key/value in turn' do
38
+ it "yields each key/value in turn" do
39
39
  items = entry.map { |k, v| [k, v] }
40
- expect(items).to eq([['_PID', pid], ['MESSAGE', msg]])
40
+ expect(items).to eq([["_PID", pid], ["MESSAGE", msg]])
41
41
  end
42
42
  end
43
43
 
44
- describe 'to_h' do
45
- it 'returns a deep copy of the entry' do
44
+ describe "to_h" do
45
+ it "returns a deep copy of the entry" do
46
46
  copy = subject.to_h
47
47
  expect(copy).to eq(hash)
48
- expect { copy['_PID'] << '3' }.to_not change { subject._pid }
48
+ expect { copy["_PID"] << "3" }.to_not change { subject._pid }
49
49
  end
50
50
  end
51
51
 
52
- describe 'catalog' do
53
- context 'without a catalog' do
54
- it 'returns nil if the entry has no catalog' do
52
+ describe "catalog" do
53
+ context "without a catalog" do
54
+ it "returns nil if the entry has no catalog" do
55
55
  expect(entry.catalog).to be nil
56
56
  end
57
57
  end
58
58
 
59
- context 'with a catalog' do
60
- let(:catalog) { 'Process @_PID@ said @MESSAGE@' }
59
+ context "with a catalog" do
60
+ let(:catalog) { "Process @_PID@ said @MESSAGE@" }
61
61
  subject(:entry) do
62
- Systemd::JournalEntry.new(hash.merge(message_id: '123'))
62
+ Systemd::JournalEntry.new(hash.merge(message_id: "123"))
63
63
  end
64
64
 
65
65
  before(:each) do
66
66
  allow(Systemd::Journal).to receive(:catalog_for).and_return(catalog)
67
67
  end
68
68
 
69
- it 'does field substitution by default' do
70
- expect(entry.catalog).to eq('Process 123 said test message')
69
+ it "does field substitution by default" do
70
+ expect(entry.catalog).to eq("Process 123 said test message")
71
71
  end
72
72
 
73
- it 'does field substitution when requested' do
73
+ it "does field substitution when requested" do
74
74
  expect(entry.catalog(replace: true))
75
- .to eq('Process 123 said test message')
75
+ .to eq("Process 123 said test message")
76
76
  end
77
77
 
78
- it 'skips field substitution if requested' do
78
+ it "skips field substitution if requested" do
79
79
  expect(entry.catalog(replace: false)).to eq(catalog)
80
80
  end
81
81
  end