evt-log 0.4.3.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c11a1528df9207238249d28f1152436f4f5fd60
4
+ data.tar.gz: 288278d234c160badf9540e0a29a3c840568eb5e
5
+ SHA512:
6
+ metadata.gz: 62061cf117b80057c70d343c4852b01c92debef5fbb7bb5b99f070b3868ad881992a44988871f53b0418732fe34bd5d8ee8fd02b98f9dd594054ccd19dc1dd65
7
+ data.tar.gz: a43679c9bd21e02f8aa887e85ff2a2efa621c61ff0292e2836565f9ea0ac6ee1b95ce1adbf6e83241eab21483f4aa6d317f96953d0f3dac9ae0c20440e2aa5e6
@@ -0,0 +1,26 @@
1
+ require 'English'
2
+
3
+ require 'rainbow'; Rainbow.enabled = true
4
+
5
+ require 'initializer'; Initializer.activate
6
+ require 'dependency'; Dependency.activate
7
+ require 'telemetry'
8
+ require 'clock'
9
+
10
+ class Log
11
+ end
12
+
13
+ require 'log/subject_name'
14
+ require 'log/registry'
15
+ require 'log/level'
16
+ require 'log/levels'
17
+ require 'log/tags'
18
+ require 'log/filter'
19
+ require 'log/telemetry'
20
+ require 'log/substitute'
21
+ require 'log/write'
22
+ require 'log/format'
23
+ require 'log/format/color'
24
+ require 'log/defaults'
25
+ require 'log/log'
26
+
@@ -0,0 +1,5 @@
1
+ require 'clock/controls'
2
+
3
+ require 'log/controls/time'
4
+ require 'log/controls/log'
5
+ require 'log/controls/subject'
@@ -0,0 +1,67 @@
1
+ module Log::Controls
2
+ module Log
3
+ def self.example
4
+ example = ::Log::Substitute::Log.new(::Log::Substitute.subject)
5
+
6
+ sink = ::Log.register_telemetry_sink(example)
7
+ example.telemetry_sink = sink
8
+
9
+ example
10
+ end
11
+
12
+ module Levels
13
+ def self.example
14
+ logger = Log.example
15
+ logger.add_level(higher)
16
+ logger.add_level(middle)
17
+ logger.add_level(lower)
18
+ logger
19
+ end
20
+
21
+ def self.higher
22
+ :higher
23
+ end
24
+
25
+ def self.middle
26
+ :middle
27
+ end
28
+
29
+ def self.lower
30
+ :lower
31
+ end
32
+ end
33
+
34
+ module Operational
35
+ def self.example
36
+ ::Log.build(subject)
37
+ end
38
+
39
+ def self.subject
40
+ 'some subject'
41
+ end
42
+ end
43
+
44
+ module Specialized
45
+ def self.example
46
+ example = Example.build('Specialized Logger')
47
+
48
+ sink = ::Log.register_telemetry_sink(example)
49
+ example.telemetry_sink = sink
50
+
51
+ example.device = ::Log::Substitute::Log::NullDevice
52
+
53
+ example.tags = :some_additional_tag
54
+
55
+ example
56
+ end
57
+
58
+ class Example < ::Log
59
+ attr_accessor :telemetry_sink
60
+
61
+ def tag!(tags)
62
+ tags << :some_additional_tag
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,27 @@
1
+ module Log::Controls
2
+ module Subject
3
+ def self.example
4
+ Example.new
5
+ end
6
+
7
+ def self.new
8
+ example
9
+ end
10
+
11
+ module Operational
12
+ def self.example
13
+ Subject::Example.build
14
+ end
15
+ end
16
+
17
+ class Example
18
+ dependency :logger, ::Log
19
+
20
+ def self.build
21
+ instance = new
22
+ ::Log.configure(instance)
23
+ instance
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module Log::Controls
2
+ Time = Clock::Controls::Time
3
+ end
@@ -0,0 +1,67 @@
1
+ module Log::Defaults
2
+ def self.level
3
+ env_level = ENV['LOG_LEVEL']
4
+ return env_level.to_sym if !env_level.nil?
5
+
6
+ :info
7
+ end
8
+
9
+ def self.tags
10
+ env_tags = ENV['LOG_TAGS']
11
+
12
+ return [] if env_tags.nil?
13
+
14
+ tags = env_tags.split(',')
15
+
16
+ tags.map { |tag| tag.to_sym }
17
+ end
18
+
19
+ def self.device
20
+ env_device = ENV['CONSOLE_DEVICE']
21
+
22
+ device = nil
23
+
24
+ if !env_device.nil?
25
+ if !['stderr', 'stdout'].include?(env_device)
26
+ raise "The CONSOLE_DEVICE should be either 'stderr' (default) or 'stdout'"
27
+ else
28
+ device = (env_device == 'stderr' ? STDERR : STDOUT)
29
+ end
30
+ else
31
+ device = STDERR
32
+ end
33
+
34
+ device
35
+ end
36
+
37
+ def self.formatters
38
+ env_formatters = ENV['LOG_FORMATTERS']
39
+
40
+ if env_formatters.nil?
41
+ env_formatters = :on
42
+ end
43
+
44
+ env_formatters.to_sym
45
+ end
46
+
47
+ def self.levels
48
+ [
49
+ :fatal,
50
+ :error,
51
+ :warn,
52
+ :info,
53
+ :debug,
54
+ :trace
55
+ ]
56
+ end
57
+
58
+ def self.level_formatters
59
+ {
60
+ error: proc { |message| Rainbow(message).bright.white.bg(:red) },
61
+ fatal: proc { |message| Rainbow(message).red.bg(:black) },
62
+ warn: proc { |message| Rainbow(message).yellow.bg(:black) },
63
+ debug: proc { |message| Rainbow(message).green },
64
+ trace: proc { |message| Rainbow(message).cyan }
65
+ }
66
+ end
67
+ end
@@ -0,0 +1,58 @@
1
+ module Log::Filter
2
+ def write_level?(message_level)
3
+ if message_level.nil? && !logger_level?
4
+ return true
5
+ end
6
+
7
+ if message_level.nil? || !logger_level?
8
+ return false
9
+ end
10
+
11
+ precedent?(message_level)
12
+ end
13
+
14
+ def precedent?(message_level)
15
+ ordinal(message_level) <= logger_ordinal
16
+ end
17
+
18
+ def write_tag?(message_tags)
19
+ message_tags ||= []
20
+
21
+ if message_tags.empty? && !logger_tags?
22
+ return true
23
+ end
24
+
25
+ if log_all_tags?
26
+ return true
27
+ end
28
+
29
+ if message_tags.empty? && log_untagged?
30
+ return true
31
+ end
32
+
33
+ if !message_tags.empty? && logger_tags?
34
+ if logger_tags_intersect?(message_tags)
35
+ return true
36
+ end
37
+ end
38
+
39
+ false
40
+ end
41
+
42
+ def log_all_tags?
43
+ logger_tag?(:_all)
44
+ end
45
+
46
+ def log_untagged?
47
+ logger_tag?(:_untagged)
48
+ end
49
+
50
+ def tags_intersect?(message_tags)
51
+ if !(message_tags & logger_excluded_tags).empty?
52
+ return false
53
+ end
54
+
55
+ !(logger_included_tags & message_tags).empty?
56
+ end
57
+ alias :logger_tags_intersect? :tags_intersect?
58
+ end
@@ -0,0 +1,29 @@
1
+ module Log::Format
2
+ def self.line(message, time, subject, level, &message_formatter)
3
+ "#{header(time, subject, level)} #{message(message, &message_formatter)}"
4
+ end
5
+
6
+ def self.message(message, &message_formatter)
7
+ return message unless block_given?
8
+ if Log::Defaults.formatters == :on
9
+ return message_formatter.(message)
10
+ else
11
+ return message
12
+ end
13
+ end
14
+
15
+ def self.header(time, subject, level)
16
+ header = "[#{time}] #{subject}"
17
+ unless level.nil?
18
+ header << " #{level.to_s.upcase}"
19
+ end
20
+ header << ':'
21
+ Color.header(header)
22
+ end
23
+
24
+ module Defaults
25
+ def self.message_formatter
26
+ proc {|message| message }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ module Log::Format::Color
2
+ def self.header(text)
3
+ Rainbow(text).white
4
+ end
5
+ end
@@ -0,0 +1,116 @@
1
+ module Log::Level
2
+ LevelInfo = Struct.new(:name, :ordinal, :message_formatter)
3
+
4
+ def level
5
+ @level
6
+ end
7
+ alias :logger_level :level
8
+
9
+ def level=(level)
10
+ if [:_min, :_max].include?(level)
11
+ if level == :_min
12
+ level = min_level
13
+ else
14
+ level = max_level
15
+ end
16
+ end
17
+
18
+ assure_level(level)
19
+ @level = level
20
+ end
21
+ alias :logger_level= :level=
22
+
23
+ def level?(level=nil)
24
+ if level.nil?
25
+ !logger_level.nil?
26
+ else
27
+ levels.has_key?(level)
28
+ end
29
+ end
30
+ alias :logger_level? :level?
31
+
32
+ def add_level(level, &message_formatter)
33
+ return nil if logger_level?(level)
34
+
35
+ Method.define(self, level)
36
+
37
+ message_formatter = Log::Format::Defaults.message_formatter unless block_given?
38
+
39
+ levels[level] = LevelInfo.new(level, levels.length, message_formatter)
40
+ end
41
+
42
+ def remove_level(level)
43
+ return nil unless logger_level?(level)
44
+ Method.remove(self, level)
45
+ levels.delete(level)
46
+ end
47
+
48
+ def assure_level(level)
49
+ if level.nil?
50
+ return
51
+ end
52
+
53
+ unless level == :_none
54
+ if !levels?
55
+ raise Log::Error, "Level #{level.inspect} cannot be set. The logger has no levels."
56
+ end
57
+
58
+ if !level?(level)
59
+ raise Log::Error, "Level #{level.inspect} must be one of: #{levels.keys.join(', ')}"
60
+ end
61
+ end
62
+ end
63
+
64
+ def ordinal(level=nil)
65
+ level ||= logger_level
66
+
67
+ if level == :_none
68
+ return -1
69
+ end
70
+
71
+ level = levels[level]
72
+ return no_ordinal if level.nil?
73
+ level.ordinal
74
+ end
75
+
76
+ def logger_ordinal
77
+ ordinal
78
+ end
79
+
80
+ def no_ordinal
81
+ -1
82
+ end
83
+
84
+ def max_level
85
+ logger_levels.keys.last
86
+ end
87
+
88
+ def min_level
89
+ logger_levels.keys.first
90
+ end
91
+
92
+ def max_level!
93
+ self.logger_level = max_level
94
+ end
95
+
96
+ def min_level!
97
+ self.logger_level = min_level
98
+ end
99
+
100
+ def no_level!
101
+ self.logger_level = nil
102
+ end
103
+
104
+ module Method
105
+ def self.define(logger, level_name)
106
+ level = level_name
107
+ logger.define_singleton_method(level) do |message=nil, tag: nil, tags: nil, &blk|
108
+ self.(message, level, tag: tag, tags: tags, &blk)
109
+ end
110
+ end
111
+
112
+ def self.remove(logger, level_name)
113
+ logger.instance_eval "undef #{level_name}"
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,27 @@
1
+ module Log::Levels
2
+ def self.included(cls)
3
+ cls.extend AddLevels
4
+ end
5
+
6
+ def levels
7
+ @levels ||= {}
8
+ end
9
+ alias :logger_levels :levels
10
+
11
+ def levels?
12
+ !levels.empty?
13
+ end
14
+ alias :logger_levels? :levels?
15
+
16
+ def level_names
17
+ levels.keys.dup
18
+ end
19
+
20
+ module AddLevels
21
+ def add_levels(logger)
22
+ Log::Defaults.levels.each do |level|
23
+ logger.add_level(level, &Log::Defaults.level_formatters[level])
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,111 @@
1
+ class Log
2
+ class Error < RuntimeError; end
3
+
4
+ extend Registry
5
+ include Levels
6
+ include Level
7
+ include Tags
8
+ include Filter
9
+ include Write
10
+ extend SubjectName
11
+ extend Telemetry::Register
12
+
13
+ def self.inherited(cls)
14
+ cls.class_exec do
15
+ dependency_module = Module.new do
16
+ define_singleton_method :included do |reciever_class|
17
+ reciever_class.class_exec do
18
+ dependency :logger, cls
19
+
20
+ define_method :logger do
21
+ @logger ||= cls.configure self
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ const_set :Dependency, dependency_module
28
+ end
29
+ end
30
+
31
+ self.inherited(self)
32
+
33
+ dependency :clock, Clock::UTC
34
+
35
+ initializer :subject
36
+
37
+ attr_writer :device
38
+
39
+ def device
40
+ @device ||= Defaults.device
41
+ end
42
+
43
+ def telemetry
44
+ @telemetry ||= ::Telemetry.build
45
+ end
46
+
47
+ def self.build(subject)
48
+ subject = subject_name(subject)
49
+ instance = new(subject)
50
+ Clock::UTC.configure(instance)
51
+ set_defaults(instance)
52
+ instance
53
+ end
54
+
55
+ def self.no_defaults(subject)
56
+ instance = new(subject)
57
+ Clock::UTC.configure(instance)
58
+ instance
59
+ end
60
+
61
+ def self.bare(subject)
62
+ no_defaults(subject)
63
+ end
64
+
65
+ def self.configure(receiver, attr_name: nil)
66
+ attr_name ||= :logger
67
+ instance = get(receiver)
68
+ receiver.public_send("#{attr_name}=", instance)
69
+ instance
70
+ end
71
+
72
+ def call(message=nil, level=nil, tag: nil, tags: nil, &blk)
73
+ tag = Array(tag)
74
+ tags = Array(tags)
75
+ tags = tags + tag
76
+
77
+ assure_level(level)
78
+
79
+ tag!(tags)
80
+
81
+ if write?(level, tags)
82
+ if block_given?
83
+ message = blk.call
84
+ end
85
+ raise ArgumentError, "Log message not provided" if message.nil?
86
+
87
+ write(message, level, tags)
88
+ end
89
+ end
90
+
91
+ def tag!(tags)
92
+ tags
93
+ end
94
+
95
+ def write?(message_level, message_tags)
96
+ write_level?(message_level) && write_tag?(message_tags)
97
+ end
98
+
99
+ def clear
100
+ level_names.each do |level_name|
101
+ remove_level(level_name)
102
+ end
103
+ self.level = nil
104
+ end
105
+
106
+ def self.set_defaults(logger)
107
+ logger.class.add_levels(logger)
108
+ logger.level = Defaults.level
109
+ logger.tags = Defaults.tags
110
+ end
111
+ end
@@ -0,0 +1,22 @@
1
+ module Log::Registry
2
+ def get(subject)
3
+ register(subject)
4
+ end
5
+
6
+ def register(subject)
7
+ subject_name = subject_name(subject)
8
+
9
+ instance = registry[subject_name]
10
+
11
+ if instance.nil?
12
+ instance = build(subject)
13
+ registry[subject_name] = instance
14
+ end
15
+
16
+ instance
17
+ end
18
+
19
+ def registry
20
+ @registry ||= {}
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module Log::SubjectName
2
+ def subject_name(subject)
3
+ if subject.is_a?(Class) || subject.is_a?(Module)
4
+ name = subject.name
5
+ elsif subject.is_a? String
6
+ name = subject
7
+ elsif subject.is_a? Symbol
8
+ name = subject.to_s
9
+ else
10
+ name = subject.class.name
11
+ end
12
+ name
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module Log::Substitute
2
+ def self.build
3
+ instance = Log.build(subject)
4
+ sink = Log.register_telemetry_sink(instance)
5
+ instance.telemetry_sink = sink
6
+ instance
7
+ end
8
+
9
+ def self.subject
10
+ '(substitute logger)'
11
+ end
12
+
13
+ class Log < ::Log
14
+ attr_accessor :telemetry_sink
15
+
16
+ def clock
17
+ @clock ||= Clock::UTC::Substitute.build
18
+ end
19
+
20
+ def device
21
+ @device ||= NullDevice
22
+ end
23
+
24
+ class NullDevice
25
+ def self.write(*)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,49 @@
1
+ module Log::Tags
2
+ def tags
3
+ @tags ||= []
4
+ end
5
+ alias :logger_tags :tags
6
+
7
+ def included_tags
8
+ @included_tags ||= []
9
+ end
10
+ alias :logger_included_tags :included_tags
11
+
12
+ def excluded_tags
13
+ @excluded_tags ||= []
14
+ end
15
+ alias :logger_excluded_tags :excluded_tags
16
+
17
+ def tags=(tags)
18
+ if tags.nil?
19
+ @tags = nil
20
+ return
21
+ end
22
+
23
+ tags = Array(tags)
24
+
25
+ tags.each do |tag|
26
+ unless tag.to_s.start_with?('-')
27
+ included_tags << tag
28
+ else
29
+ excluded_tags << tag[1..-1].to_sym
30
+ end
31
+ end
32
+
33
+ @tags = tags
34
+ end
35
+
36
+ def tag=(tag)
37
+ self.tags = tag
38
+ end
39
+
40
+ def tags?
41
+ !tags.empty?
42
+ end
43
+ alias :logger_tags? :tags?
44
+
45
+ def tag?(tag)
46
+ tags.include?(tag)
47
+ end
48
+ alias :logger_tag? :tag?
49
+ end
@@ -0,0 +1,21 @@
1
+ module Log::Telemetry
2
+ class Sink
3
+ include ::Telemetry::Sink
4
+
5
+ record :logged
6
+ end
7
+
8
+ Data = Struct.new :subject_name, :message, :level, :tags, :line
9
+
10
+ def self.sink
11
+ Sink.new
12
+ end
13
+
14
+ module Register
15
+ def register_telemetry_sink(logger)
16
+ sink = Log::Telemetry.sink
17
+ logger.telemetry.register sink
18
+ sink
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module Log::Write
2
+ def write(message, level, tags)
3
+ message = message.to_s
4
+
5
+ if message.length == 0
6
+ message = '(empty log message)'
7
+ end
8
+
9
+ line = Log::Format.line(message, clock.iso8601(precision: 5), subject, level, &levels[level] &.message_formatter)
10
+
11
+ device.write "#{line}#{$INPUT_RECORD_SEPARATOR}"
12
+
13
+ telemetry.record :logged, Log::Telemetry::Data.new(subject, message, level, tags, line)
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evt-log
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.3.2
5
+ platform: ruby
6
+ authors:
7
+ - The Eventide Project
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-12-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: evt-initializer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: evt-dependency
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: evt-telemetry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: evt-clock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rainbow
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: ntl-test_bench
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: " "
98
+ email: opensource@eventide-project.org
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - lib/log.rb
104
+ - lib/log/controls.rb
105
+ - lib/log/controls/log.rb
106
+ - lib/log/controls/subject.rb
107
+ - lib/log/controls/time.rb
108
+ - lib/log/defaults.rb
109
+ - lib/log/filter.rb
110
+ - lib/log/format.rb
111
+ - lib/log/format/color.rb
112
+ - lib/log/level.rb
113
+ - lib/log/levels.rb
114
+ - lib/log/log.rb
115
+ - lib/log/registry.rb
116
+ - lib/log/subject_name.rb
117
+ - lib/log/substitute.rb
118
+ - lib/log/tags.rb
119
+ - lib/log/telemetry.rb
120
+ - lib/log/write.rb
121
+ homepage: https://github.com/eventide-project/log
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: 2.3.3
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.5.2
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Logging to STD IO with levels, tagging, and coloring
145
+ test_files: []