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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dae3eb36e9d5eb7a551f1d33e4cc3a696894ab16
4
- data.tar.gz: 57d12976b420daac54c5d83e808a55277b7f99c4
3
+ metadata.gz: 75f81f43322e647a969b2588a304976761ce5572
4
+ data.tar.gz: 99e90a40755d66b6b234a13f96548fd8ccfc8b8f
5
5
  SHA512:
6
- metadata.gz: d5a0ad5550b4ad7078b4f5eb6cd9fd8dd03f8e51acdefed905bd3900dc30b436e2b71b57d457cedaa458dbdf338abc03f485e80d9a3573bb4bb808da8e20a3a6
7
- data.tar.gz: b97f7605cd0b0f9e67d6ab9a6eeeb46ad99b632cdbf71a6b93e27bd98f718e26f9b8d698cfd9e040c604dda47fd1bce137fc5303ae94c1ad7dc95a59abf880f1
6
+ metadata.gz: 4b3b0a212295467f075a3e77fae21399c2968a8624f93ba771624d1fc4494838664096c0d25a6428a90db46467380d68e22d9decbee116831adc61dda64a280d
7
+ data.tar.gz: 6e8f86565cc3c72a2759d385c31a1569f9dc5d24dec83b1c1b72556f7b23d5aa9dc7ebb71ee8a12602890be6fbb0930e270f8257a27ceab2c0caac5de37fde9f
data/lib/sysloggly.rb CHANGED
@@ -1,5 +1,12 @@
1
- require 'logger'
2
- require 'lograge'
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
- client = Sysloggly::Client.new(url, opts)
21
- logger = Logger.new(client)
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
- if client.respond_to?(:formatter)
24
- logger.formatter = client.formatter
25
- elsif client.respond_to?(:datetime_format)
26
- logger.datetime_format = client.datetime_format
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 'sysloggly/version'
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,6 @@
1
+ module Sysloggly
2
+ module Clients
3
+ class Filelog < Logger::LogDevice
4
+ end
5
+ end
6
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Sysloggly
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0".freeze
3
3
  end
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.2.1
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-08-03 00:00:00.000000000 Z
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/client.rb
78
- - lib/sysloggly/client/filelog.rb
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
@@ -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