klogger-logger 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Klogger
4
+ class Abstract
5
+
6
+ def initialize(highlight: false)
7
+ @highlight = highlight
8
+ end
9
+
10
+ def call(_severity, _time, _progname, _payload)
11
+ 'no formatter'
12
+ end
13
+
14
+ end
15
+ 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
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'klogger'
data/lib/klogger.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'klogger/logger'
4
+
5
+ module Klogger
6
+
7
+ def self.new(*args, **kwargs)
8
+ Logger.new(*args, **kwargs)
9
+ end
10
+
11
+ end
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: []