console 1.8.2 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/console.rb +23 -5
- data/lib/console/event.rb +1 -0
- data/lib/console/event/progress.rb +75 -0
- data/lib/console/logger.rb +5 -0
- data/lib/console/measure.rb +115 -0
- data/lib/console/version.rb +1 -1
- metadata +11 -19
- data/.editorconfig +0 -6
- data/.gitignore +0 -12
- data/.rspec +0 -4
- data/.travis.yml +0 -19
- data/Gemfile +0 -8
- data/README.md +0 -212
- data/Rakefile +0 -6
- data/console.gemspec +0 -27
- data/proposal.md +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79f9ed13eedb54202ce2111a451e6e7d744f97db971a6b619ba3decb5aa6c963
|
4
|
+
data.tar.gz: 8c77221c0e50be91b7c1857fde7b596ec7e48eebd67a43287bd01aa3f95e70b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 021e0bd5c98d7019af39186b6fa06e49aed619cb5228051a85725bd43f3f05d8015b6d9bc84baf3a49f51a9b13ac62ed65cb20051f9561939d0fb72c791b8475
|
7
|
+
data.tar.gz: '029abdaded5a4d383e7e4b666c99e2b06c0aaabed87c1da9740c6925ca5e9308eb41b52d61835e0b6a3223efff9b25a98aac555fe43c2ca441ef48f5f27e6f3f'
|
data/lib/console.rb
CHANGED
@@ -43,14 +43,32 @@ module Console
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
# You can change the log level for different classes using CONSOLE_<LEVEL> env vars.
|
47
|
+
#
|
48
|
+
# e.g. `CONSOLE_WARN=Acorn,Banana CONSOLE_DEBUG=Cat` will set the log level for Acorn and Banana to warn and Cat to
|
49
|
+
# debug. This overrides the default log level.
|
50
|
+
#
|
51
|
+
# @param logger [Logger] A logger instance to set the logging levels on.
|
52
|
+
# @param env [Hash] Environment to read levels from.
|
53
|
+
#
|
54
|
+
# @return [nil] if there were no custom logging levels specified in the environment.
|
55
|
+
# @return [Resolver] if there were custom logging levels, then the created resolver is returned.
|
46
56
|
def default_resolver(logger, env = ENV)
|
47
|
-
|
57
|
+
# find all CONSOLE_<LEVEL> variables from environment
|
58
|
+
levels = Logger::LEVELS
|
59
|
+
.map { |label, level| [level, env["CONSOLE_#{label.to_s.upcase}"]&.split(',')] }
|
60
|
+
.to_h
|
61
|
+
.compact
|
62
|
+
|
63
|
+
# if we have any levels, then create a class resolver, and each time a class is resolved, set the log level for
|
64
|
+
# that class to the specified level
|
65
|
+
if levels.any?
|
48
66
|
resolver = Resolver.new
|
49
|
-
|
50
|
-
|
51
|
-
|
67
|
+
levels.each do |level, names|
|
68
|
+
resolver.bind(names) do |klass|
|
69
|
+
logger.enable(klass, level)
|
70
|
+
end
|
52
71
|
end
|
53
|
-
|
54
72
|
return resolver
|
55
73
|
end
|
56
74
|
end
|
data/lib/console/event.rb
CHANGED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'generic'
|
22
|
+
|
23
|
+
module Console
|
24
|
+
module Event
|
25
|
+
class Progress < Generic
|
26
|
+
BLOCK = [
|
27
|
+
" ",
|
28
|
+
"▏",
|
29
|
+
"▎",
|
30
|
+
"▍",
|
31
|
+
"▌",
|
32
|
+
"▋",
|
33
|
+
"▊",
|
34
|
+
"▉",
|
35
|
+
"█",
|
36
|
+
]
|
37
|
+
|
38
|
+
def initialize(current, total)
|
39
|
+
@current = current
|
40
|
+
@total = total
|
41
|
+
end
|
42
|
+
|
43
|
+
attr :current
|
44
|
+
attr :total
|
45
|
+
|
46
|
+
def value
|
47
|
+
@current.to_f / @total.to_f
|
48
|
+
end
|
49
|
+
|
50
|
+
def bar(value = self.value, width = 70)
|
51
|
+
blocks = width * value
|
52
|
+
full_blocks = blocks.floor
|
53
|
+
partial_block = ((blocks - full_blocks) * BLOCK.size).floor
|
54
|
+
|
55
|
+
if partial_block.zero?
|
56
|
+
BLOCK.last * full_blocks
|
57
|
+
else
|
58
|
+
"#{BLOCK.last * full_blocks}#{BLOCK[partial_block]}"
|
59
|
+
end.ljust(width)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.register(terminal)
|
63
|
+
terminal[:progress_bar] ||= terminal.style(:blue, :white)
|
64
|
+
end
|
65
|
+
|
66
|
+
def as_json
|
67
|
+
{current: @current, total: @total}
|
68
|
+
end
|
69
|
+
|
70
|
+
def format(output, terminal, verbose)
|
71
|
+
output.puts "#{terminal[:progress_bar]}#{self.bar}#{terminal.reset} #{sprintf('%6.2f', self.value * 100)}%"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/console/logger.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require_relative 'filter'
|
22
|
+
require_relative 'measure'
|
22
23
|
|
23
24
|
module Console
|
24
25
|
class Logger < Filter[debug: 0, info: 1, warn: 2, error: 3, fatal: 4]
|
@@ -27,5 +28,9 @@ module Console
|
|
27
28
|
def initialize(output, **options)
|
28
29
|
super(output, **options)
|
29
30
|
end
|
31
|
+
|
32
|
+
def measure(subject, total)
|
33
|
+
Measure.new(self, subject, total)
|
34
|
+
end
|
30
35
|
end
|
31
36
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
module Console
|
22
|
+
class Measure
|
23
|
+
def initialize(output, subject, total = 0)
|
24
|
+
@output = output
|
25
|
+
@subject = subject
|
26
|
+
|
27
|
+
@start_time = Time.now
|
28
|
+
|
29
|
+
@current = 0
|
30
|
+
@total = total
|
31
|
+
end
|
32
|
+
|
33
|
+
attr :subject
|
34
|
+
|
35
|
+
attr :current
|
36
|
+
|
37
|
+
attr :total
|
38
|
+
|
39
|
+
def duration
|
40
|
+
Time.now - @start_time
|
41
|
+
end
|
42
|
+
|
43
|
+
def progress
|
44
|
+
@current.to_f / @total.to_f
|
45
|
+
end
|
46
|
+
|
47
|
+
def remaining
|
48
|
+
@total - @current
|
49
|
+
end
|
50
|
+
|
51
|
+
def average_duration
|
52
|
+
if @current > 0
|
53
|
+
duration / @current
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def estimated_remaining_time
|
58
|
+
if average_duration = self.average_duration
|
59
|
+
average_duration * remaining
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def increment(amount = 1)
|
64
|
+
@current += amount
|
65
|
+
|
66
|
+
@output.info(@subject, self) {Event::Progress.new(@current, @total)}
|
67
|
+
|
68
|
+
return self
|
69
|
+
end
|
70
|
+
|
71
|
+
def resize(total)
|
72
|
+
@total = total
|
73
|
+
|
74
|
+
@output.info(@subject, self) {Event::Progress.new(@current, @total)}
|
75
|
+
|
76
|
+
return self
|
77
|
+
end
|
78
|
+
|
79
|
+
def mark(*arguments)
|
80
|
+
@output.info(@subject, *arguments)
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_s
|
84
|
+
if estimated_remaining_time = self.estimated_remaining_time
|
85
|
+
"#{@current}/#{@total} completed in #{self.formatted_duration self.duration}, #{self.formatted_duration estimated_remaining_time} remaining."
|
86
|
+
else
|
87
|
+
"#{@current}/#{@total} completed, waiting for estimate..."
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def formatted_duration(duration)
|
94
|
+
if duration < 60.0
|
95
|
+
return "#{duration.round(2)}s"
|
96
|
+
end
|
97
|
+
|
98
|
+
duration /= 60.0
|
99
|
+
|
100
|
+
if duration < 60.0
|
101
|
+
return "#{duration.round}m"
|
102
|
+
end
|
103
|
+
|
104
|
+
duration /= 60.0
|
105
|
+
|
106
|
+
if duration < 60.0
|
107
|
+
return "#{duration.round(1)}h"
|
108
|
+
end
|
109
|
+
|
110
|
+
duration /= 24.0
|
111
|
+
|
112
|
+
return "#{duration.round(1)}d"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/console/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: console
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bake
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: covered
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -80,31 +80,24 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.0'
|
83
|
-
description:
|
83
|
+
description:
|
84
84
|
email:
|
85
|
-
- samuel.williams@oriontransfer.co.nz
|
86
85
|
executables: []
|
87
86
|
extensions: []
|
88
87
|
extra_rdoc_files: []
|
89
88
|
files:
|
90
|
-
- ".editorconfig"
|
91
|
-
- ".gitignore"
|
92
|
-
- ".rspec"
|
93
|
-
- ".travis.yml"
|
94
|
-
- Gemfile
|
95
|
-
- README.md
|
96
|
-
- Rakefile
|
97
89
|
- bake/console.rb
|
98
|
-
- console.gemspec
|
99
90
|
- lib/console.rb
|
100
91
|
- lib/console/buffer.rb
|
101
92
|
- lib/console/capture.rb
|
102
93
|
- lib/console/event.rb
|
103
94
|
- lib/console/event/failure.rb
|
104
95
|
- lib/console/event/generic.rb
|
96
|
+
- lib/console/event/progress.rb
|
105
97
|
- lib/console/event/spawn.rb
|
106
98
|
- lib/console/filter.rb
|
107
99
|
- lib/console/logger.rb
|
100
|
+
- lib/console/measure.rb
|
108
101
|
- lib/console/resolver.rb
|
109
102
|
- lib/console/serialized/logger.rb
|
110
103
|
- lib/console/split.rb
|
@@ -113,12 +106,11 @@ files:
|
|
113
106
|
- lib/console/terminal/text.rb
|
114
107
|
- lib/console/terminal/xterm.rb
|
115
108
|
- lib/console/version.rb
|
116
|
-
- proposal.md
|
117
109
|
homepage: https://github.com/socketry/console
|
118
110
|
licenses:
|
119
111
|
- MIT
|
120
112
|
metadata: {}
|
121
|
-
post_install_message:
|
113
|
+
post_install_message:
|
122
114
|
rdoc_options: []
|
123
115
|
require_paths:
|
124
116
|
- lib
|
@@ -126,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
118
|
requirements:
|
127
119
|
- - ">="
|
128
120
|
- !ruby/object:Gem::Version
|
129
|
-
version: '
|
121
|
+
version: '2.5'
|
130
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
123
|
requirements:
|
132
124
|
- - ">="
|
@@ -134,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
126
|
version: '0'
|
135
127
|
requirements: []
|
136
128
|
rubygems_version: 3.1.2
|
137
|
-
signing_key:
|
129
|
+
signing_key:
|
138
130
|
specification_version: 4
|
139
131
|
summary: Beautiful logging for Ruby.
|
140
132
|
test_files: []
|
data/.editorconfig
DELETED
data/.gitignore
DELETED
data/.rspec
DELETED
data/.travis.yml
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
dist: xenial
|
3
|
-
cache: bundler
|
4
|
-
|
5
|
-
matrix:
|
6
|
-
include:
|
7
|
-
- rvm: 2.4
|
8
|
-
- rvm: 2.5
|
9
|
-
- rvm: 2.6
|
10
|
-
- rvm: 2.7
|
11
|
-
- rvm: 2.6
|
12
|
-
env: COVERAGE=PartialSummary,Coveralls
|
13
|
-
- rvm: truffleruby
|
14
|
-
- rvm: jruby-head
|
15
|
-
- rvm: ruby-head
|
16
|
-
allow_failures:
|
17
|
-
- rvm: truffleruby
|
18
|
-
- rvm: ruby-head
|
19
|
-
- rvm: jruby-head
|
data/Gemfile
DELETED
data/README.md
DELETED
@@ -1,212 +0,0 @@
|
|
1
|
-
# Console
|
2
|
-
|
3
|
-
Provides beautiful console logging for Ruby applications. Implements fast, buffered log output.
|
4
|
-
|
5
|
-
[![Build Status](https://travis-ci.com/socketry/console.svg)](http://travis-ci.com/socketry/console)
|
6
|
-
[![Coverage Status](https://coveralls.io/repos/socketry/console/badge.svg)](https://coveralls.io/r/socketry/console)
|
7
|
-
|
8
|
-
## Motivation
|
9
|
-
|
10
|
-
When Ruby decided to reverse the order of exception backtraces, I finally gave up using the built in logging and decided restore sanity to the output of my programs once and for all!
|
11
|
-
|
12
|
-
## Installation
|
13
|
-
|
14
|
-
Add this line to your application's Gemfile:
|
15
|
-
|
16
|
-
```ruby
|
17
|
-
gem 'console'
|
18
|
-
```
|
19
|
-
|
20
|
-
And then execute:
|
21
|
-
|
22
|
-
$ bundle
|
23
|
-
|
24
|
-
## Usage
|
25
|
-
|
26
|
-
As your code executes, it generates interesting events which you want to know about. The general approach is to use an `Console::Logger` which outputs text to the terminal. The text is generated by inspecting the console that occurred.
|
27
|
-
|
28
|
-
Capturing structured information allows it to be used in different ways. These events can be sent to a logger or some other system (e.g. web browser, syslog) and analysed in more detail.
|
29
|
-
|
30
|
-
### Default Logger
|
31
|
-
|
32
|
-
Generally speaking, use `Console.logger` which is suitable for logging to the user's terminal.
|
33
|
-
|
34
|
-
### Environment Variables
|
35
|
-
|
36
|
-
#### `CONSOLE_LEVEL=debug`
|
37
|
-
|
38
|
-
Control the default logger level. You can set it to any of the supported log levels: `debug`, `info`, `warn`, `error`, `fatal`.
|
39
|
-
|
40
|
-
#### `CONSOLE_DEBUG=MyClass,MyModule::MyClass`
|
41
|
-
|
42
|
-
Enable debug logging for the specified class names. You can specify one or more class names which will be resolved at runtime.
|
43
|
-
|
44
|
-
### Module Integration
|
45
|
-
|
46
|
-
```ruby
|
47
|
-
require 'console'
|
48
|
-
|
49
|
-
# Set the log level:
|
50
|
-
Console.logger.debug!
|
51
|
-
|
52
|
-
module MyModule
|
53
|
-
extend Console
|
54
|
-
|
55
|
-
def self.test_logger
|
56
|
-
logger.debug "GOTO LINE 1."
|
57
|
-
logger.info "5 things your doctor won't tell you!"
|
58
|
-
logger.warn "Something didn't work as expected!"
|
59
|
-
logger.error "The matrix has two cats!"
|
60
|
-
end
|
61
|
-
|
62
|
-
test_logger
|
63
|
-
end
|
64
|
-
```
|
65
|
-
|
66
|
-
### Class Integration
|
67
|
-
|
68
|
-
```ruby
|
69
|
-
require 'console'
|
70
|
-
|
71
|
-
# Set the log level:
|
72
|
-
Console.logger.debug!
|
73
|
-
|
74
|
-
class MyObject
|
75
|
-
include Console
|
76
|
-
|
77
|
-
def test_logger
|
78
|
-
logger.debug "GOTO LINE 1."
|
79
|
-
logger.info "5 things your doctor won't tell you!"
|
80
|
-
logger.warn "Something didn't work as expected!"
|
81
|
-
logger.error "The matrix has two cats!"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
MyObject.new.test_logger
|
86
|
-
```
|
87
|
-
|
88
|
-
### Subject Logging
|
89
|
-
|
90
|
-
The first argument to the log method is the subject.
|
91
|
-
|
92
|
-
```ruby
|
93
|
-
class Thing
|
94
|
-
def call
|
95
|
-
Console.logger.info(self) {"Something is going on"}
|
96
|
-
end
|
97
|
-
end
|
98
|
-
```
|
99
|
-
|
100
|
-
Using this approach, you can turn on and off specific subjects by using the class name:
|
101
|
-
|
102
|
-
```ruby
|
103
|
-
$ CONSOLE_DEBUG=Thing ./script.rb
|
104
|
-
```
|
105
|
-
|
106
|
-
This will conditionally enable all log statements which have a subject of class `Thing`.
|
107
|
-
|
108
|
-
### Console Formatting
|
109
|
-
|
110
|
-
Console classes are used to wrap data which can generate structured log messages:
|
111
|
-
|
112
|
-
```ruby
|
113
|
-
require 'console'
|
114
|
-
|
115
|
-
class MyConsole < Console::Generic
|
116
|
-
def format(output, terminal, verbose)
|
117
|
-
output.puts "My console text!"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
Console.logger.info("My Console", MyConsole.new)
|
122
|
-
```
|
123
|
-
|
124
|
-
#### Failure Events
|
125
|
-
|
126
|
-
`Console::Event::Failure` represents an exception and will log the message and backtrace recursively.
|
127
|
-
|
128
|
-
#### Spawn Events
|
129
|
-
|
130
|
-
`Console::Event::Spawn` represents the execution of a command, and will log the environment, arguments and options used to execute it.
|
131
|
-
|
132
|
-
### Custom Log Levels
|
133
|
-
|
134
|
-
`Console::Filter` implements support for multiple log levels.
|
135
|
-
|
136
|
-
```ruby
|
137
|
-
require 'console'
|
138
|
-
|
139
|
-
MyLogger = Console::Filter[noise: 0, stuff: 1, broken: 2]
|
140
|
-
|
141
|
-
# verbose: true - log severity/name/pid etc.
|
142
|
-
logger = MyLogger.new(Console.logger, name: "Java", verbose: true)
|
143
|
-
|
144
|
-
logger.broken("It's so janky.")
|
145
|
-
```
|
146
|
-
|
147
|
-
### Multiple Outputs
|
148
|
-
|
149
|
-
Use `Console::Split` to log to multiple destinations.
|
150
|
-
|
151
|
-
```ruby
|
152
|
-
require 'console/terminal'
|
153
|
-
require 'console/serialized/logger'
|
154
|
-
require 'console/logger'
|
155
|
-
require 'console/split'
|
156
|
-
|
157
|
-
terminal = Console::Terminal::Logger.new
|
158
|
-
file = Console::Serialized::Logger.new(File.open("log.json", "a"))
|
159
|
-
|
160
|
-
logger = Console::Logger.new(Console::Split[terminal, file])
|
161
|
-
|
162
|
-
logger.info "I can go everywhere!"
|
163
|
-
```
|
164
|
-
|
165
|
-
### Custom Logger Output
|
166
|
-
|
167
|
-
`Console::Logger` provides a default interface which is a drop in replacemnet for `Logger` and other similar implementations. The only method required for output is `#call(*arguments, **options, &block)`.
|
168
|
-
|
169
|
-
```ruby
|
170
|
-
require 'console/logger'
|
171
|
-
|
172
|
-
output = proc do |*arguments, **options, &block|
|
173
|
-
puts "arguments: #{arguments.inspect} options: #{options.inspect} block: #{block.call}"
|
174
|
-
end
|
175
|
-
|
176
|
-
logger = Console::Logger.new(output)
|
177
|
-
|
178
|
-
logger.info("Hello World!", meta: "data") {"block"}
|
179
|
-
# => arguments: ["Hello World!"] options: {:severity=>:info, :meta=>"data"} block: block
|
180
|
-
```
|
181
|
-
|
182
|
-
## Contributing
|
183
|
-
|
184
|
-
1. Fork it
|
185
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
186
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
187
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
188
|
-
5. Create new Pull Request
|
189
|
-
|
190
|
-
## License
|
191
|
-
|
192
|
-
Released under the MIT license.
|
193
|
-
|
194
|
-
Copyright, 2019, by [Samuel Williams](https://www.codeotaku.com).
|
195
|
-
|
196
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
197
|
-
of this software and associated documentation files (the "Software"), to deal
|
198
|
-
in the Software without restriction, including without limitation the rights
|
199
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
200
|
-
copies of the Software, and to permit persons to whom the Software is
|
201
|
-
furnished to do so, subject to the following conditions:
|
202
|
-
|
203
|
-
The above copyright notice and this permission notice shall be included in
|
204
|
-
all copies or substantial portions of the Software.
|
205
|
-
|
206
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
207
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
208
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
209
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
210
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
211
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
212
|
-
THE SOFTWARE.
|
data/Rakefile
DELETED
data/console.gemspec
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
|
2
|
-
require_relative "lib/console/version"
|
3
|
-
|
4
|
-
Gem::Specification.new do |spec|
|
5
|
-
spec.name = "console"
|
6
|
-
spec.version = Console::VERSION
|
7
|
-
spec.licenses = ["MIT"]
|
8
|
-
spec.authors = ["Samuel Williams"]
|
9
|
-
spec.email = ["samuel.williams@oriontransfer.co.nz"]
|
10
|
-
|
11
|
-
spec.summary = "Beautiful logging for Ruby."
|
12
|
-
spec.homepage = "https://github.com/socketry/console"
|
13
|
-
|
14
|
-
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
15
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
-
end
|
17
|
-
|
18
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
-
spec.require_paths = ["lib"]
|
20
|
-
|
21
|
-
spec.add_development_dependency "bake"
|
22
|
-
|
23
|
-
spec.add_development_dependency "covered"
|
24
|
-
spec.add_development_dependency "bundler"
|
25
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
-
end
|
data/proposal.md
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
# Global Logger
|
2
|
-
|
3
|
-
Configure what logging looks like globally:
|
4
|
-
|
5
|
-
```ruby
|
6
|
-
Console.logger
|
7
|
-
```
|
8
|
-
|
9
|
-
Other logger instances would inherit their initial configuration from the global logger.
|
10
|
-
|
11
|
-
Rather than the output being configurable on the global logger, it would always route to `$stdout`. _Or perhaps no destinations should exist and you add one; there must be a way to attach a formatter to even the default destination._
|
12
|
-
|
13
|
-
# Adding Destinations
|
14
|
-
|
15
|
-
The global logger or any instance could log to multiple destinations:
|
16
|
-
|
17
|
-
```ruby
|
18
|
-
Console.add(some_io, formatter: some_formatter)
|
19
|
-
```
|
20
|
-
|
21
|
-
I _think_ that formatters would be defined on destinations. This would allow for writing in one format to `$stdout` and another to `syslog`, for example.
|
22
|
-
|
23
|
-
# Logger Instances
|
24
|
-
|
25
|
-
Named instances could be created with a given output:
|
26
|
-
|
27
|
-
```ruby
|
28
|
-
connection_logger = Console.new(:connection, output: ...)
|
29
|
-
```
|
30
|
-
|
31
|
-
Outputs would not reference an io object, but rather another named instance (defaulting to global). Again, Destinations + Formatters could be added to any instance. This would allow outputs to be chained.
|
32
|
-
|
33
|
-
## Instances As Subjects
|
34
|
-
|
35
|
-
Perhaps an interesting idea is letting logger instance names be subjects, controllable from the global logger. In the example above, `:connection` would become a known subject that could be enabled/disabled from the global logger:
|
36
|
-
|
37
|
-
```ruby
|
38
|
-
Console.disable(:connection)
|
39
|
-
```
|
40
|
-
|
41
|
-
This lets us very easily disable the logging of events of a particular type.
|
42
|
-
|
43
|
-
---
|
44
|
-
|
45
|
-
In [Pakyow's logger](https://gist.github.com/bryanp/0329d58c753f1fa6e99d970960ad006d#file-logger-rb), instances are created in these cases:
|
46
|
-
|
47
|
-
* Environment: Single logger for the environment, named `:pkyw`.
|
48
|
-
* Connection: Per-Request logger containing the connection id, named `:http`.
|
49
|
-
* WebSocket: Per-WebSocket logger containing the WebSocket id, named `:sock`.
|
50
|
-
* Async: The logger that async is configured with, named `:asnc`.
|
51
|
-
|
52
|
-
Instances could be initialized with metadata that is passed with the console to the formatter:
|
53
|
-
|
54
|
-
```ruby
|
55
|
-
connection_logger = Console.new(:http, output: ..., connection_id: "123")
|
56
|
-
```
|
57
|
-
|
58
|
-
# Formatters
|
59
|
-
|
60
|
-
Just a class with a `format` method that accepts an `console`, which is a hash or simple object containing the console data along with attached metadata (e.g. timestamp, metadata from the instance). Returns a string, and/or writes directly to the buffer.
|
61
|
-
|
62
|
-
# Custom Levels
|
63
|
-
|
64
|
-
Pakyow's logger uses the following levels:
|
65
|
-
|
66
|
-
* all
|
67
|
-
* verbose
|
68
|
-
* debug
|
69
|
-
* info
|
70
|
-
* warn
|
71
|
-
* error
|
72
|
-
* fatal
|
73
|
-
* unknown
|
74
|
-
* off
|
75
|
-
|
76
|
-
`all` and `off` aren't turned into logging methods in `Pakyow::Logger`, but rather the log level can be set to either one as an easy way to guarantee that all or no logs will be written, without knowing what the lowest and highest level of logging are in the system.
|
77
|
-
|
78
|
-
Projects often have different needs, so making this easily configurable on both the global logger and individual logger instances would be amazing:
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
Console.levels(
|
82
|
-
%i(all verbose debug info warn error fatal unknown off)
|
83
|
-
)
|
84
|
-
```
|