betterlog 0.1.0 → 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.
@@ -3,21 +3,16 @@
3
3
  # thread-global, this will also attempt to update context of error reporting
4
4
  # tools etc.
5
5
 
6
- class GlobalMetadata
7
- include Tins::SexySingleton
6
+ module Betterlog
7
+ class GlobalMetadata
8
+ include Tins::SexySingleton
8
9
 
9
- def data
10
- Thread.current['BP_GLOBAL_METATDATA'] || {}
11
- end
12
-
13
- def add(data_hash)
14
- data = data_hash | data
15
- Honeybadger.context(data_hash)
16
- end
17
-
18
- private
10
+ thread_local(:data) { {} }
19
11
 
20
- def data=(value)
21
- Thread.current['BP_GLOBAL_METATDATA'] = value
12
+ def add(data_hash)
13
+ data = data_hash | data
14
+ Notifiers.context(data_hash)
15
+ self
16
+ end
22
17
  end
23
18
  end
@@ -1,163 +1,165 @@
1
- class Log
2
- class Event
3
- require 'socket'
4
-
5
- def self.ify(arg, severity: :debug, notify: nil, rest: {})
6
- notify ||= rest.delete(:notify)
7
- if e = arg.ask_and_send(:exception)
8
- ify(
9
- {
10
- error_class: e.class.name,
11
- message: "#{e.class.name}: #{e.message}",
12
- backtrace: e.backtrace,
13
- },
14
- severity: severity,
15
- rest: rest,
16
- notify: notify,
17
- )
18
- elsif s = arg.ask_and_send(:to_str)
19
- new(
20
- ({ notify: s } if notify).to_h |
21
- {
22
- message: s,
1
+ module Betterlog
2
+ class Log
3
+ class Event
4
+ require 'socket'
5
+
6
+ def self.ify(arg, severity: :debug, notify: nil, rest: {})
7
+ notify ||= rest.delete(:notify)
8
+ if e = arg.ask_and_send(:exception)
9
+ ify(
10
+ {
11
+ error_class: e.class.name,
12
+ message: "#{e.class.name}: #{e.message}",
13
+ backtrace: e.backtrace,
14
+ },
23
15
  severity: severity,
24
- } | rest
25
- )
26
- elsif h = arg.ask_and_send(:to_hash)
27
- arg = h | { severity: severity } | rest
28
- new(
29
- ({ notify: h[:message] || arg.to_s } if notify).to_h |
30
- arg
31
- )
32
- else
33
- message = "Logging #{arg.inspect}"
34
- new(
35
- ({ notify: message } if notify).to_h |
36
- {
37
- message: message,
38
- severity: severity,
39
- } | rest
40
- )
16
+ rest: rest,
17
+ notify: notify,
18
+ )
19
+ elsif s = arg.ask_and_send(:to_str)
20
+ new(
21
+ ({ notify: s } if notify).to_h |
22
+ {
23
+ message: s,
24
+ severity: severity,
25
+ } | rest
26
+ )
27
+ elsif h = arg.ask_and_send(:to_hash)
28
+ arg = h | { severity: severity } | rest
29
+ new(
30
+ ({ notify: h[:message] || arg.to_s } if notify).to_h |
31
+ arg
32
+ )
33
+ else
34
+ message = "Logging #{arg.inspect}"
35
+ new(
36
+ ({ notify: message } if notify).to_h |
37
+ {
38
+ message: message,
39
+ severity: severity,
40
+ } | rest
41
+ )
42
+ end
41
43
  end
42
- end
43
-
44
- def self.parse(json)
45
- new(JSON.parse(json))
46
- rescue JSON::ParserError
47
- end
48
44
 
49
- def self.is?(json)
50
- if json = json.ask_and_send(:to_str)
51
- data = JSON.parse(json).ask_and_send(:to_hash)
52
- data&.key?('emitter')
45
+ def self.parse(json)
46
+ new(JSON.parse(json))
47
+ rescue JSON::ParserError
53
48
  end
54
- rescue JSON::ParserError
55
- false
56
- end
57
49
 
58
- def initialize(data = {})
59
- data = data.symbolize_keys_recursive | meta
60
- unless data.key?(:message)
61
- data[:message] = "a #{data[:type]} type log message of severity #{data[:severity]}"
62
- end
63
- data[:severity] =
64
- begin
65
- Severity.new((data[:severity] || :debug))
66
- rescue
67
- Severity.new(:debug)
50
+ def self.is?(json)
51
+ if json = json.ask_and_send(:to_str)
52
+ data = JSON.parse(json).ask_and_send(:to_hash)
53
+ data&.key?('emitter')
68
54
  end
69
- @data = Hash[data.sort_by(&:first)]
70
- end
55
+ rescue JSON::ParserError
56
+ false
57
+ end
71
58
 
72
- class BreakCircles
73
- def initialize
74
- @seen = {}
59
+ def initialize(data = {})
60
+ data = data.symbolize_keys_recursive | meta
61
+ unless data.key?(:message)
62
+ data[:message] = "a #{data[:type]} type log message of severity #{data[:severity]}"
63
+ end
64
+ data[:severity] =
65
+ begin
66
+ Severity.new((data[:severity] || :debug))
67
+ rescue
68
+ Severity.new(:debug)
69
+ end
70
+ @data = Hash[data.sort_by(&:first)]
75
71
  end
76
72
 
77
- IN_JSON = Tins::ModuleGroup[
78
- Float, Integer, NilClass, FalseClass, TrueClass
79
- ]
73
+ class BreakCircles
74
+ def initialize
75
+ @seen = {}
76
+ end
80
77
 
81
- def perform(object)
82
- if @seen.key?(object.__id__)
83
- :circular
84
- else
85
- @seen[object.__id__] = true
86
- case
87
- when h = object.ask_and_send(:to_hash)
88
- h.each_with_object({}) { |(k, v), h| h[k.to_s.to_sym] = perform(v) }
89
- when a = object.ask_and_send(:to_ary)
90
- a.map { |o| perform(o) }
91
- when IN_JSON === object
92
- object
78
+ IN_JSON = Tins::ModuleGroup[
79
+ Float, Integer, NilClass, FalseClass, TrueClass
80
+ ]
81
+
82
+ def perform(object)
83
+ if @seen.key?(object.__id__)
84
+ :circular
93
85
  else
94
- object.to_s
86
+ @seen[object.__id__] = true
87
+ case
88
+ when h = object.ask_and_send(:to_hash)
89
+ h.each_with_object({}) { |(k, v), h| h[k.to_s.to_sym] = perform(v) }
90
+ when a = object.ask_and_send(:to_ary)
91
+ a.map { |o| perform(o) }
92
+ when IN_JSON === object
93
+ object
94
+ else
95
+ object.to_s
96
+ end
95
97
  end
96
98
  end
97
99
  end
98
- end
99
100
 
100
- def as_hash(*a)
101
- BreakCircles.new.perform(@data)
102
- end
101
+ def as_hash(*a)
102
+ BreakCircles.new.perform(@data)
103
+ end
103
104
 
104
- def to_json(*a)
105
- as_hash.to_json(*a)
106
- end
105
+ def to_json(*a)
106
+ as_hash.to_json(*a)
107
+ end
107
108
 
108
- def format(*args)
109
- Log::EventFormatter.new(self).format(*args)
110
- end
109
+ def format(*args)
110
+ Log::EventFormatter.new(self).format(*args)
111
+ end
111
112
 
112
- alias to_s format
113
+ alias to_s format
113
114
 
114
- def []=(name, value)
115
- @data[name.to_sym] = value
116
- end
115
+ def []=(name, value)
116
+ @data[name.to_sym] = value
117
+ end
117
118
 
118
- def [](name)
119
- @data[name.to_sym]
120
- end
119
+ def [](name)
120
+ @data[name.to_sym]
121
+ end
121
122
 
122
- def severity
123
- @data[:severity]
124
- end
123
+ def severity
124
+ @data[:severity]
125
+ end
125
126
 
126
- def emitter
127
- @data[:emitter]
128
- end
127
+ def emitter
128
+ @data[:emitter]
129
+ end
129
130
 
130
- def notify?
131
- @data[:notify]
132
- end
131
+ def notify?
132
+ @data[:notify]
133
+ end
133
134
 
134
- def eql?(other)
135
- @data.eql? other.instance_variable_get(:@data)
136
- end
135
+ def eql?(other)
136
+ @data.eql? other.instance_variable_get(:@data)
137
+ end
137
138
 
138
- alias == eql?
139
+ alias == eql?
139
140
 
140
- def hash
141
- @data.hash
142
- end
141
+ def hash
142
+ @data.hash
143
+ end
143
144
 
144
- private
145
-
146
- def meta
147
- m = {
148
- timestamp: Time.now.utc.iso8601(3),
149
- pid: $$,
150
- program: File.basename($0),
151
- severity: :debug,
152
- type: 'rails',
153
- facility: 'local0',
154
- host: (Socket.gethostname rescue nil),
155
- thread_id: Thread.current.object_id
156
- }
157
- if defined? GlobalMetadata
158
- m |= GlobalMetadata.data
159
- end
160
- m
145
+ private
146
+
147
+ def meta
148
+ m = {
149
+ timestamp: Time.now.utc.iso8601(3),
150
+ pid: $$,
151
+ program: File.basename($0),
152
+ severity: :debug,
153
+ type: 'rails',
154
+ facility: 'local0',
155
+ host: (Socket.gethostname rescue nil),
156
+ thread_id: Thread.current.object_id
157
+ }
158
+ if defined? GlobalMetadata
159
+ m |= GlobalMetadata.data
160
+ end
161
+ m
162
+ end
161
163
  end
162
164
  end
163
165
  end
@@ -1,116 +1,118 @@
1
- class Log
2
- class EventFormatter
3
- include Term::ANSIColor
1
+ module Betterlog
2
+ class Log
3
+ class EventFormatter
4
+ include Term::ANSIColor
4
5
 
5
- def initialize(event)
6
- @event = event
7
- end
6
+ def initialize(event)
7
+ @event = event
8
+ end
8
9
 
9
- def format(pretty: false, color: false, format: :default)
10
- old_coloring, Term::ANSIColor.coloring = Term::ANSIColor.coloring?, color
11
- f = cc.log.formats[format] and format = f
12
- case pretty
13
- when :format
14
- format_pattern(format: format)
15
- else
16
- @event.to_json
10
+ def format(pretty: false, color: false, format: :default)
11
+ old_coloring, Term::ANSIColor.coloring = Term::ANSIColor.coloring?, color
12
+ f = cc.log.formats[format] and format = f
13
+ case pretty
14
+ when :format
15
+ format_pattern(format: format)
16
+ else
17
+ @event.to_json
18
+ end
19
+ ensure
20
+ Term::ANSIColor.coloring = old_coloring
17
21
  end
18
- ensure
19
- Term::ANSIColor.coloring = old_coloring
20
- end
21
22
 
22
- private
23
+ private
23
24
 
24
- def colorize(key, value, string = key)
25
- case style = cc.log.styles[key]
26
- when nil, String, Array
27
- apply_style(style, string)
28
- when ComplexConfig::Settings
29
- apply_style(style[value], string)
25
+ def colorize(key, value, string = key)
26
+ case style = cc.log.styles[key]
27
+ when nil, String, Array
28
+ apply_style(style, string)
29
+ when ComplexConfig::Settings
30
+ apply_style(style[value], string)
31
+ end
30
32
  end
31
- end
32
33
 
33
- def apply_style(style, string)
34
- style.nil? and return string + Term::ANSIColor.reset
35
- string = Term::ANSIColor.uncolor(string)
36
- if style.respond_to?(:each)
37
- style.
38
- each.
39
- map { |s| -> v { __send__(:color, s, v) } }.
40
- inject(string) { |v, s| s.(v) }
41
- else
42
- __send__(:color, style, string)
34
+ def apply_style(style, string)
35
+ style.nil? and return string + Term::ANSIColor.reset
36
+ string = Term::ANSIColor.uncolor(string)
37
+ if style.respond_to?(:each)
38
+ style.
39
+ each.
40
+ map { |s| -> v { __send__(:color, s, v) } }.
41
+ inject(string) { |v, s| s.(v) }
42
+ else
43
+ __send__(:color, style, string)
44
+ end
43
45
  end
44
- end
45
46
 
46
- def format_pattern(format:)
47
- format.
48
- gsub('\n', "\n").
49
- gsub('\t', "\t").
50
- gsub(/\{(-)?(%[^%]+%)?([^}]+)\}/) {
51
- invisible = $1.full?
52
- directive = $2
53
- key = $3
54
- if value = @event[key]
55
- formatted_value =
56
- if directive
57
- case directive
58
- when /\A%O%/
59
- format_object(value)
60
- when /\A%([ulif])?t%/
61
- flag = $1
62
- t = case
63
- when v = value.ask_and_send(:to_str)
64
- Time.parse(v)
65
- when v = value.ask_and_send(:to_time)
66
- v
67
- else
68
- Time.at(0)
69
- end
70
- case flag
71
- when ?u then t.utc.iso8601(3)
72
- when ?l then t.localtime.iso8601(3)
73
- when ?i then t.to_i.to_s
74
- when ?f then t.to_f.to_s
75
- else t.utc.iso8601(3)
47
+ def format_pattern(format:)
48
+ format.
49
+ gsub('\n', "\n").
50
+ gsub('\t', "\t").
51
+ gsub(/\{(-)?(%[^%]+%)?([^}]+)\}/) {
52
+ invisible = $1.full?
53
+ directive = $2
54
+ key = $3
55
+ if value = @event[key]
56
+ formatted_value =
57
+ if directive
58
+ case directive
59
+ when /\A%O%/
60
+ format_object(value)
61
+ when /\A%([ulif])?t%/
62
+ flag = $1
63
+ t = case
64
+ when v = value.ask_and_send(:to_str)
65
+ Time.parse(v)
66
+ when v = value.ask_and_send(:to_time)
67
+ v
68
+ else
69
+ Time.at(0)
70
+ end
71
+ case flag
72
+ when ?u then t.utc.iso8601(3)
73
+ when ?l then t.localtime.iso8601(3)
74
+ when ?i then t.to_i.to_s
75
+ when ?f then t.to_f.to_s
76
+ else t.utc.iso8601(3)
77
+ end
78
+ else
79
+ begin
80
+ directive[0..-2] % value
81
+ rescue ArgumentError
82
+ value.to_s
83
+ end
76
84
  end
77
85
  else
78
- begin
79
- directive[0..-2] % value
80
- rescue ArgumentError
81
- value.to_s
82
- end
86
+ value.to_s
83
87
  end
84
- else
85
- value.to_s
88
+ colorize(key, value, formatted_value)
89
+ else
90
+ unless invisible
91
+ "{#{key}}"
86
92
  end
87
- colorize(key, value, formatted_value)
88
- else
89
- unless invisible
90
- "{#{key}}"
91
93
  end
92
- end
93
- }
94
- end
94
+ }
95
+ end
95
96
 
96
- def format_object(object, depth: 0, nl: ?\n)
97
- case
98
- when a = object.ask_and_send(:to_ary)
99
- result = ''
100
- depth += 2
101
- for v in a
102
- result << "\n#{' ' * depth}- #{format_object(v, depth: depth)}"
103
- end
104
- result
105
- when h = object.ask_and_send(:to_hash)
106
- result = ''
107
- depth += 2
108
- for k, v in h
109
- result << "\n#{' ' * depth}#{k}: #{format_object(v, depth: depth)}"
97
+ def format_object(object, depth: 0, nl: ?\n)
98
+ case
99
+ when a = object.ask_and_send(:to_ary)
100
+ result = ''
101
+ depth += 2
102
+ for v in a
103
+ result << "\n#{' ' * depth}- #{format_object(v, depth: depth)}"
104
+ end
105
+ result
106
+ when h = object.ask_and_send(:to_hash)
107
+ result = ''
108
+ depth += 2
109
+ for k, v in h
110
+ result << "\n#{' ' * depth}#{k}: #{format_object(v, depth: depth)}"
111
+ end
112
+ result
113
+ else
114
+ object.to_s
110
115
  end
111
- result
112
- else
113
- object.to_s
114
116
  end
115
117
  end
116
118
  end
@@ -1,49 +1,51 @@
1
- class Log
2
- class Severity
3
- include Comparable
4
-
5
- def initialize(name)
6
- @name = name.to_s.downcase.to_sym
7
- begin
8
- @level = ActiveSupport::Logger::Severity.const_get(@name.upcase)
9
- rescue NameError
10
- @name = :UNKNOWN
11
- @level = ActiveSupport::Logger::Severity::UNKNOWN
1
+ module Betterlog
2
+ class Log
3
+ class Severity
4
+ include Comparable
5
+
6
+ def initialize(name)
7
+ @name = name.to_s.downcase.to_sym
8
+ begin
9
+ @level = Logger::Severity.const_get(@name.upcase)
10
+ rescue NameError
11
+ @name = :UNKNOWN
12
+ @level = Logger::Severity::UNKNOWN
13
+ end
12
14
  end
13
- end
14
15
 
15
- def self.all
16
- ActiveSupport::Logger::Severity.constants.map { |c| new(c) }
17
- end
16
+ def self.all
17
+ @all_constants ||= Logger::Severity.constants.map { |c| new(c) }
18
+ end
18
19
 
19
- def to_i
20
- @level
21
- end
20
+ def to_i
21
+ @level
22
+ end
22
23
 
23
- def to_s
24
- @name.to_s.upcase
25
- end
24
+ def to_s
25
+ @name.to_s.upcase
26
+ end
26
27
 
27
- def to_sym
28
- @name
29
- end
28
+ def to_sym
29
+ @name
30
+ end
30
31
 
31
- def as_json(*)
32
- to_sym
33
- end
32
+ def as_json(*)
33
+ to_sym
34
+ end
34
35
 
35
- def <=>(other)
36
- to_i <=> other.to_i
37
- end
36
+ def <=>(other)
37
+ to_i <=> other.to_i
38
+ end
38
39
 
39
- def eql?(other)
40
- to_sym == other.to_sym
41
- end
40
+ def eql?(other)
41
+ to_sym == other.to_sym
42
+ end
42
43
 
43
- alias == eql?
44
+ alias == eql?
44
45
 
45
- def hash
46
- @name.hash
46
+ def hash
47
+ @name.hash
48
+ end
47
49
  end
48
50
  end
49
51
  end