loggability 0.15.1 → 0.18.2
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
- 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
|