sysloggly 0.2.1 → 0.3.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/sysloggly.rb +36 -13
- data/lib/sysloggly/clients/filelog.rb +6 -0
- data/lib/sysloggly/clients/networklog.rb +45 -0
- data/lib/sysloggly/formatters/simple_formatter.rb +65 -0
- data/lib/sysloggly/formatters/syslog_formatter.rb +39 -0
- data/lib/sysloggly/version.rb +1 -1
- metadata +6 -5
- data/lib/sysloggly/client.rb +0 -113
- data/lib/sysloggly/client/filelog.rb +0 -35
- data/lib/sysloggly/client/syslog.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75f81f43322e647a969b2588a304976761ce5572
|
4
|
+
data.tar.gz: 99e90a40755d66b6b234a13f96548fd8ccfc8b8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b3b0a212295467f075a3e77fae21399c2968a8624f93ba771624d1fc4494838664096c0d25a6428a90db46467380d68e22d9decbee116831adc61dda64a280d
|
7
|
+
data.tar.gz: 6e8f86565cc3c72a2759d385c31a1569f9dc5d24dec83b1c1b72556f7b23d5aa9dc7ebb71ee8a12602890be6fbb0930e270f8257a27ceab2c0caac5de37fde9f
|
data/lib/sysloggly.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "logger"
|
2
|
+
require "lograge"
|
3
|
+
require "uri"
|
4
|
+
|
5
|
+
require "sysloggly/version"
|
6
|
+
require "sysloggly/clients/filelog"
|
7
|
+
require "sysloggly/clients/networklog"
|
8
|
+
require "sysloggly/formatters/simple_formatter"
|
9
|
+
require "sysloggly/formatters/syslog_formatter"
|
3
10
|
|
4
11
|
#
|
5
12
|
# Sysloggly
|
@@ -16,22 +23,38 @@ module Sysloggly
|
|
16
23
|
yield self
|
17
24
|
end
|
18
25
|
|
26
|
+
|
27
|
+
# Creates a new logger instance
|
28
|
+
#
|
29
|
+
# @return [Logger]
|
30
|
+
# @api public
|
19
31
|
def self.new(url, opts = {})
|
20
|
-
|
21
|
-
|
32
|
+
raise InputURLRequired.new unless url
|
33
|
+
|
34
|
+
begin
|
35
|
+
input_uri = URI.parse(url)
|
36
|
+
rescue URI::InvalidURIError => e
|
37
|
+
raise InputURLRequired.new("Invalid Input URL: #{url}")
|
38
|
+
end
|
39
|
+
|
40
|
+
client, formatter = nil
|
22
41
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
42
|
+
case input_uri.scheme
|
43
|
+
when "file"
|
44
|
+
client = Sysloggly::Clients::Filelog.new(input_uri.path)
|
45
|
+
formatter = Sysloggly::Formatters::SimpleFormatter.new(input_uri, opts)
|
46
|
+
when "udp", "tcp"
|
47
|
+
client = Sysloggly::Clients::Networklog.new(input_uri, opts)
|
48
|
+
formatter = Sysloggly::Formatters::SyslogFormatter.new(input_uri, opts)
|
49
|
+
else
|
50
|
+
raise Sysloggly::UnsupportedScheme.new("#{input_uri.scheme} is unsupported")
|
27
51
|
end
|
28
52
|
|
53
|
+
logger = Logger.new(client)
|
54
|
+
logger.formatter = formatter
|
55
|
+
|
29
56
|
logger
|
30
57
|
end
|
31
58
|
end
|
32
59
|
|
33
|
-
require
|
34
|
-
require 'sysloggly/client'
|
35
|
-
require 'sysloggly/client/filelog'
|
36
|
-
require 'sysloggly/client/syslog'
|
37
|
-
require 'sysloggly/rails' if Object.const_defined?(:Rails) && Rails.const_defined?(:Railtie)
|
60
|
+
require "sysloggly/rails" if Object.const_defined?(:Rails) && Rails.const_defined?(:Railtie)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "socket"
|
2
|
+
|
3
|
+
module Sysloggly
|
4
|
+
module Clients
|
5
|
+
class Networklog
|
6
|
+
attr_reader :input_uri, :socket
|
7
|
+
|
8
|
+
# Creates a new client that conforms to the Logger::LogDevice specification.
|
9
|
+
#
|
10
|
+
# @return [Sysloggly::Client::Networklog]
|
11
|
+
# @api public
|
12
|
+
def initialize(input_uri)
|
13
|
+
@input_uri = input_uri
|
14
|
+
|
15
|
+
case @input_uri.scheme
|
16
|
+
when "udp"
|
17
|
+
@socket = UDPSocket.new
|
18
|
+
@socket.connect(@input_uri.host, @input_uri.port)
|
19
|
+
when "tcp"
|
20
|
+
@socket = TCPSocket.new(@input_uri.host, @input_uri.port)
|
21
|
+
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
|
22
|
+
@socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Required by Logger::LogDevice
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
def write(message)
|
30
|
+
begin
|
31
|
+
@socket.send(message, 0)
|
32
|
+
rescue Timeout::Error => e
|
33
|
+
STDOUT.puts "WARNING: Timeout::Error posting message: #{message}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Required by Logger::LogDevice
|
38
|
+
#
|
39
|
+
# @api public
|
40
|
+
def close
|
41
|
+
@socket.close
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "multi_json"
|
2
|
+
require "socket"
|
3
|
+
|
4
|
+
module Sysloggly
|
5
|
+
module Formatters
|
6
|
+
class SimpleFormatter
|
7
|
+
attr_reader :input_uri, :opts
|
8
|
+
|
9
|
+
def initialize(input_uri, opts)
|
10
|
+
@input_uri = input_uri
|
11
|
+
@opts = opts
|
12
|
+
|
13
|
+
@hostname = opts[:hostname] || Socket.gethostname.split(".").first
|
14
|
+
@progname = opts[:progname]
|
15
|
+
@custom_options = opts.except(:hostname, :progname)
|
16
|
+
|
17
|
+
if ["udp", "tcp"].include?(@input_uri.scheme) && !@input_uri.path.empty?
|
18
|
+
if @facility = @input_uri.path.split("/")[1]
|
19
|
+
@facility = @facility.to_i
|
20
|
+
unless @facility <= 23 && @facility >= 0
|
21
|
+
raise Sysloggly::UnknownFacility.new(@facility.to_s)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
@facility = 23
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Specifies the date/time format for this client
|
30
|
+
#
|
31
|
+
# @api public
|
32
|
+
def datetime_format
|
33
|
+
"%b %e %H:%M:%S"
|
34
|
+
end
|
35
|
+
|
36
|
+
# @api public
|
37
|
+
def call(severity, datetime, progname, payload)
|
38
|
+
message = "#{severity} [#{datetime.strftime(datetime_format)}] #{@hostname} "
|
39
|
+
|
40
|
+
message << MultiJson.dump(hashify_message(payload).merge(@custom_options))
|
41
|
+
message << "\r\n" if ["file", "tcp"].include?(@input_uri.scheme)
|
42
|
+
|
43
|
+
message
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
def hashify_message(msg)
|
48
|
+
if msg.is_a?(Hash)
|
49
|
+
msg
|
50
|
+
elsif msg.is_a?(Exception)
|
51
|
+
{ exception_class: msg.class.name, message: msg.message }
|
52
|
+
elsif msg.is_a?(String)
|
53
|
+
begin
|
54
|
+
JSON.parse(msg)
|
55
|
+
rescue
|
56
|
+
{ message: msg }
|
57
|
+
end
|
58
|
+
else
|
59
|
+
{ message: msg.inspect }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Sysloggly
|
2
|
+
module Formatters
|
3
|
+
class SyslogFormatter < SimpleFormatter
|
4
|
+
# Syslog specific PRI calculation.
|
5
|
+
# See RFC3164 4.1.1
|
6
|
+
def pri(severity)
|
7
|
+
severity_value = case severity
|
8
|
+
when "FATAL"
|
9
|
+
0
|
10
|
+
when "ERROR"
|
11
|
+
3
|
12
|
+
when "WARN"
|
13
|
+
4
|
14
|
+
when "INFO"
|
15
|
+
6
|
16
|
+
when "DEBUG"
|
17
|
+
7
|
18
|
+
end
|
19
|
+
(@facility << 3) + severity_value
|
20
|
+
end
|
21
|
+
|
22
|
+
# Generate a syslog compat message
|
23
|
+
# See RFC3164 4.1.1 - 4.1.3
|
24
|
+
#
|
25
|
+
# @api public
|
26
|
+
def call(severity, datetime, progname, payload)
|
27
|
+
message = "<#{pri(severity)}>#{datetime.strftime(datetime_format)} #{@hostname} "
|
28
|
+
|
29
|
+
# Include process ID in progname/log tag - RFC3164 § 5.3
|
30
|
+
message << "#{@progname || progname || $0}[#{Process.pid}]: "
|
31
|
+
|
32
|
+
message << MultiJson.dump(hashify_message(payload).merge(@custom_options))
|
33
|
+
message << "\r\n" if ["file", "tcp"].include?(@input_uri.scheme)
|
34
|
+
|
35
|
+
message
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/sysloggly/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sysloggly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joergen Dahlke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -74,10 +74,11 @@ extensions: []
|
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
76
|
- lib/sysloggly.rb
|
77
|
-
- lib/sysloggly/
|
78
|
-
- lib/sysloggly/
|
79
|
-
- lib/sysloggly/client/syslog.rb
|
77
|
+
- lib/sysloggly/clients/filelog.rb
|
78
|
+
- lib/sysloggly/clients/networklog.rb
|
80
79
|
- lib/sysloggly/extensions/honeybadger.rb
|
80
|
+
- lib/sysloggly/formatters/simple_formatter.rb
|
81
|
+
- lib/sysloggly/formatters/syslog_formatter.rb
|
81
82
|
- lib/sysloggly/rails.rb
|
82
83
|
- lib/sysloggly/version.rb
|
83
84
|
homepage: https://github.com/jdahlke/sysloggly
|
data/lib/sysloggly/client.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
require 'socket'
|
3
|
-
require 'uri'
|
4
|
-
|
5
|
-
module Sysloggly
|
6
|
-
module Client
|
7
|
-
|
8
|
-
# Creates a new client that conforms to the Logger::LogDevice specification.
|
9
|
-
#
|
10
|
-
# @return [Sysloggly::Client::Syslog, Sysloggly::Client::FileLog] returns an instance of an Sysloggly client class
|
11
|
-
# @api public
|
12
|
-
def self.new(url, opts = {})
|
13
|
-
unless url
|
14
|
-
raise InputURLRequired.new
|
15
|
-
end
|
16
|
-
|
17
|
-
begin
|
18
|
-
input_uri = URI.parse(url)
|
19
|
-
rescue URI::InvalidURIError => e
|
20
|
-
raise InputURLRequired.new("Invalid Input URL: #{url}")
|
21
|
-
end
|
22
|
-
|
23
|
-
case input_uri.scheme
|
24
|
-
when 'file'
|
25
|
-
Sysloggly::Client::Filelog.new(input_uri, opts)
|
26
|
-
when 'udp', 'tcp'
|
27
|
-
Sysloggly::Client::Syslog.new(input_uri, opts)
|
28
|
-
else
|
29
|
-
raise Sysloggly::UnsupportedScheme.new("#{input_uri.scheme} is unsupported")
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
module InstanceMethods
|
35
|
-
|
36
|
-
# Specifies the date/time format for this client
|
37
|
-
def datetime_format
|
38
|
-
"%b %e %H:%M:%S"
|
39
|
-
end
|
40
|
-
|
41
|
-
def setup_options
|
42
|
-
@hostname = opts[:hostname] || Socket.gethostname.split('.').first
|
43
|
-
@progname = opts[:progname]
|
44
|
-
@custom_options = opts.except(:hostname, :progname)
|
45
|
-
|
46
|
-
if ['udp', 'tcp'].include?(@input_uri.scheme) && !@input_uri.path.empty?
|
47
|
-
if @facility = @input_uri.path.split('/')[1]
|
48
|
-
@facility = @facility.to_i
|
49
|
-
unless @facility <= 23 && @facility >= 0
|
50
|
-
raise Sysloggly::UnknownFacility.new(@facility.to_s)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
else
|
54
|
-
@facility = 23
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Syslog specific PRI calculation.
|
59
|
-
# See RFC3164 4.1.1
|
60
|
-
def pri(severity)
|
61
|
-
severity_value = case severity
|
62
|
-
when "FATAL"
|
63
|
-
0
|
64
|
-
when "ERROR"
|
65
|
-
3
|
66
|
-
when "WARN"
|
67
|
-
4
|
68
|
-
when "INFO"
|
69
|
-
6
|
70
|
-
when "DEBUG"
|
71
|
-
7
|
72
|
-
end
|
73
|
-
(@facility << 3) + severity_value
|
74
|
-
end
|
75
|
-
|
76
|
-
# Generate a syslog compat message
|
77
|
-
# See RFC3164 4.1.1 - 4.1.3
|
78
|
-
def formatter
|
79
|
-
proc do |severity, datetime, progname, msg|
|
80
|
-
processid = Process.pid
|
81
|
-
message = "<#{pri(severity)}>#{datetime.strftime(datetime_format)} #{@hostname} "
|
82
|
-
|
83
|
-
# Include process ID in progname/log tag - RFC3164 § 5.3
|
84
|
-
message << "#{@progname || progname || $0}[#{processid}]: "
|
85
|
-
|
86
|
-
# Only log JSON to Syslog
|
87
|
-
message << MultiJson.dump(hashify_message(msg).merge(@custom_options))
|
88
|
-
|
89
|
-
if ['file', 'tcp'].include?(@input_uri.scheme )
|
90
|
-
message << "\r\n"
|
91
|
-
end
|
92
|
-
message
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def hashify_message(msg)
|
97
|
-
if msg.is_a?(Hash)
|
98
|
-
msg
|
99
|
-
elsif msg.is_a?(Exception)
|
100
|
-
{ exception_class: msg.class.name, message: msg.message }
|
101
|
-
elsif msg.is_a?(String)
|
102
|
-
begin
|
103
|
-
JSON.parse(msg)
|
104
|
-
rescue
|
105
|
-
{ message: msg }
|
106
|
-
end
|
107
|
-
else
|
108
|
-
{ message: msg.inspect }
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Sysloggly
|
2
|
-
module Client
|
3
|
-
class Filelog
|
4
|
-
include Sysloggly::Client::InstanceMethods
|
5
|
-
|
6
|
-
attr_reader :input_uri, :opts
|
7
|
-
attr_reader :filelog
|
8
|
-
|
9
|
-
def initialize(input_uri, opts)
|
10
|
-
@input_uri = input_uri
|
11
|
-
@opts = opts
|
12
|
-
|
13
|
-
@filelog = File.open(@input_uri.path, File::WRONLY | File::APPEND | File::CREAT)
|
14
|
-
|
15
|
-
setup_options
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# Required by Logger::LogDevice
|
21
|
-
#
|
22
|
-
# @api public
|
23
|
-
def write(message)
|
24
|
-
@filelog.write(message)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Required by Logger::LogDevice
|
28
|
-
#
|
29
|
-
# @api public
|
30
|
-
def close
|
31
|
-
@filelog.close
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Sysloggly
|
2
|
-
module Client
|
3
|
-
class Syslog
|
4
|
-
include Sysloggly::Client::InstanceMethods
|
5
|
-
|
6
|
-
attr_reader :input_uri, :opts
|
7
|
-
attr_reader :syslog
|
8
|
-
|
9
|
-
def initialize(input_uri, opts)
|
10
|
-
@input_uri = input_uri
|
11
|
-
@opts = opts
|
12
|
-
|
13
|
-
case @input_uri.scheme
|
14
|
-
when 'udp'
|
15
|
-
@syslog = UDPSocket.new
|
16
|
-
@syslog.connect(@input_uri.host, @input_uri.port)
|
17
|
-
when 'tcp'
|
18
|
-
@syslog = TCPSocket.new(@input_uri.host, @input_uri.port)
|
19
|
-
@syslog.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
|
20
|
-
@syslog.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
|
21
|
-
end
|
22
|
-
|
23
|
-
setup_options
|
24
|
-
end
|
25
|
-
|
26
|
-
# Required by Logger::LogDevice
|
27
|
-
#
|
28
|
-
# @api public
|
29
|
-
def write(message)
|
30
|
-
begin
|
31
|
-
@syslog.send(message, 0)
|
32
|
-
rescue Timeout::Error => e
|
33
|
-
STDOUT.puts "WARNING: Timeout::Error posting message: #{message}"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Required by Logger::LogDevice
|
38
|
-
#
|
39
|
-
# @api public
|
40
|
-
def close
|
41
|
-
@syslog.close
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|