ougai-formatters-customizable 1.0.0 → 1.0.1
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 +4 -4
- data/README.md +311 -311
- data/lib/ougai/formatters/colors.rb +91 -91
- data/lib/ougai/formatters/colors/configuration.rb +119 -119
- data/lib/ougai/formatters/customizable.rb +160 -160
- data/lib/ougai/formatters/customizable/version.rb +8 -8
- metadata +21 -28
@@ -1,91 +1,91 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Ougai
|
4
|
-
module Formatters
|
5
|
-
# List of useful ANSI escape sequences for terminal font formatting. Source
|
6
|
-
# is https://gist.github.com/chrisopedia/8754917.
|
7
|
-
module Colors
|
8
|
-
# -- Comments compared to Ougai initial coloring --
|
9
|
-
# Non-bold font colors do not use \e[0;{value}m because it seems to be
|
10
|
-
# incompatible with background colors: \e[41m\e[0;34mtext\e[0m does not print
|
11
|
-
# background red while \e[41m\e[34mtext\e[0m works. However, to put font in
|
12
|
-
# bold/bright mode, \e[41m\e[1;34mtext\e[0m works
|
13
|
-
# => Tested on Windows PowerShell and MinGW64
|
14
|
-
#
|
15
|
-
# Colors values cannot be frozen as .concat is called upon them
|
16
|
-
|
17
|
-
# Reset formatting. To be appended after every formatted text
|
18
|
-
RESET = "\e[0m"
|
19
|
-
# Font black color
|
20
|
-
BLACK = "\e[30m"
|
21
|
-
# Font red color
|
22
|
-
RED = "\e[31m"
|
23
|
-
# Font green color
|
24
|
-
GREEN = "\e[32m"
|
25
|
-
# Font yello color
|
26
|
-
YELLOW = "\e[33m"
|
27
|
-
# Font blue color
|
28
|
-
BLUE = "\e[34m"
|
29
|
-
# Font purple color
|
30
|
-
PURPLE = "\e[35m"
|
31
|
-
# Font cyan color
|
32
|
-
CYAN = "\e[36m"
|
33
|
-
# Font white color
|
34
|
-
WHITE = "\e[37m"
|
35
|
-
# Font bright/bold red color
|
36
|
-
BOLD_RED = "\e[1;31m"
|
37
|
-
# Font bright/bold green color
|
38
|
-
BOLD_GREEN = "\e[1;32m"
|
39
|
-
# Font bright/bold yellow color
|
40
|
-
BOLD_YELLOW = "\e[1;33m"
|
41
|
-
# Font bright/bold blue color
|
42
|
-
BOLD_BLUE = "\e[1;34m"
|
43
|
-
# Font bright/bold purple color
|
44
|
-
BOLD_PURPLE = "\e[1;35m"
|
45
|
-
# Font bright/bold cyan color
|
46
|
-
BOLD_CYAN = "\e[1;36m"
|
47
|
-
# Font bright/bold white color
|
48
|
-
BOLD_WHITE = "\e[1;37m"
|
49
|
-
# Background black color
|
50
|
-
BG_BLACK = "\e[40m"
|
51
|
-
# Background red color
|
52
|
-
BG_RED = "\e[41m"
|
53
|
-
# Background green color
|
54
|
-
BG_GREEN = "\e[42m"
|
55
|
-
# Background yellow color
|
56
|
-
BG_YELLOW = "\e[43m"
|
57
|
-
# Background blue color
|
58
|
-
BG_BLUE = "\e[44m"
|
59
|
-
# Background purple color
|
60
|
-
BG_PURPLE = "\e[45m"
|
61
|
-
# Background cyan color
|
62
|
-
BG_CYAN = "\e[46m"
|
63
|
-
# Background white color
|
64
|
-
BG_WHITE = "\e[47m"
|
65
|
-
|
66
|
-
class << self
|
67
|
-
# Color a text by prepending a font styling escape sequence and
|
68
|
-
# appending a reset sequence. This method does a pure String concatenation
|
69
|
-
# and does not check the values are properly escaped. This allows
|
70
|
-
# customization, depending on user's terminal, to use custom escape
|
71
|
-
# sequences.
|
72
|
-
#
|
73
|
-
# @param [String] color color to prepend. Color can be from the list
|
74
|
-
# above or have a complete custom String value depending on the
|
75
|
-
# terminal. If +nil+, text is not modified.
|
76
|
-
# @param [String] text text to be colored
|
77
|
-
# @param [String] reset reset font styling escape sequence
|
78
|
-
#
|
79
|
-
# @return [String] colored or uncolored text
|
80
|
-
def color_text(color, text, reset = Ougai::Formatters::Colors::RESET)
|
81
|
-
return text if color.nil?
|
82
|
-
|
83
|
-
# .concat is preferred in Ruby:
|
84
|
-
# https://coderwall.com/p/ac5j9g/or-concat-what-is-faster-for-appending-string-in-ruby
|
85
|
-
''.dup.concat(color).concat(text).concat(reset)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ougai
|
4
|
+
module Formatters
|
5
|
+
# List of useful ANSI escape sequences for terminal font formatting. Source
|
6
|
+
# is https://gist.github.com/chrisopedia/8754917.
|
7
|
+
module Colors
|
8
|
+
# -- Comments compared to Ougai initial coloring --
|
9
|
+
# Non-bold font colors do not use \e[0;{value}m because it seems to be
|
10
|
+
# incompatible with background colors: \e[41m\e[0;34mtext\e[0m does not print
|
11
|
+
# background red while \e[41m\e[34mtext\e[0m works. However, to put font in
|
12
|
+
# bold/bright mode, \e[41m\e[1;34mtext\e[0m works
|
13
|
+
# => Tested on Windows PowerShell and MinGW64
|
14
|
+
#
|
15
|
+
# Colors values cannot be frozen as .concat is called upon them
|
16
|
+
|
17
|
+
# Reset formatting. To be appended after every formatted text
|
18
|
+
RESET = "\e[0m"
|
19
|
+
# Font black color
|
20
|
+
BLACK = "\e[30m"
|
21
|
+
# Font red color
|
22
|
+
RED = "\e[31m"
|
23
|
+
# Font green color
|
24
|
+
GREEN = "\e[32m"
|
25
|
+
# Font yello color
|
26
|
+
YELLOW = "\e[33m"
|
27
|
+
# Font blue color
|
28
|
+
BLUE = "\e[34m"
|
29
|
+
# Font purple color
|
30
|
+
PURPLE = "\e[35m"
|
31
|
+
# Font cyan color
|
32
|
+
CYAN = "\e[36m"
|
33
|
+
# Font white color
|
34
|
+
WHITE = "\e[37m"
|
35
|
+
# Font bright/bold red color
|
36
|
+
BOLD_RED = "\e[1;31m"
|
37
|
+
# Font bright/bold green color
|
38
|
+
BOLD_GREEN = "\e[1;32m"
|
39
|
+
# Font bright/bold yellow color
|
40
|
+
BOLD_YELLOW = "\e[1;33m"
|
41
|
+
# Font bright/bold blue color
|
42
|
+
BOLD_BLUE = "\e[1;34m"
|
43
|
+
# Font bright/bold purple color
|
44
|
+
BOLD_PURPLE = "\e[1;35m"
|
45
|
+
# Font bright/bold cyan color
|
46
|
+
BOLD_CYAN = "\e[1;36m"
|
47
|
+
# Font bright/bold white color
|
48
|
+
BOLD_WHITE = "\e[1;37m"
|
49
|
+
# Background black color
|
50
|
+
BG_BLACK = "\e[40m"
|
51
|
+
# Background red color
|
52
|
+
BG_RED = "\e[41m"
|
53
|
+
# Background green color
|
54
|
+
BG_GREEN = "\e[42m"
|
55
|
+
# Background yellow color
|
56
|
+
BG_YELLOW = "\e[43m"
|
57
|
+
# Background blue color
|
58
|
+
BG_BLUE = "\e[44m"
|
59
|
+
# Background purple color
|
60
|
+
BG_PURPLE = "\e[45m"
|
61
|
+
# Background cyan color
|
62
|
+
BG_CYAN = "\e[46m"
|
63
|
+
# Background white color
|
64
|
+
BG_WHITE = "\e[47m"
|
65
|
+
|
66
|
+
class << self
|
67
|
+
# Color a text by prepending a font styling escape sequence and
|
68
|
+
# appending a reset sequence. This method does a pure String concatenation
|
69
|
+
# and does not check the values are properly escaped. This allows
|
70
|
+
# customization, depending on user's terminal, to use custom escape
|
71
|
+
# sequences.
|
72
|
+
#
|
73
|
+
# @param [String] color color to prepend. Color can be from the list
|
74
|
+
# above or have a complete custom String value depending on the
|
75
|
+
# terminal. If +nil+, text is not modified.
|
76
|
+
# @param [String] text text to be colored
|
77
|
+
# @param [String] reset reset font styling escape sequence
|
78
|
+
#
|
79
|
+
# @return [String] colored or uncolored text
|
80
|
+
def color_text(color, text, reset = Ougai::Formatters::Colors::RESET)
|
81
|
+
return text if color.nil?
|
82
|
+
|
83
|
+
# .concat is preferred in Ruby:
|
84
|
+
# https://coderwall.com/p/ac5j9g/or-concat-what-is-faster-for-appending-string-in-ruby
|
85
|
+
''.dup.concat(color).concat(text).concat(reset)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,119 +1,119 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'ougai/formatters/colors'
|
4
|
-
|
5
|
-
module Ougai
|
6
|
-
module Formatters
|
7
|
-
module Colors
|
8
|
-
# Handle the colorization of output, mainly aimed at console formatting.
|
9
|
-
# The configuration,split by subject such as +level+, +msg+,
|
10
|
-
# or +datetime+ is basically a Hash: +config+ with the subject as key
|
11
|
-
# and values. Values can be have three types:
|
12
|
-
#
|
13
|
-
# - +String+: the color escape sequence for the subject
|
14
|
-
# - +Hash+: the color escape sequence per severity. If not all severities
|
15
|
-
# are defined, a +:default+ value must be defined
|
16
|
-
# - +Symbol+: refers to another key and same coloring is applied
|
17
|
-
class Configuration
|
18
|
-
class << self
|
19
|
-
# list default color configuration
|
20
|
-
# @note 'any' severity label decided in
|
21
|
-
# +Ougai::Logging::Severity#to_label+
|
22
|
-
# @note values are copied from +Ougai::Formatters::Readable+ coloring
|
23
|
-
# values
|
24
|
-
# @return [Hash] default color configuration is severities only
|
25
|
-
def default_configuration
|
26
|
-
{
|
27
|
-
severity: {
|
28
|
-
trace: Ougai::Formatters::Colors::BLUE,
|
29
|
-
debug: Ougai::Formatters::Colors::WHITE,
|
30
|
-
info: Ougai::Formatters::Colors::CYAN,
|
31
|
-
warn: Ougai::Formatters::Colors::YELLOW,
|
32
|
-
error: Ougai::Formatters::Colors::RED,
|
33
|
-
fatal: Ougai::Formatters::Colors::PURPLE,
|
34
|
-
any: Ougai::Formatters::Colors::GREEN
|
35
|
-
}
|
36
|
-
}
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Configuration accept following keys:
|
41
|
-
# - +:load_default_config+ If true, then default configuration
|
42
|
-
# values is fetched to fill missing value from the provided
|
43
|
-
# configuration. Default is true.
|
44
|
-
# - any remaining key is considered to be color-related and is translated
|
45
|
-
# into a *subject => color rule* mapping
|
46
|
-
#
|
47
|
-
# @param [Hash] configuration color configuration. Cannot be nil
|
48
|
-
def initialize(configuration = {})
|
49
|
-
# check if loading or not from default configuration
|
50
|
-
if configuration.fetch(:load_default_config) { true }
|
51
|
-
@config = Configuration.default_configuration
|
52
|
-
else
|
53
|
-
@config = {}
|
54
|
-
end
|
55
|
-
|
56
|
-
configuration.each do |key, val|
|
57
|
-
default_val = @config[key]
|
58
|
-
# default value is a Hash AND input value is a Hash => merge
|
59
|
-
if val.is_a?(Hash) && default_val.is_a?(Hash)
|
60
|
-
@config[key] = default_val.merge(val)
|
61
|
-
# Input value is assigned because one of the follow
|
62
|
-
# 1) input value is not defined in default configuration
|
63
|
-
# 2) input value is not a Hash which overrides the default value
|
64
|
-
# 3) default value is not a Hash and input is a Hash => Arbitrary
|
65
|
-
else
|
66
|
-
@config[key] = val
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Convenience method to color a subject for a given log severity
|
72
|
-
#
|
73
|
-
# @param [Symbol] subject_key to fetch the color to color the text
|
74
|
-
# @param [String] text to be colored text
|
75
|
-
# @param [Symbol] severity log level
|
76
|
-
#
|
77
|
-
# @return [String] a colored text depending on the subject
|
78
|
-
def color(subject_key, text, severity)
|
79
|
-
color = get_color_for(subject_key, severity)
|
80
|
-
Ougai::Formatters::Colors.color_text(color, text)
|
81
|
-
end
|
82
|
-
|
83
|
-
# Return the color for a given suject and a given severity. This color
|
84
|
-
# can then be applied to any text via
|
85
|
-
# +Ougai::Formatters::Colors.color_text+
|
86
|
-
#
|
87
|
-
# +get_color_for+ handles color inheritance: if a subject inherit color
|
88
|
-
# from another subject, subject value is the symbol refering to the
|
89
|
-
# other subject.
|
90
|
-
#
|
91
|
-
# @note !!WARNING!!: Circular references are not checked and lead to infinite
|
92
|
-
# loop
|
93
|
-
#
|
94
|
-
# @param [Symbol] subject_key to define the color to color the text
|
95
|
-
# @param [Symbol] severity log level
|
96
|
-
#
|
97
|
-
# @return [String,nil] requested color String value or +nil+ if not colored
|
98
|
-
def get_color_for(subject_key, severity)
|
99
|
-
# no colorization
|
100
|
-
return nil unless @config.key?(subject_key)
|
101
|
-
|
102
|
-
# no severity dependence nor inheritance
|
103
|
-
color = @config[subject_key]
|
104
|
-
return color if color.is_a? String
|
105
|
-
|
106
|
-
# inheritance from another subject
|
107
|
-
return get_color_for(color, severity) if color.is_a? Symbol
|
108
|
-
|
109
|
-
# severity dependent but not inherited value or return +nil+ if
|
110
|
-
# configuration is incorrect
|
111
|
-
severity = severity.downcase.to_sym
|
112
|
-
color.fetch(severity) { color[:default] }
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ougai/formatters/colors'
|
4
|
+
|
5
|
+
module Ougai
|
6
|
+
module Formatters
|
7
|
+
module Colors
|
8
|
+
# Handle the colorization of output, mainly aimed at console formatting.
|
9
|
+
# The configuration,split by subject such as +level+, +msg+,
|
10
|
+
# or +datetime+ is basically a Hash: +config+ with the subject as key
|
11
|
+
# and values. Values can be have three types:
|
12
|
+
#
|
13
|
+
# - +String+: the color escape sequence for the subject
|
14
|
+
# - +Hash+: the color escape sequence per severity. If not all severities
|
15
|
+
# are defined, a +:default+ value must be defined
|
16
|
+
# - +Symbol+: refers to another key and same coloring is applied
|
17
|
+
class Configuration
|
18
|
+
class << self
|
19
|
+
# list default color configuration
|
20
|
+
# @note 'any' severity label decided in
|
21
|
+
# +Ougai::Logging::Severity#to_label+
|
22
|
+
# @note values are copied from +Ougai::Formatters::Readable+ coloring
|
23
|
+
# values
|
24
|
+
# @return [Hash] default color configuration is severities only
|
25
|
+
def default_configuration
|
26
|
+
{
|
27
|
+
severity: {
|
28
|
+
trace: Ougai::Formatters::Colors::BLUE,
|
29
|
+
debug: Ougai::Formatters::Colors::WHITE,
|
30
|
+
info: Ougai::Formatters::Colors::CYAN,
|
31
|
+
warn: Ougai::Formatters::Colors::YELLOW,
|
32
|
+
error: Ougai::Formatters::Colors::RED,
|
33
|
+
fatal: Ougai::Formatters::Colors::PURPLE,
|
34
|
+
any: Ougai::Formatters::Colors::GREEN
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Configuration accept following keys:
|
41
|
+
# - +:load_default_config+ If true, then default configuration
|
42
|
+
# values is fetched to fill missing value from the provided
|
43
|
+
# configuration. Default is true.
|
44
|
+
# - any remaining key is considered to be color-related and is translated
|
45
|
+
# into a *subject => color rule* mapping
|
46
|
+
#
|
47
|
+
# @param [Hash] configuration color configuration. Cannot be nil
|
48
|
+
def initialize(configuration = {})
|
49
|
+
# check if loading or not from default configuration
|
50
|
+
if configuration.fetch(:load_default_config) { true }
|
51
|
+
@config = Configuration.default_configuration
|
52
|
+
else
|
53
|
+
@config = {}
|
54
|
+
end
|
55
|
+
|
56
|
+
configuration.each do |key, val|
|
57
|
+
default_val = @config[key]
|
58
|
+
# default value is a Hash AND input value is a Hash => merge
|
59
|
+
if val.is_a?(Hash) && default_val.is_a?(Hash)
|
60
|
+
@config[key] = default_val.merge(val)
|
61
|
+
# Input value is assigned because one of the follow
|
62
|
+
# 1) input value is not defined in default configuration
|
63
|
+
# 2) input value is not a Hash which overrides the default value
|
64
|
+
# 3) default value is not a Hash and input is a Hash => Arbitrary
|
65
|
+
else
|
66
|
+
@config[key] = val
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Convenience method to color a subject for a given log severity
|
72
|
+
#
|
73
|
+
# @param [Symbol] subject_key to fetch the color to color the text
|
74
|
+
# @param [String] text to be colored text
|
75
|
+
# @param [Symbol] severity log level
|
76
|
+
#
|
77
|
+
# @return [String] a colored text depending on the subject
|
78
|
+
def color(subject_key, text, severity)
|
79
|
+
color = get_color_for(subject_key, severity)
|
80
|
+
Ougai::Formatters::Colors.color_text(color, text)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return the color for a given suject and a given severity. This color
|
84
|
+
# can then be applied to any text via
|
85
|
+
# +Ougai::Formatters::Colors.color_text+
|
86
|
+
#
|
87
|
+
# +get_color_for+ handles color inheritance: if a subject inherit color
|
88
|
+
# from another subject, subject value is the symbol refering to the
|
89
|
+
# other subject.
|
90
|
+
#
|
91
|
+
# @note !!WARNING!!: Circular references are not checked and lead to infinite
|
92
|
+
# loop
|
93
|
+
#
|
94
|
+
# @param [Symbol] subject_key to define the color to color the text
|
95
|
+
# @param [Symbol] severity log level
|
96
|
+
#
|
97
|
+
# @return [String,nil] requested color String value or +nil+ if not colored
|
98
|
+
def get_color_for(subject_key, severity)
|
99
|
+
# no colorization
|
100
|
+
return nil unless @config.key?(subject_key)
|
101
|
+
|
102
|
+
# no severity dependence nor inheritance
|
103
|
+
color = @config[subject_key]
|
104
|
+
return color if color.is_a? String
|
105
|
+
|
106
|
+
# inheritance from another subject
|
107
|
+
return get_color_for(color, severity) if color.is_a? Symbol
|
108
|
+
|
109
|
+
# severity dependent but not inherited value or return +nil+ if
|
110
|
+
# configuration is incorrect
|
111
|
+
severity = severity.downcase.to_sym
|
112
|
+
color.fetch(severity) { color[:default] }
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -1,160 +1,160 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'ougai/formatters/base'
|
4
|
-
require 'ougai/formatters/colors/configuration'
|
5
|
-
|
6
|
-
module Ougai
|
7
|
-
module Formatters
|
8
|
-
# Ougai log printing can be split in three components:
|
9
|
-
# 1. Main log message: usually with timestamp, log severity and a single
|
10
|
-
# line message
|
11
|
-
# 2. Log data: the structured logging component. Can be represented by
|
12
|
-
# a Hash
|
13
|
-
# 3. Errors: errors require specific log formatting
|
14
|
-
#
|
15
|
-
# Customizable offers a flexible way to handle each component
|
16
|
-
# independently by assigning a proc to the following keys:
|
17
|
-
#
|
18
|
-
# 1. +:format_msg+ Format message. Proc arguments are +|level, datetime, progname, data|+. This block must remove the key +:msg+ from +data+
|
19
|
-
# 2. +:format_data+ Format data. Proc argument is +|data|+.
|
20
|
-
# 3. +:format_err+ Format err. Proc argument is +|data|+. The proc must remove the key +:err+
|
21
|
-
class Customizable < Ougai::Formatters::Base
|
22
|
-
class << self
|
23
|
-
# Define the default main log message formatting to use. A non-null
|
24
|
-
# color configuration has to be provided. The configuration can however
|
25
|
-
# be empty
|
26
|
-
#
|
27
|
-
# @param [Ougai::Formatters::Colors::Configuration] color_config the
|
28
|
-
# color configuration to use
|
29
|
-
#
|
30
|
-
# @return [Proc] main message formatter
|
31
|
-
def default_msg_format(color_config)
|
32
|
-
proc do |severity, datetime, _progname, data|
|
33
|
-
msg = data.delete(:msg)
|
34
|
-
severity = color_config.color(:severity, severity, severity)
|
35
|
-
datetime = color_config.color(:datetime, datetime, severity)
|
36
|
-
msg = color_config.color(:msg, msg, severity)
|
37
|
-
|
38
|
-
"[#{datetime}] #{severity}: #{msg}"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Define the default error formatting to use which handles field
|
43
|
-
# exclusion and plain mode for
|
44
|
-
#
|
45
|
-
# @param [Array<Symbol>] excluded_fields list of key to exclude from
|
46
|
-
# +data+ before printing logs
|
47
|
-
# @param [Boolean] plain parameter to define if
|
48
|
-
# in plain mode or not
|
49
|
-
#
|
50
|
-
# @return [Proc] data formatter
|
51
|
-
def default_data_format(excluded_fields, plain)
|
52
|
-
proc do |data|
|
53
|
-
excluded_fields.each { |field| data.delete(field) }
|
54
|
-
next nil if data.empty?
|
55
|
-
|
56
|
-
data.ai(plain: plain)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Define the default error formatting to use.
|
61
|
-
#
|
62
|
-
# @param [Integer] trace_indent space indentation to prepend before
|
63
|
-
# trace content
|
64
|
-
#
|
65
|
-
# @return [Proc] error formatter
|
66
|
-
def default_err_format(trace_indent = 4)
|
67
|
-
proc do |data|
|
68
|
-
next nil unless data.key?(:err)
|
69
|
-
|
70
|
-
err = data.delete(:err)
|
71
|
-
err_str = " #{err[:name]} (#{err[:message]}):"
|
72
|
-
err_str += "\n" + (' ' * trace_indent) + err[:stack] if err.key?(:stack)
|
73
|
-
err_str
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Intialize a formatter
|
79
|
-
#
|
80
|
-
# @param [String] app_name application name (execution program name if nil)
|
81
|
-
# @param [String] hostname hostname (hostname if nil)
|
82
|
-
# @param [Hash] opts the initial values of attributes
|
83
|
-
# @option opts [String] :trace_max_lines (100) the value of
|
84
|
-
# trace_max_lines attribute
|
85
|
-
# @option opts [String] :plain (false) the value of plain attribute
|
86
|
-
# @option opts [String] :excluded_fields ([]) the value of
|
87
|
-
# excluded_fields attribute
|
88
|
-
# @option opts [Ougai::Formatters::Colors::Configuration] :color_config
|
89
|
-
# assign a color configuration.
|
90
|
-
# @option opts [Proc] :format_msg main message formatter
|
91
|
-
# @option opts [Proc] :format_data data formatter
|
92
|
-
# @option opts [Proc] :format_err error formatter
|
93
|
-
def initialize(app_name = nil, hostname = nil, opts = {})
|
94
|
-
aname, hname, opts = Base.parse_new_params([app_name, hostname, opts])
|
95
|
-
super(aname, hname, opts)
|
96
|
-
|
97
|
-
# Message logging
|
98
|
-
color_config = opts.fetch(:color_config) {
|
99
|
-
color_config = Ougai::Formatters::Colors::Configuration.new({})
|
100
|
-
}
|
101
|
-
@format_msg = opts.fetch(:format_msg) {
|
102
|
-
Customizable.default_msg_format(color_config)
|
103
|
-
}
|
104
|
-
|
105
|
-
# Data logging
|
106
|
-
plain = opts.fetch(:plain) { false }
|
107
|
-
excluded_fields = opts[:excluded_fields] || []
|
108
|
-
@format_data = opts.fetch(:format_data) {
|
109
|
-
Customizable.default_data_format(excluded_fields, plain)
|
110
|
-
}
|
111
|
-
|
112
|
-
# Error logging
|
113
|
-
trace_indent = opts.fetch(:trace_indent) { 4 }
|
114
|
-
@format_err = opts.fetch(:format_err) {
|
115
|
-
Customizable.default_err_format(trace_indent)
|
116
|
-
}
|
117
|
-
|
118
|
-
# Ensure dependency are present
|
119
|
-
load_dependent
|
120
|
-
end
|
121
|
-
|
122
|
-
# Format a log entry
|
123
|
-
#
|
124
|
-
# @param [String] severity log severity, in capital letters
|
125
|
-
# @param [Time] time timestamp of the log. Is formatted by +strftime+
|
126
|
-
# @param [String] progname optional program name
|
127
|
-
# @param [Hash] data log data. Main message is stored under the key +:msg+
|
128
|
-
# while errors are logged under the key +:err+.
|
129
|
-
#
|
130
|
-
# @return [String] log text, ready to be printed out
|
131
|
-
def _call(severity, time, progname, data)
|
132
|
-
strs = ''.dup
|
133
|
-
# Main message
|
134
|
-
dt = format_datetime(time)
|
135
|
-
msg_str = @format_msg.call(severity, dt, progname, data)
|
136
|
-
strs.concat(msg_str)
|
137
|
-
|
138
|
-
# Error: displayed before additional data
|
139
|
-
err_str = @format_err.call(data)
|
140
|
-
strs.concat("\n").concat(err_str) unless err_str.nil?
|
141
|
-
|
142
|
-
# Additional data
|
143
|
-
data_str = @format_data.call(data)
|
144
|
-
strs.concat("\n").concat(data_str) unless data_str.nil?
|
145
|
-
|
146
|
-
strs.concat("\n")
|
147
|
-
end
|
148
|
-
|
149
|
-
protected
|
150
|
-
|
151
|
-
# Ensure +awesompe_print+ is loaded
|
152
|
-
def load_dependent
|
153
|
-
require '
|
154
|
-
rescue LoadError
|
155
|
-
puts 'You must install the
|
156
|
-
raise
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ougai/formatters/base'
|
4
|
+
require 'ougai/formatters/colors/configuration'
|
5
|
+
|
6
|
+
module Ougai
|
7
|
+
module Formatters
|
8
|
+
# Ougai log printing can be split in three components:
|
9
|
+
# 1. Main log message: usually with timestamp, log severity and a single
|
10
|
+
# line message
|
11
|
+
# 2. Log data: the structured logging component. Can be represented by
|
12
|
+
# a Hash
|
13
|
+
# 3. Errors: errors require specific log formatting
|
14
|
+
#
|
15
|
+
# Customizable offers a flexible way to handle each component
|
16
|
+
# independently by assigning a proc to the following keys:
|
17
|
+
#
|
18
|
+
# 1. +:format_msg+ Format message. Proc arguments are +|level, datetime, progname, data|+. This block must remove the key +:msg+ from +data+
|
19
|
+
# 2. +:format_data+ Format data. Proc argument is +|data|+.
|
20
|
+
# 3. +:format_err+ Format err. Proc argument is +|data|+. The proc must remove the key +:err+
|
21
|
+
class Customizable < Ougai::Formatters::Base
|
22
|
+
class << self
|
23
|
+
# Define the default main log message formatting to use. A non-null
|
24
|
+
# color configuration has to be provided. The configuration can however
|
25
|
+
# be empty
|
26
|
+
#
|
27
|
+
# @param [Ougai::Formatters::Colors::Configuration] color_config the
|
28
|
+
# color configuration to use
|
29
|
+
#
|
30
|
+
# @return [Proc] main message formatter
|
31
|
+
def default_msg_format(color_config)
|
32
|
+
proc do |severity, datetime, _progname, data|
|
33
|
+
msg = data.delete(:msg)
|
34
|
+
severity = color_config.color(:severity, severity, severity)
|
35
|
+
datetime = color_config.color(:datetime, datetime, severity)
|
36
|
+
msg = color_config.color(:msg, msg, severity)
|
37
|
+
|
38
|
+
"[#{datetime}] #{severity}: #{msg}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Define the default error formatting to use which handles field
|
43
|
+
# exclusion and plain mode for amazing-print
|
44
|
+
#
|
45
|
+
# @param [Array<Symbol>] excluded_fields list of key to exclude from
|
46
|
+
# +data+ before printing logs
|
47
|
+
# @param [Boolean] plain parameter to define if Amazing-Print renders
|
48
|
+
# in plain mode or not
|
49
|
+
#
|
50
|
+
# @return [Proc] data formatter
|
51
|
+
def default_data_format(excluded_fields, plain)
|
52
|
+
proc do |data|
|
53
|
+
excluded_fields.each { |field| data.delete(field) }
|
54
|
+
next nil if data.empty?
|
55
|
+
|
56
|
+
data.ai(plain: plain)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Define the default error formatting to use.
|
61
|
+
#
|
62
|
+
# @param [Integer] trace_indent space indentation to prepend before
|
63
|
+
# trace content
|
64
|
+
#
|
65
|
+
# @return [Proc] error formatter
|
66
|
+
def default_err_format(trace_indent = 4)
|
67
|
+
proc do |data|
|
68
|
+
next nil unless data.key?(:err)
|
69
|
+
|
70
|
+
err = data.delete(:err)
|
71
|
+
err_str = " #{err[:name]} (#{err[:message]}):"
|
72
|
+
err_str += "\n" + (' ' * trace_indent) + err[:stack] if err.key?(:stack)
|
73
|
+
err_str
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Intialize a formatter
|
79
|
+
#
|
80
|
+
# @param [String] app_name application name (execution program name if nil)
|
81
|
+
# @param [String] hostname hostname (hostname if nil)
|
82
|
+
# @param [Hash] opts the initial values of attributes
|
83
|
+
# @option opts [String] :trace_max_lines (100) the value of
|
84
|
+
# trace_max_lines attribute
|
85
|
+
# @option opts [String] :plain (false) the value of plain attribute
|
86
|
+
# @option opts [String] :excluded_fields ([]) the value of
|
87
|
+
# excluded_fields attribute
|
88
|
+
# @option opts [Ougai::Formatters::Colors::Configuration] :color_config
|
89
|
+
# assign a color configuration.
|
90
|
+
# @option opts [Proc] :format_msg main message formatter
|
91
|
+
# @option opts [Proc] :format_data data formatter
|
92
|
+
# @option opts [Proc] :format_err error formatter
|
93
|
+
def initialize(app_name = nil, hostname = nil, opts = {})
|
94
|
+
aname, hname, opts = Base.parse_new_params([app_name, hostname, opts])
|
95
|
+
super(aname, hname, opts)
|
96
|
+
|
97
|
+
# Message logging
|
98
|
+
color_config = opts.fetch(:color_config) {
|
99
|
+
color_config = Ougai::Formatters::Colors::Configuration.new({})
|
100
|
+
}
|
101
|
+
@format_msg = opts.fetch(:format_msg) {
|
102
|
+
Customizable.default_msg_format(color_config)
|
103
|
+
}
|
104
|
+
|
105
|
+
# Data logging
|
106
|
+
plain = opts.fetch(:plain) { false }
|
107
|
+
excluded_fields = opts[:excluded_fields] || []
|
108
|
+
@format_data = opts.fetch(:format_data) {
|
109
|
+
Customizable.default_data_format(excluded_fields, plain)
|
110
|
+
}
|
111
|
+
|
112
|
+
# Error logging
|
113
|
+
trace_indent = opts.fetch(:trace_indent) { 4 }
|
114
|
+
@format_err = opts.fetch(:format_err) {
|
115
|
+
Customizable.default_err_format(trace_indent)
|
116
|
+
}
|
117
|
+
|
118
|
+
# Ensure dependency are present
|
119
|
+
load_dependent
|
120
|
+
end
|
121
|
+
|
122
|
+
# Format a log entry
|
123
|
+
#
|
124
|
+
# @param [String] severity log severity, in capital letters
|
125
|
+
# @param [Time] time timestamp of the log. Is formatted by +strftime+
|
126
|
+
# @param [String] progname optional program name
|
127
|
+
# @param [Hash] data log data. Main message is stored under the key +:msg+
|
128
|
+
# while errors are logged under the key +:err+.
|
129
|
+
#
|
130
|
+
# @return [String] log text, ready to be printed out
|
131
|
+
def _call(severity, time, progname, data)
|
132
|
+
strs = ''.dup
|
133
|
+
# Main message
|
134
|
+
dt = format_datetime(time)
|
135
|
+
msg_str = @format_msg.call(severity, dt, progname, data)
|
136
|
+
strs.concat(msg_str)
|
137
|
+
|
138
|
+
# Error: displayed before additional data
|
139
|
+
err_str = @format_err.call(data)
|
140
|
+
strs.concat("\n").concat(err_str) unless err_str.nil?
|
141
|
+
|
142
|
+
# Additional data
|
143
|
+
data_str = @format_data.call(data)
|
144
|
+
strs.concat("\n").concat(data_str) unless data_str.nil?
|
145
|
+
|
146
|
+
strs.concat("\n")
|
147
|
+
end
|
148
|
+
|
149
|
+
protected
|
150
|
+
|
151
|
+
# Ensure +awesompe_print+ is loaded
|
152
|
+
def load_dependent
|
153
|
+
require 'amazing_print'
|
154
|
+
rescue LoadError
|
155
|
+
puts 'You must install the amazing_print gem to use this output.'
|
156
|
+
raise
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|