loggability 0.15.1 → 0.18.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +47 -0
- data/Manifest.txt +12 -4
- data/Rakefile +1 -1
- data/lib/loggability.rb +16 -13
- data/lib/loggability/log_device.rb +86 -0
- data/lib/loggability/log_device/appending.rb +34 -0
- data/lib/loggability/log_device/datadog.rb +90 -0
- data/lib/loggability/log_device/file.rb +37 -0
- data/lib/loggability/log_device/http.rb +310 -0
- data/lib/loggability/logger.rb +11 -37
- data/spec/helpers.rb +1 -1
- data/spec/loggability/log_device/appending_spec.rb +27 -0
- data/spec/loggability/log_device/datadog_spec.rb +67 -0
- data/spec/loggability/log_device/file_spec.rb +27 -0
- data/spec/loggability/log_device/http_spec.rb +217 -0
- data/spec/loggability/logger_spec.rb +43 -2
- data/spec/loggability_spec.rb +13 -0
- metadata +52 -26
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -667
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b2c4fcb2846387b2e46bb742c60358c79cad2569644325e3db8995bfc4f1367
|
4
|
+
data.tar.gz: 8ee45fa6eaf6cfea8d84d8410877bd90053d71a4d692f0a391209d14702430d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcc3cc14f69340ca900ccd458c57e6a85d1b6b895614843ca9427e061f43320ccc7149034091afb0c4ff2bf3ada6a6dcbd05e4f94432224e3bd38b0a6ad1c6b1
|
7
|
+
data.tar.gz: c451e216cd87c63794169f0932650f34f78ae99a0eda842497fbef91df1eaf2564500a6160bdf10eb73f81d900cb320f81d4f207e03f0360c8b3df98a92345cb
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -2,6 +2,53 @@
|
|
2
2
|
|
3
3
|
---
|
4
4
|
|
5
|
+
== v0.18.2 [2020-12-28] Michael Granger <ged@faeriemud.org>
|
6
|
+
|
7
|
+
Improvements:
|
8
|
+
|
9
|
+
- Make the version spec even less specific.
|
10
|
+
|
11
|
+
|
12
|
+
== v0.18.1 [2020-12-28] Michael Granger <ged@faeriemud.org>
|
13
|
+
|
14
|
+
Improvements:
|
15
|
+
|
16
|
+
- Change version spec to work with Ruby 3 versions.
|
17
|
+
|
18
|
+
|
19
|
+
== v0.18.0 [2020-12-24] Michael Granger <ged@faeriemud.org>
|
20
|
+
|
21
|
+
Improvements:
|
22
|
+
|
23
|
+
- Add memory management to the http log device
|
24
|
+
- Add a dead-simple log server example
|
25
|
+
- Update for Ruby 3, add my updated gem cert
|
26
|
+
|
27
|
+
Thanks again to Mahmood Khan <mkhan1484@gmail.com> for the patch.
|
28
|
+
|
29
|
+
|
30
|
+
== v0.17.0 [2020-02-27] Michael Granger <ged@faeriemud.org>
|
31
|
+
|
32
|
+
Bugfixes:
|
33
|
+
|
34
|
+
- Fix the construction of the client in the http log device
|
35
|
+
|
36
|
+
Improvements:
|
37
|
+
|
38
|
+
- Add support for log devices to the aggregate #output_to
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
== v0.16.0 [2020-02-24] Michael Granger <ged@faeriemud.org>
|
43
|
+
|
44
|
+
Improvements:
|
45
|
+
|
46
|
+
- Expose a "log device" API and add the ability to write to multiple devices
|
47
|
+
- Add a device for logging to an HTTP service
|
48
|
+
|
49
|
+
Thanks to Mahmood Khan <mkhan1484@gmail.com> for the patch.
|
50
|
+
|
51
|
+
|
5
52
|
== v0.15.1 [2020-01-09] Michael Granger <ged@faeriemud.org>
|
6
53
|
|
7
54
|
Bugfixes:
|
data/Manifest.txt
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
.simplecov
|
2
|
-
ChangeLog
|
3
2
|
History.rdoc
|
4
|
-
Manifest.txt
|
5
|
-
README.md
|
6
|
-
Rakefile
|
7
3
|
lib/loggability.rb
|
8
4
|
lib/loggability/constants.rb
|
9
5
|
lib/loggability/formatter.rb
|
@@ -14,8 +10,16 @@ lib/loggability/formatter/structured.rb
|
|
14
10
|
lib/loggability/logclient.rb
|
15
11
|
lib/loggability/logger.rb
|
16
12
|
lib/loggability/loghost.rb
|
13
|
+
lib/loggability/log_device.rb
|
14
|
+
lib/loggability/log_device/appending.rb
|
15
|
+
lib/loggability/log_device/datadog.rb
|
16
|
+
lib/loggability/log_device/file.rb
|
17
|
+
lib/loggability/log_device/http.rb
|
17
18
|
lib/loggability/override.rb
|
18
19
|
lib/loggability/spechelpers.rb
|
20
|
+
Manifest.txt
|
21
|
+
Rakefile
|
22
|
+
README.md
|
19
23
|
spec/helpers.rb
|
20
24
|
spec/loggability/formatter/color_spec.rb
|
21
25
|
spec/loggability/formatter/default_spec.rb
|
@@ -24,6 +28,10 @@ spec/loggability/formatter/structured_spec.rb
|
|
24
28
|
spec/loggability/formatter_spec.rb
|
25
29
|
spec/loggability/logger_spec.rb
|
26
30
|
spec/loggability/loghost_spec.rb
|
31
|
+
spec/loggability/log_device/appending_spec.rb
|
32
|
+
spec/loggability/log_device/datadog_spec.rb
|
33
|
+
spec/loggability/log_device/file_spec.rb
|
34
|
+
spec/loggability/log_device/http_spec.rb
|
27
35
|
spec/loggability/override_spec.rb
|
28
36
|
spec/loggability/spechelpers_spec.rb
|
29
37
|
spec/loggability_spec.rb
|
data/Rakefile
CHANGED
data/lib/loggability.rb
CHANGED
@@ -9,7 +9,7 @@ require 'date'
|
|
9
9
|
module Loggability
|
10
10
|
|
11
11
|
# Package version constant
|
12
|
-
VERSION = '0.
|
12
|
+
VERSION = '0.18.2'
|
13
13
|
|
14
14
|
# The key for the global logger (Loggability's own logger)
|
15
15
|
GLOBAL_KEY = :__global__
|
@@ -29,7 +29,7 @@ module Loggability
|
|
29
29
|
(?<severity>(?i:debug|info|warn|error|fatal))
|
30
30
|
(?:
|
31
31
|
\s+
|
32
|
-
(?<target>(?:[\w
|
32
|
+
(?<target>(?:[\w\-/:\.\[\]]|\\[ ])+)
|
33
33
|
)?
|
34
34
|
(?: \s+\(
|
35
35
|
(?<format>\w+)
|
@@ -38,10 +38,16 @@ module Loggability
|
|
38
38
|
$
|
39
39
|
}x
|
40
40
|
|
41
|
-
require 'loggability/constants'
|
42
|
-
include Loggability::Constants
|
43
41
|
|
44
|
-
|
42
|
+
# Automatically load subordinate classes/modules
|
43
|
+
autoload :Constants, 'loggability/constants'
|
44
|
+
autoload :LogDevice, 'loggability/log_device'
|
45
|
+
autoload :Logger, 'loggability/logger'
|
46
|
+
autoload :LogHost, 'loggability/loghost'
|
47
|
+
autoload :LogClient, 'loggability/logclient'
|
48
|
+
autoload :Override, 'loggability/override'
|
49
|
+
|
50
|
+
include Loggability::Constants
|
45
51
|
|
46
52
|
|
47
53
|
##
|
@@ -55,10 +61,6 @@ module Loggability
|
|
55
61
|
@config = CONFIG_DEFAULTS.dup.freeze
|
56
62
|
|
57
63
|
|
58
|
-
# Automatically log the log host and log client mixins when they're referenced
|
59
|
-
autoload :LogHost, 'loggability/loghost'
|
60
|
-
autoload :LogClient, 'loggability/logclient'
|
61
|
-
autoload :Override, 'loggability/override'
|
62
64
|
|
63
65
|
|
64
66
|
### Cast the given +device+ to a Loggability::Logger, if possible, and return it. If
|
@@ -144,12 +146,12 @@ module Loggability
|
|
144
146
|
|
145
147
|
### Call the method with the given +methodname+ across the loggers of all loghosts with
|
146
148
|
### the given +arg+ and/or +block+.
|
147
|
-
def self::aggregate( methodname,
|
149
|
+
def self::aggregate( methodname, *args, &block )
|
148
150
|
# self.log.debug "Aggregating a call to %p with %p to %d log hosts" %
|
149
151
|
# [ methodname, arg, Loggability.log_hosts.length ]
|
150
152
|
Loggability.log_hosts.values.each do |loghost|
|
151
153
|
# self.log.debug " %p.logger.%s( %p )" % [ loghost, methodname, arg ]
|
152
|
-
loghost.logger.send( methodname,
|
154
|
+
loghost.logger.send( methodname, *args, &block )
|
153
155
|
end
|
154
156
|
end
|
155
157
|
|
@@ -189,8 +191,8 @@ module Loggability
|
|
189
191
|
#
|
190
192
|
# Aggregate method: set all loggers to log to +destination+. See Loggability::Logger#output_to
|
191
193
|
# for more info.
|
192
|
-
def self::output_to( newdevice )
|
193
|
-
self.aggregate( :output_to, newdevice )
|
194
|
+
def self::output_to( newdevice, *args )
|
195
|
+
self.aggregate( :output_to, newdevice, *args )
|
194
196
|
end
|
195
197
|
class << self
|
196
198
|
alias_method :write_to, :output_to
|
@@ -321,6 +323,7 @@ module Loggability
|
|
321
323
|
target = case target
|
322
324
|
when 'STDOUT' then $stdout
|
323
325
|
when 'STDERR' then $stderr
|
326
|
+
when /:/ then Loggability::LogDevice.parse_device_spec( target )
|
324
327
|
else
|
325
328
|
target
|
326
329
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set nosta noet ts=4 sw=4:
|
3
|
+
# encoding: utf-8
|
4
|
+
|
5
|
+
require 'loggability' unless defined?( Loggability )
|
6
|
+
|
7
|
+
|
8
|
+
# An abstract base class for logging devices. A device manages the actual writing of messages
|
9
|
+
# to whatever destination logs are supposed to be shipped to, along with any buffering,
|
10
|
+
# encoding, or serialization that needs to be done.
|
11
|
+
#
|
12
|
+
# Log devices are loadable by name via the ::create method if they are declared in a
|
13
|
+
# directory named `loggability/log_device/` in the gem path.
|
14
|
+
#
|
15
|
+
# Concrete log devices are required to implement two methods: #write and #close.
|
16
|
+
#
|
17
|
+
# [write]
|
18
|
+
# Takes one argument, which is the message that needs to be written.
|
19
|
+
#
|
20
|
+
# [close]
|
21
|
+
# Close any open filehandles or connections established by the device.
|
22
|
+
class Loggability::LogDevice
|
23
|
+
|
24
|
+
|
25
|
+
# Regexp used to split up logging devices in config lines
|
26
|
+
DEVICE_TARGET_REGEX = /^([\s*a-z]\w*)(?:\[(.*)\])?/
|
27
|
+
|
28
|
+
|
29
|
+
### Parses out the target class name and its arguments from the +target_spec+
|
30
|
+
### then requires the subclass and instantiates it by passing the arguments.
|
31
|
+
### The +target_spec+ comes from a config file in the format of:
|
32
|
+
###
|
33
|
+
### logging:
|
34
|
+
### datadog[data_dog_api_key]
|
35
|
+
###
|
36
|
+
### In the above example:
|
37
|
+
### * "datadog" is the log device to send logs to
|
38
|
+
### * "data_dog_api_key" is the argument that will be passed onto the datadog
|
39
|
+
### log device's constructor
|
40
|
+
def self::parse_device_spec( target_spec )
|
41
|
+
targets = target_spec.split( ';' ).compact
|
42
|
+
return targets.map do |t|
|
43
|
+
target_subclass = t[ DEVICE_TARGET_REGEX, 1 ]&.strip.to_sym
|
44
|
+
target_subclass_args = t[ DEVICE_TARGET_REGEX, 2 ]
|
45
|
+
|
46
|
+
self.create( target_subclass, target_subclass_args )
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
### Requires the subclass and instantiates it with the passed-in arguments and
|
52
|
+
### then returns an instance of it.
|
53
|
+
def self::create( target, *target_args )
|
54
|
+
modname = target.to_s.capitalize
|
55
|
+
|
56
|
+
self.load_device_type( target ) unless self.const_defined?( modname, false )
|
57
|
+
subclass = self.const_get( modname, false )
|
58
|
+
|
59
|
+
return subclass.new( *target_args )
|
60
|
+
rescue NameError => err
|
61
|
+
raise LoadError, "failed to load %s LogDevice: %s" % [ target, err.message ]
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
### Attempt to load a LogDevice of the given +type+.
|
66
|
+
def self::load_device_type( type )
|
67
|
+
require_path = "loggability/log_device/%s" % [ type.to_s.downcase ]
|
68
|
+
require( require_path )
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
### Write a +message+ to the device. This needs to be overridden by concrete
|
73
|
+
### subclasses; calling this implementation will raise an NotImplementedError.
|
74
|
+
def write( message )
|
75
|
+
raise NotImplementedError, "%s is not implemented by %s" % [ __callee__, self.class.name ]
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
### Close the device. This needs to be overridden by concrete subclasses;
|
80
|
+
### calling this implementation will raise an NotImplementedError.
|
81
|
+
def close
|
82
|
+
raise NotImplementedError, "%s is not implemented by %s" % [ __callee__, self.class.name ]
|
83
|
+
end
|
84
|
+
|
85
|
+
end # class Loggability::LogDevice
|
86
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set nosta noet ts=4 sw=4:
|
3
|
+
# encoding: utf-8
|
4
|
+
|
5
|
+
require 'loggability/logger' unless defined?( Loggability::Logger )
|
6
|
+
|
7
|
+
# A log device that appends to the object it's constructed with instead of writing
|
8
|
+
# to a file descriptor or a file.
|
9
|
+
class Loggability::LogDevice::Appending < Loggability::LogDevice
|
10
|
+
|
11
|
+
### Create a new +Appending+ log device that will append content to +array+.
|
12
|
+
def initialize( target )
|
13
|
+
@target = target || []
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
######
|
18
|
+
public
|
19
|
+
######
|
20
|
+
|
21
|
+
# The target of the log device
|
22
|
+
attr_reader :target
|
23
|
+
|
24
|
+
|
25
|
+
### Append the specified +message+ to the target.
|
26
|
+
def write( message )
|
27
|
+
@target << message
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
### No-op -- this is here just so Logger doesn't complain
|
32
|
+
def close; end
|
33
|
+
|
34
|
+
end # class Loggability::LogDevice::Appending
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set nosta noet ts=4 sw=4:
|
3
|
+
# encoding: utf-8
|
4
|
+
|
5
|
+
require 'uri'
|
6
|
+
require 'socket'
|
7
|
+
require 'net/https'
|
8
|
+
require 'json'
|
9
|
+
require 'concurrent'
|
10
|
+
require 'loggability/logger' unless defined?( Loggability::Logger )
|
11
|
+
|
12
|
+
require 'loggability/log_device/http'
|
13
|
+
|
14
|
+
|
15
|
+
# A log device that sends logs to Datadog's HTTP endpoint
|
16
|
+
# for receiving logs
|
17
|
+
class Loggability::LogDevice::Datadog < Loggability::LogDevice::Http
|
18
|
+
|
19
|
+
### Datadog's HTTP endpoint URL for sending logs to
|
20
|
+
DEFAULT_ENDPOINT = URI( "https://http-intake.logs.datadoghq.com/v1/input" )
|
21
|
+
|
22
|
+
### The max number of messages that can be sent to datadog in a single payload
|
23
|
+
MAX_BATCH_SIZE = 480
|
24
|
+
|
25
|
+
### The max size in bytes for a single message.
|
26
|
+
### Limiting the message size to 200kB to leave room for other info such as
|
27
|
+
### tags, metadata, etc.
|
28
|
+
### DataDog's max size for a single log entry is 256kB
|
29
|
+
MAX_MESSAGE_BYTESIZE = 204_800
|
30
|
+
|
31
|
+
### The max size in bytes of all messages in the batch.
|
32
|
+
### Limiting the total messages size to 4MB to leave room for other info such as
|
33
|
+
### tags, metadata, etc.
|
34
|
+
### Datadog's max size for the entire payload is 5MB
|
35
|
+
MAX_BATCH_BYTESIZE = 4_194_304
|
36
|
+
|
37
|
+
# Override the default HTTP device options for sending logs to DD
|
38
|
+
DEFAULT_OPTIONS = {
|
39
|
+
max_batch_size: MAX_BATCH_SIZE,
|
40
|
+
max_message_bytesize: MAX_MESSAGE_BYTESIZE,
|
41
|
+
max_batch_bytesize: MAX_BATCH_BYTESIZE,
|
42
|
+
}
|
43
|
+
|
44
|
+
|
45
|
+
### Create a new Datadog
|
46
|
+
def initialize( api_key, endpoint=DEFAULT_ENDPOINT, options={} )
|
47
|
+
if endpoint.is_a?( Hash )
|
48
|
+
options = endpoint
|
49
|
+
endpoint = DEFAULT_ENDPOINT
|
50
|
+
end
|
51
|
+
|
52
|
+
super( endpoint, options )
|
53
|
+
|
54
|
+
@api_key = api_key
|
55
|
+
@hostname = Socket.gethostname
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
######
|
60
|
+
public
|
61
|
+
######
|
62
|
+
|
63
|
+
##
|
64
|
+
# The name of the current host
|
65
|
+
attr_reader :hostname
|
66
|
+
|
67
|
+
##
|
68
|
+
# The configured Datadog API key
|
69
|
+
attr_reader :api_key
|
70
|
+
|
71
|
+
|
72
|
+
### Format an individual log +message+ for Datadog.
|
73
|
+
def format_log_message( message )
|
74
|
+
return {
|
75
|
+
hostname: self.hostname,
|
76
|
+
message: message
|
77
|
+
}.to_json
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
### Overridden to add the configured API key to the headers of each request.
|
82
|
+
def make_batch_request
|
83
|
+
request = super
|
84
|
+
|
85
|
+
request[ 'DD-API-KEY' ] = self.api_key
|
86
|
+
|
87
|
+
return request
|
88
|
+
end
|
89
|
+
|
90
|
+
end # class Loggability::LogDevice::Datadog
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set nosta noet ts=4 sw=4:
|
3
|
+
# encoding: utf-8
|
4
|
+
|
5
|
+
require 'logger'
|
6
|
+
require 'loggability/logger' unless defined?( Loggability::Logger )
|
7
|
+
|
8
|
+
# A log device that delegates to the ruby's default Logger's file device and writes
|
9
|
+
# to a file descriptor or a file.
|
10
|
+
class Loggability::LogDevice::File < Loggability::LogDevice
|
11
|
+
|
12
|
+
### Create a new +File+ device that will write to the file using the built-in ruby's +File+ log device
|
13
|
+
def initialize( target )
|
14
|
+
@target = ::Logger::LogDevice.new( target )
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
######
|
19
|
+
public
|
20
|
+
######
|
21
|
+
|
22
|
+
# The target of the log device
|
23
|
+
attr_reader :target
|
24
|
+
|
25
|
+
|
26
|
+
### Append the specified +message+ to the target.
|
27
|
+
def write( message )
|
28
|
+
self.target.write( message )
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
### close the file
|
33
|
+
def close
|
34
|
+
self.target.close
|
35
|
+
end
|
36
|
+
|
37
|
+
end # class Loggability::LogDevice::File
|