improved_logging 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/README.md +86 -0
- data/Rakefile +12 -0
- data/improved_logging.gemspec +27 -0
- data/lib/improved_logging.rb +4 -0
- data/lib/improved_logging/improved_logging.rb +135 -0
- data/lib/improved_logging/version.rb +3 -0
- data/spec/improved_logging_spec.rb +44 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/version_spec.rb +8 -0
- metadata +106 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use ruby-1.9.2@improved_logging_gem --create
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# improved_logging
|
2
|
+
|
3
|
+
Improves the log format and adds an optional `exception` parameter to the
|
4
|
+
`warn()` and `error()` methods to print a stack trace automatically.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem 'improved_logging'
|
10
|
+
```
|
11
|
+
|
12
|
+
In your `application.rb`, include the following (or similar):
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
config.logger = ActiveSupport::BufferedLogger.new(config.paths.log.first)
|
16
|
+
config.logger.level = Logger::DEBUG
|
17
|
+
```
|
18
|
+
|
19
|
+
## Configuration
|
20
|
+
|
21
|
+
By default it behaves differently in development mode, it doesn't log the time,
|
22
|
+
process ID or hostname. If `Rails.env` is not `development` those will be logged.
|
23
|
+
|
24
|
+
There are some options that can be set, add these lines to an initializer:
|
25
|
+
|
26
|
+
`ImprovedLogging.verbose = false`
|
27
|
+
|
28
|
+
* This suppresses printing of the hostname, process ID and timestamp. This
|
29
|
+
defaults to false in development mode, true otherwise.
|
30
|
+
|
31
|
+
`ImprovedLogging.hostname_maxlen = 15`
|
32
|
+
|
33
|
+
* This sets the maximum number of characters of the hostname that will be
|
34
|
+
printed. The beginning of the hostname is truncated, rather than the end,
|
35
|
+
because often the end of the hostname is more unique than the beginning.
|
36
|
+
The default is 10.
|
37
|
+
|
38
|
+
`ImprovedLogging.custom = "my-custom-string"`
|
39
|
+
|
40
|
+
* This sets a custom string that will be printed at the beginning of the
|
41
|
+
output, if desired.
|
42
|
+
|
43
|
+
## Format
|
44
|
+
|
45
|
+
It adds severity level (with colour, if colour is enabled), hostname and
|
46
|
+
process ID to each log line, and it and adds warn() and exception() methods that
|
47
|
+
take an exception as an argument and print the stack trace.
|
48
|
+
|
49
|
+
Sample verbose output:
|
50
|
+
|
51
|
+
<pre>
|
52
|
+
fossil.4685 Started GET "/my-mlg?page=1&page_size=10&_=1314650041431" for 127.0.0.1 at 2011-08-29 16:34:01 -0400
|
53
|
+
fossil.4685 16:34:01 INFO Processing by TimelineEventsController#personal_and_friends as JSON
|
54
|
+
fossil.4685 16:34:01 INFO Parameters: {"page"=>"1", "page_size"=>"10", "_"=>"1314650041431"}
|
55
|
+
fossil.4685 16:34:01 DEBUG User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`nickname` = 'AgoraDavid' LIMIT 1
|
56
|
+
fossil.4685 16:34:01 DEBUG CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`nickname` = 'AgoraDavid' LIMIT 1
|
57
|
+
fossil.4685 16:34:01 DEBUG TimelineEvent Load (0.5ms) SELECT `timeline_events`.* FROM `timeline_events` WHERE (actor_id IN (1)) ORDER BY updated_at DESC LIMIT 10 OFFSET 0
|
58
|
+
fossil.4685 16:34:01 DEBUG SQL (0.2ms) SELECT COUNT(*) FROM `votes` WHERE `votes`.`voteable_id` = 1 AND `votes`.`voteable_type` = 'TimelineEvent' AND `votes`.`vote` = 0
|
59
|
+
fossil.4685 16:34:01 INFO Rendered shared/event_message_templates/_user_created.html.haml (1.7ms)
|
60
|
+
fossil.4685 16:34:01 DEBUG User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
|
61
|
+
fossil.4685 16:34:01 DEBUG SQL (0.4ms) SELECT COUNT(*) FROM `comments` WHERE (`comments`.commentable_id = 1 AND `comments`.commentable_type = 'TimelineEvent')
|
62
|
+
fossil.4685 16:34:01 DEBUG Comment Load (0.2ms) SELECT `comments`.* FROM `comments` WHERE (`comments`.commentable_id = 1 AND `comments`.commentable_type = 'TimelineEvent')
|
63
|
+
fossil.4685 16:34:01 DEBUG CACHE (0.0ms) SELECT COUNT(*) FROM `comments` WHERE (`comments`.commentable_id = 1 AND `comments`.commentable_type = 'TimelineEvent')
|
64
|
+
fossil.4685 16:34:01 INFO Rendered shared/event_message_templates/_new_comment_form.html.haml (8.2ms)
|
65
|
+
fossil.4685 16:34:01 INFO Rendered shared/event_message_templates/_comments.html.haml (22.9ms)
|
66
|
+
fossil.4685 16:34:01 INFO Rendered shared/event_message_templates/_message_template.html.haml (69.2ms)
|
67
|
+
fossil.4685 16:34:01 INFO Rendered shared/feed.haml (72.6ms)
|
68
|
+
fossil.4685 16:34:01 INFO Completed 200 OK in 246ms (Views: 3.4ms | ActiveRecord: 2.0ms)
|
69
|
+
</pre>
|
70
|
+
|
71
|
+
## Contributing to improved_logging
|
72
|
+
|
73
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
74
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
75
|
+
* Fork the project
|
76
|
+
* Start a feature/bugfix branch
|
77
|
+
* Commit and push until you are happy with your contribution
|
78
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
79
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
80
|
+
|
81
|
+
## License
|
82
|
+
|
83
|
+
Code originally found in https://github.com/pauldowman/better_logging
|
84
|
+
|
85
|
+
Uses the same license as better_logging,
|
86
|
+
Creative Commons "Attribution-Share Alike", http://creativecommons.org/licenses/by-sa/3.0/
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
8
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
9
|
+
spec.rspec_opts = ['--backtrace']
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => :spec
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "improved_logging/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "improved_logging"
|
7
|
+
s.version = ImprovedLogging::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["David Czarnecki"]
|
10
|
+
s.email = ["dczarnecki@agoragames.com"]
|
11
|
+
s.homepage = "https://github.com/agoragames/improved_logging"
|
12
|
+
s.summary = %q{Adds improved logging capabilities to the ActiveSupport::BufferedLogger class}
|
13
|
+
s.description = %q{Adds improved logging capabilities to the ActiveSupport::BufferedLogger class}
|
14
|
+
|
15
|
+
s.rubyforge_project = "improved_logging"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency('activesupport', '~> 3.0.9')
|
23
|
+
s.add_dependency('i18n', '~> 0.5.0')
|
24
|
+
|
25
|
+
s.add_development_dependency('rake', '~> 0.9.2')
|
26
|
+
s.add_development_dependency('rspec', '~> 2.6.0')
|
27
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# This module, when included into ActiveSupport::BufferedLogger, improves the
|
2
|
+
# logging format. See the README file for more info.
|
3
|
+
#
|
4
|
+
# This is distributed under a Creative Commons "Attribution-Share Alike"
|
5
|
+
# license: for details see:
|
6
|
+
# http://creativecommons.org/licenses/by-sa/3.0/
|
7
|
+
#
|
8
|
+
module ImprovedLogging
|
9
|
+
LENGTH = ::ActiveSupport::BufferedLogger::Severity.constants.map{|c| c.to_s.length}.max
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.class_eval do
|
13
|
+
alias_method_chain :add, :extra_info
|
14
|
+
alias_method_chain :error, :exception_param
|
15
|
+
alias_method_chain :warn, :exception_param
|
16
|
+
end
|
17
|
+
|
18
|
+
# Get the length to format the output so that the pid column lines up.
|
19
|
+
# The severity levels probably won't change but this avoids hard-coding
|
20
|
+
# them anyway, just in case.
|
21
|
+
# Most of this is done with class_eval so it should only be done once
|
22
|
+
# while the class is being loaded.
|
23
|
+
if_stmts = ""
|
24
|
+
for c in ::ActiveSupport::BufferedLogger::Severity.constants
|
25
|
+
if_stmts += <<-EOT
|
26
|
+
if severity == #{c}
|
27
|
+
severity_name = sprintf("%1$*2$s", "#{c}", #{LENGTH * -1})
|
28
|
+
use_colour = false
|
29
|
+
if ::Rails.version.to_i >= 3
|
30
|
+
use_colour = true if ::ActiveSupport::LogSubscriber.colorize_logging
|
31
|
+
else
|
32
|
+
use_colour = true if defined?(::ActiveRecord) && ::ActiveRecord::Base.colorize_logging
|
33
|
+
end
|
34
|
+
if use_colour
|
35
|
+
if severity == INFO
|
36
|
+
severity_name = "\033[32m" + severity_name + "\033[0m"
|
37
|
+
elsif severity == WARN
|
38
|
+
severity_name = "\033[33m" + severity_name + "\033[0m"
|
39
|
+
elsif severity == ERROR || severity == FATAL
|
40
|
+
severity_name = "\033[31m" + severity_name + "\033[0m"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
return severity_name
|
44
|
+
end
|
45
|
+
EOT
|
46
|
+
end
|
47
|
+
base.class_eval <<-EOT, __FILE__, __LINE__
|
48
|
+
def self.severity_name(severity)
|
49
|
+
#{if_stmts}
|
50
|
+
return "UNKNOWN"
|
51
|
+
end
|
52
|
+
EOT
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def self.verbose=(boolean)
|
57
|
+
@@verbose = boolean
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.custom=(string)
|
61
|
+
@@custom = string
|
62
|
+
@@line_prefix = format_line_prefix
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.hostname_maxlen=(integer)
|
66
|
+
@@hostname_maxlen = integer
|
67
|
+
@@line_prefix = format_line_prefix
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.format_line_prefix
|
71
|
+
if @@full_hostname.length < @@hostname_maxlen
|
72
|
+
hostname = @@full_hostname
|
73
|
+
else
|
74
|
+
hostname = @@full_hostname[-(@@hostname_maxlen)..-1]
|
75
|
+
end
|
76
|
+
|
77
|
+
line_prefix = sprintf("%1$*2$s", "#{hostname}.#{@@pid} ", -(7 + hostname.length))
|
78
|
+
line_prefix = "#{@@custom} #{line_prefix}" if @@custom
|
79
|
+
return line_prefix
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.get_hostname
|
83
|
+
`hostname -s`.strip
|
84
|
+
end
|
85
|
+
|
86
|
+
# The following are cached as class variables for speed.
|
87
|
+
|
88
|
+
# These are configurable, put something like the following in an initializer:
|
89
|
+
# ImprovedLogging.verbose = false
|
90
|
+
@@verbose = defined?(::Rails) ? ::Rails.env != "development" : false
|
91
|
+
@@full_hostname = get_hostname
|
92
|
+
@@hostname_maxlen = 10
|
93
|
+
@@custom = nil
|
94
|
+
|
95
|
+
# These are not configurable
|
96
|
+
@@pid = $$
|
97
|
+
@@line_prefix = format_line_prefix
|
98
|
+
|
99
|
+
|
100
|
+
# the cached pid can be wrong after a fork(), this checks if it has changed and
|
101
|
+
# re-caches the line_prefix
|
102
|
+
def update_pid
|
103
|
+
if @@pid != $$
|
104
|
+
@@pid = $$
|
105
|
+
@@line_prefix = ImprovedLogging.format_line_prefix
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def add_with_extra_info(severity, message = nil, progname = nil, &block)
|
110
|
+
update_pid
|
111
|
+
time = @@verbose ? "#{Time.new.strftime('%H:%M:%S')} " : ""
|
112
|
+
message = "#{time}#{::ActiveSupport::BufferedLogger.severity_name(severity)} #{message}"
|
113
|
+
|
114
|
+
# Make sure every line has the PID and hostname and custom string
|
115
|
+
# so we can use grep to isolate output from one process or server.
|
116
|
+
# gsub works even when the output contains "\n", though there's
|
117
|
+
# probably a small performance cost.
|
118
|
+
message = message.gsub(/^/, @@line_prefix) if @@verbose
|
119
|
+
|
120
|
+
add_without_extra_info(severity, message, progname, &block)
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# add an optional second parameter to the error & warn methods to allow a stack trace:
|
125
|
+
|
126
|
+
def error_with_exception_param(message, exception = nil)
|
127
|
+
message += "\n#{exception.inspect}\n#{exception.backtrace.join("\n")}" if exception
|
128
|
+
error_without_exception_param(message)
|
129
|
+
end
|
130
|
+
|
131
|
+
def warn_with_exception_param(message, exception = nil)
|
132
|
+
message += "\n#{exception.inspect}\n#{exception.backtrace.join("\n")}" if exception
|
133
|
+
warn_without_exception_param(message)
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_support/core_ext/module'
|
3
|
+
require 'active_support'
|
4
|
+
require 'improved_logging'
|
5
|
+
|
6
|
+
describe ActiveSupport::BufferedLogger do
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
@logger = ActiveSupport::BufferedLogger.new(StringIO.new)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should include the ImprovedLogging module' do
|
13
|
+
ActiveSupport::BufferedLogger.included_modules.should include(::ImprovedLogging)
|
14
|
+
@logger.methods.should include(:add_with_extra_info)
|
15
|
+
@logger.methods.should include(:error_with_exception_param)
|
16
|
+
@logger.methods.should include(:warn_with_exception_param)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should call #add when you log a message' do
|
20
|
+
@logger.should_receive(:add).with(0, 'message', nil)
|
21
|
+
|
22
|
+
@logger.debug('message')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should allow you to pass an exception to the error method' do
|
26
|
+
@logger.should_receive(:error).with('message', anything())
|
27
|
+
|
28
|
+
begin
|
29
|
+
raise StandardError.new
|
30
|
+
rescue => e
|
31
|
+
@logger.error('message', e)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should allow you to pass an exception to the warn method' do
|
36
|
+
@logger.should_receive(:warn).with('message', anything())
|
37
|
+
|
38
|
+
begin
|
39
|
+
raise StandardError.new
|
40
|
+
rescue => e
|
41
|
+
@logger.warn('message', e)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: improved_logging
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Czarnecki
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-30 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: &70343856580340 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.9
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70343856580340
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: i18n
|
27
|
+
requirement: &70343856579840 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.5.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70343856579840
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70343856579380 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.9.2
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70343856579380
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &70343856578920 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.6.0
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70343856578920
|
58
|
+
description: Adds improved logging capabilities to the ActiveSupport::BufferedLogger
|
59
|
+
class
|
60
|
+
email:
|
61
|
+
- dczarnecki@agoragames.com
|
62
|
+
executables: []
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- .gitignore
|
67
|
+
- .rvmrc
|
68
|
+
- CHANGELOG.md
|
69
|
+
- Gemfile
|
70
|
+
- README.md
|
71
|
+
- Rakefile
|
72
|
+
- improved_logging.gemspec
|
73
|
+
- lib/improved_logging.rb
|
74
|
+
- lib/improved_logging/improved_logging.rb
|
75
|
+
- lib/improved_logging/version.rb
|
76
|
+
- spec/improved_logging_spec.rb
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
- spec/version_spec.rb
|
79
|
+
homepage: https://github.com/agoragames/improved_logging
|
80
|
+
licenses: []
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project: improved_logging
|
99
|
+
rubygems_version: 1.8.6
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: Adds improved logging capabilities to the ActiveSupport::BufferedLogger class
|
103
|
+
test_files:
|
104
|
+
- spec/improved_logging_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
- spec/version_spec.rb
|