sysloggly 0.1.0 → 0.2.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 +34 -2
- data/lib/sysloggly/client.rb +113 -0
- data/lib/sysloggly/client/filelog.rb +35 -0
- data/lib/sysloggly/client/syslog.rb +45 -0
- data/lib/sysloggly/extensions/honeybadger.rb +15 -0
- data/lib/sysloggly/rails.rb +25 -23
- data/lib/sysloggly/version.rb +1 -1
- metadata +14 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b099237d625daa44f15bb246d47057788d2a8098
|
4
|
+
data.tar.gz: 49351d18111a1f4ddd94711b499f7b5efd0c0447
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36635b1c8513a980a6823240b9de4b27b7d0963bf8d2889117ed3327526f0db3e781e3ee0591ab6228a2ce212bbc4b9167c8b86a01971f2dce59c66e6433c94b
|
7
|
+
data.tar.gz: 21b936e1a842600b077b6b9e58277ce1b74cce45fb327b31780b9f009392ee94dbde7e78ab51d0784a19eb4d179d2197382135944a4122467bed5780881816d0
|
data/lib/sysloggly.rb
CHANGED
@@ -1,5 +1,37 @@
|
|
1
|
+
require 'logger'
|
1
2
|
require 'lograge'
|
2
|
-
require 'syslogger'
|
3
3
|
|
4
|
-
|
4
|
+
#
|
5
|
+
# Sysloggly
|
6
|
+
#
|
7
|
+
# @config [uri] only supports [udp|tcp|file]
|
8
|
+
module Sysloggly
|
9
|
+
class InputURLRequired < ArgumentError; end
|
10
|
+
class UnsupportedScheme < ArgumentError; end
|
11
|
+
class UnknownFacility < ArgumentError; end
|
12
|
+
|
13
|
+
mattr_accessor :progname, :env, :uri, :logger
|
14
|
+
|
15
|
+
def self.configure
|
16
|
+
yield self
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.new(url, opts = {})
|
20
|
+
client = Sysloggly::Client.new(url, opts)
|
21
|
+
logger = Logger.new(client)
|
22
|
+
|
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
|
27
|
+
end
|
28
|
+
|
29
|
+
logger
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
5
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)
|
@@ -0,0 +1,113 @@
|
|
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
|
@@ -0,0 +1,35 @@
|
|
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
|
@@ -0,0 +1,45 @@
|
|
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
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Sysloggly
|
2
|
+
module Extensions
|
3
|
+
module Honeybadger #:nodoc:
|
4
|
+
def notify(exception_or_opts, opts = {})
|
5
|
+
uuid = super(exception_or_opts, opts)
|
6
|
+
|
7
|
+
if uuid
|
8
|
+
Sysloggly.logger.error(exception_or_opts)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Honeybadger.singleton_class.send(:prepend, Sysloggly::Extensions::Honeybadger)
|
data/lib/sysloggly/rails.rb
CHANGED
@@ -1,33 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# Sysloggly default configuration:
|
3
|
+
# @config progname: Rails app name
|
4
|
+
# @config env: Rails env
|
5
|
+
# @config logger: file log to sysloggly.log in the rails log directory
|
6
|
+
#
|
1
7
|
module Sysloggly
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
config
|
8
|
+
# @private
|
9
|
+
class Railtie < Rails::Railtie
|
10
|
+
config.after_initialize do |app|
|
11
|
+
Sysloggly.configure do |config|
|
12
|
+
config.progname ||= app.class.parent_name
|
13
|
+
config.env ||= Rails.env
|
14
|
+
config.uri ||= "file://#{Rails.root.join('log','sysloggly.log')}"
|
7
15
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
honeybadger = YAML.load_file(Rails.root.join('config', 'honeybadger.yml'))
|
14
|
-
environment = honeybadger['env'].to_s
|
15
|
-
rescue
|
16
|
-
end
|
17
|
-
|
18
|
-
# add https://github.com/crohr/syslogger
|
19
|
-
syslogger = Syslogger.new(app_name, Syslog::LOG_PID, Syslog::LOG_LOCAL7)
|
20
|
-
config.syslogger = syslogger
|
16
|
+
config.logger = Sysloggly.new(config.uri, {
|
17
|
+
env: config.env,
|
18
|
+
progname: config.progname
|
19
|
+
})
|
20
|
+
end
|
21
21
|
|
22
|
-
|
22
|
+
app.configure do
|
23
|
+
# @see https://github.com/roidrage/lograge
|
23
24
|
config.lograge.enabled = true
|
24
25
|
config.lograge.formatter = Lograge::Formatters::Json.new
|
25
26
|
config.lograge.keep_original_rails_log = true
|
26
|
-
config.lograge.logger =
|
27
|
-
config.lograge.custom_options = lambda do |event|
|
28
|
-
{ env: environment }
|
29
|
-
end
|
27
|
+
config.lograge.logger = Sysloggly.logger
|
30
28
|
end
|
29
|
+
Lograge.setup(app)
|
30
|
+
|
31
|
+
# load extensions
|
32
|
+
require 'sysloggly/extensions/honeybadger' if defined?(Honeybadger)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
data/lib/sysloggly/version.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sysloggly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.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-03-
|
11
|
+
date: 2017-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: multi_json
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: lograge
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -68,16 +68,21 @@ dependencies:
|
|
68
68
|
version: '0'
|
69
69
|
description: Lograge and Syslog integration for Rails apps.
|
70
70
|
email:
|
71
|
-
- joergen.dahlke@gmail.
|
71
|
+
- joergen.dahlke@gmail.com
|
72
72
|
executables: []
|
73
73
|
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
|
80
|
+
- lib/sysloggly/extensions/honeybadger.rb
|
77
81
|
- lib/sysloggly/rails.rb
|
78
82
|
- lib/sysloggly/version.rb
|
79
83
|
homepage: https://github.com/jdahlke/sysloggly
|
80
|
-
licenses:
|
84
|
+
licenses:
|
85
|
+
- MIT
|
81
86
|
metadata: {}
|
82
87
|
post_install_message:
|
83
88
|
rdoc_options: []
|
@@ -85,16 +90,16 @@ require_paths:
|
|
85
90
|
- lib
|
86
91
|
required_ruby_version: !ruby/object:Gem::Requirement
|
87
92
|
requirements:
|
88
|
-
- - "
|
93
|
+
- - "~>"
|
89
94
|
- !ruby/object:Gem::Version
|
90
|
-
version: '0'
|
95
|
+
version: '2.0'
|
91
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
97
|
requirements:
|
93
98
|
- - ">="
|
94
99
|
- !ruby/object:Gem::Version
|
95
100
|
version: '0'
|
96
101
|
requirements: []
|
97
|
-
rubyforge_project:
|
102
|
+
rubyforge_project: sysloggly
|
98
103
|
rubygems_version: 2.5.2
|
99
104
|
signing_key:
|
100
105
|
specification_version: 4
|