evt-log 0.4.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []