tty-logger 0.1.0 → 0.2.0

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