console 1.29.2 → 1.36.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/context/command-line.md +47 -0
  4. data/context/configuration.md +23 -0
  5. data/context/events.md +71 -0
  6. data/context/getting-started.md +170 -0
  7. data/context/index.yaml +28 -0
  8. data/context/integration.md +37 -0
  9. data/lib/console/capture.rb +29 -3
  10. data/lib/console/clock.rb +9 -3
  11. data/lib/console/compatible/logger.rb +34 -3
  12. data/lib/console/config.rb +96 -0
  13. data/lib/console/event/failure.rb +33 -4
  14. data/lib/console/event/generic.rb +22 -1
  15. data/lib/console/event/spawn.rb +39 -7
  16. data/lib/console/event.rb +7 -1
  17. data/lib/console/filter.rb +83 -7
  18. data/lib/console/format/safe.rb +205 -58
  19. data/lib/console/format.rb +5 -1
  20. data/lib/console/interface.rb +18 -10
  21. data/lib/console/logger.rb +25 -38
  22. data/lib/console/output/default.rb +31 -6
  23. data/lib/console/output/failure.rb +9 -2
  24. data/lib/console/output/null.rb +5 -2
  25. data/lib/console/output/sensitive.rb +42 -1
  26. data/lib/console/output/serialized.rb +32 -7
  27. data/lib/console/output/split.rb +12 -1
  28. data/lib/console/output/terminal.rb +68 -15
  29. data/lib/console/output/wrapper.rb +12 -1
  30. data/lib/console/output.rb +14 -3
  31. data/lib/console/progress.rb +56 -9
  32. data/lib/console/resolver.rb +19 -2
  33. data/lib/console/terminal/formatter/failure.rb +18 -6
  34. data/lib/console/terminal/formatter/progress.rb +16 -3
  35. data/lib/console/terminal/formatter/spawn.rb +16 -5
  36. data/lib/console/terminal/formatter.rb +16 -0
  37. data/lib/console/terminal/text.rb +66 -20
  38. data/lib/console/terminal/xterm.rb +18 -3
  39. data/lib/console/terminal.rb +7 -9
  40. data/lib/console/version.rb +2 -2
  41. data/lib/console/warn.rb +2 -2
  42. data/lib/console.rb +2 -1
  43. data/license.md +6 -3
  44. data/readme.md +60 -6
  45. data/releases.md +115 -1
  46. data.tar.gz.sig +0 -0
  47. metadata +20 -12
  48. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60457e10e6e444b206349262e1a13a45d2da0fa1aad7ecfa48f22e4b48e44eb8
4
- data.tar.gz: 2b9bc10d6e5981286f93fd573e4ca7afad7aa1da9399ec4e8f4f643e38afcc0c
3
+ metadata.gz: 749f01df7fec2a4868a2b4958b23ee328ddb2911b0fc2a635bdf298d901cae60
4
+ data.tar.gz: 32daa46920a77f0fa713685d0176dc24ed034fe39fe99cde3d1d789ecfb1c48b
5
5
  SHA512:
6
- metadata.gz: 0a2554093f2fd42567a2cfa5924518a9e689e19394630a88af25d3e89f20a29250d12dc0a63216aa719b49c6dd957f28e79a8fead0a35103a2c5930794791273
7
- data.tar.gz: 003a9d78b6d2835b63f202dcbf3d95618339b04a1f363e07b40a6502008be14b0a85a09b114a85d9b136083e8ce9fa4334371c1ba0fe53161d299e2f7cee4da6
6
+ metadata.gz: 51796e3366c0778f6e811428ff9e8aeffb0a34fe99ce0528488fd9931c392596c1a654f34e49781f68afd1377898ef16ce6aeaaa3a35c82c201bf4579f423073
7
+ data.tar.gz: 82af50570a7e55a26562cda15f7ccf5622bcc956ef6b6a065f4a1e38ecf663911f84ccf6a47de1443bc85f1b1e79effeec1fcbdccc21480c0b18b53872efdc13
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,47 @@
1
+ # Command Line
2
+
3
+ This guide explains how the `console` gem can be controlled using environment variables.
4
+
5
+ ## Environment Variables
6
+
7
+ The following program, `app.rb` will be used to explain the different environmet variables:
8
+
9
+ ~~~ ruby
10
+ #!/usr/bin/env ruby
11
+
12
+ require 'console'
13
+
14
+ class MyApplication
15
+ def do_work
16
+ Console.logger.debug(self, "Doing some work.")
17
+ end
18
+ end
19
+
20
+ Console.logger.debug(self, "Creating the application.")
21
+ application = MyApplication.new
22
+ application.do_work
23
+ ~~~
24
+
25
+ ### `CONSOLE_LEVEL=debug`
26
+
27
+ Control the default logger level. You can set it to any of the supported log levels: `debug`, `info`, `warn`, `error`, `fatal`.
28
+
29
+ By default, the debug level is not enabled, but you can enable it using `CONSOLE_LEVEL=debug`:
30
+
31
+ <pre>&gt; <font color="#00AFFF">CONSOLE_LEVEL</font><font color="#00A6B2">=</font><font color="#00AFFF">debug</font> <font color="#005FD7">./app.rb</font>
32
+ <font color="#00AAAA"> 0.0s debug:</font> <b>Object</b> <font color="#717171">[oid=0x3c] [ec=0x50] [pid=990900] [2022-10-12 17:28:15 +1300]</font>
33
+ | Creating the application.
34
+ <font color="#00AAAA"> 0.0s debug:</font> <b>MyApplication</b> <font color="#717171">[oid=0x64] [ec=0x50] [pid=990900] [2022-10-12 17:28:15 +1300]</font>
35
+ | Doing some work.
36
+ </pre>
37
+
38
+ ### `CONSOLE_DEBUG=MyClass,MyModule::MyClass`
39
+
40
+ Enable debug logging for the specified class names. You can specify one or more class names which will be resolved at runtime. This is specifically related to subject logging.
41
+
42
+ By default, the debug level is not enabled, but you can enable it for the specific `MyApplication` class using `CONSOLE_DEBUG=MyApplication`:
43
+
44
+ <pre>&gt; <font color="#00AFFF">CONSOLE_DEBUG</font><font color="#00A6B2">=</font><font color="#00AFFF">MyApplication</font> <font color="#005FD7">./app.rb</font>
45
+ <font color="#00AAAA"> 0.0s debug:</font> <b>MyApplication</b> <font color="#717171">[oid=0x64] [ec=0x78] [pid=991855] [2022-10-12 17:30:56 +1300]</font>
46
+ | Doing some work.
47
+ </pre>
@@ -0,0 +1,23 @@
1
+ # Configuration
2
+
3
+ This guide explains how to implement per-project configuration for the `console` gem.
4
+
5
+ ## Configuration File
6
+
7
+ The `console` gem can load a configuration file, by default `config/console.rb`. This file is evaluated in an instance of {ruby Console::Config} which allows you to override methods that implement the default behaviour for a given project.
8
+
9
+ Here is an example configuration file:
10
+
11
+ ```ruby
12
+ # config/console.rb
13
+
14
+ # Override the default log level
15
+ def log_level
16
+ :debug
17
+ end
18
+
19
+ # Override the default output
20
+ def make_output
21
+ Console::Output::Datadog.new(Console::Output::Default.new)
22
+ end
23
+ ```
data/context/events.md ADDED
@@ -0,0 +1,71 @@
1
+ # Events
2
+
3
+ This guide explains how to log structured events with a well-defined schema.
4
+
5
+ ## Overview
6
+
7
+ Logs often fall into two categories:
8
+
9
+ - Free-form logs which include some structured data, but are primarily text-based and used for debugging or troubleshooting.
10
+ - Structured logs which are designed to be machine-readable and can be used for monitoring, alerting, auditing and analytics.
11
+
12
+ Events are a type of structured log which are designed to be machine-readable and have a well-defined schema. They are used to represent a specific occurrence within a system, such as a request, a response, an error, or a warning. You can create custom events to represent any structured data you like.
13
+
14
+ ## Core Concepts
15
+
16
+ - {ruby Console::Event::Generic} is the base class for all events.
17
+ - {ruby Console::Terminal::Formatter} includes a collection of formatters for rendering specific events in a human-readable format.
18
+
19
+ ## Emitting Events
20
+
21
+ To emit an event, you can create an instance of a specific event class and call the `#emit` method. For example, to emit a failure event:
22
+
23
+ ```ruby
24
+ def handle_request
25
+ begin
26
+ # ... user code ...
27
+ rescue => error
28
+ Console::Event::Failure.for(error).emit(self, "Failed to handle request!")
29
+ end
30
+ end
31
+ ```
32
+
33
+ This will emit a failure event with the error message and backtrace.
34
+
35
+ ### Emitting Events with Different Severity Levels
36
+
37
+ Events can have different severity levels, such as `:info`, `:warn`, `:error`, and `:fatal`. You can specify the severity level when emitting an event:
38
+
39
+ ```ruby
40
+ Console::Event::Failure.for(error).emit(self, "Failed to handle request!", severity: :debug)
41
+ ```
42
+
43
+ ## Custom Events
44
+
45
+ You can create custom events by subclassing {ruby Console::Event::Generic} and defining the schema for the event. For example, to create a custom event for tracking user logins:
46
+
47
+ ```ruby
48
+ class UserLoginEvent < Console::Event::Generic
49
+ def self.for(request, user)
50
+ self.new(user.id, request.ip)
51
+ end
52
+
53
+ def new(id, ip)
54
+ @id = id
55
+ @ip = ip
56
+ end
57
+
58
+ def to_hash
59
+ {
60
+ # Specifying a type field is recommended:
61
+ type: :login,
62
+
63
+ # Custom fields:
64
+ id: @id,
65
+ ip: @ip
66
+ }
67
+ end
68
+ end
69
+
70
+ UserLoginEvent.for(request, user).emit(self, "User logged in.")
71
+ ```
@@ -0,0 +1,170 @@
1
+ # Getting Started
2
+
3
+ This guide explains how to use `console` for logging.
4
+
5
+ ## Installation
6
+
7
+ Add the gem to your project:
8
+
9
+ ~~~ bash
10
+ $ bundle add console
11
+ ~~~
12
+
13
+ ## Core Concepts
14
+
15
+ `console` has several core concepts:
16
+
17
+ - A log message which consists of a set of arguments and options, which includes a timestamp, severity, and other structured data.
18
+ - The {ruby Console} module which provides an abstract interface for logging.
19
+ - A {ruby Console::Logger} instance which is the main entry point for logging for a specific system and writes data to a given output formatter.
20
+ - An output instance such as {ruby Console::XTerm}, {ruby Console::Serialized::Logger} which formats these log messages and writes them to a specific output device.
21
+ - An event instance, such as {ruby Console::Event::Progress} or {ruby Console::Event::Spawn} which represents a structured event within a system, which can be formatted in a specific way.
22
+
23
+ ## Basic Logging
24
+
25
+ Out of the box, {ruby Console} provides a logger interface that outputs to the current terminal via `stderr`.
26
+
27
+ ~~~ ruby
28
+ require 'console'
29
+
30
+ Console.info("Hello World")
31
+ ~~~
32
+
33
+ <pre>
34
+ <font color="#00AA00"> 0.0s info:</font> <b>Hello World</b> <font color="#717171">[pid=219113] [2020-08-08 12:21:26 +1200]</font>
35
+ </pre>
36
+
37
+ The method name `info` indicates the severity level of the log message. You can filter out severity levels, and by default, `debug` messages are filtered out. Here are some examples of the different log levels:
38
+
39
+ ~~~ ruby
40
+ require 'console'
41
+
42
+ Console.debug("The input voltage has stabilized.")
43
+ Console.info("Making a request to the machine.")
44
+ Console.warn("The machine has detected a temperature anomaly.")
45
+ Console.error("The machine was unable to complete the request!")
46
+ Console.fatal("Depressurisation detected, evacuate the area!")
47
+ ~~~
48
+
49
+ From the terminal, you can control the log level using the `CONSOLE_LEVEL` environment variable. To log all messages including `debug`:
50
+
51
+ ~~~ bash
52
+ $ CONSOLE_LEVEL=debug ./machine
53
+ ~~~
54
+
55
+ Alternatively to restrict log messages to warnings and above:
56
+
57
+ ~~~ bash
58
+ $ CONSOLE_LEVEL=warn ./machine
59
+ ~~~
60
+
61
+ If otherwise unspecified, Ruby's standard `$DEBUG` and `$VERBOSE` global variables will be checked and adjust the log level appropriately.
62
+
63
+ ## Metadata
64
+
65
+ You can add any options you like to a log message and they will be included as part of the log output:
66
+
67
+ ~~~ ruby
68
+ duration = measure{...}
69
+ Console.info("Execution completed!", duration: duration)
70
+ ~~~
71
+
72
+ ## Subject Logging
73
+
74
+ The first argument to the log statement becomes the implicit subject of the log message.
75
+
76
+ ~~~ ruby
77
+ require 'console'
78
+
79
+ class Machine
80
+ def initialize(voltage)
81
+ @voltage = voltage.floor
82
+ Console.info(self, "The input voltage has stabilized.")
83
+ end
84
+ end
85
+
86
+ Machine.new(5.5)
87
+ ~~~
88
+
89
+ The given subject, in this case `self`, is used on the first line, along with associated metadata, while the message itself appears on subsequent lines:
90
+
91
+ <pre>
92
+ <font color="#00AA00"> 0.0s info:</font> <b>Machine</b> <font color="#717171">[oid=0x3c] [pid=219041] [2020-08-08 12:17:33 +1200]</font>
93
+ | The input voltage has stabilized.
94
+ </pre>
95
+
96
+ If you want to disable log messages which come from this particular class, you can execute your command:
97
+
98
+ ~~~ bash
99
+ $ CONSOLE_FATAL=Machine ./machine
100
+ ~~~
101
+
102
+ This will prevent any log message which has a subject of class `Machine` from logging messages of a severity less than `fatal`.
103
+
104
+ ## Exception Logging
105
+
106
+ If your code has an unhandled exception, you may wish to log it. In order to log a full backtrace, you must log the subject followed by the exception.
107
+
108
+ ~~~ ruby
109
+ require 'console'
110
+
111
+ class Cache
112
+ def initialize
113
+ @entries = {}
114
+ end
115
+
116
+ def fetch(key)
117
+ @entries.fetch(key)
118
+ rescue => error
119
+ Console.warn(self, "Cache fetch failure!", error)
120
+ end
121
+ end
122
+
123
+ Cache.new.fetch(:foo)
124
+ ~~~
125
+
126
+ This will produce the following output:
127
+
128
+ <pre><font color="#C01C28"> 0.0s error:</font> <b>Cache</b> <font color="#8B8A88">[oid=0x848] [ec=0x85c] [pid=571936] [2024-05-03 10:55:11 +1200]</font>
129
+ | Cache fetch failure!
130
+ | <font color="#C01C28"><b>KeyError</b></font>: <b>key not found: :foo (</b><u style="text-decoration-style:solid"><b>KeyError</b></u><b>)</b>
131
+ | → <font color="#C01C28">test.rb:15</font> in `fetch&apos;
132
+ | <font color="#C01C28">test.rb:15</font> in `fetch&apos;
133
+ | <font color="#C01C28">test.rb:21</font> in `&lt;top (required)&gt;&apos;
134
+ </pre>
135
+
136
+ ## Program Structure
137
+
138
+ Generally, programs should use the global `Console` interface to log messages.
139
+
140
+ Individual classes should not be catching and logging exceptions. It makes for simpler code if this is handled in a few places near the top of your program. Exceptions should collect enough information such that logging them produces a detailed backtrace leading to the failure.
141
+
142
+ ### Multiple Outputs
143
+
144
+ Use `Console::Split` to log to multiple destinations.
145
+
146
+ ``` ruby
147
+ require "console"
148
+ require "console/output/split"
149
+
150
+ terminal = Console::Output::Terminal.new($stderr)
151
+ serialized = Console::Output::Serialized.new(File.open("log.json", "a"))
152
+ Console.logger = Console::Logger.new(Console::Output::Split[terminal, serialized])
153
+
154
+ Console.info "I can go everywhere!"
155
+ ```
156
+
157
+ ### Custom Log Levels
158
+
159
+ `Console::Filter` implements support for multiple log levels.
160
+
161
+ ``` ruby
162
+ require "console"
163
+
164
+ MyLogger = Console::Filter[noise: 0, stuff: 1, broken: 2]
165
+
166
+ # verbose: true - log severity/name/pid etc.
167
+ logger = MyLogger.new(Console.logger, name: "Java", verbose: true)
168
+
169
+ logger.broken("It's so janky.")
170
+ ```
@@ -0,0 +1,28 @@
1
+ # Automatically generated context index for Utopia::Project guides.
2
+ # Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
3
+ ---
4
+ description: Beautiful logging for Ruby.
5
+ metadata:
6
+ documentation_uri: https://socketry.github.io/console/
7
+ funding_uri: https://github.com/sponsors/ioquatix/
8
+ source_code_uri: https://github.com/socketry/console.git
9
+ files:
10
+ - path: getting-started.md
11
+ title: Getting Started
12
+ description: This guide explains how to use `console` for logging.
13
+ - path: command-line.md
14
+ title: Command Line
15
+ description: This guide explains how the `console` gem can be controlled using environment
16
+ variables.
17
+ - path: configuration.md
18
+ title: Configuration
19
+ description: This guide explains how to implement per-project configuration for
20
+ the `console` gem.
21
+ - path: integration.md
22
+ title: Integration
23
+ description: This guide explains how to integrate the `console` output into different
24
+ systems.
25
+ - path: events.md
26
+ title: Events
27
+ description: This guide explains how to log structured events with a well-defined
28
+ schema.
@@ -0,0 +1,37 @@
1
+ # Integration
2
+
3
+ This guide explains how to integrate the `console` output into different systems.
4
+
5
+ ## Output Redirection
6
+
7
+ The `console` is primarily an interface for logging, with a general purpose implementation which can log to a terminal (human readable) or a file (JSON by default). Output can also be augmented, redirected or manipulated by adding output wrappers. The output wrappers are generally configured using environment variables.
8
+
9
+ ### `Console::Output::Datadog`
10
+
11
+ This output wrapper augments log messages with trace metadata so that the log messages can be correlated with spans. Note that the default output is still used `Console::Output::Default`.
12
+
13
+ ~~~ bash
14
+ $ CONSOLE_OUTPUT='Console::Output::Datadog,Console::Output::Default' ./app.rb
15
+ ~~~
16
+
17
+ The `Console::Output::Datadog` is a wrapper that augments the metadata of the log message with the `trace_id` and `span_id`.
18
+
19
+ ### Custom Output Wrapper
20
+
21
+ It's straight forward to define your own output wrapper:
22
+
23
+ ~~~ ruby
24
+ # Add a happy face to all log messages.
25
+ class HappyLogger
26
+ def call(subject = nil, *arguments, **options, &block)
27
+ arguments << "😊"
28
+
29
+ @output.call(subject, *arguments, **options, &block)
30
+ end
31
+ end
32
+ ~~~
33
+
34
+ ## Adapters
35
+
36
+ - [Console::Adapter::Rails](https://github.com/socketry/console-adapter-rails)
37
+ - [Console::Adapter::Sidekiq](https://github.com/socketry/console-adapter-sidekiq)
@@ -1,64 +1,90 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
5
5
 
6
6
  require_relative "filter"
7
7
  require_relative "output/failure"
8
8
 
9
9
  module Console
10
- # A general sink which captures all events into a buffer.
10
+ # A buffer which captures all logged messages into a buffer.
11
11
  class Capture
12
+ # Create a new log capture buffer.
12
13
  def initialize
13
14
  @records = []
14
15
  @verbose = false
15
16
  end
16
17
 
18
+ # @attribute [Array(Hash)] All records captured by this buffer.
17
19
  attr :records
18
20
 
19
- # @deprecated Use {#records} instead of {#buffer}.
21
+ # @deprecated Use {records} instead of {buffer}.
20
22
  alias buffer records
21
23
 
24
+ # @deprecated Use {records} instead of {to_a}.
22
25
  alias to_a records
23
26
 
27
+ # @attribute [Boolean] If true, the buffer will capture verbose messages.
24
28
  attr :verbose
25
29
 
30
+ # Whether the buffer includes any records with the given subject or message pattern.
31
+ #
32
+ # @returns [Boolean] True if the buffer includes any records with the given pattern.
26
33
  def include?(pattern)
27
34
  @records.any? do |record|
28
35
  record[:subject].to_s&.match?(pattern) or record[:message].to_s&.match?(pattern)
29
36
  end
30
37
  end
31
38
 
39
+ # Iterate over all records in the buffer.
40
+ #
41
+ # @yields {|record| ...} each record in the buffer.
42
+ # @parameter record [Hash] The record itself.
32
43
  def each(&block)
33
44
  @records.each(&block)
34
45
  end
35
46
 
36
47
  include Enumerable
37
48
 
49
+ # @returns [Hash] The first record in the buffer.
38
50
  def first
39
51
  @records.first
40
52
  end
41
53
 
54
+ # @returns [Hash] The last record in the buffer.
42
55
  def last
43
56
  @records.last
44
57
  end
45
58
 
59
+ # Clear all records from the buffer.
46
60
  def clear
47
61
  @records.clear
48
62
  end
49
63
 
64
+ # @returns [Boolean] True if the buffer is empty.
50
65
  def empty?
51
66
  @records.empty?
52
67
  end
53
68
 
69
+ # Sets the verbose flag which controls whether verbose messages are captured.
54
70
  def verbose!(value = true)
55
71
  @verbose = value
56
72
  end
57
73
 
74
+ # @returns [Boolean] True if the buffer is capturing verbose messages.
58
75
  def verbose?
59
76
  @verbose
60
77
  end
61
78
 
79
+ # Record a log message in the buffer.
80
+ #
81
+ # @parameter subject [Object] The subject of the log message.
82
+ # @parameter arguments [Array] The arguments to the log message.
83
+ # @parameter severity [Symbol] The severity of the log message.
84
+ # @parameter event [Event] The event associated with the log message.
85
+ # @parameter options [Hash] Additional options to pass to the log message.
86
+ # @yields {|buffer| ...} A block which can be used to write additional information to the log message.
87
+ # @parameter buffer [IO] The (optional) buffer to write to.
62
88
  def call(subject = nil, *arguments, severity: UNKNOWN, event: nil, **options, &block)
63
89
  record = {
64
90
  time: ::Time.now.iso8601,
data/lib/console/clock.rb CHANGED
@@ -1,13 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2021-2022, by Samuel Williams.
4
+ # Copyright, 2021-2025, by Samuel Williams.
5
+ # Copyright, 2026, by William T. Nelson.
5
6
 
6
7
  module Console
8
+ # A simple clock utility for tracking and formatting time.
7
9
  module Clock
10
+ # Format a duration in seconds as a human readable string.
11
+ #
12
+ # @parameter duration [Numeric] The duration in seconds.
13
+ # @returns [String] The formatted duration.
8
14
  def self.formatted_duration(duration)
9
15
  if duration < 60.0
10
- return "#{duration.round(2)}s"
16
+ return format("%.2fs", duration)
11
17
  end
12
18
 
13
19
  duration /= 60.0
@@ -27,7 +33,7 @@ module Console
27
33
  return "#{duration.floor}d"
28
34
  end
29
35
 
30
- # Get the current elapsed monotonic time.
36
+ # @returns [Time] The current monotonic time.
31
37
  def self.now
32
38
  ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
33
39
  end
@@ -1,35 +1,55 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2022-2024, by Samuel Williams.
4
+ # Copyright, 2022-2025, by Samuel Williams.
5
+ # Copyright, 2025, by Yasha Krasnou.
5
6
 
6
7
  require "logger"
7
8
 
8
9
  module Console
10
+ # @namespace
9
11
  module Compatible
10
12
  # A compatible interface for {::Logger} which can be used with {Console}.
11
13
  class Logger < ::Logger
14
+ # A compatible log device which can be used with {Console}. Suitable for use with code which (incorrectly) assumes that the log device a public interface and has certain methods/behaviours.
12
15
  class LogDevice
16
+ # Create a new log device.
17
+ #
18
+ # @parameter subject [String] The subject of the log messages.
19
+ # @parameter output [Console::Interface] The output interface.
13
20
  def initialize(subject, output)
14
21
  @subject = subject
15
22
  @output = output
16
23
  end
17
24
 
25
+ # Write a message to the log device.
26
+ #
27
+ # @parameter message [String] The message to write.
18
28
  def write(message)
19
29
  @output.call(@subject, message)
20
30
  end
21
31
 
32
+ # Log a message with the given severity.
33
+ #
34
+ # @paraemter arguments [Array] The arguments to log.
35
+ # @parameter options [Hash] Additional options.
22
36
  def call(*arguments, **options)
23
37
  @output.call(*arguments, **options)
24
38
  end
25
39
 
40
+ # Reopen the log device. This is a no-op.
26
41
  def reopen
27
42
  end
28
43
 
44
+ # Close the log device. This is a no-op.
29
45
  def close
30
46
  end
31
47
  end
32
-
48
+
49
+ # Create a new (compatible) logger.
50
+ #
51
+ # @parameter subject [String] The subject of the log messages.
52
+ # @parameter output [Console::Interface] The output interface.
33
53
  def initialize(subject, output = Console)
34
54
  super(nil)
35
55
 
@@ -37,7 +57,13 @@ module Console
37
57
  @logdev = LogDevice.new(subject, output)
38
58
  end
39
59
 
40
- def add(severity, message = nil, progname = nil)
60
+ # Log a message with the given severity.
61
+ #
62
+ # @parameter severity [Integer] The severity of the message.
63
+ # @parameter message [String] The message to log.
64
+ # @parameter progname [String] The program name.
65
+ # @returns [Boolean] True if the message was logged.
66
+ def add(severity, message = nil, progname = nil, **options)
41
67
  severity ||= UNKNOWN
42
68
 
43
69
  if @logdev.nil? or severity < level
@@ -59,12 +85,17 @@ module Console
59
85
 
60
86
  @logdev.call(
61
87
  progname, message,
88
+ **options,
62
89
  severity: format_severity(severity)
63
90
  )
64
91
 
65
92
  return true
66
93
  end
67
94
 
95
+ # Format the severity.
96
+ #
97
+ # @parameter value [Integer] The severity value.
98
+ # @returns [Symbol] The formatted severity.
68
99
  def format_severity(value)
69
100
  super.downcase.to_sym
70
101
  end