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 +4 -4
- data/lib/syslogger/creators.rb +20 -0
- data/lib/syslogger/formatter/rfc5424.rb +66 -11
- data/lib/syslogger/io.rb +9 -1
- data/lib/syslogger/logger.rb +13 -2
- data/lib/syslogger.rb +1 -0
- data/spec/syslogger/formatter/rfc5424_spec.rb +20 -1
- data/spec/syslogger/io_spec.rb +22 -0
- metadata +30 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5aca48fbb6352b4a7a4bc1c8efc5f02a98b532b
|
4
|
+
data.tar.gz: 6aa5cb54e9e791362bbb2e8f63fd4f383cc8b259
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
@
|
52
|
-
|
53
|
-
@
|
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
|
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
|
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 :
|
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"),
|
75
|
-
appname, procid
|
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
|
-
|
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
|
-
|
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)
|
data/lib/syslogger/logger.rb
CHANGED
@@ -16,7 +16,18 @@ module SysLogger
|
|
16
16
|
@default_formatter = SysLogger::Formatter::RFC5424.new
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
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,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
|
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
|
data/spec/syslogger/io_spec.rb
CHANGED
@@ -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.
|
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:
|
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.
|
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
|