logbang 0.0.1
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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +81 -0
- data/Rakefile +2 -0
- data/lib/logbang.rb +3 -0
- data/lib/logbang/helper.rb +80 -0
- data/lib/logbang/railtie.rb +20 -0
- data/lib/logbang/version.rb +3 -0
- data/logbang.gemspec +19 -0
- metadata +88 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jason Stirk
|
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,81 @@
|
|
1
|
+
# logbang
|
2
|
+
|
3
|
+
Logbang provides `log!`, which is `Rails.logger.debug` on steroids.
|
4
|
+
|
5
|
+
Logbang allows you to scatter `log!` calls throughout your Rails
|
6
|
+
application (views, controller, helpers) and appends the message to the
|
7
|
+
logs in a pretty, coloured format.
|
8
|
+
|
9
|
+
It also keeps track of the timing information, and generates a timing
|
10
|
+
table at the end of the request showing the time between calls, and
|
11
|
+
unique tokens you can use to jump directly to the relevant position in
|
12
|
+
the logs.
|
13
|
+
|
14
|
+
It is useful for any kind of debugging where navigating full stack
|
15
|
+
traces is hard, or where you are hunting performance issues and want to
|
16
|
+
selectively drill down into pieces of your code, rather than profile the
|
17
|
+
entire execution.
|
18
|
+
|
19
|
+
It's also great for wrapping around a piece of functionality to be able
|
20
|
+
to pinpoint which SQL queries are related.
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
gem 'logbang'
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
$ bundle
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install logbang
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
Simply call `log!` (with a message or without) anywhere that is called
|
39
|
+
in the context of +ActionController::Base+ (controller, views, helpers).
|
40
|
+
|
41
|
+
It will create log entries that look like this:
|
42
|
+
|
43
|
+
```
|
44
|
+
= Marked: container-start - 4380ee5
|
45
|
+
```
|
46
|
+
|
47
|
+
They'll be bright yellow, so you can't miss them!
|
48
|
+
|
49
|
+
At the end of a successful request, a table with timing information will
|
50
|
+
be output :
|
51
|
+
|
52
|
+
```
|
53
|
+
= 56e83ce @ 0ms (+ 0ms) /app/views/agreements/index.html.erb
|
54
|
+
= 8933225 @ 391ms (+ 391ms) helper-start
|
55
|
+
= 8dc03cc @ 444ms (+ 53ms) helper-end
|
56
|
+
= 4380ee5 @ 625ms (+ 180ms) container-start
|
57
|
+
= bcec099 @ 694ms (+ 69ms) container-end
|
58
|
+
```
|
59
|
+
|
60
|
+
Note that the random ID in the first column of the table match up with
|
61
|
+
the individual log lines so as that you can easily find them. They
|
62
|
+
change every request so the chances of having multiple matches is
|
63
|
+
reduced.
|
64
|
+
|
65
|
+
The second column shows the time since the first call to `log!`, and the
|
66
|
+
third column is the delta from the previous log entry. Both these values
|
67
|
+
are incredibly helpful when you're hunting of debugging performance
|
68
|
+
issues, or testing optimisations.
|
69
|
+
|
70
|
+
Where possible, logbang will indent subsequent calls to log when it can
|
71
|
+
work out that they are nested. Currently this is fairly naive, and can
|
72
|
+
only make the match when the files are the direct caller (eg. a view
|
73
|
+
calling a helper, or a helper calling another helper).
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
|
77
|
+
1. Fork it
|
78
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
79
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
80
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
81
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/logbang.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Logbang
|
4
|
+
# Adds the +log!+ functionality to the Rails ActionController::Base
|
5
|
+
# method, and sets up an after_filter to dump the timing statistics at
|
6
|
+
# the end of each request.
|
7
|
+
module Helper
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
helper_method :log!
|
12
|
+
after_filter :dump_log!
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a log entry with timing data and a unique ID.
|
16
|
+
#
|
17
|
+
# This will show as a yellow log entry like :
|
18
|
+
# = Marked: container-start - 6d5c4c5
|
19
|
+
#
|
20
|
+
# If +message+ is left blank, the caller filename will be used.
|
21
|
+
def log!(message=nil)
|
22
|
+
call_list = caller.find_all { |x| x =~ /#{Rails.root}/ }
|
23
|
+
mycaller = call_list[0].to_s.gsub(/^([^:]+):.*/, '\1')
|
24
|
+
|
25
|
+
message = mycaller.gsub(/#{Rails.root}/,'') if message.nil?
|
26
|
+
|
27
|
+
call_list.reject! { |x| x =~ Regexp.new("^#{mycaller}") }
|
28
|
+
parent = call_list[0].to_s.gsub(/^([^:]+):.*/, '\1') if call_list[0]
|
29
|
+
|
30
|
+
@log_markers ||= []
|
31
|
+
time = Time.now.to_f
|
32
|
+
id = Digest::MD5.hexdigest("#{message}#{time}")
|
33
|
+
@log_markers << { :time => time,
|
34
|
+
:caller => mycaller,
|
35
|
+
:parent => parent,
|
36
|
+
:marker => message,
|
37
|
+
:id => id
|
38
|
+
}
|
39
|
+
Logbang::Railtie.log "Marked: #{message} - #{id[0..6]}"
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Dumps out the logs and timing data at the end of the request, like:
|
45
|
+
#
|
46
|
+
# = 56e83ce @ 0ms (+ 0ms) /app/views/agreements/index.html.erb
|
47
|
+
# = 8933225 @ 391ms (+ 391ms) helper-start
|
48
|
+
# = 8dc03cc @ 444ms (+ 53ms) helper-end
|
49
|
+
# = 4380ee5 @ 625ms (+ 180ms) container-start
|
50
|
+
# = bcec099 @ 694ms (+ 69ms) container-end
|
51
|
+
def dump_log!
|
52
|
+
return nil if @log_markers.blank?
|
53
|
+
known_markers = {}
|
54
|
+
first = nil
|
55
|
+
last = nil
|
56
|
+
@log_markers.each do |marker|
|
57
|
+
first = marker[:time] if first.blank?
|
58
|
+
last = first if last.nil?
|
59
|
+
idx = known_markers[marker[:caller]]
|
60
|
+
if idx.nil? then
|
61
|
+
idx = known_markers[marker[:parent]]
|
62
|
+
if idx.nil? then
|
63
|
+
idx = 0
|
64
|
+
else
|
65
|
+
idx += 1
|
66
|
+
end
|
67
|
+
known_markers[marker[:caller]] = idx
|
68
|
+
end
|
69
|
+
|
70
|
+
duration = ((marker[:time] - last) * 1000).to_i
|
71
|
+
total = ((marker[:time] - first) * 1000).to_i
|
72
|
+
|
73
|
+
message = "#{marker[:id][0..6]} @ #{sprintf('% 5d',total)}ms (+#{sprintf('% 5d', duration)}ms) #{" " * idx} #{marker[:marker]}"
|
74
|
+
Logbang::Railtie.log message
|
75
|
+
last = marker[:time]
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Logbang
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
initializer "logbang.configure_rails_initialization" do
|
4
|
+
ActionController::Base.send(:include, Logbang::Helper)
|
5
|
+
end
|
6
|
+
|
7
|
+
# Writes the log string out to the Rails logger in a pretty yellow
|
8
|
+
# colour that is almost impossible to miss!
|
9
|
+
def self.log(message)
|
10
|
+
out = ""
|
11
|
+
out << ActiveSupport::LogSubscriber::YELLOW
|
12
|
+
out << ActiveSupport::LogSubscriber::BOLD
|
13
|
+
out << " = "
|
14
|
+
out << message
|
15
|
+
out << ActiveSupport::LogSubscriber::CLEAR
|
16
|
+
Rails.logger.info out
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
data/logbang.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/logbang/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jason Stirk"]
|
6
|
+
gem.email = ["jason@reinteractive.net"]
|
7
|
+
gem.description = %q{Scatter "log!" calls in your Rails app to make debugging and timing easy}
|
8
|
+
gem.summary = %q{Scatter "log!" calls in your Rails app to make debugging and timing easy}
|
9
|
+
gem.homepage = "http://github.com/jstirk/logbang"
|
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 = "logbang"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Logbang::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency('activesupport')
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logbang
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jason Stirk
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-08-16 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: activesupport
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
description: Scatter "log!" calls in your Rails app to make debugging and timing easy
|
35
|
+
email:
|
36
|
+
- jason@reinteractive.net
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- LICENSE
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- lib/logbang.rb
|
50
|
+
- lib/logbang/helper.rb
|
51
|
+
- lib/logbang/railtie.rb
|
52
|
+
- lib/logbang/version.rb
|
53
|
+
- logbang.gemspec
|
54
|
+
homepage: http://github.com/jstirk/logbang
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
hash: 3
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.8.10
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: Scatter "log!" calls in your Rails app to make debugging and timing easy
|
87
|
+
test_files: []
|
88
|
+
|