perfume 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 454092b73948923a75a389d4a257cd138ae50bf8
4
- data.tar.gz: 6b5fa43f55f038d41d5335eeb199cc986f39f59b
3
+ metadata.gz: 03528ec0794024092661cf896356eb5d9cb6c13b
4
+ data.tar.gz: 9630838ee4a98b5bcb7572373da237c841390931
5
5
  SHA512:
6
- metadata.gz: a8deebaf11ab4fae66403efb78f2978e5fa928aad29cf75040ff551832a4a44eab95945dde167ab60ec69fccf28884862edf5728f81caa64a1625ea8ca1ccd61
7
- data.tar.gz: b6cd61497493f609e3a23c348116e4e97a1dc5e53bbe5b62a108985171a157eb18d33c75d8697e570261eab52cf18c1831308555dd343499c6c051f0567c6781
6
+ metadata.gz: 1b01545fa77bab4667234b0bc9ff5f55b9542c660e17127b4e8320f7f7ed478d587b6c2fcb722faef136f01b69770c25dd21cf6c9906cc4d3d5970340732297e
7
+ data.tar.gz: 1b730f6be75d0ba73521d18d549bd1f5b1e9e398a6a9698e9e1a091895f84061a3d72c96d7678e02c0bbecaba996da21e3a3b32558661b680134d764141add02
data/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ...
8
+
9
+ ## [0.3.0]
10
+
11
+ ### Changed
12
+
13
+ - Logging artifacts moved out from perfume and transferred into gallus.
14
+
7
15
  ## [0.2.0]
8
16
 
9
17
  ### Added
data/README.md CHANGED
@@ -20,7 +20,7 @@ shorthands to deal with common problems. At the moment it includes the following
20
20
  Add this line to your application's Gemfile:
21
21
 
22
22
  ```ruby
23
- gem 'perfume', '0.2.0'
23
+ gem 'perfume', '0.3.0'
24
24
  ```
25
25
 
26
26
  And then execute:
@@ -29,7 +29,7 @@ And then execute:
29
29
 
30
30
  Or install it yourself as:
31
31
 
32
- $ gem install perfume --version 0.2.0
32
+ $ gem install perfume --version 0.3.0
33
33
 
34
34
  ## Usage
35
35
 
@@ -0,0 +1,47 @@
1
+ # Usage: LEVEL=INFO N=10000 bundle exec ruby hacking/benchmarks.rb
2
+
3
+ require 'log4r'
4
+ require 'gallus'
5
+ require 'stringio'
6
+ require 'benchmark'
7
+
8
+ LEVEL = ENV.fetch('LEVEL', 'INFO')
9
+
10
+ $gallus = Gallus::Log.configure('test') do |log|
11
+ log.level = LEVEL
12
+ log.output << Gallus::Output::Stream.new(StringIO.new, Gallus::Format::SimpleLog.new)
13
+ end
14
+
15
+ N = ENV.fetch('N', 10000).to_i
16
+ calls = []
17
+
18
+ N.times do
19
+ %w[debug info warn error].each do |level|
20
+ calls << level
21
+ end
22
+ end
23
+
24
+ Log4r::IOOutputter.new('stream', StringIO.new, formatter: Log4r::PatternFormatter.new(pattern: "%l @ %d $ %C - %m"))
25
+
26
+ $log4r = Log4r::Logger.new('test')
27
+ $log4r.level = Log4r.const_get(LEVEL)
28
+ $log4r.add('stream')
29
+
30
+ payload = { one: 1, two: "Two", three: Object.new, four: "Yada! yada! yada!" }
31
+
32
+ Benchmark.bm do |x|
33
+ x.report("Log4r: ") do
34
+ calls.dup.shuffle.each do |level|
35
+ $log4r.send(level) do
36
+ formatted_payload = payload.map { |k,v| "#{k}=#{v.inspect}" }.join(" ")
37
+ "This is fancy little message; #{formatted_payload}"
38
+ end
39
+ end
40
+ end
41
+
42
+ x.report("Gallus: ") do
43
+ calls.dup.shuffle.each do |level|
44
+ $gallus.send(level, "This is fancy little message", payload)
45
+ end
46
+ end
47
+ end
@@ -3,7 +3,7 @@ module Gallus
3
3
  class SimpleConsole
4
4
  def call(event)
5
5
  parts = [ [ event.message, event.payload ].compact.join('; ') ]
6
- parts.unshift("#{event.level.name}:") unless event.level == Level::INFO
6
+ parts.unshift(format("%s:", event.level.name)) unless event.level == Level::INFO
7
7
  parts.compact.join(' ')
8
8
  end
9
9
  end
@@ -3,7 +3,7 @@ module Gallus
3
3
  class SimpleLog
4
4
  def call(event)
5
5
  message = [ event.message, event.payload ].compact.join('; ')
6
- "#{event.level.to_s[0]} @ #{event.recorded_at.iso8601} $ #{event.logger} > #{message}"
6
+ format("%s @ %s $ %s > %s", event.level, event.recorded_at.iso8601, event.logger, message)
7
7
  end
8
8
  end
9
9
  end
data/lib/gallus/log.rb CHANGED
@@ -46,15 +46,16 @@ module Gallus
46
46
  end
47
47
  end
48
48
 
49
- attr_accessor :name, :level, :output, :serialization
49
+ attr_accessor :name, :level, :serialization
50
+ attr_reader :output
50
51
 
51
52
  def initialize(parent, name, &block)
52
53
  @parent, @name = parent, name.to_s
53
54
 
54
- if @parent
55
+ if parent
56
+ @output = (@parent.output || []).dup
57
+ @serialization = @parent.serialization
55
58
  self.level = @parent.level
56
- self.output = @parent.output.dup
57
- self.serialization = @parent.serialization
58
59
  end
59
60
 
60
61
  yield self if block_given?
@@ -91,7 +92,6 @@ module Gallus
91
92
  @@root = Log.configure do |log|
92
93
  log.name = 'root'
93
94
  log.level = Level::INFO
94
- log.output = []
95
95
  log.serialization = Serialization::Inspect.new
96
96
  end
97
97
  end
@@ -0,0 +1,17 @@
1
+ module Gallus
2
+ module Logging
3
+ def self.included(klass)
4
+ klass.extend(ClassMethods)
5
+ end
6
+
7
+ def log
8
+ self.class.log
9
+ end
10
+
11
+ module ClassMethods
12
+ def log
13
+ @log ||= ::Gallus::Log.configure(self.name)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,8 +1,8 @@
1
1
  module Gallus
2
2
  module Output
3
- class Stderr
3
+ class Stderr < Stream
4
4
  def initialize(format)
5
- super(STDERR, format)
5
+ super($stderr, format)
6
6
  end
7
7
  end
8
8
  end
@@ -1,8 +1,8 @@
1
1
  module Gallus
2
2
  module Output
3
- class Stdout
3
+ class Stdout < Stream
4
4
  def initialize(format)
5
- super(STDOUT, format)
5
+ super($stdout, format)
6
6
  end
7
7
  end
8
8
  end
@@ -0,0 +1,20 @@
1
+ module Gallus
2
+ # Public: Similarly to Perfume::Logging no point to initialize global logger for your
3
+ # modules/packages. Include this mixin to define LOGGER constant and log class method
4
+ # shortcut.
5
+ #
6
+ # Often used practice is to define such top level logger as a parent with default
7
+ # outputters, formatters, log level, etc.
8
+ module PackageLogging
9
+ def self.included(klass)
10
+ klass.const_set(:LOG, ::Gallus::Log.configure(klass.name))
11
+ klass.extend(ClassMethods)
12
+ end
13
+
14
+ module ClassMethods
15
+ def log
16
+ const_get(:LOG)
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/gallus.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'date'
1
+ require 'time'
2
2
  require 'thread'
3
3
 
4
4
  module Gallus
@@ -15,4 +15,6 @@ module Gallus
15
15
  require 'gallus/event'
16
16
  require 'gallus/repository'
17
17
  require 'gallus/log'
18
+ require 'gallus/logging'
19
+ require 'gallus/package_logging'
18
20
  end
data/lib/perfume/all.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  module Perfume
2
- require 'perfume/logging'
3
2
  require 'perfume/service'
4
3
  require 'perfume/promise'
5
4
  require 'perfume/shell'
@@ -1,12 +1,13 @@
1
1
  require 'active_support/core_ext/hash/keys'
2
2
  require 'perfume/super_object'
3
+ require 'gallus'
3
4
 
4
5
  module Perfume
5
6
  # Public: The pattern is simple, our Service is a struct with init arguments that
6
7
  # additionally is callable. It also comes with class level `call` method that
7
8
  # executes stuff on new instance of the object.
8
9
  class Service < SuperObject
9
- include Logging
10
+ include Gallus::Logging
10
11
 
11
12
  # Public: Shorthand to instantionante with arguments and perform call in one shot.
12
13
  # You should actually always intend to use this method as it's easier to mock
@@ -1,3 +1,3 @@
1
1
  module Perfume
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
data/perfume.gemspec CHANGED
@@ -24,8 +24,8 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "minitest", "~> 5.8"
25
25
  spec.add_development_dependency "minitest-reporters", "~> 1.1"
26
26
  spec.add_development_dependency "mocha", "~> 1.1"
27
+ spec.add_development_dependency "log4r", "~> 1.1", ">= 1.0"
27
28
  # spec.add_development_dependency "rake-bump", "~> 0.4"
28
29
 
29
30
  spec.add_dependency "activesupport", "~> 4.2", ">= 3.0"
30
- spec.add_dependency "log4r", "~> 1.1", ">= 1.1"
31
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perfume
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jobandtalent
@@ -82,45 +82,45 @@ dependencies:
82
82
  - !ruby/object:Gem::Version
83
83
  version: '1.1'
84
84
  - !ruby/object:Gem::Dependency
85
- name: activesupport
85
+ name: log4r
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: '4.2'
90
+ version: '1.1'
91
91
  - - ">="
92
92
  - !ruby/object:Gem::Version
93
- version: '3.0'
94
- type: :runtime
93
+ version: '1.0'
94
+ type: :development
95
95
  prerelease: false
96
96
  version_requirements: !ruby/object:Gem::Requirement
97
97
  requirements:
98
98
  - - "~>"
99
99
  - !ruby/object:Gem::Version
100
- version: '4.2'
100
+ version: '1.1'
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '3.0'
103
+ version: '1.0'
104
104
  - !ruby/object:Gem::Dependency
105
- name: log4r
105
+ name: activesupport
106
106
  requirement: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '1.1'
110
+ version: '4.2'
111
111
  - - ">="
112
112
  - !ruby/object:Gem::Version
113
- version: '1.1'
113
+ version: '3.0'
114
114
  type: :runtime
115
115
  prerelease: false
116
116
  version_requirements: !ruby/object:Gem::Requirement
117
117
  requirements:
118
118
  - - "~>"
119
119
  - !ruby/object:Gem::Version
120
- version: '1.1'
120
+ version: '4.2'
121
121
  - - ">="
122
122
  - !ruby/object:Gem::Version
123
- version: '1.1'
123
+ version: '3.0'
124
124
  description: Bunch of tools and utilities for common day-to-day tasks while working
125
125
  with microservices.!
126
126
  email:
@@ -141,16 +141,19 @@ files:
141
141
  - bin/console
142
142
  - bin/setup
143
143
  - docker-compose.yml
144
+ - hacking/benchmarks.rb
144
145
  - lib/gallus.rb
145
146
  - lib/gallus/event.rb
146
147
  - lib/gallus/format/simple_console.rb
147
148
  - lib/gallus/format/simple_log.rb
148
149
  - lib/gallus/level.rb
149
150
  - lib/gallus/log.rb
151
+ - lib/gallus/logging.rb
150
152
  - lib/gallus/output/null.rb
151
153
  - lib/gallus/output/stderr.rb
152
154
  - lib/gallus/output/stdout.rb
153
155
  - lib/gallus/output/stream.rb
156
+ - lib/gallus/package_logging.rb
154
157
  - lib/gallus/payload.rb
155
158
  - lib/gallus/repository.rb
156
159
  - lib/gallus/serialization/inspect.rb
@@ -160,10 +163,6 @@ files:
160
163
  - lib/perfume/console.rb
161
164
  - lib/perfume/core_ext/dir.rb
162
165
  - lib/perfume/exit.rb
163
- - lib/perfume/logging.rb
164
- - lib/perfume/logging/command_line_output_formatter.rb
165
- - lib/perfume/logging/log4r_adapter.rb
166
- - lib/perfume/logging/package_logger.rb
167
166
  - lib/perfume/promise.rb
168
167
  - lib/perfume/service.rb
169
168
  - lib/perfume/shell.rb
@@ -1,25 +0,0 @@
1
- module Perfume
2
- module Logging
3
- # Internal: For command line apps we rather don't want to display all the logging information
4
- # to the user. Just to avoid noise, INFO messages are displayed as is, and any other log levels
5
- # are prefixed with the level name. Example:
6
- #
7
- # This is simple info message.
8
- # And another one.
9
- # WARN: Uups, something's not right here...
10
- # And another info message.
11
- # DEBUG: We need to go deeper!
12
- # ERROR: Limbo!
13
- #
14
- class CommandLineOutputFormatter < Log4r::Formatter
15
- def initialize
16
- @info_formatter = Log4r::PatternFormatter.new(:pattern => "%m")
17
- @else_formatter = Log4r::PatternFormatter.new(:pattern => "%l: %m")
18
- end
19
-
20
- def format(logevent)
21
- (Log4r::INFO == logevent.level ? @info_formatter : @else_formatter).format(logevent)
22
- end
23
- end
24
- end
25
- end
@@ -1,37 +0,0 @@
1
- module Perfume
2
- module Logging
3
- # Internal: Adapter for Log4r logging system. It's a poor version of what Slf4j does to Log4j in
4
- # java apps. Just tiny layer to improve on logging payloads.
5
- class Log4rAdapter
6
- class Event
7
- def initialize(message, payload)
8
- @proc = -> {
9
- payload ||= {}
10
- payload_formatted = payload.map { |k,v| "#{k}=#{v.is_a?(Proc) ? v.call.inspect : v.inspect}" }.join(" ")
11
- str = [ message, payload_formatted.empty? ? nil : payload_formatted].compact.join("; ")
12
- }
13
- end
14
-
15
- def to_proc
16
- @proc
17
- end
18
- end
19
-
20
- def initialize(log)
21
- @log = log
22
- end
23
-
24
- %w[level level= add name].each do |method|
25
- define_method(method) do |*args, &block|
26
- @log.send(method, *args, &block)
27
- end
28
- end
29
-
30
- %w[debug info warn error fatal].each do |level|
31
- define_method(level) do |obj_or_msg, payload=nil|
32
- @log.send(level, obj_or_msg.is_a?(String) ? Event.new(obj_or_msg, payload).to_proc : obj_or_msg)
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,25 +0,0 @@
1
- require 'log4r'
2
- require 'perfume/logging/log4r_adapter'
3
-
4
- module Perfume
5
- module Logging
6
- # Public: Similarly to Perfume::Logging no point to initialize global logger for your
7
- # modules/packages. Include this mixin to define LOGGER constant and log class method
8
- # shortcut.
9
- #
10
- # Often used practice is to define such top level logger as a parent with default
11
- # outputters, formatters, log level, etc.
12
- module PackageLogger
13
- def self.included(klass)
14
- klass.const_set(:LOGGER, Gallus::Log.configure(klass.name))
15
- klass.extend(ClassMethods)
16
- end
17
-
18
- module ClassMethods
19
- def log
20
- const_get(:LOGGER)
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,26 +0,0 @@
1
- require 'log4r'
2
-
3
- module Perfume
4
- # Public: Log4r is awesome, but why initialize it for every class manually if you
5
- # can use simple extension that will do it for you. This one injects class and
6
- # instance `log` methods to access class logger.
7
- module Logging
8
- require 'perfume/logging/log4r_adapter'
9
- require 'perfume/logging/command_line_output_formatter'
10
- require 'perfume/logging/package_logger'
11
-
12
- def self.included(klass)
13
- klass.extend(ClassMethods)
14
- end
15
-
16
- def log
17
- self.class.log
18
- end
19
-
20
- module ClassMethods
21
- def log
22
- @log ||= Gallus::Log.configure(self.name)
23
- end
24
- end
25
- end
26
- end