semlogr 0.1.3 → 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/.rspec +1 -0
- data/.rubocop.yml +24 -9
- data/CHANGELOG.md +27 -0
- data/README.md +8 -13
- data/Rakefile +12 -2
- data/lib/semlogr/component_registry.rb +18 -0
- data/lib/semlogr/context/log_context.rb +27 -0
- data/lib/semlogr/enrichers/aggregate.rb +15 -0
- data/lib/semlogr/enrichers/host.rb +4 -1
- data/lib/semlogr/enrichers/log_context.rb +16 -0
- data/lib/semlogr/enrichers/property.rb +5 -1
- data/lib/semlogr/enrichers/thread.rb +5 -1
- data/lib/semlogr/error.rb +10 -0
- data/lib/semlogr/events/log_event.rb +13 -1
- data/lib/semlogr/log_severity.rb +22 -5
- data/lib/semlogr/logger.rb +23 -53
- data/lib/semlogr/logger_configuration.rb +17 -12
- data/lib/semlogr/properties/output_properties.rb +0 -1
- data/lib/semlogr/sinks/aggregate.rb +15 -0
- data/lib/semlogr/sinks/colored_console.rb +6 -3
- data/lib/semlogr/sinks/console.rb +2 -0
- data/lib/semlogr/sinks/file.rb +4 -1
- data/lib/semlogr/sinks/filtering.rb +16 -0
- data/lib/semlogr/version.rb +1 -1
- data/lib/semlogr.rb +25 -5
- data/samples/basic.rb +4 -59
- data/samples/context.rb +9 -0
- data/samples/enrichment.rb +12 -0
- data/samples/filtering.rb +11 -0
- data/samples/log_context.rb +12 -0
- data/samples/sinks.rb +10 -0
- data/semlogr.gemspec +5 -1
- metadata +60 -6
- data/output.html +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd4e69c32518a7128075aabc31c8ec3384dd4c8b
|
4
|
+
data.tar.gz: 1e264cb0025475bf2774b05d5484756f99585131
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e556941e43501f47c519d55eeed10f99317d7ec7ec804e9c537da9d82185a881ca4a0f8309f4856af63639eab3314f6606e142d4d4aeaf5155c1ed8b702a9090
|
7
|
+
data.tar.gz: 465b051b985524bd0d1c2012df6e0a52c982c0f93fd5c2d0e76cad325f0603ec372912ab8b0940ca552dc34efbec9662b6c1427c712e104731f221afea0b0d8f
|
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
@@ -3,19 +3,34 @@ AllCops:
|
|
3
3
|
|
4
4
|
Documentation:
|
5
5
|
Enabled: false
|
6
|
+
OrderedGems:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
Layout/MultilineMethodCallIndentation:
|
10
|
+
EnforcedStyle: indented
|
6
11
|
|
12
|
+
# Do not use Rubocop to enforce complexity rules, these will me
|
13
|
+
# managed via the PR prorcess to not let in clearly complex code.
|
14
|
+
Metrics/ClassLength:
|
15
|
+
Enabled: false
|
16
|
+
Metrics/ModuleLength:
|
17
|
+
Enabled: false
|
18
|
+
Metrics/MethodLength:
|
19
|
+
Enabled: false
|
20
|
+
Metrics/BlockNesting:
|
21
|
+
Enabled: false
|
7
22
|
Metrics/AbcSize:
|
8
|
-
|
9
|
-
Metrics/BlockLength:
|
10
|
-
ExcludedMethods: ['describe']
|
23
|
+
Enabled: false
|
11
24
|
Metrics/CyclomaticComplexity:
|
12
|
-
|
25
|
+
Enabled: false
|
26
|
+
Metrics/ParameterLists:
|
27
|
+
Enabled: false
|
28
|
+
Metrics/BlockLength:
|
29
|
+
Enabled: false
|
30
|
+
Metrics/PerceivedComplexity:
|
31
|
+
Enabled: false
|
13
32
|
Metrics/LineLength:
|
14
|
-
|
15
|
-
Metrics/MethodLength:
|
16
|
-
Max: 20
|
33
|
+
Enabled: false
|
17
34
|
|
18
35
|
Style/EmptyMethod:
|
19
36
|
EnforcedStyle: expanded
|
20
|
-
Style/MultilineMethodCallIndentation:
|
21
|
-
EnforcedStyle: indented
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
### 0.2.0
|
4
|
+
|
5
|
+
* Introduce simpler logger configuration
|
6
|
+
* Add ambient log property context
|
7
|
+
* Add samples
|
8
|
+
* Specs specs specs!
|
9
|
+
* Fix coloring of exceptions with colored console sink
|
10
|
+
|
11
|
+
### 0.1.3
|
12
|
+
|
13
|
+
* Move to Oj for json serialization of log events
|
14
|
+
|
15
|
+
### 0.1.2
|
16
|
+
|
17
|
+
* Do not format backtrace as newline seperated string in json formatter
|
18
|
+
* Change from configure to create_logger and don't implicitly set Semlogr.logger
|
19
|
+
* Add null logger
|
20
|
+
|
21
|
+
### 0.1.1
|
22
|
+
|
23
|
+
* Various fixes
|
24
|
+
|
25
|
+
### 0.1.0
|
26
|
+
|
27
|
+
* Initial release
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Semlogr
|
4
4
|
|
5
|
-
Semlogr is a semantic logger for Ruby inspired
|
5
|
+
Semlogr is a semantic logger for Ruby inspired and primarily ported from the awesome semantic logger for .NET [Serilog](http://serilog.net/).
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -20,31 +20,26 @@ then:
|
|
20
20
|
|
21
21
|
## Getting Started
|
22
22
|
|
23
|
-
Create an instance of the logger configuring one or more sinks.
|
23
|
+
Create an instance of the logger configuring one or more sinks.
|
24
24
|
|
25
25
|
```ruby
|
26
26
|
require "semlogr"
|
27
|
-
require "semlogr/sinks/colored_console"
|
28
27
|
|
29
|
-
logger = Semlogr
|
30
|
-
c.log_at
|
28
|
+
Semlogr.logger = Semlogr.create_logger do |c|
|
29
|
+
c.log_at :info
|
31
30
|
|
32
|
-
c.write_to
|
31
|
+
c.write_to :colored_console
|
33
32
|
end
|
34
33
|
|
35
|
-
|
34
|
+
Semlogr.info('Customer {customer_id} did something interesting', customer_id: 1234)
|
36
35
|
```
|
37
36
|
|
37
|
+
More configuration examples can be found inside the samples directory.
|
38
|
+
|
38
39
|
## Development
|
39
40
|
|
40
41
|
After cloning the repository run `bundle install` to get up and running, to run the specs just run `rake spec`. You can also experiment in an interactive pry console using `bin/console`.
|
41
42
|
|
42
|
-
## Changes
|
43
|
-
|
44
|
-
### 0.1.0
|
45
|
-
|
46
|
-
- Initial commit, long long way to go :)!
|
47
|
-
|
48
43
|
## Contributing
|
49
44
|
|
50
45
|
See anything broken or something you would like to improve? feel free to submit an issue or better yet a pull request!
|
data/Rakefile
CHANGED
@@ -2,7 +2,17 @@ require 'bundler/gem_tasks'
|
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
require 'rubocop/rake_task'
|
4
4
|
|
5
|
-
RSpec::Core::RakeTask.new(:spec)
|
6
5
|
RuboCop::RakeTask.new(:rubocop)
|
7
6
|
|
8
|
-
|
7
|
+
RSpec::Core::RakeTask.new('test:unit') do |c|
|
8
|
+
c.rspec_opts = '--fail-fast --pattern spec/unit/**{,/*/**}/*_spec.rb'
|
9
|
+
end
|
10
|
+
|
11
|
+
task 'test:performance' do
|
12
|
+
Dir['spec/performance/**/*.rb'].each do |file|
|
13
|
+
require_relative file
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
task test: %w[test:unit test:performance]
|
18
|
+
task default: %w[rubocop test]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'semlogr/error'
|
2
|
+
|
3
|
+
module Semlogr
|
4
|
+
class ComponentRegistry
|
5
|
+
@mappings = {}
|
6
|
+
|
7
|
+
def self.register(type, mapping)
|
8
|
+
(@mappings[type] ||= {}).update(mapping)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.resolve(type, key, *params)
|
12
|
+
mapping = @mappings[type] && @mappings[type][key]
|
13
|
+
raise ComponentNotRegisteredError.new(type, key) unless mapping
|
14
|
+
|
15
|
+
mapping.new(*params)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Semlogr
|
2
|
+
module Context
|
3
|
+
class LogContext
|
4
|
+
def self.current
|
5
|
+
Thread.current[:semlogr_log_context] ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.push_property(**properties)
|
9
|
+
LogContext.current << properties
|
10
|
+
|
11
|
+
yield if block_given?
|
12
|
+
ensure
|
13
|
+
LogContext.current.pop
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.get_property(key)
|
17
|
+
LogContext.current
|
18
|
+
.reverse_each
|
19
|
+
.each do |properties|
|
20
|
+
return properties[key] if properties.key?(key)
|
21
|
+
end
|
22
|
+
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'socket'
|
2
|
+
require 'semlogr/component_registry'
|
2
3
|
|
3
4
|
module Semlogr
|
4
5
|
module Enrichers
|
5
6
|
class Host
|
6
7
|
def enrich(log_event)
|
7
|
-
log_event.
|
8
|
+
log_event.add_property_if_absent(host: Socket.gethostname)
|
8
9
|
end
|
9
10
|
end
|
11
|
+
|
12
|
+
ComponentRegistry.register(:enricher, host: Host)
|
10
13
|
end
|
11
14
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'semlogr/context/log_context'
|
2
|
+
|
3
|
+
module Semlogr
|
4
|
+
module Enrichers
|
5
|
+
class LogContext
|
6
|
+
def enrich(log_event)
|
7
|
+
Context::LogContext.current
|
8
|
+
.each do |properties|
|
9
|
+
log_event.add_property_if_absent(properties)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
ComponentRegistry.register(:enricher, log_context: LogContext)
|
15
|
+
end
|
16
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'semlogr/component_registry'
|
2
|
+
|
1
3
|
module Semlogr
|
2
4
|
module Enrichers
|
3
5
|
class Property
|
@@ -6,8 +8,10 @@ module Semlogr
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def enrich(log_event)
|
9
|
-
log_event.
|
11
|
+
log_event.add_property_if_absent(@properties)
|
10
12
|
end
|
11
13
|
end
|
14
|
+
|
15
|
+
ComponentRegistry.register(:enricher, property: Property)
|
12
16
|
end
|
13
17
|
end
|
@@ -1,9 +1,13 @@
|
|
1
|
+
require 'semlogr/component_registry'
|
2
|
+
|
1
3
|
module Semlogr
|
2
4
|
module Enrichers
|
3
5
|
class Thread
|
4
6
|
def enrich(log_event)
|
5
|
-
log_event.
|
7
|
+
log_event.add_property_if_absent(thread_id: ::Thread.current.object_id)
|
6
8
|
end
|
7
9
|
end
|
10
|
+
|
11
|
+
ComponentRegistry.register(:enricher, thread: Thread)
|
8
12
|
end
|
9
13
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'semlogr/templates/parser'
|
2
|
+
|
1
3
|
module Semlogr
|
2
4
|
module Events
|
3
5
|
class LogEvent
|
@@ -7,7 +9,7 @@ module Semlogr
|
|
7
9
|
attr_reader :properties
|
8
10
|
attr_reader :timestamp
|
9
11
|
|
10
|
-
def initialize(severity, template, error, properties)
|
12
|
+
def initialize(severity, template, error: nil, **properties)
|
11
13
|
@timestamp = Time.now.utc
|
12
14
|
@severity = severity
|
13
15
|
@template = template
|
@@ -15,6 +17,12 @@ module Semlogr
|
|
15
17
|
@properties = properties
|
16
18
|
end
|
17
19
|
|
20
|
+
def self.create(severity, template, properties)
|
21
|
+
template = Templates::Parser.parse(template)
|
22
|
+
|
23
|
+
LogEvent.new(severity, template, properties)
|
24
|
+
end
|
25
|
+
|
18
26
|
def get_property(name)
|
19
27
|
@properties[name]
|
20
28
|
end
|
@@ -23,6 +31,10 @@ module Semlogr
|
|
23
31
|
@properties.merge!(properties)
|
24
32
|
end
|
25
33
|
|
34
|
+
def add_property_if_absent(properties)
|
35
|
+
@properties.merge!(properties) { |_, old, _| old }
|
36
|
+
end
|
37
|
+
|
26
38
|
def render(output)
|
27
39
|
@template.render(output, @properties)
|
28
40
|
end
|
data/lib/semlogr/log_severity.rb
CHANGED
@@ -9,6 +9,23 @@ module Semlogr
|
|
9
9
|
@display_string = display_string
|
10
10
|
end
|
11
11
|
|
12
|
+
def self.create(severity)
|
13
|
+
case severity
|
14
|
+
when :debug
|
15
|
+
LogSeverity::DEBUG
|
16
|
+
when :info
|
17
|
+
LogSeverity::INFO
|
18
|
+
when :warn
|
19
|
+
LogSeverity::WARN
|
20
|
+
when :error
|
21
|
+
LogSeverity::ERROR
|
22
|
+
when :fatal
|
23
|
+
LogSeverity::FATAL
|
24
|
+
else
|
25
|
+
LogSeverity::DEBUG
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
12
29
|
def <=>(other)
|
13
30
|
@value <=> other.value
|
14
31
|
end
|
@@ -21,10 +38,10 @@ module Semlogr
|
|
21
38
|
@display_string
|
22
39
|
end
|
23
40
|
|
24
|
-
DEBUG = LogSeverity.new(
|
25
|
-
INFO = LogSeverity.new(
|
26
|
-
WARN = LogSeverity.new(
|
27
|
-
ERROR = LogSeverity.new(
|
28
|
-
FATAL = LogSeverity.new(
|
41
|
+
DEBUG = LogSeverity.new(0, 'DEBUG')
|
42
|
+
INFO = LogSeverity.new(1, 'INFO')
|
43
|
+
WARN = LogSeverity.new(2, 'WARN')
|
44
|
+
ERROR = LogSeverity.new(3, 'ERROR')
|
45
|
+
FATAL = LogSeverity.new(4, 'FATAL')
|
29
46
|
end
|
30
47
|
end
|
data/lib/semlogr/logger.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
|
-
require 'logger'
|
2
1
|
require 'semlogr/logger_configuration'
|
3
2
|
require 'semlogr/log_severity'
|
4
3
|
require 'semlogr/events/log_event'
|
5
|
-
require 'semlogr/templates/parser'
|
6
4
|
require 'semlogr/enrichers/property'
|
5
|
+
require 'semlogr/enrichers/aggregate'
|
7
6
|
|
8
7
|
module Semlogr
|
9
8
|
class Logger
|
10
|
-
def initialize(min_severity,
|
9
|
+
def initialize(min_severity, enricher, sink)
|
11
10
|
@min_severity = min_severity
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@sinks = sinks
|
11
|
+
@enricher = enricher
|
12
|
+
@sink = sink
|
15
13
|
end
|
16
14
|
|
17
15
|
def self.create
|
@@ -41,39 +39,40 @@ module Semlogr
|
|
41
39
|
@min_severity <= LogSeverity::FATAL
|
42
40
|
end
|
43
41
|
|
44
|
-
def debug(template = nil,
|
45
|
-
log(LogSeverity::DEBUG, template,
|
42
|
+
def debug(template = nil, **properties, &block)
|
43
|
+
log(LogSeverity::DEBUG, template, properties, &block)
|
46
44
|
end
|
47
45
|
|
48
|
-
def info(template = nil,
|
49
|
-
log(LogSeverity::INFO, template,
|
46
|
+
def info(template = nil, **properties, &block)
|
47
|
+
log(LogSeverity::INFO, template, properties, &block)
|
50
48
|
end
|
51
49
|
|
52
|
-
def warn(template = nil,
|
53
|
-
log(LogSeverity::WARN, template,
|
50
|
+
def warn(template = nil, **properties, &block)
|
51
|
+
log(LogSeverity::WARN, template, properties, &block)
|
54
52
|
end
|
55
53
|
|
56
|
-
def error(template = nil,
|
57
|
-
log(LogSeverity::ERROR, template,
|
54
|
+
def error(template = nil, **properties, &block)
|
55
|
+
log(LogSeverity::ERROR, template, properties, &block)
|
58
56
|
end
|
59
57
|
|
60
|
-
def fatal(template = nil,
|
61
|
-
log(LogSeverity::FATAL, template,
|
58
|
+
def fatal(template = nil, **properties, &block)
|
59
|
+
log(LogSeverity::FATAL, template, properties, &block)
|
62
60
|
end
|
63
61
|
|
64
62
|
def with_context(**properties)
|
63
|
+
property_enricher = Enrichers::Property.new(properties)
|
64
|
+
enricher = Enrichers::Aggregate.new([@enricher, property_enricher])
|
65
|
+
|
65
66
|
Logger.new(
|
66
67
|
@min_severity,
|
67
|
-
|
68
|
-
@
|
69
|
-
@sinks
|
68
|
+
enricher,
|
69
|
+
@sink
|
70
70
|
)
|
71
71
|
end
|
72
72
|
|
73
73
|
private
|
74
74
|
|
75
|
-
def log(severity, template,
|
76
|
-
return true if @sinks.size.zero?
|
75
|
+
def log(severity, template, properties, &block)
|
77
76
|
return true if severity < @min_severity
|
78
77
|
|
79
78
|
if block
|
@@ -82,42 +81,13 @@ module Semlogr
|
|
82
81
|
|
83
82
|
properties ||= {}
|
84
83
|
properties[:progname] = progname if progname
|
85
|
-
error = properties.delete(:error)
|
86
84
|
end
|
87
85
|
|
88
|
-
log_event =
|
89
|
-
|
90
|
-
|
91
|
-
enrich(log_event)
|
92
|
-
emit(log_event)
|
86
|
+
log_event = Events::LogEvent.create(severity, template, properties)
|
87
|
+
@enricher.enrich(log_event)
|
88
|
+
@sink.emit(log_event)
|
93
89
|
|
94
90
|
true
|
95
91
|
end
|
96
|
-
|
97
|
-
def create_log_event(severity, template, error, properties)
|
98
|
-
template = Templates::Parser.parse(template)
|
99
|
-
|
100
|
-
Events::LogEvent.new(severity, template, error, properties)
|
101
|
-
end
|
102
|
-
|
103
|
-
def filter?(log_event)
|
104
|
-
@filters.each do |filter|
|
105
|
-
return true if filter.call(log_event)
|
106
|
-
end
|
107
|
-
|
108
|
-
false
|
109
|
-
end
|
110
|
-
|
111
|
-
def enrich(log_event)
|
112
|
-
@enrichers.each do |enricher|
|
113
|
-
enricher.enrich(log_event)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def emit(log_event)
|
118
|
-
@sinks.each do |sink|
|
119
|
-
sink.emit(log_event)
|
120
|
-
end
|
121
|
-
end
|
122
92
|
end
|
123
93
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
+
require 'semlogr/component_registry'
|
2
|
+
require 'semlogr/enrichers/aggregate'
|
3
|
+
require 'semlogr/sinks/aggregate'
|
4
|
+
require 'semlogr/sinks/filtering'
|
5
|
+
|
1
6
|
module Semlogr
|
2
7
|
class LoggerConfiguration
|
3
|
-
attr_reader :min_severity
|
4
|
-
attr_reader :enrichers
|
5
|
-
attr_reader :filters
|
6
|
-
attr_reader :sinks
|
7
|
-
|
8
8
|
def initialize
|
9
9
|
@min_severity = LogSeverity::DEBUG
|
10
10
|
@enrichers = []
|
@@ -13,27 +13,32 @@ module Semlogr
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def log_at(severity)
|
16
|
-
@min_severity = severity
|
16
|
+
@min_severity = LogSeverity.create(severity)
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def filter(filter)
|
20
20
|
@filters << filter
|
21
21
|
end
|
22
22
|
|
23
|
-
def enrich_with(enricher)
|
23
|
+
def enrich_with(enricher, *params)
|
24
|
+
enricher = ComponentRegistry.resolve(:enricher, enricher, *params) if enricher.is_a?(Symbol)
|
24
25
|
@enrichers << enricher
|
25
26
|
end
|
26
27
|
|
27
|
-
def write_to(sink)
|
28
|
+
def write_to(sink, *params)
|
29
|
+
sink = ComponentRegistry.resolve(:sink, sink, *params) if sink.is_a?(Symbol)
|
28
30
|
@sinks << sink
|
29
31
|
end
|
30
32
|
|
31
33
|
def create_logger
|
34
|
+
enricher = Enrichers::Aggregate.new(@enrichers)
|
35
|
+
sink = Sinks::Aggregate.new(@sinks)
|
36
|
+
sink = Sinks::Filtering.new(@filters, sink) if @filters.any?
|
37
|
+
|
32
38
|
Logger.new(
|
33
39
|
@min_severity,
|
34
|
-
|
35
|
-
|
36
|
-
@sinks
|
40
|
+
enricher,
|
41
|
+
sink
|
37
42
|
)
|
38
43
|
end
|
39
44
|
end
|
@@ -48,14 +48,13 @@ module Semlogr
|
|
48
48
|
when :message
|
49
49
|
render_message(output, log_event)
|
50
50
|
when :severity
|
51
|
-
|
52
|
-
colorize(output, color) do
|
51
|
+
colorize(output, LOG_SEVERITY_COLORS[log_event.severity]) do
|
53
52
|
token.render(output, output_properties)
|
54
53
|
end
|
55
54
|
when :error
|
56
55
|
return unless output_properties[:error]
|
57
56
|
|
58
|
-
colorize(output,
|
57
|
+
colorize(output, LOG_SEVERITY_COLORS[log_event.severity]) do
|
59
58
|
token.render(output, output_properties)
|
60
59
|
end
|
61
60
|
else
|
@@ -79,10 +78,14 @@ module Semlogr
|
|
79
78
|
end
|
80
79
|
|
81
80
|
def colorize(output, color)
|
81
|
+
color = :white unless color
|
82
|
+
|
82
83
|
output << "\e[#{COLOR_CODES[color]}m"
|
83
84
|
yield
|
84
85
|
output << "\e[0m"
|
85
86
|
end
|
86
87
|
end
|
88
|
+
|
89
|
+
ComponentRegistry.register(:sink, colored_console: ColoredConsole)
|
87
90
|
end
|
88
91
|
end
|
data/lib/semlogr/sinks/file.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
require 'logger'
|
1
2
|
require 'semlogr/formatters/text_formatter'
|
2
3
|
|
3
4
|
module Semlogr
|
4
5
|
module Sinks
|
5
6
|
class File
|
6
|
-
def initialize(file, shift_age:
|
7
|
+
def initialize(file, shift_age: 0, shift_size: 1_048_576, formatter: nil)
|
7
8
|
@logdev = ::Logger::LogDevice.new(file, shift_age: shift_age, shift_size: shift_size)
|
8
9
|
@formatter = formatter || Formatters::TextFormatter.new
|
9
10
|
end
|
@@ -13,5 +14,7 @@ module Semlogr
|
|
13
14
|
@logdev.write(output)
|
14
15
|
end
|
15
16
|
end
|
17
|
+
|
18
|
+
ComponentRegistry.register(:sink, file: File)
|
16
19
|
end
|
17
20
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Semlogr
|
2
|
+
module Sinks
|
3
|
+
class Filtering
|
4
|
+
def initialize(filters, sink)
|
5
|
+
@filters = filters
|
6
|
+
@sink = sink
|
7
|
+
end
|
8
|
+
|
9
|
+
def emit(log_event)
|
10
|
+
filtered = @filters.any? { |filter| filter.call(log_event) }
|
11
|
+
|
12
|
+
@sink.emit(log_event) unless filtered
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/semlogr/version.rb
CHANGED
data/lib/semlogr.rb
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
require 'semlogr/version'
|
2
2
|
require 'semlogr/logger'
|
3
3
|
require 'semlogr/null_logger'
|
4
|
+
require 'semlogr/context/log_context'
|
5
|
+
|
6
|
+
# Built-in enrichers
|
7
|
+
require 'semlogr/enrichers/host'
|
8
|
+
require 'semlogr/enrichers/log_context'
|
9
|
+
require 'semlogr/enrichers/property'
|
10
|
+
require 'semlogr/enrichers/thread'
|
11
|
+
|
12
|
+
# Built-in sinks
|
13
|
+
require 'semlogr/sinks/console'
|
14
|
+
require 'semlogr/sinks/colored_console'
|
15
|
+
require 'semlogr/sinks/file'
|
16
|
+
|
17
|
+
# Built-in formatters
|
18
|
+
require 'semlogr/formatters/json_formatter'
|
19
|
+
require 'semlogr/formatters/text_formatter'
|
4
20
|
|
5
21
|
module Semlogr
|
6
22
|
@logger = nil
|
@@ -20,22 +36,26 @@ module Semlogr
|
|
20
36
|
end
|
21
37
|
|
22
38
|
def self.debug(template = nil, **properties, &block)
|
23
|
-
logger.debug(template,
|
39
|
+
logger.debug(template, properties, &block)
|
24
40
|
end
|
25
41
|
|
26
42
|
def self.info(template = nil, **properties, &block)
|
27
|
-
logger.info(template,
|
43
|
+
logger.info(template, properties, &block)
|
28
44
|
end
|
29
45
|
|
30
46
|
def self.warn(template = nil, **properties, &block)
|
31
|
-
logger.warn(template,
|
47
|
+
logger.warn(template, properties, &block)
|
32
48
|
end
|
33
49
|
|
34
50
|
def self.error(template = nil, **properties, &block)
|
35
|
-
logger.error(template,
|
51
|
+
logger.error(template, properties, &block)
|
36
52
|
end
|
37
53
|
|
38
54
|
def self.fatal(template = nil, **properties, &block)
|
39
|
-
logger.fatal(template,
|
55
|
+
logger.fatal(template, properties, &block)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.with_context(**properties)
|
59
|
+
logger.with_context(properties)
|
40
60
|
end
|
41
61
|
end
|
data/samples/basic.rb
CHANGED
@@ -1,64 +1,9 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
require 'semlogr'
|
3
|
-
require 'semlogr/sinks/console'
|
4
|
-
require 'semlogr/sinks/colored_console'
|
5
|
-
require 'semlogr/sinks/file'
|
6
|
-
require 'semlogr/formatters/json_formatter'
|
7
|
-
require 'semlogr/enrichers/thread'
|
8
|
-
require 'semlogr/enrichers/host'
|
9
|
-
require 'semlogr/enrichers/property'
|
10
3
|
|
11
|
-
logger = Semlogr::Logger.create do |c|
|
12
|
-
c.
|
13
|
-
|
14
|
-
c.write_to Semlogr::Sinks::Console.new
|
15
|
-
c.write_to Semlogr::Sinks::ColoredConsole.new
|
16
|
-
c.write_to Semlogr::Sinks::Console.new(formatter: Semlogr::Formatters::JsonFormatter.new)
|
17
|
-
|
18
|
-
c.enrich_with Semlogr::Enrichers::Thread.new
|
19
|
-
c.enrich_with Semlogr::Enrichers::Host.new
|
20
|
-
c.enrich_with Semlogr::Enrichers::Property.new(version: '1.0')
|
21
|
-
|
22
|
-
c.filter_when lambda { |log_event|
|
23
|
-
log_event.get_property(:id) == 123
|
24
|
-
}
|
4
|
+
Semlogr.logger = Semlogr::Logger.create do |c|
|
5
|
+
c.write_to :console
|
25
6
|
end
|
26
7
|
|
27
|
-
|
28
|
-
|
29
|
-
logger.debug('Test {id}, string {string}', id: 123, string: 'foo')
|
30
|
-
logger.debug('Test {id}, string {string}', id: 1234, string: 'foo')
|
31
|
-
logger.info('Test {id}, string {string}', id: 1234, string: 'foo')
|
32
|
-
logger.warn('Test {id}, string {string}', id: 1234, string: 'foo')
|
33
|
-
logger.fatal('Test {id}, string {string}', id: 1234, string: 'foo')
|
34
|
-
logger.fatal('Test array {array}', array: [1, 2, 3, 'foo'])
|
35
|
-
|
36
|
-
logger.debug do
|
37
|
-
'Testing with a block'
|
38
|
-
end
|
39
|
-
|
40
|
-
logger.debug do
|
41
|
-
['Testing with a block, id: {id}', id: 1234]
|
42
|
-
end
|
43
|
-
|
44
|
-
logger.error('ERROR!!!', error: StandardError.new('test'))
|
45
|
-
logger.error('ERROR!!!', error: StandardError.new('test'))
|
46
|
-
|
47
|
-
begin
|
48
|
-
def bob
|
49
|
-
foo
|
50
|
-
end
|
51
|
-
|
52
|
-
def foo
|
53
|
-
raise StandardError, 'foo'
|
54
|
-
end
|
55
|
-
|
56
|
-
bob
|
57
|
-
rescue => ex
|
58
|
-
logger.warn('Oops, id: {id}', id: 1234, error: ex)
|
59
|
-
logger.error('Oops, id: {id}', id: 1234, error: ex)
|
60
|
-
|
61
|
-
logger.error do
|
62
|
-
['Testing error with a block, id: {id}', error: ex, id: 1234]
|
63
|
-
end
|
64
|
-
end
|
8
|
+
Semlogr.info('Customer {id} checked out', id: 123)
|
9
|
+
Semlogr.error('Failed to save data', error: StandardError.new('foo'))
|
data/samples/context.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'semlogr'
|
3
|
+
|
4
|
+
Semlogr.logger = Semlogr::Logger.create do |c|
|
5
|
+
c.write_to :console, formatter: Semlogr::Formatters::JsonFormatter.new
|
6
|
+
end
|
7
|
+
|
8
|
+
Semlogr.with_context(id: 2, correlation_id: '1234')
|
9
|
+
.info('Customer {id} checked out', id: 1)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'semlogr'
|
3
|
+
|
4
|
+
Semlogr.logger = Semlogr::Logger.create do |c|
|
5
|
+
c.write_to :console, formatter: Semlogr::Formatters::JsonFormatter.new
|
6
|
+
|
7
|
+
c.enrich_with :host
|
8
|
+
c.enrich_with :thread
|
9
|
+
c.enrich_with :property, correlation_id: '1234'
|
10
|
+
end
|
11
|
+
|
12
|
+
Semlogr.info('Customer {id} checked out', id: 1)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'semlogr'
|
3
|
+
|
4
|
+
Semlogr.logger = Semlogr::Logger.create do |c|
|
5
|
+
c.write_to :console
|
6
|
+
|
7
|
+
c.filter ->(e) { e.get_property(:id) == 123 }
|
8
|
+
end
|
9
|
+
|
10
|
+
Semlogr.info('Customer {id} checked out', id: 123)
|
11
|
+
Semlogr.info('Customer {id} checked out', id: 456)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'semlogr'
|
3
|
+
|
4
|
+
Semlogr.logger = Semlogr::Logger.create do |c|
|
5
|
+
c.write_to :console, formatter: Semlogr::Formatters::JsonFormatter.new
|
6
|
+
|
7
|
+
c.enrich_with :log_context
|
8
|
+
end
|
9
|
+
|
10
|
+
Semlogr::Context::LogContext.push_property(a: 1) do
|
11
|
+
Semlogr.info('Customer {id} checked out', id: 1)
|
12
|
+
end
|
data/samples/sinks.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'semlogr'
|
3
|
+
|
4
|
+
Semlogr.logger = Semlogr::Logger.create do |c|
|
5
|
+
c.write_to :console, formatter: Semlogr::Formatters::JsonFormatter.new
|
6
|
+
c.write_to :colored_console
|
7
|
+
end
|
8
|
+
|
9
|
+
Semlogr.info('Customer {id} checked out', id: 123)
|
10
|
+
Semlogr.error('Failed to save data', error: StandardError.new('foo'))
|
data/semlogr.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
|
@@ -27,5 +28,8 @@ Gem::Specification.new do |spec|
|
|
27
28
|
spec.add_development_dependency 'pry', '~> 0.10.3'
|
28
29
|
spec.add_development_dependency 'rake', '~> 10.0'
|
29
30
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
30
|
-
spec.add_development_dependency 'rubocop', '
|
31
|
+
spec.add_development_dependency 'rubocop', '0.49.1'
|
32
|
+
spec.add_development_dependency 'simplecov', '~>0.15.1'
|
33
|
+
spec.add_development_dependency 'benchmark-memory', '~>0.1.2'
|
34
|
+
spec.add_development_dependency 'benchmark-ips', '~>2.7.2'
|
31
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: semlogr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Sedich
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lru_redux
|
@@ -96,18 +96,60 @@ dependencies:
|
|
96
96
|
version: '3.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.49.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.49.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.15.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.15.1
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: benchmark-memory
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.1.2
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 0.1.2
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: benchmark-ips
|
99
141
|
requirement: !ruby/object:Gem::Requirement
|
100
142
|
requirements:
|
101
143
|
- - "~>"
|
102
144
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
145
|
+
version: 2.7.2
|
104
146
|
type: :development
|
105
147
|
prerelease: false
|
106
148
|
version_requirements: !ruby/object:Gem::Requirement
|
107
149
|
requirements:
|
108
150
|
- - "~>"
|
109
151
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
152
|
+
version: 2.7.2
|
111
153
|
description: A modern semantic logger for Ruby inspired by Serilog.
|
112
154
|
email:
|
113
155
|
- stefan.sedich@gmail.com
|
@@ -118,6 +160,7 @@ files:
|
|
118
160
|
- ".gitignore"
|
119
161
|
- ".rspec"
|
120
162
|
- ".rubocop.yml"
|
163
|
+
- CHANGELOG.md
|
121
164
|
- Gemfile
|
122
165
|
- LICENSE.md
|
123
166
|
- README.md
|
@@ -125,9 +168,14 @@ files:
|
|
125
168
|
- bin/console
|
126
169
|
- bin/setup
|
127
170
|
- lib/semlogr.rb
|
171
|
+
- lib/semlogr/component_registry.rb
|
172
|
+
- lib/semlogr/context/log_context.rb
|
173
|
+
- lib/semlogr/enrichers/aggregate.rb
|
128
174
|
- lib/semlogr/enrichers/host.rb
|
175
|
+
- lib/semlogr/enrichers/log_context.rb
|
129
176
|
- lib/semlogr/enrichers/property.rb
|
130
177
|
- lib/semlogr/enrichers/thread.rb
|
178
|
+
- lib/semlogr/error.rb
|
131
179
|
- lib/semlogr/events/log_event.rb
|
132
180
|
- lib/semlogr/formatters/json_formatter.rb
|
133
181
|
- lib/semlogr/formatters/property_value_formatter.rb
|
@@ -137,17 +185,23 @@ files:
|
|
137
185
|
- lib/semlogr/logger_configuration.rb
|
138
186
|
- lib/semlogr/null_logger.rb
|
139
187
|
- lib/semlogr/properties/output_properties.rb
|
188
|
+
- lib/semlogr/sinks/aggregate.rb
|
140
189
|
- lib/semlogr/sinks/colored_console.rb
|
141
190
|
- lib/semlogr/sinks/console.rb
|
142
191
|
- lib/semlogr/sinks/file.rb
|
192
|
+
- lib/semlogr/sinks/filtering.rb
|
143
193
|
- lib/semlogr/templates/parser.rb
|
144
194
|
- lib/semlogr/templates/property_token.rb
|
145
195
|
- lib/semlogr/templates/template.rb
|
146
196
|
- lib/semlogr/templates/template_cache.rb
|
147
197
|
- lib/semlogr/templates/text_token.rb
|
148
198
|
- lib/semlogr/version.rb
|
149
|
-
- output.html
|
150
199
|
- samples/basic.rb
|
200
|
+
- samples/context.rb
|
201
|
+
- samples/enrichment.rb
|
202
|
+
- samples/filtering.rb
|
203
|
+
- samples/log_context.rb
|
204
|
+
- samples/sinks.rb
|
151
205
|
- semlogr.gemspec
|
152
206
|
homepage: https://github.com/semlogr/semlogr
|
153
207
|
licenses:
|
@@ -169,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
223
|
version: '0'
|
170
224
|
requirements: []
|
171
225
|
rubyforge_project:
|
172
|
-
rubygems_version: 2.
|
226
|
+
rubygems_version: 2.6.13
|
173
227
|
signing_key:
|
174
228
|
specification_version: 4
|
175
229
|
summary: Semantic logging for Ruby
|
data/output.html
DELETED
File without changes
|