tty-logger 0.1.0 → 0.2.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.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Logger
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec-benchmark"
4
+
5
+ RSpec.describe TTY::Logger::Formatters::JSON do
6
+ include RSpec::Benchmark::Matchers
7
+
8
+ it "formats large hashes(2048 keys) 2x slower than the native JSON" do
9
+ large_data = Hash[Array.new(2048) { |i| [i + 1, "hey"] }]
10
+ formatter = described_class.new
11
+
12
+ expect {
13
+ formatter.dump(large_data)
14
+ }.to perform_slower_than {
15
+ ::JSON.dump(large_data)
16
+ }.at_least(2).times
17
+ end
18
+
19
+ it "formats large values 2x slower than the native JSON" do
20
+ large_data = { "foo" => "b#{'a'*2048}" }
21
+ formatter = described_class.new
22
+
23
+ expect {
24
+ formatter.dump(large_data)
25
+ }.to perform_slower_than {
26
+ ::JSON.dump(large_data)
27
+ }.at_least(2).times
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec-benchmark"
4
+ require "logger"
5
+
6
+ RSpec.describe TTY::Logger do
7
+ include RSpec::Benchmark::Matchers
8
+
9
+ let(:output) { StringIO.new }
10
+
11
+ it "performs 3x slower than native logger" do
12
+ native_logger = Logger.new(output)
13
+ logger = described_class.new(output: output)
14
+
15
+ expect {
16
+ logger.info("Deployment done!")
17
+ }.to perform_slower_than {
18
+ native_logger.info("Deployment done!")
19
+ }.at_least(3).times
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rspec-benchmark"
4
+
5
+ RSpec.describe TTY::Logger::Formatters::Text do
6
+ include RSpec::Benchmark::Matchers
7
+
8
+ it "formats large hashes(2048 keys) 1.25x slower than the native JSON" do
9
+ large_data = Hash[Array.new(2048) { |i| [i + 1, "hey"] }]
10
+ formatter = described_class.new
11
+
12
+ expect {
13
+ formatter.dump(large_data)
14
+ }.to perform_slower_than {
15
+ ::JSON.dump(large_data)
16
+ }.at_least(1.25).times
17
+ end
18
+
19
+ it "formats large values 4x slower than the native JSON" do
20
+ large_data = { "foo" => "b#{'a'*2048}" }
21
+ formatter = described_class.new
22
+
23
+ expect {
24
+ formatter.dump(large_data)
25
+ }.to perform_slower_than {
26
+ ::JSON.dump(large_data)
27
+ }.at_least(4).times
28
+ end
29
+ end
@@ -55,13 +55,15 @@ RSpec.describe TTY::Logger::Config do
55
55
  expect(config.to_h).to eq({
56
56
  date_format: "%F",
57
57
  formatter: :text,
58
+ filters: {},
58
59
  handlers: [:console],
59
60
  level: :info,
60
61
  max_bytes: 8192,
61
62
  max_depth: 3,
62
63
  metadata: [],
63
64
  output: $stderr,
64
- time_format: "%T.%3N"
65
+ time_format: "%T.%3N",
66
+ types: {}
65
67
  })
66
68
  end
67
69
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::Logger, "#copy" do
4
+ let(:output) { StringIO.new }
5
+ let(:styles) { TTY::Logger::Handlers::Console::STYLES }
6
+
7
+ it "copies ouptut, fields and configuration over to child logger" do
8
+ logger = TTY::Logger.new(output: output, fields: {app: "parent", env: "prod"})
9
+ child_logger = logger.copy(app: "child") do |config|
10
+ config.filters = ["logging"]
11
+ end
12
+
13
+ logger.info("Parent logging")
14
+ child_logger.warn("Child logging")
15
+
16
+ expect(output.string).to eq([
17
+ "\e[32m#{styles[:info][:symbol]}\e[0m ",
18
+ "\e[32minfo\e[0m ",
19
+ "Parent logging ",
20
+ "\e[32mapp\e[0m=parent \e[32menv\e[0m=prod\n",
21
+ "\e[33m#{styles[:warn][:symbol]}\e[0m ",
22
+ "\e[33mwarning\e[0m ",
23
+ "Child [FILTERED] ",
24
+ "\e[33mapp\e[0m=child \e[33menv\e[0m=prod\n"
25
+ ].join)
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::Logger, "filters" do
4
+ let(:output) { StringIO.new }
5
+ let(:styles) { TTY::Logger::Handlers::Console::STYLES }
6
+
7
+ it "filters a sensitive data from a message" do
8
+ logger = TTY::Logger.new(output: output) do |config|
9
+ config.filters = ["secret", "password"]
10
+ end
11
+
12
+ logger.info("Super secret info with password")
13
+
14
+ expect(output.string).to eq([
15
+ "\e[32m#{styles[:info][:symbol]}\e[0m ",
16
+ "\e[32minfo\e[0m ",
17
+ "Super [FILTERED] info with [FILTERED]\n"].join)
18
+ end
19
+
20
+ it "filters a sensitive data from a message with custom placeholder" do
21
+ logger = TTY::Logger.new(output: output) do |config|
22
+ config.filters = { "secret" => "<SECRET>" }
23
+ end
24
+
25
+ logger.info("Super secret info")
26
+
27
+ expect(output.string).to eq([
28
+ "\e[32m#{styles[:info][:symbol]}\e[0m ",
29
+ "\e[32minfo\e[0m ",
30
+ "Super <SECRET> info \n"].join)
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TTY::Logger, "#log_at" do
4
+ let(:output) { StringIO.new }
5
+
6
+ it "logs temporarily at noisy level" do
7
+ logger = TTY::Logger.new(output: output) do |config|
8
+ config.handlers = [:stream]
9
+ end
10
+
11
+ logger.debug("not logged")
12
+
13
+ logger.log_at :debug do
14
+ logger.debug("logged")
15
+ end
16
+
17
+ logger.debug("not logged")
18
+
19
+ expect(output.string).to eq("level=debug message=logged\n")
20
+ end
21
+
22
+ it "logs temporarily at quiet level" do
23
+ logger = TTY::Logger.new(output: output) do |config|
24
+ config.handlers = [:stream]
25
+ end
26
+
27
+ logger.log_at TTY::Logger::ERROR_LEVEL do
28
+ logger.debug("not logged")
29
+ logger.error("logged")
30
+ end
31
+
32
+ expect(output.string).to eq("level=error message=logged\n")
33
+ end
34
+ end
@@ -4,6 +4,20 @@ RSpec.describe TTY::Logger, "#log" do
4
4
  let(:output) { StringIO.new }
5
5
  let(:styles) { TTY::Logger::Handlers::Console::STYLES }
6
6
 
7
+ it "logs without a method name directly using level" do
8
+ logger = TTY::Logger.new(output: output) do |config|
9
+ config.level = :debug
10
+ end
11
+
12
+ logger.log(:debug, "Deploying...")
13
+
14
+ expect(output.string).to eq([
15
+ "\e[36m#{styles[:debug][:symbol]}\e[0m ",
16
+ "\e[36mdebug\e[0m ",
17
+ "Deploying... \n"
18
+ ].join)
19
+ end
20
+
7
21
  it "logs a message at debug level" do
8
22
  logger = TTY::Logger.new(output: output) do |config|
9
23
  config.level = :debug
@@ -84,9 +98,7 @@ RSpec.describe TTY::Logger, "#log" do
84
98
  end
85
99
 
86
100
  it "logs a message in a block" do
87
- logger = TTY::Logger.new(output: output) do |config|
88
- config.level = :debug
89
- end
101
+ logger = TTY::Logger.new(output: output)
90
102
 
91
103
  logger.info { "Successfully deployed" }
92
104
 
@@ -96,6 +108,30 @@ RSpec.describe TTY::Logger, "#log" do
96
108
  "Successfully deployed \n"].join)
97
109
  end
98
110
 
111
+ it "logs a message in a block as an array of elements" do
112
+ logger = TTY::Logger.new(output: output)
113
+
114
+ logger.info { ["Successfully", "deployed"] }
115
+
116
+ expect(output.string).to eq([
117
+ "\e[32m#{styles[:info][:symbol]}\e[0m ",
118
+ "\e[32minfo\e[0m ",
119
+ "Successfully deployed \n"].join)
120
+ end
121
+
122
+ it "logs a message in a block with metadata" do
123
+ logger = TTY::Logger.new(output: output)
124
+
125
+ logger.info { ["Successfully", "deployed", {app: "myapp", env: "prod"}] }
126
+
127
+ expect(output.string).to eq([
128
+ "\e[32m#{styles[:info][:symbol]}\e[0m ",
129
+ "\e[32minfo\e[0m ",
130
+ "Successfully deployed ",
131
+ "\e[32mapp\e[0m=myapp \e[32menv\e[0m=prod\n"
132
+ ].join)
133
+ end
134
+
99
135
  it "doesn't log when lower level" do
100
136
  logger = TTY::Logger.new(output: output) do |config|
101
137
  config.level = :warn
@@ -118,10 +154,10 @@ RSpec.describe TTY::Logger, "#log" do
118
154
  "\e[32mapp\e[0m=myapp \e[32menv\e[0m=prod\n"].join)
119
155
  end
120
156
 
121
- it "logs message with fields" do
157
+ it "logs message with scoped fields" do
122
158
  logger = TTY::Logger.new(output: output)
123
159
 
124
- logger.with(app: 'myapp', env: 'prod').info("Successfully deployed")
160
+ logger.info("Successfully deployed", app: 'myapp', env: 'prod')
125
161
 
126
162
  expect(output.string).to eq([
127
163
  "\e[32m#{styles[:info][:symbol]}\e[0m ",
@@ -130,15 +166,38 @@ RSpec.describe TTY::Logger, "#log" do
130
166
  "\e[32mapp\e[0m=myapp \e[32menv\e[0m=prod\n"].join)
131
167
  end
132
168
 
133
- it "logs message with scoped fields" do
134
- logger = TTY::Logger.new(output: output)
169
+ it "adds new custom log type" do
170
+ heart = "❤"
171
+ logger = TTY::Logger.new(output: output) do |config|
172
+ config.types = {thanks: {level: :info}}
173
+ config.handlers = [
174
+ [:console, {
175
+ styles: {
176
+ thanks: {
177
+ symbol: heart,
178
+ label: "thanks",
179
+ color: :red,
180
+ levelpad: 1
181
+ }
182
+ }
183
+ }]
184
+ ]
185
+ end
135
186
 
136
- logger.info("Successfully deployed", app: 'myapp', env: 'prod')
187
+ logger.thanks("Great work!", app: "myapp", env: "prod")
137
188
 
138
189
  expect(output.string).to eq([
139
- "\e[32m#{styles[:info][:symbol]}\e[0m ",
140
- "\e[32minfo\e[0m ",
141
- "Successfully deployed ",
142
- "\e[32mapp\e[0m=myapp \e[32menv\e[0m=prod\n"].join)
190
+ "\e[31m#{heart}\e[0m ",
191
+ "\e[31mthanks\e[0m ",
192
+ "Great work! ",
193
+ "\e[31mapp\e[0m=myapp \e[31menv\e[0m=prod\n"].join)
194
+ end
195
+
196
+ it "fails to add already defined log type" do
197
+ expect {
198
+ TTY::Logger.new do |config|
199
+ config.types = {success: {level: :info}}
200
+ end
201
+ }.to raise_error(TTY::Logger::Error, "Already defined log type :success")
143
202
  end
144
203
  end
@@ -1,22 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  begin
4
- require 'rspec/core/rake_task'
4
+ require "rspec/core/rake_task"
5
5
 
6
- desc 'Run all specs'
6
+ desc "Run all specs"
7
7
  RSpec::Core::RakeTask.new(:spec) do |task|
8
- task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
8
+ task.pattern = "spec/{unit,integration}{,/*/**}/*_spec.rb"
9
9
  end
10
10
 
11
11
  namespace :spec do
12
- desc 'Run unit specs'
12
+ desc "Run unit specs"
13
13
  RSpec::Core::RakeTask.new(:unit) do |task|
14
- task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
14
+ task.pattern = "spec/unit{,/*/**}/*_spec.rb"
15
15
  end
16
16
 
17
- desc 'Run integration specs'
17
+ desc "Run integration specs"
18
18
  RSpec::Core::RakeTask.new(:integration) do |task|
19
- task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
19
+ task.pattern = "spec/integration{,/*/**}/*_spec.rb"
20
+ end
21
+
22
+ desc "Run integration specs"
23
+ RSpec::Core::RakeTask.new(:perf) do |task|
24
+ task.pattern = "spec/perf{,/*/**}/*_spec.rb"
20
25
  end
21
26
  end
22
27
 
@@ -32,4 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "bundler", ">= 1.5"
33
33
  spec.add_development_dependency "rake"
34
34
  spec.add_development_dependency "rspec", "~> 3.0"
35
+ if RUBY_VERSION.split(".")[1].to_i > 0
36
+ #spec.add_development_dependency "rspec-benchmark", "~> 0.5"
37
+ end
35
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-21 00:00:00.000000000 Z
11
+ date: 2019-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pastel
@@ -77,9 +77,12 @@ files:
77
77
  - LICENSE.txt
78
78
  - README.md
79
79
  - Rakefile
80
+ - examples/child.rb
80
81
  - examples/console.rb
82
+ - examples/custom_type.rb
81
83
  - examples/error.rb
82
84
  - examples/handler.rb
85
+ - examples/log.rb
83
86
  - examples/output.rb
84
87
  - examples/override.rb
85
88
  - examples/stream.rb
@@ -95,11 +98,16 @@ files:
95
98
  - lib/tty/logger/handlers/stream.rb
96
99
  - lib/tty/logger/levels.rb
97
100
  - lib/tty/logger/version.rb
101
+ - spec/perf/json_formatter_spec.rb
102
+ - spec/perf/log_spec.rb
103
+ - spec/perf/text_formatter_spec.rb
98
104
  - spec/spec_helper.rb
99
105
  - spec/unit/add_handler_spec.rb
100
106
  - spec/unit/config_spec.rb
107
+ - spec/unit/copy_spec.rb
101
108
  - spec/unit/event_spec.rb
102
109
  - spec/unit/exception_spec.rb
110
+ - spec/unit/filter_spec.rb
103
111
  - spec/unit/formatter_spec.rb
104
112
  - spec/unit/formatters/json_spec.rb
105
113
  - spec/unit/formatters/text_spec.rb
@@ -108,6 +116,7 @@ files:
108
116
  - spec/unit/handlers/null_spec.rb
109
117
  - spec/unit/handlers/stream_spec.rb
110
118
  - spec/unit/levels_spec.rb
119
+ - spec/unit/log_at_spec.rb
111
120
  - spec/unit/log_metadata_spec.rb
112
121
  - spec/unit/log_spec.rb
113
122
  - spec/unit/output_spec.rb