syslogger5424 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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