tagged_logging 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ *.rbc
2
+ .bundle
3
+ bundle
4
+ .config
5
+ .yardoc
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.9.2-p290@go-saas-commons
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ bundler_args: --local
6
+ env:
7
+ - "TESTOPTS=-v"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in go_saas_commons.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tagged_logging (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ multi_json (1.3.4)
10
+ rake (0.9.2.2)
11
+ simplecov (0.6.2)
12
+ multi_json (~> 1.3)
13
+ simplecov-html (~> 0.5.3)
14
+ simplecov-html (0.5.3)
15
+ test-unit (2.4.8)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ rake
22
+ simplecov
23
+ tagged_logging!
24
+ test-unit
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 ThoughtWorks, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # TaggedLogging
2
+
3
+ The rails tagged logger is awesome, but it's only available in rails. This gem makes it available for non-rails applications
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'tagged_logging'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install tagged_logging
18
+
19
+ ## Usage
20
+
21
+ ```{ruby}
22
+ class MyApplication
23
+ include TaggedLogging
24
+ push_tags(MyApplication, Process.pid)
25
+
26
+ def initialize
27
+ info('Initializing application')
28
+ end
29
+
30
+ def perform
31
+ tagged("Perform") do
32
+ info("performing some task")
33
+ end
34
+ end
35
+
36
+ at_exit do
37
+ info('Exiting application')
38
+ end
39
+ end
40
+
41
+ app = MyApplication.new
42
+ app.perform
43
+ ```
44
+
45
+ The above will print the following:
46
+
47
+ [2012-12-15T14:52:10+05:30] - INFO - [MyApplication] [11321] - Initializing application
48
+ [2012-12-15T14:52:10+05:30] - INFO - [MyApplication] [11321] [Perform] - performing some task
49
+ [2012-12-15T14:52:10+05:30] - INFO - [MyApplication] [11321] - Exiting application
50
+
51
+ If you'd rather prefer to not pollute your class with the logger methods:
52
+ ```{ruby}
53
+ class MyApplication
54
+ class MyLogger
55
+ include TaggedLogging
56
+ end
57
+
58
+ class <<self
59
+ attr_accessor :logger
60
+ end
61
+
62
+ def logger
63
+ self.class.logger
64
+ end
65
+
66
+ self.logger = MyLogger
67
+ logger.push_tags(MyApplication, Process.pid)
68
+
69
+ def initialize
70
+ logger.info('Initializing application')
71
+ end
72
+
73
+ def perform
74
+ logger.tagged("Perform") do
75
+ logger.info("performing some task")
76
+ end
77
+ end
78
+
79
+ at_exit do
80
+ logger.info('Exiting application')
81
+ end
82
+ end
83
+
84
+ app = MyApplication.new
85
+ app.perform
86
+ ```
87
+
88
+ ## Contributing
89
+
90
+ 1. Fork it
91
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
92
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
93
+ 4. Push to the branch (`git push origin my-new-feature`)
94
+ 5. Create new Pull Request
95
+
96
+ # License
97
+
98
+ MIT License (see the LICENSE file)
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ desc "run tests"
6
+ Rake::TestTask.new do |t|
7
+ t.libs << "test"
8
+ t.test_files = FileList['test/**/*test.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,119 @@
1
+ #Copied from ActiveSupport
2
+ class Object
3
+ # An object is blank if it's false, empty, or a whitespace string.
4
+ # For example, "", " ", +nil+, [], and {} are all blank.
5
+ #
6
+ # This simplifies:
7
+ #
8
+ # if address.nil? || address.empty?
9
+ #
10
+ # ...to:
11
+ #
12
+ # if address.blank?
13
+ unless method_defined? :blank?
14
+ def blank?
15
+ respond_to?(:empty?) ? empty? : !self
16
+ end
17
+ end
18
+ end
19
+
20
+ class NilClass
21
+ # +nil+ is blank:
22
+ #
23
+ # nil.blank? # => true
24
+ #
25
+ unless method_defined? :blank?
26
+ def blank?
27
+ true
28
+ end
29
+ end
30
+ end
31
+
32
+ class FalseClass
33
+ # +false+ is blank:
34
+ #
35
+ # false.blank? # => true
36
+ #
37
+ unless method_defined? :blank?
38
+ def blank?
39
+ true
40
+ end
41
+ end
42
+ end
43
+
44
+ class TrueClass
45
+ # +true+ is not blank:
46
+ #
47
+ # true.blank? # => false
48
+ #
49
+ unless method_defined? :blank?
50
+ def blank?
51
+ false
52
+ end
53
+ end
54
+ end
55
+
56
+ class Array
57
+ # An array is blank if it's empty:
58
+ #
59
+ # [].blank? # => true
60
+ # [1,2,3].blank? # => false
61
+ #
62
+ unless method_defined? :blank?
63
+ alias_method :blank?, :empty?
64
+ end
65
+ end
66
+
67
+ class Hash
68
+ # A hash is blank if it's empty:
69
+ #
70
+ # {}.blank? # => true
71
+ # {:key => 'value'}.blank? # => false
72
+ #
73
+ unless method_defined? :blank?
74
+ alias_method :blank?, :empty?
75
+ end
76
+ end
77
+
78
+ class String
79
+ if defined?(Encoding) && "".respond_to?(:encode)
80
+ def encoding_aware?
81
+ true
82
+ end
83
+ else
84
+ def encoding_aware?
85
+ false
86
+ end
87
+ end
88
+ # 0x3000: fullwidth whitespace
89
+ NON_WHITESPACE_REGEXP = %r![^\s#{[0x3000].pack("U")}]!
90
+
91
+ # A string is blank if it's empty or contains whitespaces only:
92
+ #
93
+ # "".blank? # => true
94
+ # " ".blank? # => true
95
+ # " ".blank? # => true
96
+ # " something here ".blank? # => false
97
+ #
98
+ def blank?
99
+ # 1.8 does not takes [:space:] properly
100
+ if encoding_aware?
101
+ self !~ /[^[:space:]]/
102
+ else
103
+ self !~ NON_WHITESPACE_REGEXP
104
+ end
105
+ end
106
+ end
107
+
108
+ class Numeric #:nodoc:
109
+ # No number is blank:
110
+ #
111
+ # 1.blank? # => false
112
+ # 0.blank? # => false
113
+ #
114
+ unless method_defined? :blank?
115
+ def blank?
116
+ false
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,54 @@
1
+ require 'time'
2
+ module TaggedLogging
3
+ class Formatter < ::Logger::Formatter
4
+
5
+ FORMAT = "[%s] - %4s - %s - %s\n"
6
+
7
+ def call(severity, time, progname, msg)
8
+ str = case msg
9
+ when ::String
10
+ msg
11
+ when ::Exception
12
+ "#{ msg.message } (#{ msg.class })\n | " <<
13
+ (msg.backtrace || []).join("\n | ")
14
+ else
15
+ msg.inspect
16
+ end
17
+ FORMAT % [format_datetime(time), severity, tags_text, msg]
18
+ end
19
+
20
+ def push_tags(*tags)
21
+ tags.flatten.reject(&:blank?).tap do |new_tags|
22
+ current_tags.concat new_tags
23
+ end
24
+ end
25
+
26
+ def pop_tags(size = 1)
27
+ current_tags.pop size
28
+ end
29
+
30
+ def clear_tags!
31
+ current_tags.clear
32
+ end
33
+
34
+ def current_tags
35
+ Thread.current[:__tagged_logging_current_tags] ||= []
36
+ end
37
+
38
+ def tags_text
39
+ tags = current_tags
40
+ if tags.any?
41
+ tags.collect { |tag| "[#{tag}] " }.join.strip
42
+ end
43
+ end
44
+
45
+ private
46
+ def format_datetime(time)
47
+ if @datetime_format.nil?
48
+ time.iso8601
49
+ else
50
+ time.strftime(@datetime_format)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,61 @@
1
+ require 'logger'
2
+
3
+ module TaggedLogging
4
+ def self.included(receiver)
5
+ receiver.class_eval do
6
+ extend ClassMethods
7
+ include InstanceMethods
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ def tagged(*new_tags, &block)
13
+ new_tags = push_tags(*new_tags)
14
+ yield(self)
15
+ ensure
16
+ pop_tags(new_tags.size)
17
+ end
18
+
19
+ [:push_tags, :pop_tags, :clear_tags!].each do |method_name|
20
+ define_method(method_name) do |*args, &block|
21
+ logger.formatter.send(method_name, *args, &block)
22
+ end
23
+ end
24
+
25
+ def logger
26
+ @@logger ||= ::Logger.new(STDOUT).tap do |l|
27
+ l.level = ::Logger::INFO
28
+ l.formatter = ::TaggedLogging::Formatter.new
29
+ end
30
+ end
31
+
32
+ def logger=(logger)
33
+ @@logger = logger
34
+ end
35
+
36
+ def flush
37
+ clear_tags!
38
+ logger.flush if defined?(logger.super)
39
+ end
40
+
41
+ [:debug, :info, :warn, :error, :fatal].each do |method_name|
42
+ define_method(method_name) do |*args, &block|
43
+ self.logger.send(method_name, *args, &block)
44
+ end
45
+ end
46
+ end
47
+
48
+ module InstanceMethods
49
+ [:debug, :info, :warn, :error, :fatal].each do |method_name|
50
+ define_method(method_name) do |*args, &block|
51
+ self.class.logger.send(method_name, *args, &block)
52
+ end
53
+ end
54
+
55
+ [:tagged, :flush, :logger, :logger=, :push_tags, :pop_tags, :clear_tags!].each do |method_name|
56
+ define_method(method_name) do |*args, &block|
57
+ self.class.send(method_name, *args, &block)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,8 @@
1
+ module TaggedLogging
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 0
6
+ VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ require "tagged_logging/version"
2
+ require "tagged_logging/logger"
3
+
4
+ module TaggedLogging
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/tagged_logging/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ketan Padegaonkar"]
6
+ gem.email = ["KetanPadegaonkar@gmail.com"]
7
+ gem.description = %q{Provides a rails style TaggedLogging for ruby apps}
8
+ gem.summary = %q{Provides a rails style TaggedLogging for ruby apps}
9
+ gem.homepage = "https://github.com/ketan/tagged-logger"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "tagged_logging"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = TaggedLogging::Version::VERSION
17
+
18
+ gem.add_development_dependency 'test-unit'
19
+ gem.add_development_dependency "simplecov"
20
+ gem.add_development_dependency 'rake'
21
+ end
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+ require 'tagged_logging/formatter'
3
+ require 'tagged_logging/blank_ext'
4
+
5
+ class LoggerTest < Test::Unit::TestCase
6
+
7
+ class MyLogger
8
+ include TaggedLogging
9
+ end
10
+
11
+ setup do
12
+ @output = StringIO.new
13
+ @logger = MyLogger
14
+ @logger.logger = ::Logger.new(@output)
15
+ @logger.logger.formatter = TaggedLogging::Formatter.new
16
+ @logger.flush
17
+ end
18
+
19
+ test "tagged once" do
20
+ @logger.tagged("BCX") { @logger.info "Funky time" }
21
+ assert_match "INFO - [BCX] - Funky time\n", @output.string
22
+ end
23
+
24
+ test "tagged twice" do
25
+ @logger.tagged("BCX") { @logger.tagged("Jason") { @logger.info "Funky time" } }
26
+ assert_match "INFO - [BCX] [Jason] - Funky time\n", @output.string
27
+ end
28
+
29
+ test "tagged thrice at once" do
30
+ @logger.tagged("BCX", "Jason", "New") { @logger.info "Funky time" }
31
+ assert_match "INFO - [BCX] [Jason] [New] - Funky time", @output.string
32
+ end
33
+
34
+ test "tagged are flattened" do
35
+ @logger.tagged("BCX", %w(Jason New)) { @logger.info "Funky time" }
36
+ assert_match "[BCX] [Jason] [New] - Funky time", @output.string
37
+ end
38
+
39
+ test "provides access to the logger instance" do
40
+ @logger.tagged("BCX") { |logger| logger.info "Funky time" }
41
+ assert_match "[BCX] - Funky time", @output.string
42
+ end
43
+
44
+ test "push and pop tags directly" do
45
+ assert_equal %w(A B C), @logger.push_tags('A', ['B', ' ', ['C']])
46
+ @logger.info 'a'
47
+ assert_equal %w(C), @logger.pop_tags
48
+ @logger.info 'b'
49
+ assert_equal %w(B), @logger.pop_tags(1)
50
+ @logger.info 'c'
51
+ assert_equal [], @logger.clear_tags!
52
+ @logger.info 'd'
53
+
54
+ assert_match "INFO - [A] [B] [C] - a", @output.string
55
+ assert_match "INFO - [A] [B] - b", @output.string
56
+ assert_match "INFO - [A] - c", @output.string
57
+ assert_match "INFO - - d", @output.string
58
+ end
59
+
60
+ test "does not strip message content" do
61
+ @logger.info " \t\t Hello"
62
+ assert_match "INFO - - \t\t Hello\n", @output.string
63
+ end
64
+
65
+ test "tagged once with blank and nil" do
66
+ @logger.tagged(nil, "", "New") { @logger.info "Funky time" }
67
+ assert_match "INFO - [New] - Funky time", @output.string
68
+ end
69
+
70
+ test "keeps each tag in their own thread" do
71
+ @logger.tagged("BCX") do
72
+ Thread.new do
73
+ @logger.tagged("OMG") { @logger.info "Cool story bro" }
74
+ end.join
75
+ @logger.info "Funky time"
76
+ end
77
+ assert_match "INFO - [OMG] - Cool story bro", @output.string
78
+ assert_match "INFO - [BCX] - Funky time\n", @output.string
79
+ end
80
+
81
+ test "cleans up the taggings on flush" do
82
+ @logger.tagged("BCX") do
83
+ Thread.new do
84
+ @logger.tagged("OMG") do
85
+ @logger.flush
86
+ @logger.info "Cool story bro"
87
+ end
88
+ end.join
89
+ end
90
+ assert_match "INFO - - Cool story bro", @output.string
91
+ end
92
+
93
+ test "mixed levels of tagging" do
94
+ @logger.tagged("BCX") do
95
+ @logger.tagged("Jason") { @logger.info "Funky time" }
96
+ @logger.info "Junky time!"
97
+ end
98
+
99
+ assert_match "INFO - [BCX] [Jason] - Funky time", @output.string
100
+ assert_match "INFO - [BCX] - Junky time!", @output.string
101
+ end
102
+
103
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'simplecov'
4
+ SimpleCov.start do
5
+ add_filter "/.bundle/"
6
+ add_filter "/bundle/"
7
+ end
8
+
9
+ Bundler.require
10
+ require 'test/unit'
Binary file
Binary file
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tagged_logging
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ketan Padegaonkar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: test-unit
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: simplecov
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Provides a rails style TaggedLogging for ruby apps
63
+ email:
64
+ - KetanPadegaonkar@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - .rvmrc
71
+ - .travis.yml
72
+ - Gemfile
73
+ - Gemfile.lock
74
+ - LICENSE
75
+ - README.md
76
+ - Rakefile
77
+ - lib/tagged_logging.rb
78
+ - lib/tagged_logging/blank_ext.rb
79
+ - lib/tagged_logging/formatter.rb
80
+ - lib/tagged_logging/logger.rb
81
+ - lib/tagged_logging/version.rb
82
+ - tagged_logging.gemspec
83
+ - test/logger_test.rb
84
+ - test/test_helper.rb
85
+ - vendor/cache/multi_json-1.3.4.gem
86
+ - vendor/cache/rake-0.9.2.2.gem
87
+ - vendor/cache/simplecov-0.6.2.gem
88
+ - vendor/cache/simplecov-html-0.5.3.gem
89
+ - vendor/cache/test-unit-2.4.8.gem
90
+ homepage: https://github.com/ketan/tagged-logger
91
+ licenses: []
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.24
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: Provides a rails style TaggedLogging for ruby apps
114
+ test_files:
115
+ - test/logger_test.rb
116
+ - test/test_helper.rb