ougai-formatters-customizable 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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.