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