klogger-logger 1.0.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 +7 -0
- data/lib/klogger/colors.rb +26 -0
- data/lib/klogger/formatters/abstract.rb +15 -0
- data/lib/klogger/formatters/go.rb +49 -0
- data/lib/klogger/formatters/json.rb +24 -0
- data/lib/klogger/formatters/simple.rb +32 -0
- data/lib/klogger/json_highlighter.rb +61 -0
- data/lib/klogger/logger.rb +123 -0
- data/lib/klogger/version.rb +12 -0
- data/lib/klogger-logger.rb +3 -0
- data/lib/klogger.rb +11 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 721caa676f9ec6ff59d0faa7823f40b63c9ca1fbcde1ac017e19c0f809000574
|
4
|
+
data.tar.gz: '0686ea87fa8f6f86a79b599ed11009061608adcf2884069381fad7f4b6a69d4e'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 594e56869cb217f308d49e1d5ab5a6669b6c69cb617e64f853a357fd8a30b8d2fc88803157cf54bb7ee9e12641ab2264fab364d7e57f5814c712bbdeb8238805
|
7
|
+
data.tar.gz: 737f6c90d84067dbb1f6697f5f3c6466c83ebc5d1dd3054481b4397bf40737705b4a345d9901fb923768e28374615c0c428f113beb113d3d56785edcedd4de5c
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Klogger
|
4
|
+
module Colors
|
5
|
+
|
6
|
+
COLORS = {
|
7
|
+
info: 75,
|
8
|
+
warn: 220,
|
9
|
+
debug: 252,
|
10
|
+
error: 203,
|
11
|
+
fatal: 203,
|
12
|
+
white: 255,
|
13
|
+
gray: 243
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
def colorize(text, color)
|
19
|
+
color = COLORS[color]
|
20
|
+
"\e[38;5;#{color}m#{text}\e[0m"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'klogger/formatters/abstract'
|
4
|
+
require 'klogger/colors'
|
5
|
+
|
6
|
+
module Klogger
|
7
|
+
module Formatters
|
8
|
+
class Go < Abstract
|
9
|
+
|
10
|
+
EXCLUDE_FROM_TAGS = [:time, :severity, :message].freeze
|
11
|
+
|
12
|
+
# rubocop:disable Metrics/AbcSize
|
13
|
+
# rubocop:disable Metrics/MethodLength
|
14
|
+
def call(_severity, time, _progname, payload)
|
15
|
+
string = String.new
|
16
|
+
string << time.strftime('%Y-%m-%d %H:%M:%S %z')
|
17
|
+
string << ' '
|
18
|
+
string << colorize(payload[:severity].ljust(8, ' ').upcase, payload[:severity].to_sym)
|
19
|
+
if payload[:message]
|
20
|
+
string << colorize(payload[:message], :white)
|
21
|
+
string << ' '
|
22
|
+
end
|
23
|
+
payload.each do |key, value|
|
24
|
+
next if EXCLUDE_FROM_TAGS.include?(key)
|
25
|
+
|
26
|
+
string << colorize("#{key}=", :gray)
|
27
|
+
string << colorize(sanitize_value(value), :white)
|
28
|
+
string << ' '
|
29
|
+
end
|
30
|
+
string + "\n"
|
31
|
+
end
|
32
|
+
# rubocop:enable Metrics/AbcSize
|
33
|
+
# rubocop:enable Metrics/MethodLength
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def colorize(text, color)
|
38
|
+
return text unless @highlight
|
39
|
+
|
40
|
+
Colors.colorize(text, color)
|
41
|
+
end
|
42
|
+
|
43
|
+
def sanitize_value(value)
|
44
|
+
value.to_s.gsub("\n", '\\\\n')
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'klogger/formatters/abstract'
|
5
|
+
require 'klogger/json_highlighter'
|
6
|
+
|
7
|
+
module Klogger
|
8
|
+
module Formatters
|
9
|
+
class JSON < Abstract
|
10
|
+
|
11
|
+
def call(_severity, _time, _progname, payload)
|
12
|
+
json = payload.to_json
|
13
|
+
if @highlight
|
14
|
+
json.gsub!('","', '", "')
|
15
|
+
json.gsub!(/\A{/, '{ ')
|
16
|
+
json.gsub!(/\}\z/, ' }')
|
17
|
+
json = JSONHighlighter.highlight(json)
|
18
|
+
end
|
19
|
+
json + "\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'klogger/formatters/abstract'
|
4
|
+
|
5
|
+
module Klogger
|
6
|
+
module Formatters
|
7
|
+
class Simple < Abstract
|
8
|
+
|
9
|
+
def call(_severity, _time, _progname, payload)
|
10
|
+
string = String.new
|
11
|
+
payload.each do |key, value|
|
12
|
+
string << ' ' if string.length.positive?
|
13
|
+
string << "#{colorize(key.to_s + ':', payload[:severity].to_sym)} #{sanitize_value(value)}"
|
14
|
+
end
|
15
|
+
string + "\n"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def colorize(text, color)
|
21
|
+
return text unless @highlight
|
22
|
+
|
23
|
+
Colors.colorize(text, color)
|
24
|
+
end
|
25
|
+
|
26
|
+
def sanitize_value(value)
|
27
|
+
value.to_s.gsub("\n", '\\\\n')
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rouge'
|
4
|
+
|
5
|
+
# This class is responsible for receiving log data and sending it to an underlying
|
6
|
+
module Klogger
|
7
|
+
class JSONHighlighter
|
8
|
+
|
9
|
+
class Theme < Rouge::CSSTheme
|
10
|
+
|
11
|
+
style Text, fg: '#ffffff'
|
12
|
+
style Literal::String,
|
13
|
+
Literal::Number, fg: '#35AEFF'
|
14
|
+
style Punctuation, fg: '#888888'
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
class ErrorTheme < Theme
|
19
|
+
|
20
|
+
style Literal::String,
|
21
|
+
Literal::Number, fg: '#FF355D'
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
class WarnTheme < Theme
|
26
|
+
|
27
|
+
style Literal::String,
|
28
|
+
Literal::Number, fg: '#FFD700'
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
class DebugTheme < Theme
|
33
|
+
|
34
|
+
style Text, fg: '#999999'
|
35
|
+
style Literal::String,
|
36
|
+
Literal::Number, fg: '#cccccc'
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
LEXER = Rouge::Lexers::JSON.new
|
41
|
+
FORMATTER = Rouge::Formatters::Terminal256
|
42
|
+
FORMATTERS = {
|
43
|
+
info: FORMATTER.new(Theme.new),
|
44
|
+
debug: FORMATTER.new(DebugTheme.new),
|
45
|
+
warn: FORMATTER.new(WarnTheme.new),
|
46
|
+
error: FORMATTER.new(ErrorTheme.new),
|
47
|
+
fatal: FORMATTER.new(ErrorTheme.new)
|
48
|
+
}.freeze
|
49
|
+
|
50
|
+
class << self
|
51
|
+
|
52
|
+
def highlight(output)
|
53
|
+
severity = ::Regexp.last_match(1).to_sym if output.match(/"severity":"(\w+)"/)
|
54
|
+
formatter = FORMATTERS[severity] || FORMATTERS[:info]
|
55
|
+
formatter.format(LEXER.lex(output))
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'klogger/formatters/json'
|
5
|
+
require 'klogger/formatters/simple'
|
6
|
+
require 'klogger/formatters/go'
|
7
|
+
|
8
|
+
module Klogger
|
9
|
+
class Logger < ::Logger
|
10
|
+
|
11
|
+
attr_reader :name
|
12
|
+
attr_reader :destinations
|
13
|
+
attr_reader :extra
|
14
|
+
|
15
|
+
LEVELS = [:debug, :info, :warn, :error, :fatal].freeze
|
16
|
+
FORMATTERS = {
|
17
|
+
json: Formatters::JSON,
|
18
|
+
simple: Formatters::Simple,
|
19
|
+
go: Formatters::Go
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
def initialize(name, destination: $stdout, formatter: :json, highlight: false, extra: {})
|
23
|
+
@name = name
|
24
|
+
@extra = extra
|
25
|
+
@destinations = []
|
26
|
+
|
27
|
+
super(destination)
|
28
|
+
self.formatter = FORMATTERS[formatter].new(highlight: highlight)
|
29
|
+
end
|
30
|
+
|
31
|
+
def exception(exception, message = nil, **additional)
|
32
|
+
error({ message: message,
|
33
|
+
exception: exception.class.name,
|
34
|
+
exception_message: exception.message,
|
35
|
+
backtrace: exception.backtrace[0, 4].join("\n") }.merge(additional))
|
36
|
+
end
|
37
|
+
|
38
|
+
LEVELS.each do |level|
|
39
|
+
define_method(level) do |message = nil, progname = nil, **additional, &block|
|
40
|
+
add(Logger.const_get(level.to_s.upcase), message, progname, **additional, &block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def group(**additional)
|
45
|
+
groups << additional
|
46
|
+
yield
|
47
|
+
ensure
|
48
|
+
groups.pop
|
49
|
+
end
|
50
|
+
|
51
|
+
def silence!
|
52
|
+
@silence = true
|
53
|
+
yield if block_given?
|
54
|
+
ensure
|
55
|
+
unsilence! if block_given?
|
56
|
+
end
|
57
|
+
|
58
|
+
def unsilence!
|
59
|
+
@silence = false
|
60
|
+
yield if block_given?
|
61
|
+
ensure
|
62
|
+
silence! if block_given?
|
63
|
+
end
|
64
|
+
|
65
|
+
def silenced?
|
66
|
+
@silence == true
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_destination(destination)
|
70
|
+
@destinations << destination
|
71
|
+
end
|
72
|
+
|
73
|
+
def remove_destination(destination)
|
74
|
+
@destinations.delete(destination)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def groups
|
80
|
+
@groups ||= []
|
81
|
+
end
|
82
|
+
|
83
|
+
def add(severity, message = nil, progname = nil, **extra, &block)
|
84
|
+
return if silenced?
|
85
|
+
|
86
|
+
severity ||= Logger::UNKNOWN
|
87
|
+
return if severity < level
|
88
|
+
|
89
|
+
payload = create_payload(severity, message, extra)
|
90
|
+
|
91
|
+
@destinations.each do |destination|
|
92
|
+
destination.call(self, payload.dup)
|
93
|
+
rescue StandardError => e
|
94
|
+
# If something goes wrong in here, we don't want to break the application
|
95
|
+
# so we will rescue that and we'll just use standard warn.
|
96
|
+
Kernel.warn "Error while sending payload to destination (#{e.class}): #{e.message}"
|
97
|
+
end
|
98
|
+
|
99
|
+
super(severity, payload, progname, &block)
|
100
|
+
end
|
101
|
+
|
102
|
+
# rubocop:disable Metrics/AbcSize
|
103
|
+
def create_payload(severity, message, extra)
|
104
|
+
payload = { time: Time.now.to_s, severity: LEVELS[severity]&.to_s, logger: @name }
|
105
|
+
payload.merge!(@extra)
|
106
|
+
|
107
|
+
if message.is_a?(Hash)
|
108
|
+
payload.merge!(message)
|
109
|
+
elsif message
|
110
|
+
payload[:message] = message
|
111
|
+
end
|
112
|
+
|
113
|
+
payload.merge!(extra)
|
114
|
+
payload.delete(:message) if payload[:message].nil?
|
115
|
+
payload.compact!
|
116
|
+
|
117
|
+
groups.each { |group| payload.merge!(group) }
|
118
|
+
payload
|
119
|
+
end
|
120
|
+
# rubocop:enable Metrics/AbcSize
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Klogger
|
4
|
+
|
5
|
+
VERSION_FILE_ROOT = File.expand_path('../../VERSION', __dir__)
|
6
|
+
if File.file?(VERSION_FILE_ROOT)
|
7
|
+
VERSION = File.read(VERSION_FILE_ROOT).strip.sub(/\Av/, '')
|
8
|
+
else
|
9
|
+
VERSION = '0.0.0.dev'
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
data/lib/klogger.rb
ADDED
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: klogger-logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Cooke
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-03-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json
|
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: rouge
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.30'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '5.0'
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '3.30'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '5.0'
|
47
|
+
description: A simple Ruby logger
|
48
|
+
email:
|
49
|
+
- adam@krystal.uk
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- lib/klogger-logger.rb
|
55
|
+
- lib/klogger.rb
|
56
|
+
- lib/klogger/colors.rb
|
57
|
+
- lib/klogger/formatters/abstract.rb
|
58
|
+
- lib/klogger/formatters/go.rb
|
59
|
+
- lib/klogger/formatters/json.rb
|
60
|
+
- lib/klogger/formatters/simple.rb
|
61
|
+
- lib/klogger/json_highlighter.rb
|
62
|
+
- lib/klogger/logger.rb
|
63
|
+
- lib/klogger/version.rb
|
64
|
+
homepage: https://github.com/krystal/klogger
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.6'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubygems_version: 3.3.26
|
84
|
+
signing_key:
|
85
|
+
specification_version: 4
|
86
|
+
summary: A simple Ruby logger
|
87
|
+
test_files: []
|