journald-logger 0.0.2 → 1.0.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/README.md +82 -0
- data/journald-logger.gemspec +1 -2
- data/lib/journald/logger/exceptionable.rb +35 -0
- data/lib/journald/logger/loggable.rb +85 -0
- data/lib/journald/logger/sysloggable.rb +13 -0
- data/lib/journald/logger/version.rb +2 -2
- data/lib/journald/logger.rb +98 -2
- data/lib/journald/tracer_logger.rb +18 -0
- metadata +18 -15
- data/README.rdoc +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: facbc1ed0842610f785cefd1744337d8f76c282f
|
|
4
|
+
data.tar.gz: 3f90384e426a5009ba0dab5dfd412572e1407946
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f269abff54386cb0cfadbbadffec2125e782c8d91e9093850c546fa369b59273ff3a694d1925651c7f72bc961c8944eb5046e59084a92b9f8c8dd856defe58ca
|
|
7
|
+
data.tar.gz: 4d41970f8f8bb429ef8d1067ab65b6c0112c4572caf02daa6414ff4a00cc55911109a2268b2e7a32edc0d0f3ac68384375ec6dc20592cf65872fe13972f45fb9
|
data/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# journald-logger
|
|
2
|
+
|
|
3
|
+
A Logger drop-in replacement that logs directly to systemd-journal with some additional features
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
require 'journald/logger'
|
|
9
|
+
|
|
10
|
+
logger = Journald::Logger.new('gandalf') # simple logger, sets SYSLOG_IDENTIFIER to 'gandalf'
|
|
11
|
+
logger = Journald::TracerLogger.new('gandalf') # tracing logger, logs caller's file, line number and function name
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Logger replacement
|
|
15
|
+
|
|
16
|
+
This gem is designed to be accurate drop-in Logger replacement
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
logger.warn "you shall not pass!" # works
|
|
20
|
+
logger.info("gollum") { "my preciousss" } # also works!
|
|
21
|
+
logger.progname = "saruman" # sets value for SYSLOG_IDENTIFIER to 'saruman'
|
|
22
|
+
logger.formatter = SomeFormatter.new # does nothing, journald-logger does not require a formatter
|
|
23
|
+
logger.close # does nothing, nothing to close
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
We map Ruby severity to Syslog priority by this map
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
LEVEL_MAP = {
|
|
30
|
+
::Logger::UNKNOWN => LOG_ALERT,
|
|
31
|
+
::Logger::FATAL => LOG_CRIT,
|
|
32
|
+
::Logger::ERROR => LOG_ERR,
|
|
33
|
+
::Logger::WARN => LOG_WARNING,
|
|
34
|
+
::Logger::INFO => LOG_INFO,
|
|
35
|
+
::Logger::DEBUG => LOG_DEBUG,
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
You may notice it's somewhat different from the one from Syslog::Logger
|
|
40
|
+
|
|
41
|
+
## Tags
|
|
42
|
+
|
|
43
|
+
Tags are used to add systemd-journal fields to all subsequent log calls until removed
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
logger = Journald::Logger.new('gandalf', world: 'arda') # set world tag in costructor
|
|
47
|
+
logger.tag :location, 'moria' # add/replace location
|
|
48
|
+
logger.tag(:object, 'balrog') do # use object field in the block
|
|
49
|
+
# log as 'MESSAGE=you shall not pass!', 'PRIORITY=4', 'LOCATION=moria', 'OBJECT=balrog', 'WORLD=arda'
|
|
50
|
+
logger.warn 'you shall not pass!'
|
|
51
|
+
end
|
|
52
|
+
logger.untag :location # remove location
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Tag names must follow systemd-journal fields naming convention:
|
|
56
|
+
letters, numbers, underscores, cannot begin with underscore. Library upcases all letters automatically
|
|
57
|
+
|
|
58
|
+
## systemd-journal style
|
|
59
|
+
|
|
60
|
+
Two methods which look similarly to native systemd-journal api
|
|
61
|
+
|
|
62
|
+
```ruby
|
|
63
|
+
logger.send({
|
|
64
|
+
message: 'hi!',
|
|
65
|
+
priority: Journald::LOG_NOTICE,
|
|
66
|
+
any_field: 'any_value',
|
|
67
|
+
}) # tags will be added here
|
|
68
|
+
logger.print Journald::LOG_NOTICE, 'hi!' # and here
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Syslog style
|
|
72
|
+
|
|
73
|
+
Just to add some more confusion you may use methods with syslog severity names prefixed with ```log_```
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
logger.log_err 'Error'
|
|
77
|
+
logger.log_debug 'Debug'
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT, see LICENSE.txt
|
data/journald-logger.gemspec
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
lib = File.expand_path('../lib', __FILE__)
|
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
3
|
require 'journald/logger/version'
|
|
@@ -17,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
|
17
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
17
|
spec.require_paths = ['lib']
|
|
19
18
|
|
|
20
|
-
spec.required_ruby_version = '>=
|
|
19
|
+
spec.required_ruby_version = '>= 2.0.0'
|
|
21
20
|
|
|
22
21
|
spec.add_runtime_dependency 'journald-native', '~> 1.0'
|
|
23
22
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Journald
|
|
2
|
+
class Logger
|
|
3
|
+
module Exceptionable
|
|
4
|
+
def exception(e, priority: nil, severity: nil)
|
|
5
|
+
priority ||= severity_to_priority(severity) || Journald::LOG_CRIT
|
|
6
|
+
real_exception(e, priority, false)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def real_exception(e, priority, is_cause)
|
|
12
|
+
# for Ruby 2.1 get cause if present
|
|
13
|
+
cause = if e.respond_to? :cause; e.cause; end
|
|
14
|
+
# for Ruby 2.1 get backtrace if present
|
|
15
|
+
bt = e.respond_to?(:backtrace_locations) && e.backtrace_locations.length > 0
|
|
16
|
+
|
|
17
|
+
tag_trace_location(e.backtrace_locations[0]) if bt
|
|
18
|
+
|
|
19
|
+
send({
|
|
20
|
+
priority: priority,
|
|
21
|
+
message: "Exception #{e.inspect}",
|
|
22
|
+
gem_logger_message_type: is_cause ? 'ExceptionCause' : 'Exception',
|
|
23
|
+
exception_class: e.class.name,
|
|
24
|
+
exception_message: e.message,
|
|
25
|
+
backtrace: e.backtrace.join("\n"),
|
|
26
|
+
cause: cause ? cause.inspect : nil,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
untag_trace_location if bt
|
|
30
|
+
|
|
31
|
+
real_exception(cause, priority, true) if cause
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Journald
|
|
2
|
+
class Logger
|
|
3
|
+
module Loggable
|
|
4
|
+
# ruby Logger style
|
|
5
|
+
|
|
6
|
+
# our map differs from Syslog::Logger
|
|
7
|
+
LEVEL_MAP = {
|
|
8
|
+
::Logger::UNKNOWN => LOG_ALERT,
|
|
9
|
+
::Logger::FATAL => LOG_CRIT,
|
|
10
|
+
::Logger::ERROR => LOG_ERR,
|
|
11
|
+
::Logger::WARN => LOG_WARNING,
|
|
12
|
+
::Logger::INFO => LOG_INFO,
|
|
13
|
+
::Logger::DEBUG => LOG_DEBUG,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
def add(severity, message = nil, progname = nil, &block)
|
|
17
|
+
priority = severity_to_priority(severity) || LEVEL_MAP[::Logger::UNKNOWN]
|
|
18
|
+
|
|
19
|
+
# some black magic from Logger O__o
|
|
20
|
+
progname ||= self.progname
|
|
21
|
+
if message.nil?
|
|
22
|
+
if block_given?
|
|
23
|
+
message = block.call
|
|
24
|
+
else
|
|
25
|
+
message = progname
|
|
26
|
+
progname = self.progname
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
send({
|
|
31
|
+
priority: priority,
|
|
32
|
+
message: message,
|
|
33
|
+
syslog_identifier: progname,
|
|
34
|
+
})
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
alias_method :log, :add
|
|
38
|
+
|
|
39
|
+
# add methods a la Logger.warn or Logger.error
|
|
40
|
+
::Logger::Severity::constants.each do |severity|
|
|
41
|
+
severity_key = severity.downcase
|
|
42
|
+
severity_value = ::Logger::Severity.const_get(severity)
|
|
43
|
+
|
|
44
|
+
define_method(severity_key) do |progname = nil, &block|
|
|
45
|
+
add(severity_value, nil, progname, &block)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
define_method("#{severity_key}?".to_sym) do
|
|
49
|
+
true # journald always logs everything
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def <<(value)
|
|
54
|
+
debug(value)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Logger accessors
|
|
58
|
+
|
|
59
|
+
# journald always logs everything
|
|
60
|
+
def level
|
|
61
|
+
::Logger::DEBUG
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def sev_threshold
|
|
65
|
+
::Logger::DEBUG
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def level=(_); end
|
|
69
|
+
def sev_threshold=(_); end
|
|
70
|
+
|
|
71
|
+
# journald does not require formatter or formatting
|
|
72
|
+
def formatter; end
|
|
73
|
+
def formatter=(_); end
|
|
74
|
+
def datetime_format; end
|
|
75
|
+
def datetime_format=(_); end
|
|
76
|
+
|
|
77
|
+
def close; end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
def severity_to_priority(severity)
|
|
81
|
+
LEVEL_MAP[severity]
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Journald
|
|
2
|
+
class Logger
|
|
3
|
+
module Sysloggable
|
|
4
|
+
# methods with syslog priorities like logger.log_err, logger.log_warning
|
|
5
|
+
[:LOG_EMERG, :LOG_ALERT, :LOG_CRIT, :LOG_ERR, :LOG_WARNING, :LOG_NOTICE, :LOG_INFO, :LOG_DEBUG].each do |level|
|
|
6
|
+
define_method(level.downcase) do |message = nil, &block|
|
|
7
|
+
message ||= block.call
|
|
8
|
+
print(Journald.const_get(level), message)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/journald/logger.rb
CHANGED
|
@@ -1,6 +1,102 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'logger'
|
|
2
|
+
require 'journald/native'
|
|
3
|
+
|
|
4
|
+
require_relative 'logger/version'
|
|
5
|
+
require_relative 'logger/exceptionable'
|
|
6
|
+
require_relative 'logger/loggable'
|
|
7
|
+
require_relative 'logger/sysloggable'
|
|
8
|
+
|
|
9
|
+
require_relative 'tracer_logger'
|
|
2
10
|
|
|
3
11
|
module Journald
|
|
4
|
-
|
|
12
|
+
class Logger
|
|
13
|
+
include Exceptionable
|
|
14
|
+
include Loggable
|
|
15
|
+
include Sysloggable
|
|
16
|
+
|
|
17
|
+
def initialize(progname = nil, tags = {})
|
|
18
|
+
@tags = tags
|
|
19
|
+
@logger = Native
|
|
20
|
+
self.progname = progname
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def progname
|
|
24
|
+
tag_value(:syslog_identifier)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def progname=(value)
|
|
28
|
+
tag(:syslog_identifier, value)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# systemd-journal style
|
|
32
|
+
|
|
33
|
+
# send systemd-journal message
|
|
34
|
+
def send(hash)
|
|
35
|
+
hash_to_send = @tags.merge(hash)
|
|
36
|
+
real_send(hash_to_send)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def print(priority, message)
|
|
40
|
+
send({
|
|
41
|
+
priority: priority,
|
|
42
|
+
message: message,
|
|
43
|
+
})
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# add tags
|
|
47
|
+
|
|
48
|
+
# add tag to all log messages
|
|
49
|
+
def tag(key, value)
|
|
50
|
+
@tags[key] = value
|
|
51
|
+
|
|
52
|
+
if block_given?
|
|
53
|
+
yield
|
|
54
|
+
untag(key)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# get tag value
|
|
59
|
+
def tag_value(key)
|
|
60
|
+
@tags[key]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# stop adding the tag
|
|
64
|
+
def untag(key)
|
|
65
|
+
@tags.delete(key)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
protected
|
|
69
|
+
|
|
70
|
+
def tag_trace_location(location)
|
|
71
|
+
tag :code_file, location.path
|
|
72
|
+
tag :code_line, location.lineno
|
|
73
|
+
tag :code_func, location.label
|
|
74
|
+
|
|
75
|
+
if block_given?
|
|
76
|
+
yield
|
|
77
|
+
untag_trace_location
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def untag_trace_location
|
|
82
|
+
untag :code_file
|
|
83
|
+
untag :code_line
|
|
84
|
+
untag :code_func
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def real_send(hash)
|
|
90
|
+
hash = hash.delete_if { |_, v| v.nil? }
|
|
91
|
+
|
|
92
|
+
array_to_send = hash.map do |k,v|
|
|
93
|
+
key = k.to_s.upcase
|
|
94
|
+
value = v.to_s
|
|
95
|
+
|
|
96
|
+
"#{key}=#{value}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
@logger.send(*array_to_send)
|
|
100
|
+
end
|
|
5
101
|
end
|
|
6
102
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Journald
|
|
2
|
+
class TracerLogger
|
|
3
|
+
def initialize(progname = nil, tags = {})
|
|
4
|
+
@wrapped_logger = Logger.new(progname, tags)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def method_missing(meth, *args, &block)
|
|
8
|
+
super unless @wrapped_logger.respond_to? meth
|
|
9
|
+
|
|
10
|
+
@wrapped_logger.__send__(:tag_trace_location, caller_locations[0])
|
|
11
|
+
@wrapped_logger.__send__(meth, *args, &block)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
15
|
+
@wrapped_logger.respond_to?(method_name, include_private)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: journald-logger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anton Smirnov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-11-
|
|
11
|
+
date: 2014-11-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: journald-native
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - ~>
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '1.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - ~>
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '1.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - ~>
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: '1.6'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - ~>
|
|
38
|
+
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '1.6'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rake
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
|
-
- -
|
|
45
|
+
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
47
|
version: '0'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
|
-
- -
|
|
52
|
+
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '0'
|
|
55
55
|
description:
|
|
@@ -59,14 +59,18 @@ executables: []
|
|
|
59
59
|
extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
|
61
61
|
files:
|
|
62
|
-
- .gitignore
|
|
62
|
+
- ".gitignore"
|
|
63
63
|
- Gemfile
|
|
64
64
|
- LICENSE.txt
|
|
65
|
-
- README.
|
|
65
|
+
- README.md
|
|
66
66
|
- Rakefile
|
|
67
67
|
- journald-logger.gemspec
|
|
68
68
|
- lib/journald/logger.rb
|
|
69
|
+
- lib/journald/logger/exceptionable.rb
|
|
70
|
+
- lib/journald/logger/loggable.rb
|
|
71
|
+
- lib/journald/logger/sysloggable.rb
|
|
69
72
|
- lib/journald/logger/version.rb
|
|
73
|
+
- lib/journald/tracer_logger.rb
|
|
70
74
|
homepage: https://github.com/sandfox-im/journald-logger
|
|
71
75
|
licenses:
|
|
72
76
|
- MIT
|
|
@@ -77,19 +81,18 @@ require_paths:
|
|
|
77
81
|
- lib
|
|
78
82
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
83
|
requirements:
|
|
80
|
-
- -
|
|
84
|
+
- - ">="
|
|
81
85
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
86
|
+
version: 2.0.0
|
|
83
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
88
|
requirements:
|
|
85
|
-
- -
|
|
89
|
+
- - ">="
|
|
86
90
|
- !ruby/object:Gem::Version
|
|
87
91
|
version: '0'
|
|
88
92
|
requirements: []
|
|
89
93
|
rubyforge_project:
|
|
90
|
-
rubygems_version: 2.
|
|
94
|
+
rubygems_version: 2.4.4
|
|
91
95
|
signing_key:
|
|
92
96
|
specification_version: 4
|
|
93
97
|
summary: systemd-journal native logger
|
|
94
98
|
test_files: []
|
|
95
|
-
has_rdoc:
|