ougai-formatters-customizable 0.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64f9b36ed7779caff3e9ce05fe6062d1f6c0ab7e7754b55463a3475147bc1b27
4
- data.tar.gz: 62c6c4db4205f4faea3a3c5f6cc5cb1c1b3cdbf6849f1cf3085636eb5e5e19b0
3
+ metadata.gz: f9ac580c652c5578865e731227f1488dfb95bec37644f78366414bc69268424c
4
+ data.tar.gz: b8afc7c9c56f01bcd742987e08c4e0daa201aad503fd86c9950061169bb3a440
5
5
  SHA512:
6
- metadata.gz: 445010e474a5863bf5311395b474857825962a67b7f2f72ad030656f46e8e99b339264dff77057d06e2f8bde3eda75ce661c620fd7afade58f94461b0a2393db
7
- data.tar.gz: 7b06933a749c5632e87d7828f6009145c4d21ec3e01a23696d982e160bc96bd1fa8854a71c8a142d5e400deac0becbe2264055c9c17005855f50cbd1a448509a
6
+ metadata.gz: 92ae20d2af4f58607ceaebc80197d3195441a5b2e54733ec2bdc094c0a479425e7c5f85403a80c194455cdfbbd1bf7080b9c55ddd746dba6c680fec7ec454602
7
+ data.tar.gz: 9e1adbf551fc7f260a92155da26d5959c2819d8905f0be3495b96a133338a2da6489036f23ca427bf64826106ec3adacb9fc1798032aa06a572476ff45480ade
data/README.md CHANGED
@@ -1,39 +1,311 @@
1
- # Ougai::Formatters::Customizable
2
-
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ougai/formatters/customizable`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
6
-
7
- ## Installation
8
-
9
- Add this line to your application's Gemfile:
10
-
11
- ```ruby
12
- gem 'ougai-formatters-customizable'
13
- ```
14
-
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
- $ gem install ougai-formatters-customizable
22
-
23
- ## Usage
24
-
25
- TODO: Write usage instructions here
26
-
27
- ## Development
28
-
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
-
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
-
33
- ## Contributing
34
-
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ougai-formatters-customizable.
36
-
37
- ## License
38
-
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
1
+ # Ougai-formatters-customizable
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/ougai-formatters-customizable.svg)](https://badge.fury.io/rb/ougai-formatters-customizable)
4
+ [![Build Status](https://travis-ci.com/Al-un/ougai-formatters-customizable.svg?branch=master)](https://travis-ci.com/Al-un/ougai-formatters-customizable)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/eaf20e90252260db1b68/maintainability)](https://codeclimate.com/github/Al-un/ougai-formatters-customizable/maintainability)
6
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/eaf20e90252260db1b68/test_coverage)](https://codeclimate.com/github/Al-un/ougai-formatters-customizable/test_coverage)
7
+
8
+ A fully customizable formatters for [Ougai](https://github.com/tilfin/ougai)
9
+ library. Customization is about formatting and colorization
10
+
11
+ **Formatting**
12
+
13
+ Ougai log printing can be split in three components:
14
+
15
+ 1. Main log message: usually timestamp, log severity and a message
16
+ 2. Data: the structured logging, represented by a Hash
17
+ 3. Errors
18
+
19
+ **Colorization**
20
+
21
+ Each part of the main log message can be colored independently. Colorization can
22
+ be extended to custom formatters as well.
23
+
24
+ ## Usage
25
+
26
+ In your Gemfile, add *ougai-formatters-customizable* and its dependencies:
27
+
28
+ ```ruby
29
+ gem 'awesome_print'
30
+ gem 'ougai'
31
+ gem 'ougai-formatters-customizable'
32
+ ```
33
+
34
+ Then initialize a formatter and assign it to your logger:
35
+
36
+ ```ruby
37
+ formatter = Ougai::Formatters::Customizable.new
38
+ # See Ougai documentation about how to initialize a Ougai logger
39
+ logger.formatter = formatter
40
+ ```
41
+
42
+ The default *Customizable* configuration is exactly identical to a
43
+ *Ougai::Formatters::Readable* as-of Ougai 1.7.0.
44
+
45
+ #### Datetime format
46
+
47
+ Inherited from Ruby logger formatters, you can assign a datetime format:
48
+
49
+ ```ruby
50
+ formatter.datetime_format = '%H:%M:%S.%L' # print time only such as '15:42:36.246'
51
+ ```
52
+
53
+ #### Message formatter: `format_msg`
54
+
55
+ Main log message formatter is a `proc` which takes four arguments:
56
+
57
+ - [String] severity: log severity. Is in capital letters
58
+ - [String] datetime: log timestamp. Is already formatted according to `datetime_format`.
59
+ Has to be treated like a String
60
+ - [String] progname: optional program name
61
+ - [Hash] data: structured log data. The main message is logged under the `:msg` key.
62
+
63
+ Custom message formatter can be assigned at initialization via the key `format_msg`:
64
+
65
+ ```ruby
66
+ formatter = Ougai::Formatters::Customizable.new(
67
+ format_msg: proc do |severity, datetime, _progname, data|
68
+ msg = data.delete(:msg)
69
+ format('%s %s: %s', severity, datetime, msg)
70
+ end
71
+ )
72
+ ```
73
+
74
+ **Notes**
75
+
76
+ - It is recommended that this proc removes the `:msg` key from `data` to avoid
77
+ duplicates
78
+ - Although not mandatory, this formatter aims at outputting a single line String
79
+
80
+ #### Data formatter: `format_data`
81
+
82
+ Data formatter is a `proc` which takes only `data` as argument. Custom data
83
+ formatter can be assigned at initialization via `format_data` key:
84
+
85
+ ```ruby
86
+ formatter = Ougai::Formatters::Customizable.new(
87
+ format_data: proc do |data|
88
+ data.ai # Awesome-print printing
89
+ end
90
+ )
91
+ ```
92
+
93
+ **Notes**
94
+
95
+ - Data formatter must return `nil` if `data` is empty.
96
+ - Default data formatter takes the `excluded_fields` option into account. You
97
+ need to add it to your custom formatter if you want to keep it.
98
+
99
+ #### Error formatter: `format_err`
100
+
101
+ Error formatter is a `proc` with only `data` as argument and can be assigned at
102
+ initialization via the `format_err` key:
103
+
104
+ ```ruby
105
+ formatter = Ougai::Formatters::Customizable.new(
106
+ format_err: proc do |data|
107
+ next nil unless data.key?(:err)
108
+
109
+ err = data.delete(:err)
110
+ " #{err[:name]} (#{err[:message]})"
111
+ end
112
+ )
113
+ ```
114
+
115
+ **Notes**
116
+
117
+ - Error formatter must return `nil` if `data` does not contain the `:err` key
118
+ - Error formatter must remove `:err` key
119
+ - Default error formatter takes the `trace_indent` option into account. You need
120
+ to add it to your custom formatter if you want to keep it
121
+
122
+ #### Colorization
123
+
124
+ Colorization is handled by an instance of `Ougai::Formatters::Colors::Configuration`
125
+ and is basically a mapping *subject => value* to define the colors. Default subject
126
+ are:
127
+
128
+ - `:severity`: log severity coloring
129
+ - `:datetime`: datetime coloring
130
+ - `:msg`: log main message coloring
131
+
132
+ You can add your own subject if you need it in your custom formatters.
133
+
134
+ Values can have three types:
135
+
136
+ - String: this color is applied to the subject regardless the situation
137
+ - Hash: the color is defined by log severity. Non defined severity colors are
138
+ fetched from the `default` severity
139
+ - Symbol: the color is copied from the referenced symbol
140
+
141
+ Example:
142
+
143
+ ```ruby
144
+ color_configuration = Ougai::Formatters::Colors::Configuration.new(
145
+ severity: {
146
+ trace: Ougai::Formatters::Colors::WHITE,
147
+ debug: Ougai::Formatters::Colors::GREEN,
148
+ info: Ougai::Formatters::Colors::CYAN,
149
+ warn: Ougai::Formatters::Colors::YELLOW,
150
+ error: Ougai::Formatters::Colors::RED,
151
+ fatal: Ougai::Formatters::Colors::PURPLE
152
+ },
153
+ msg: :severity,
154
+ datetime: {
155
+ default: Ougai::Formatters::Colors::PURPLE,
156
+ error: Ougai::Formatters::Colors::RED,
157
+ fatal: Ougai::Formatters::Colors::RED
158
+ },
159
+ custom: Ougai::Formatters::Colors::BLUE
160
+ )
161
+ ```
162
+
163
+ - *Severity* has a different color dependending on log severity
164
+ - Main log *message* color is identical to severity color
165
+ - *Datetime* has a red color for *error* and *fatal* logs. Otherwise it is
166
+ colored in purple.
167
+ - A *custom* subject is always colored in blue regardless log severity
168
+
169
+ **Notes**
170
+
171
+ - If `:severity` is not defined, it is loaded from a default configuration
172
+ - If `:severity` is partially defined, missing severities are fetched from
173
+ default configuration
174
+ - Circular references are not checked and infinite loops can then be triggered.
175
+
176
+ ## Integration
177
+
178
+ #### Lograge / Lograge-sql
179
+
180
+ I initially made this gem to couple Ougai with [lograge](https://github.com/roidrage/lograge)/[lograge-sql](https://github.com/iMacTia/lograge-sql). Lograge logs has to be
181
+ formatted in a way so that our custom formatters can catch it:
182
+
183
+ ```ruby
184
+ # config/initializers/lograge.rb
185
+ config.lograge.formatter = Class.new do |fmt|
186
+ def fmt.call(data)
187
+ { request: data }
188
+ end
189
+ end
190
+ ```
191
+
192
+ I chose this format because I am also using Loggly and it is pretty convenient
193
+ to filter by `json.request.*` to fetch Lograge logs.
194
+
195
+ If using lograge-sql, make sure that Lograge format it as a Hash so that we can
196
+ leverage our main message formatter and data formatter:
197
+
198
+ ```ruby
199
+ # config/initializers/lograge.rb
200
+ config.lograge_sql.extract_event = proc do |event|
201
+ {
202
+ name: event.payload[:name],
203
+ duration: event.duration.to_f.round(2),
204
+ sql: event.payload[:sql]
205
+ }
206
+ end
207
+ config.lograge_sql.formatter = proc do |sql_queries|
208
+ sql_queries
209
+ end
210
+ ```
211
+
212
+ Wrap everything together example:
213
+
214
+ ```ruby
215
+ # Define our colors
216
+ color_configuration = Ougai::Formatters::Colors::Configuration.new(
217
+ severity: {
218
+ trace: Ougai::Formatters::Colors::WHITE,
219
+ debug: Ougai::Formatters::Colors::GREEN,
220
+ info: Ougai::Formatters::Colors::CYAN,
221
+ warn: Ougai::Formatters::Colors::YELLOW,
222
+ error: Ougai::Formatters::Colors::RED,
223
+ fatal: Ougai::Formatters::Colors::PURPLE
224
+ },
225
+ msg: :severity,
226
+ datetime: {
227
+ default: Ougai::Formatters::Colors::PURPLE,
228
+ error: Ougai::Formatters::Colors::RED,
229
+ fatal: Ougai::Formatters::Colors::RED
230
+ }
231
+ )
232
+
233
+ # Lograge specific configuration
234
+ EXCLUDED_FIELD = [:credit_card] # example only
235
+ LOGRAGE_REJECT = [:sql_queries, :sql_queries_count]
236
+
237
+ # Console formatter configuration
238
+ console_formatter = Ougai::Formatters::Customizable.new(
239
+ format_msg: proc do |severity, datetime, _progname, data|
240
+ # Remove :msg regardless the outcome
241
+ msg = data.delete(:msg)
242
+ # Lograge specfic stuff: do not print sql queries in main log message
243
+ if data.key?(:request)
244
+ lograge = data[:request].reject { |k, _v| LOGRAGE_REJECT.include?(k) }
245
+ .map { |key, val| "#{key}: #{val}" }
246
+ .join(', ')
247
+ msg = color_config.color(:msg, lograge, severity)
248
+ # Standard text
249
+ else
250
+ msg = color_config.color(:msg, msg, severity)
251
+ end
252
+
253
+ # Standardize output
254
+ format('%s %s: %s',
255
+ color_config.color(:severity, severity, severity),
256
+ color_config.color(:datetime, datetime, severity),
257
+ msg)
258
+ end,
259
+ format_data: proc do |data|
260
+ # Lograge specfic stuff: main controller output handled by msg formatter
261
+ if data.key?(:request)
262
+ lograge_data = data[:request]
263
+ # concatenate SQL queries
264
+ if lograge_data.key?(:sql_queries)
265
+ lograge_data[:sql_queries].map do |sql_query|
266
+ format('%<duration>6.2fms %<name>25s %<sql>s', sql_query)
267
+ end
268
+ .join("\n")
269
+ # no queries: nothing to print
270
+ else
271
+ nil
272
+ end
273
+ # Default styling
274
+ else
275
+ # report excluded field parameter here: no need to add it to options
276
+ EXCLUDED_FIELD.each { |field| data.delete(field) }
277
+ next nil if data.empty?
278
+
279
+ # report plain parameter here: no need to add it to options
280
+ data.ai(plain: false)
281
+ end
282
+ end
283
+ )
284
+ console_formatter.datetime_format = '%H:%M:%S.%L' # local development: need only time
285
+
286
+ # Define console logger
287
+ console_logger = Log::Ougai::Logger.new(STDOUT)
288
+ console_logger.formatter = console_formatter
289
+
290
+ # Not this gem related: define file logger
291
+ file_logger = Log::Ougai::Logger.new(Rails.root.join('log/ougai.log'))
292
+ file_logger.formatter = Ougai::Formatters::Bunyan.new
293
+
294
+ # Extend console logger to file logger
295
+ console_logger.extend(Ougai::Logger.broadcast(file_logger))
296
+
297
+ # Assign Ougai logger
298
+ config.logger = console_logger
299
+ ```
300
+
301
+ Output looks like
302
+ ![Screenshot](https://raw.githubusercontent.com/Al-un/ougai-formatters-customizable/master/images/screenshot.png)
303
+
304
+
305
+ ## Contributing
306
+
307
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Al-un/ougai-formatters-customizable.
308
+
309
+ ## License
310
+
311
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -16,30 +16,51 @@ module Ougai
16
16
 
17
17
  # Reset formatting. To be appended after every formatted text
18
18
  RESET = "\e[0m"
19
- # Foreground colors
19
+ # Font black color
20
20
  BLACK = "\e[30m"
21
+ # Font red color
21
22
  RED = "\e[31m"
23
+ # Font green color
22
24
  GREEN = "\e[32m"
25
+ # Font yello color
23
26
  YELLOW = "\e[33m"
27
+ # Font blue color
24
28
  BLUE = "\e[34m"
29
+ # Font purple color
25
30
  PURPLE = "\e[35m"
31
+ # Font cyan color
26
32
  CYAN = "\e[36m"
33
+ # Font white color
27
34
  WHITE = "\e[37m"
35
+ # Font bright/bold red color
28
36
  BOLD_RED = "\e[1;31m"
37
+ # Font bright/bold green color
29
38
  BOLD_GREEN = "\e[1;32m"
39
+ # Font bright/bold yellow color
30
40
  BOLD_YELLOW = "\e[1;33m"
41
+ # Font bright/bold blue color
31
42
  BOLD_BLUE = "\e[1;34m"
32
- BOLD_MAGENTA = "\e[1;35m"
43
+ # Font bright/bold purple color
44
+ BOLD_PURPLE = "\e[1;35m"
45
+ # Font bright/bold cyan color
33
46
  BOLD_CYAN = "\e[1;36m"
47
+ # Font bright/bold white color
34
48
  BOLD_WHITE = "\e[1;37m"
35
- # Background colors
49
+ # Background black color
36
50
  BG_BLACK = "\e[40m"
51
+ # Background red color
37
52
  BG_RED = "\e[41m"
53
+ # Background green color
38
54
  BG_GREEN = "\e[42m"
55
+ # Background yellow color
39
56
  BG_YELLOW = "\e[43m"
57
+ # Background blue color
40
58
  BG_BLUE = "\e[44m"
41
- BG_MAGENTA = "\e[45m"
59
+ # Background purple color
60
+ BG_PURPLE = "\e[45m"
61
+ # Background cyan color
42
62
  BG_CYAN = "\e[46m"
63
+ # Background white color
43
64
  BG_WHITE = "\e[47m"
44
65
 
45
66
  class << self
@@ -53,8 +74,9 @@ module Ougai
53
74
  # above or have a complete custom String value depending on the
54
75
  # terminal. If +nil+, text is not modified.
55
76
  # @param [String] text text to be colored
56
- # @param [String] reset reset font styling escape sequence. Default
57
- # to +\e[0m+
77
+ # @param [String] reset reset font styling escape sequence
78
+ #
79
+ # @return [String] colored or uncolored text
58
80
  def color_text(color, text, reset = Ougai::Formatters::Colors::RESET)
59
81
  return text if color.nil?
60
82
 
@@ -9,10 +9,11 @@ module Ougai
9
9
  # The configuration,split by subject such as +level+, +msg+,
10
10
  # or +datetime+ is basically a Hash: +config+ with the subject as key
11
11
  # and values. Values can be have three types:
12
- # - String: the color escape sequence for the subject
13
- # - Hash: the color escape sequence per severity. If not all severities
14
- # are defined, a +:default+ value must be defined
15
- # - Symbol: refers to another key and same coloring is applied
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
16
17
  class Configuration
17
18
  class << self
18
19
  # list default color configuration
@@ -20,6 +21,7 @@ module Ougai
20
21
  # +Ougai::Logging::Severity#to_label+
21
22
  # @note values are copied from +Ougai::Formatters::Readable+ coloring
22
23
  # values
24
+ # @return [Hash] default color configuration is severities only
23
25
  def default_configuration
24
26
  {
25
27
  severity: {
@@ -35,10 +37,14 @@ module Ougai
35
37
  end
36
38
  end
37
39
 
38
- # @param [Hash] configuration Color configuration mapping. Cannot be nil
39
- # @param [Boolean] load_default_config If true, then default configuration
40
- # values is fetched to fill missing value from the provided
41
- # configuration. Default is true.
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
42
48
  def initialize(configuration = {})
43
49
  # check if loading or not from default configuration
44
50
  if configuration.fetch(:load_default_config) { true }
@@ -62,10 +68,13 @@ module Ougai
62
68
  end
63
69
  end
64
70
 
71
+ # Convenience method to color a subject for a given log severity
72
+ #
65
73
  # @param [Symbol] subject_key to fetch the color to color the text
66
74
  # @param [String] text to be colored text
67
75
  # @param [Symbol] severity log level
68
- # @return a colored text depending on the subject
76
+ #
77
+ # @return [String] a colored text depending on the subject
69
78
  def color(subject_key, text, severity)
70
79
  color = get_color_for(subject_key, severity)
71
80
  Ougai::Formatters::Colors.color_text(color, text)
@@ -78,12 +87,14 @@ module Ougai
78
87
  # +get_color_for+ handles color inheritance: if a subject inherit color
79
88
  # from another subject, subject value is the symbol refering to the
80
89
  # other subject.
81
- # !!WARNING!!: Circular references are not checked and lead to infinite
90
+ #
91
+ # @note !!WARNING!!: Circular references are not checked and lead to infinite
82
92
  # loop
83
93
  #
84
- # @param [Symbol] subject_key: to define the color to color the text
85
- # @param [Symbol] severity: log level
86
- # @return requested color String value or +nil+ if not colored
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
87
98
  def get_color_for(subject_key, severity)
88
99
  # no colorization
89
100
  return nil unless @config.key?(subject_key)
@@ -1,145 +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 with three procs:
17
- # +format_msg+ Format message. Proc arguments are
18
- # +|level, datetime, progname, data|+. This block must
19
- # remove the key +:msg+ from +data+
20
- # +format_data+ Format data. Proc argument is +|data|+.
21
- # +format_err+ Format err. Proc argument is +|data|+. The proc must
22
- # remove the key +:err+
23
- class Customizable < Ougai::Formatters::Base
24
- class << self
25
- # Define the default main log message formatting to use.
26
- # @param [Ougai::Formatters::Colors::Configuration] color_config: the
27
- # color configuration to use. Cannot be null but can have an
28
- # empty +config+ hash meaning that there is no colorization
29
- def default_msg_format(color_config)
30
- proc do |severity, datetime, _progname, data|
31
- msg = data.delete(:msg)
32
- severity = color_config.color(:severity, severity, severity)
33
-
34
- "[#{datetime}] #{severity}: #{msg}"
35
- end
36
- end
37
-
38
- # Define the default error formatting to use.
39
- # @param [Array<Symbol>] excluded_fields list of key to exclude from
40
- # +data+ before printing logs
41
- # @param [Boolean] plain parameter to define if Awesome-Print renders
42
- # in plain mode or not
43
- def default_data_format(excluded_fields, plain)
44
- proc do |data|
45
- excluded_fields.each { |field| data.delete(field) }
46
- next nil if data.empty?
47
-
48
- data.ai(plain: plain)
49
- end
50
- end
51
-
52
- # Define the default error formatting to use.
53
- # @param [Integer] trace_indent space indentation to prepend before
54
- # trace content
55
- def default_err_format(trace_indent = 4)
56
- proc do |data|
57
- next nil unless data.key?(:err)
58
-
59
- err = data.delete(:err)
60
- err_str = " #{err[:name]} (#{err[:message]}):"
61
- err_str += "\n" + (' ' * trace_indent) + err[:stack] if err.key?(:stack)
62
- err_str
63
- end
64
- end
65
- end
66
-
67
- # Intialize a formatter
68
- #
69
- # @param [String] app_name application name (execution program name if nil)
70
- # @param [String] hostname hostname (hostname if nil)
71
- # @param [Hash] opts the initial values of attributes
72
- # @option opts [String] :trace_max_lines (100) the value of trace_max_lines attribute
73
- # @option opts [String] :plain (false) the value of plain attribute
74
- # @option opts [String] :excluded_fields ([]) the value of excluded_fields attribute
75
- # @option opts [Ougai::Formatters::Colors::Configuration] :color_config
76
- # assign a color configuration. Takes predecence over :colors
77
- # @option opts [Proc] :format_msg main message formatter
78
- # @option opts [Proc] :format_data data formatter
79
- # @option opts [Proc] :format_err error formatter
80
- def initialize(app_name = nil, hostname = nil, opts = {})
81
- aname, hname, opts = Base.parse_new_params([app_name, hostname, opts])
82
- super(aname, hname, opts)
83
-
84
- # Message logging
85
- color_config = opts.fetch(:color_config) {
86
- color_config = Ougai::Formatters::Colors::Configuration.new({})
87
- }
88
- @format_msg = opts.fetch(:format_msg) {
89
- Customizable.default_msg_format(color_config)
90
- }
91
-
92
- # Data logging
93
- plain = opts.fetch(:plain) { false }
94
- excluded_fields = opts[:excluded_fields] || []
95
- @format_data = opts.fetch(:format_data) {
96
- Customizable.default_data_format(excluded_fields, plain)
97
- }
98
-
99
- # Error logging
100
- trace_indent = opts.fetch(:trace_indent) { 4 }
101
- @format_err = opts.fetch(:format_err) {
102
- Customizable.default_err_format(trace_indent)
103
- }
104
-
105
- # Ensure dependency are present
106
- load_dependent
107
- end
108
-
109
- # Format a log entry
110
- #
111
- # @param [String] severity log severity, in capital letters
112
- # @param [Time] time timestamp of the log. Is formatted by +strftime+
113
- # @param [String] progname optional program name
114
- # @param [Hash] data log data. Main message is stored under the key +:msg+
115
- # while errors are logged under the key +:err+.
116
- def _call(severity, time, progname, data)
117
- strs = ''.dup
118
- # Main message
119
- dt = format_datetime(time)
120
- msg_str = @format_msg.call(severity, dt, progname, data)
121
- strs.concat(msg_str)
122
-
123
- # Error: displayed before additional data
124
- err_str = @format_err.call(data)
125
- strs.concat("\n").concat(err_str) unless err_str.nil?
126
-
127
- # Additional data
128
- data_str = @format_data.call(data)
129
- strs.concat("\n").concat(data_str) unless data_str.nil?
130
-
131
- strs.concat("\n")
132
- end
133
-
134
- protected
135
-
136
- # Ensure `awesompe_print` is loaded
137
- def load_dependent
138
- require 'awesome_print'
139
- rescue LoadError
140
- puts 'You must install the awesome_print gem to use this output.'
141
- raise
142
- end
143
- end
144
- end
145
- 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 awesome-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 Awesome-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 'awesome_print'
154
+ rescue LoadError
155
+ puts 'You must install the awesome_print gem to use this output.'
156
+ raise
157
+ end
158
+ end
159
+ end
160
+ end
@@ -1,7 +1,8 @@
1
- # frozen_string_literal: true
2
-
3
- module Ougai
4
- module Formatters
5
- CUSTOMIZABLE_VERSION = '0.1.0'
6
- end
7
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Ougai
4
+ module Formatters
5
+ # Customizable extension version
6
+ CUSTOMIZABLE_VERSION = '1.0.0'
7
+ end
8
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ougai-formatters-customizable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Al-un
@@ -92,6 +92,34 @@ dependencies:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
94
  version: '3.0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: simplecov
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: simplecov-console
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
95
123
  description: |2
96
124
  This library aims at providing a fully flexible formatter compatible with the
97
125
  Ougai library. Customization is about colorization and log formatting.