perfume 0.2.0 → 0.3.0

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