semlogr 0.1.3 → 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/.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
|