syslogger5424 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3abf248dd903f96ba27cb315cfe45894ec6b1c31
4
- data.tar.gz: 352eb7acd93d6a73707d72badbef8086a56030b6
3
+ metadata.gz: a5aca48fbb6352b4a7a4bc1c8efc5f02a98b532b
4
+ data.tar.gz: 6aa5cb54e9e791362bbb2e8f63fd4f383cc8b259
5
5
  SHA512:
6
- metadata.gz: dc7dd918ef546c5063e3dea450519282c85c4387a49101bc8d00b13b4399024b8b0ec02c9f87526e3c3f12d73a408b4f94804f6d0396a2cfececa89e81f786a8
7
- data.tar.gz: 1a520cb2224f81e34bdd5f4988d4fd36662b4a6c4b9f4fd1cbf2623e415821698a255ee2e23c492acccf4fc3283b29a6a8a5c620479239386f70a042ccf90462
6
+ metadata.gz: 7553cda8c414c9e79787c7af26c01cba6f8f9e43891c661d10dd0ccb1aa2be069df49ffa7d15dd76c46bf29b57a4040ac61f28eb0a44d15355b1663a26653504
7
+ data.tar.gz: 9a5cc28f8a00d500d2968f3194fc66a7d6fcc67f63d2169e837c1e0566fb734db3e1ff53bdbf2e453d3d1ef78e7ad31b7c1d5eac33115f75c5bc3db2b3c02bae
@@ -0,0 +1,20 @@
1
+ require 'socket'
2
+
3
+
4
+ module SysLogger
5
+ module Creators
6
+ def self.unix_dgram_socket(socket_path)
7
+ proc {
8
+ client = Socket.new(Socket::Constants::AF_LOCAL, Socket::Constants::SOCK_DGRAM, 0)
9
+ client.connect(Socket.pack_sockaddr_un(socket_path))
10
+ client
11
+ }
12
+ end
13
+
14
+ def self.unix_stream_socket(socket_path)
15
+ proc {
16
+ UnixSocket.new(socket_path)
17
+ }
18
+ end
19
+ end
20
+ end
@@ -3,7 +3,7 @@ module SysLogger
3
3
  class RFC5424 < ::Logger::Formatter
4
4
  attr_reader :msgid, :procid, :appname
5
5
 
6
- Format = "<%s>1 %s %s %s %s %s [meta x-group=\"%s\"] %s\n"
6
+ Format = "<%s>1 %s %s %s %s %s %s %s\n"
7
7
 
8
8
  FACILITIES = {
9
9
  :kern => 0,
@@ -48,43 +48,98 @@ module SysLogger
48
48
  def initialize(appname = nil, procid = nil, msgid = nil, facility = nil)
49
49
  super()
50
50
 
51
- @msgid = format(msgid, 32)
52
- @procid = format(procid || Process.pid.to_s, 128)
53
- @appname = format(appname, 48)
51
+ @counter = 0
52
+
53
+ @hostname = Socket.gethostname
54
+ @msgid = format_field(msgid, 32)
55
+ @procid = procid
56
+ @procid = format_field(procid || Process.pid.to_s, 128)
57
+ @appname = format_field(appname, 48)
54
58
 
55
59
  self.facility = facility || :local7
56
60
  end
57
61
 
58
- def facility; @facility; end
62
+ def facility
63
+ @facility
64
+ end
65
+
59
66
  def facility=(f)
60
67
  @facility = FACILITIES[f.to_s.downcase.to_sym] || @facility
61
68
  end
62
69
 
63
70
  def call(severity, datetime, progname, message)
64
71
  severity = SEVERITIES[severity.to_s.downcase.to_sym] || SEVERITIES[:info]
65
- pri = (facility * 8) + severity
72
+ pri = (facility << 3) | severity
66
73
 
67
74
  # Since we're using RFC5424 format, it makes more sense to use the
68
75
  # passed in progname as the msgid rather than changing the appname when
69
76
  # a block was received to generate the message.
70
- message_id = progname.nil? ? msgid : format(progname, 32)
77
+ message_id = progname.nil? ? msgid : format_field(progname, 32)
78
+
79
+ @counter = (@counter + 1) % 65536
80
+
81
+ structured_data = {
82
+ "meta" => {
83
+ "x-group" => rand(99999999),
84
+ "x-counter" => @counter
85
+ }
86
+ }
87
+
88
+ sd = format_sdata(structured_data)
71
89
 
72
- x_group = rand(99999999)
73
90
  lines = msg2str(message).split(/\r?\n/).reject(&:empty?).map do |line|
74
- Format % [pri, datetime.strftime("%FT%T.%6N%:z"), Socket.gethostname,
75
- appname, procid, message_id, x_group, line]
91
+ Format % [pri, datetime.strftime("%FT%T.%6N%:z"), @hostname,
92
+ @appname, format_field(@procid || Process.pid.to_s, 128),
93
+ message_id, sd, line]
76
94
  end
77
95
 
78
96
  lines.join
79
97
  end
80
98
 
81
- def format(text, max_length)
99
+ private
100
+ def format_field(text, max_length)
82
101
  if text
83
102
  text[0..max_length].gsub(/\s+/, '')
84
103
  else
85
104
  '-'
86
105
  end
87
106
  end
107
+
108
+ def format_sdata(sdata)
109
+ if sdata.empty?
110
+ '-'
111
+ end
112
+ # TODO clean up of SD-NAMe and PARAM-VALUE is kind of brute force
113
+ # here, could be done better per RFC5424
114
+ r = []
115
+ sdata.each { |sid, hash|
116
+ s = []
117
+ s.push(sid.to_s.gsub(/[^-\w]/, ""))
118
+ hash.each { |n, v|
119
+ paramname = n.to_s.gsub(/[^-\w]/, "")
120
+ paramvalue = v.to_s.gsub(/[\]"=]/, "")
121
+ s.push("#{paramname}=\"#{paramvalue}\"")
122
+ }
123
+ r.push("["+s.join(" ")+"]")
124
+ }
125
+ rx = []
126
+ r.each { |x|
127
+ rx.push("[#{x}]")
128
+ }
129
+ r.join("")
130
+ end
131
+
132
+ def msg2str(msg)
133
+ case msg
134
+ when ::String
135
+ msg
136
+ when ::Exception
137
+ "#{ msg.message } (#{ msg.class })\n" <<
138
+ (msg.backtrace || []).join("\n")
139
+ else
140
+ msg.inspect
141
+ end
142
+ end
88
143
  end
89
144
  end
90
145
  end
data/lib/syslogger/io.rb CHANGED
@@ -3,10 +3,18 @@ module SysLogger
3
3
  def initialize(&file_creator)
4
4
  @file_creator = file_creator
5
5
  @file = @file_creator.call
6
+ @connect_pid = Process.pid
6
7
  end
7
8
 
8
9
  def file
9
- @file.closed? ? @file = @file_creator.call : @file
10
+ # re-connect on fork
11
+ if Process.pid != @connect_pid
12
+ @file.close
13
+ end
14
+ if @file.nil? || @file.closed?
15
+ @file = @file_creator.call
16
+ end
17
+ @file
10
18
  end
11
19
 
12
20
  def write(message)
@@ -16,7 +16,18 @@ module SysLogger
16
16
  @default_formatter = SysLogger::Formatter::RFC5424.new
17
17
  end
18
18
 
19
- alias_method :<<, :info
20
- alias_method :write, :info
19
+ def <<(msg)
20
+ # Logger's version of this just dumps the input without formatting. there
21
+ # is never a case where we don't want to format the content to the syslog
22
+ # server properly.
23
+ # default to a serverity of info.
24
+ msg.split(/\r?\n/).each { |line|
25
+ if line then
26
+ self.info(line)
27
+ end
28
+ }
29
+ end
30
+
31
+ alias_method :write, :<<
21
32
  end
22
33
  end
data/lib/syslogger.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "syslogger/logger"
2
2
  require "syslogger/io"
3
3
  require "syslogger/formatter/rfc5424"
4
+ require "syslogger/creators"
4
5
 
5
6
  module SysLogger
6
7
  extend self
@@ -1,3 +1,6 @@
1
+ require 'date'
2
+
3
+
1
4
  describe SysLogger::Formatter::RFC5424 do
2
5
  its(:msgid) { is_expected.to eq "-" }
3
6
  its(:procid) { is_expected.to eq Process.pid.to_s }
@@ -7,7 +10,23 @@ describe SysLogger::Formatter::RFC5424 do
7
10
  describe "#call" do
8
11
  it "generates Format" do
9
12
  expect(subject.call(::Logger::INFO, DateTime.now, "Prog", "Message")).
10
- to match /<190>1.* - #{Process.pid} Prog \[meta x-group=".*"\] Message/
13
+ to match(/<190>1.* - #{Process.pid} Prog \[meta x-group="[^"]+" x-counter="[^"]+"\] Message/)
14
+ end
15
+
16
+ it "counts sequentially" do
17
+ line1 = subject.call(::Logger::INFO, DateTime.now, "Prog", "Message1")
18
+ if line1 =~ /.*x-counter="([^"]+)".*/
19
+ counter1 = $1.to_i
20
+ else
21
+ counter1 = 0
22
+ end
23
+ line2 = subject.call(::Logger::INFO, DateTime.now, "Prog", "Message2")
24
+ if line2 =~ /.*x-counter="([^"]+)".*/
25
+ counter2 = $1.to_i
26
+ else
27
+ counter2 = 0
28
+ end
29
+ expect(counter2).to be > counter1
11
30
  end
12
31
  end
13
32
  end
@@ -1,3 +1,8 @@
1
+ require 'socket'
2
+ require 'rspec/temp_dir'
3
+
4
+ require 'syslogger/creators'
5
+
1
6
  describe SysLogger::IO do
2
7
  let(:io) { StringIO.new }
3
8
 
@@ -10,5 +15,22 @@ describe SysLogger::IO do
10
15
  subject.write("foobar")
11
16
  expect(io.string).to eq "foobar"
12
17
  end
18
+
19
+ end
20
+
21
+ describe "unix_dgram_socket" do
22
+ let(:socket_path) { "#{temp_dir}/listen.sock" }
23
+ subject { SysLogger::IO.new(&SysLogger::Creators::unix_dgram_socket(socket_path)) }
24
+
25
+ describe "#write integration" do
26
+ include_context "uses temp dir"
27
+
28
+ it "actually can write to a domain socket" do
29
+ s = Socket.new(Socket::Constants::AF_LOCAL, Socket::Constants::SOCK_DGRAM, 0)
30
+ s.bind(Socket.pack_sockaddr_un(socket_path))
31
+ subject.write("foobar\n")
32
+ expect(s.recvfrom(1024)[0]).to eq "foobar\n"
33
+ end
34
+ end
13
35
  end
14
36
  end
metadata CHANGED
@@ -1,83 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syslogger5424
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - EasyPost
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-30 00:00:00.000000000 Z
11
+ date: 2016-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mono_logger
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec-its
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-temp_dir
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  description:
@@ -87,6 +101,7 @@ extensions: []
87
101
  extra_rdoc_files: []
88
102
  files:
89
103
  - lib/syslogger.rb
104
+ - lib/syslogger/creators.rb
90
105
  - lib/syslogger/formatter/rfc5424.rb
91
106
  - lib/syslogger/io.rb
92
107
  - lib/syslogger/logger.rb
@@ -104,17 +119,17 @@ require_paths:
104
119
  - lib
105
120
  required_ruby_version: !ruby/object:Gem::Requirement
106
121
  requirements:
107
- - - ">="
122
+ - - '>='
108
123
  - !ruby/object:Gem::Version
109
124
  version: '0'
110
125
  required_rubygems_version: !ruby/object:Gem::Requirement
111
126
  requirements:
112
- - - ">="
127
+ - - '>='
113
128
  - !ruby/object:Gem::Version
114
129
  version: '0'
115
130
  requirements: []
116
131
  rubyforge_project:
117
- rubygems_version: 2.2.2
132
+ rubygems_version: 2.0.14.1
118
133
  signing_key:
119
134
  specification_version: 4
120
135
  summary: Logging via syslog using RFC 5424 format