scribbler 0.2.3 → 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.
- data/.gitignore +2 -0
- data/.irbrc +2 -0
- data/.rvmrc +1 -1
- data/README.md +87 -40
- data/bin/scribbler +1 -1
- data/lib/scribbler.rb +63 -2
- data/lib/scribbler/base.rb +15 -191
- data/lib/scribbler/{cli.rb → cli_client.rb} +29 -29
- data/lib/scribbler/configurator.rb +61 -13
- data/lib/scribbler/executable.rb +12 -4
- data/lib/scribbler/includeables.rb +13 -43
- data/lib/scribbler/log_location.rb +13 -0
- data/lib/scribbler/logger.rb +152 -0
- data/lib/scribbler/version.rb +1 -1
- data/scribbler.gemspec +1 -0
- data/spec/lib/scribbler/base_spec.rb +16 -0
- data/spec/{scribbler/cli_spec.rb → lib/scribbler/cli_client_spec.rb} +4 -4
- data/spec/{scribbler → lib/scribbler}/configurator_spec.rb +14 -3
- data/spec/lib/scribbler/executable_spec.rb +28 -0
- data/spec/lib/scribbler/includeables_spec.rb +24 -0
- data/spec/lib/scribbler/log_location_spec.rb +11 -0
- data/spec/lib/scribbler/logger_spec.rb +172 -0
- data/spec/{scribbler → lib/scribbler}/version_spec.rb +0 -0
- data/spec/lib/scribbler_spec.rb +47 -0
- data/spec/spec_helper.rb +6 -8
- data/spec/support/examples/scribbler_example.rb +1 -1
- data/templates/scribbler.rb +3 -3
- metadata +62 -39
- data/spec/scribbler/base_spec.rb +0 -140
- data/spec/scribbler/executable_spec.rb +0 -21
- data/spec/scribbler/includeables_spec.rb +0 -9
- data/spec/scribbler_spec.rb +0 -7
data/.gitignore
CHANGED
data/.irbrc
ADDED
data/.rvmrc
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Scribbler
|
2
2
|
|
3
3
|
[](http://travis-ci.org/jphenow/scribbler "Travis-CI Scribbler")
|
4
|
+
[](https://codeclimate.com/github/jphenow/scribbler)
|
4
5
|
|
5
6
|
[RubyGems](https://rubygems.org/gems/scribbler)
|
6
7
|
|
@@ -11,79 +12,122 @@ Currently it assists in:
|
|
11
12
|
* Centralized log method for file, message, and error checks
|
12
13
|
- Currently also able to notify NewRelic, abstraction and extension to come
|
13
14
|
|
15
|
+
## Notes on upgrading to 0.3.0
|
16
|
+
|
17
|
+
Scribbler was initially written with a lot of class-level (almost entirely) operations.
|
18
|
+
For sanity sake, the version 0.3.0 is the big step towards dropping most of the gem into
|
19
|
+
instances. There isn't much functionality change yet, but it will make expanding the gem much
|
20
|
+
simpler to develop.
|
21
|
+
|
22
|
+
### Changes For You
|
23
|
+
|
24
|
+
`Scribbler::Base` is now deprecated, look to remove. See `Scribbler`
|
25
|
+
|
26
|
+
`Scribbler.configure` now yields the configurator so you now want to change from:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
Scribbler::Base.configure do
|
30
|
+
config.some_config_options
|
31
|
+
# ...
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
to
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
Scribbler.configure do |config|
|
39
|
+
config.some_config_options
|
40
|
+
# ...
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
14
44
|
## Usage
|
15
45
|
|
16
46
|
In your Rails project add
|
17
47
|
|
18
|
-
|
48
|
+
```ruby
|
49
|
+
gem 'scribbler'
|
50
|
+
```
|
19
51
|
|
20
52
|
to your Gemfile and
|
21
53
|
|
22
|
-
|
54
|
+
```bash
|
55
|
+
bundle install
|
56
|
+
```
|
23
57
|
|
24
58
|
Then
|
25
59
|
|
26
|
-
|
60
|
+
```bash
|
61
|
+
scribbler install # For options do `scribbler` first
|
62
|
+
```
|
27
63
|
|
28
64
|
You'll find your configuration options in `config/initializers/scribbler.rb`.
|
29
65
|
**Better, more documented examples in the template file provided by `scribbler install`**
|
30
66
|
As an example, with this configuration file in a Rails app called `Blogger`:
|
31
67
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# config.log_directory = File.new '/a/better/path'
|
68
|
+
```ruby
|
69
|
+
Scribbler.configure do |config|
|
70
|
+
config.application_include = true
|
36
71
|
|
37
|
-
|
72
|
+
# config.log_directory = File.new '/a/better/path'
|
38
73
|
|
39
|
-
|
74
|
+
config.use_template_by_default = true # Default: false
|
40
75
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
76
|
+
# config.template = proc do |options|
|
77
|
+
# <<-MSG
|
78
|
+
# ##########
|
79
|
+
# Cool template bro!
|
80
|
+
# Message: #{options[:message]}
|
81
|
+
# MSG
|
82
|
+
# end
|
83
|
+
end
|
84
|
+
```
|
49
85
|
|
50
86
|
You are given a few methods for free. To get the production logfile location:
|
51
87
|
|
52
|
-
|
53
|
-
|
88
|
+
```ruby
|
89
|
+
Blogger.production_log_location
|
90
|
+
# => <#Path: Rails.root.join('log', 'production.log')>
|
91
|
+
```
|
54
92
|
|
55
93
|
or
|
56
94
|
|
57
|
-
|
58
|
-
|
95
|
+
```ruby
|
96
|
+
Scribbler.production_log_location
|
97
|
+
# => <#Path: Rails.root.join('log', 'production.log')>
|
98
|
+
```
|
59
99
|
|
60
100
|
More importantly you're given access to a sweet `log` method:
|
61
101
|
|
62
|
-
|
63
|
-
|
64
|
-
|
102
|
+
```ruby
|
103
|
+
# Notifies NewRelic and drops the message in log found at Blogger.production_log_location
|
104
|
+
Blogger.log :production, :error => e, :message => "#{e} broke stuff"
|
105
|
+
Scribbler.log :production, :error => e, :message => "#{e} broke stuff"
|
65
106
|
|
66
|
-
|
67
|
-
|
68
|
-
|
107
|
+
# Only logs to log/delayed_job.log and doesn't notify NewRelic
|
108
|
+
Blogger.log :delayed_job, :message => "Successfully executed Delayed Job"
|
109
|
+
Scribbler.log :delayed_job, :message => "Successfully executed Delayed Job"
|
69
110
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
111
|
+
# Doesn't notify NewRelic but gives the method access to the error and logs the message
|
112
|
+
# to the given logfile
|
113
|
+
Blogger.log 'production', :new_relic => false, :error => e, :message => "#{e} broke stuff"
|
114
|
+
Scribbler.log 'production', :new_relic => false, :error => e, :message => "#{e} broke stuff"
|
74
115
|
|
75
|
-
|
76
|
-
|
77
|
-
|
116
|
+
# Logs to given file without using the fancy log methods
|
117
|
+
Blogger.log File.expand_path(File.join(File.dirname(__FILE__), 'logfile.log')), :message => "#{e} broke stuff"
|
118
|
+
Scribbler.log File.expand_path(File.join(File.dirname(__FILE__), 'logfile.log')), :message => "#{e} broke stuff"
|
119
|
+
```
|
78
120
|
|
79
121
|
Log options with the default template proc:
|
80
122
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
123
|
+
```
|
124
|
+
# options - Hash of options for logging on Ngin
|
125
|
+
# :error - Error object, mostly for passing to NewRelic
|
126
|
+
# :message - Message to log in the actual file [REQUIRED]
|
127
|
+
# :custom_fields - Custom fields dropped into the default template
|
128
|
+
# :template - Whether or not to use the template at this log
|
129
|
+
# :new_relic - Notify NewRelic of the error (default: true)
|
130
|
+
```
|
87
131
|
|
88
132
|
With the template enabled (either during call to log [:template => true] or by setting to
|
89
133
|
be used by default) you will have each log entry wrapped into a template to pretty-up and
|
@@ -94,7 +138,10 @@ docs and specs for more information.
|
|
94
138
|
|
95
139
|
* Configure the module/class receiving the include
|
96
140
|
* Configurable notification gem (NewRelic, Airbrake, etc.)
|
141
|
+
* Have default template cascade through hashes/arrays for prettier viewing
|
97
142
|
* Currently attempts to notify NewRelic if its there, abstract and allow custom services
|
98
143
|
* Allow a class to set default options for a log call within itself
|
99
144
|
* Allow there to be a log made without the option[:message], in case its all custom_fields or someting
|
100
145
|
* Allow event hooks on log call?
|
146
|
+
* Log4r support
|
147
|
+
* Bring class-level methods down to instance methods (More OO)
|
data/bin/scribbler
CHANGED
@@ -7,7 +7,7 @@ class ScribblerExecutable < Thor
|
|
7
7
|
desc "install", "Installs the necessary files for Scribbler (default: config/initializers/scribbler.rb)"
|
8
8
|
method_option :path, :aliases => "-p", :desc => "Specify a different path for the scribbler initialization"
|
9
9
|
def install
|
10
|
-
Scribbler::Executable.install(options)
|
10
|
+
Scribbler::Executable.new.install(options)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
data/lib/scribbler.rb
CHANGED
@@ -1,7 +1,68 @@
|
|
1
1
|
require 'active_support/all'
|
2
2
|
require 'scribbler/version'
|
3
3
|
require 'scribbler/configurator'
|
4
|
-
require 'scribbler/
|
4
|
+
require 'scribbler/log_location'
|
5
|
+
require 'scribbler/logger'
|
5
6
|
require 'scribbler/includeables'
|
6
|
-
require 'scribbler/
|
7
|
+
require 'scribbler/cli_client'
|
7
8
|
require 'scribbler/executable'
|
9
|
+
|
10
|
+
module Scribbler
|
11
|
+
include Includeables
|
12
|
+
# Rails style configure block with some cleanup afterwards. This is the
|
13
|
+
# main method that kicks off the module and is necessary for its operation
|
14
|
+
#
|
15
|
+
# &block - Block is class_eval'd to give total access to the config file.
|
16
|
+
# Most importantly giving access to `config` object
|
17
|
+
#
|
18
|
+
# Examples:
|
19
|
+
#
|
20
|
+
# Scribbler.configure do |config|
|
21
|
+
# config.logs = %w[log1 log2]
|
22
|
+
# config.application_include = true
|
23
|
+
# end
|
24
|
+
# # => Nothing
|
25
|
+
#
|
26
|
+
# Returns Nothing
|
27
|
+
# TODO Abstract the callbacks so that we can just add them where they're written
|
28
|
+
def self.configure
|
29
|
+
yield config
|
30
|
+
include_in_application
|
31
|
+
end
|
32
|
+
|
33
|
+
# Simply returns the configurator class.
|
34
|
+
#
|
35
|
+
# Examples:
|
36
|
+
#
|
37
|
+
# Scribbler.config
|
38
|
+
# # => Scribbler::Configurator
|
39
|
+
#
|
40
|
+
# Returns the singleton configurator
|
41
|
+
def self.config
|
42
|
+
@config ||= Configurator.new
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# If the config agrees, attempt to include our special methods
|
48
|
+
# in the main application object.
|
49
|
+
#
|
50
|
+
# Example:
|
51
|
+
#
|
52
|
+
# Scribbler.include_in_application
|
53
|
+
# # => Nothing
|
54
|
+
#
|
55
|
+
# Returns Nothing
|
56
|
+
#
|
57
|
+
# TODO: Allow config to define where we send the include
|
58
|
+
def self.include_in_application
|
59
|
+
if config.application_include
|
60
|
+
begin
|
61
|
+
::Rails.application.class.parent.send :include, Includeables
|
62
|
+
rescue NameError
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
require 'scribbler/base'
|
data/lib/scribbler/base.rb
CHANGED
@@ -1,199 +1,23 @@
|
|
1
1
|
module Scribbler
|
2
|
-
|
3
|
-
# Gets the path of this Gem
|
4
|
-
#
|
5
|
-
# Examples:
|
6
|
-
#
|
7
|
-
# Base.gem_path
|
8
|
-
# # => '/some/home/.rvm/gems/ruby-1.9.3-p125/gems/scribbler-0.0.1/'
|
9
|
-
#
|
10
|
-
# Returns String of the current gem's directory path
|
11
|
-
def self.gem_path
|
12
|
-
File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
13
|
-
end
|
14
|
-
|
15
|
-
# Gets all the paths to the template files in the gem's template directory
|
16
|
-
#
|
17
|
-
# Examples:
|
18
|
-
#
|
19
|
-
# Base.templates
|
20
|
-
# # => ['/some/home/.rvm/gems/ruby-1.9.3-p125/gems/scribbler-0.0.1/templates/1.rb',
|
21
|
-
# # '/some/home/.rvm/gems/ruby-1.9.3-p125/gems/scribbler-0.0.1/templates/2.rb]
|
22
|
-
#
|
23
|
-
# Returns Array of Strings of the gem's template files
|
24
|
-
def self.templates
|
25
|
-
Dir.glob(File.join(gem_path, 'templates', '*'))
|
26
|
-
end
|
27
|
-
|
28
|
-
# Gets the path to the default install directory. If Rails is present
|
29
|
-
# it will default to the Rails.root/config/initializers/. Otherwise
|
30
|
-
# it assumes its the $PWD/config/initializer. Should look at a cleaner
|
31
|
-
# abstraction of this
|
32
|
-
#
|
33
|
-
# Examples:
|
34
|
-
#
|
35
|
-
# Base.default_install_path
|
36
|
-
# # => '/some/home/projects/rails_app/config/initializers/'
|
37
|
-
#
|
38
|
-
# Returns String for best guess of a good install path
|
39
|
-
def self.default_install_path
|
40
|
-
begin
|
41
|
-
::Rails.root.join 'config', 'initializers', ''
|
42
|
-
rescue NameError
|
43
|
-
File.join Dir.pwd, 'config', 'initializers', ''
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Rails style configure block with some cleanup afterwards. This is the
|
48
|
-
# main method that kicks off the module and is necessary for its operation
|
49
|
-
#
|
50
|
-
# &block - Block is class_eval'd to give total access to the config file.
|
51
|
-
# Most importantly giving access to `config` object
|
52
|
-
#
|
53
|
-
# Examples:
|
54
|
-
#
|
55
|
-
# Base.configure do
|
56
|
-
# config.logs = %w[log1 log2]
|
57
|
-
# config.application_include = true
|
58
|
-
# end
|
59
|
-
# # => Nothing
|
60
|
-
#
|
61
|
-
# Returns Nothing
|
62
|
-
# TODO Abstract the callbacks so that we can just add them where they're written
|
2
|
+
module Base
|
63
3
|
def self.configure(&block)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
# Returns the singleton configurator
|
77
|
-
def self.config
|
78
|
-
Scribbler::Configurator
|
79
|
-
end
|
80
|
-
|
81
|
-
# Public: Save ourselves some repetition. Notifies error to NewRelic
|
82
|
-
# and drops given string into a given log.
|
83
|
-
#
|
84
|
-
# location - Either a pathname from the above method or symbol for an above
|
85
|
-
# method
|
86
|
-
# options - Hash of options for logging on Ngin
|
87
|
-
# :error - Error object, mostly for passing to NewRelic
|
88
|
-
# :message - Message to log in the actual file
|
89
|
-
# :custom_fields - Custom fields dropped into the default template
|
90
|
-
# :template - Whether or not to use the template at this log
|
91
|
-
# :new_relic - Notify NewRelic of the error (default: true)
|
92
|
-
#
|
93
|
-
# Examples
|
94
|
-
#
|
95
|
-
# log(Ngin.subseason_log_location, :error => e, :message => "Error message stuff", :new_relic => false)
|
96
|
-
#
|
97
|
-
# log(:subseason, :error => e, :message => "Error message stuff")
|
98
|
-
#
|
99
|
-
# log(:subseason, :message => "Logging like a bauss")
|
100
|
-
#
|
101
|
-
# Returns Nothing.
|
102
|
-
def self.log(location, options={})
|
103
|
-
options = {
|
104
|
-
:template => config.use_template_by_default,
|
105
|
-
:stack_frame => options[:call_stack] ? Kernel.caller[1..-1] : nil
|
106
|
-
}.merge options
|
107
|
-
begin
|
108
|
-
NewRelic::Agent.notice_error(options[:error]) if options[:error] and options[:new_relic] != false
|
109
|
-
rescue NameError
|
110
|
-
nil
|
111
|
-
end
|
112
|
-
|
113
|
-
apply_to_log location, options
|
114
|
-
end
|
115
|
-
|
116
|
-
private
|
117
|
-
# Builds the message and any other options into a string
|
118
|
-
# using the template defined in the configure
|
119
|
-
#
|
120
|
-
# options - options hash that comprises most of the important log pieces
|
121
|
-
# :message - The message we're wrapping into the templater [required]
|
122
|
-
# :template - Whether or not to use the template method
|
123
|
-
# **Other option information given in the .log docs
|
124
|
-
#
|
125
|
-
# Examples
|
126
|
-
#
|
127
|
-
# Base.build_with_template(:message => "...", :template => false)
|
128
|
-
# # => "..."
|
129
|
-
#
|
130
|
-
# Base.build_with_template
|
131
|
-
# # => nil
|
132
|
-
#
|
133
|
-
# Base.build_with_template(:message => "...", :template => true)
|
134
|
-
# # => <<-EXAMPLE
|
135
|
-
# --------------------
|
136
|
-
# TEMPLATE STUFF
|
137
|
-
# ....
|
138
|
-
# EXAMPLE
|
139
|
-
#
|
140
|
-
# Returns nil, a string, or a string built with calling the Configurator.template method
|
141
|
-
def self.build_with_template(options={})
|
142
|
-
if options[:message].present?
|
143
|
-
options[:message] = options[:message].strip_heredoc.rstrip
|
144
|
-
options[:template] ? config.template.call(options) : options[:message]
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
# Drops built message into the log with the given location
|
149
|
-
#
|
150
|
-
# location - location either found with Base.*_log_location or by hoping a valid
|
151
|
-
# path string or Path object were passed
|
152
|
-
# options - options hash
|
153
|
-
# :message - Message to be built and put in log file [required]
|
154
|
-
# ** Other hash information given in Base.log
|
155
|
-
#
|
156
|
-
# Examples
|
157
|
-
#
|
158
|
-
# Base.apply_to_log :some_loc, :message => "...", :template => false, :error => e
|
159
|
-
# # => Nothing
|
160
|
-
#
|
161
|
-
# Returns Nothing
|
162
|
-
def self.apply_to_log(location, options={})
|
163
|
-
if can_apply_to_log? location, options
|
164
|
-
File.open log_at(location), 'a' do |f|
|
165
|
-
f.puts build_with_template(options)
|
166
|
-
end
|
4
|
+
ActiveSupport::Deprecation.deprecated_method_warning :configure,
|
5
|
+
"Scribbler is now preferred over Scribbler::Base see github for more info"
|
6
|
+
Scribbler.configure { |config| config.instance_eval(&block) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.method_missing(method, *args, &block)
|
10
|
+
if Scribbler.respond_to? method
|
11
|
+
ActiveSupport::Deprecation.deprecated_method_warning method,
|
12
|
+
"Scribbler is now preferred over Scribbler::Base see github for more info"
|
13
|
+
Scribbler.public_send method, *args, &block
|
14
|
+
else
|
15
|
+
super
|
167
16
|
end
|
168
17
|
end
|
169
18
|
|
170
|
-
|
171
|
-
|
172
|
-
location.present? and
|
173
|
-
(options[:message].present? or
|
174
|
-
options[:object].present? or
|
175
|
-
options[:custom_fields].present?)
|
176
|
-
end
|
177
|
-
|
178
|
-
# If the config agrees, attempt to include our special methods
|
179
|
-
# in the main application object.
|
180
|
-
#
|
181
|
-
# Example:
|
182
|
-
#
|
183
|
-
# Base.include_in_application
|
184
|
-
# # => Nothing
|
185
|
-
#
|
186
|
-
# Returns Nothing
|
187
|
-
#
|
188
|
-
# TODO: Allow config to define where we send the include
|
189
|
-
def self.include_in_application
|
190
|
-
if config.application_include
|
191
|
-
begin
|
192
|
-
::Rails.application.class.parent.send :include, Includeables
|
193
|
-
rescue NameError
|
194
|
-
nil
|
195
|
-
end
|
196
|
-
end
|
19
|
+
def self.respond_to?(method, include_private = false)
|
20
|
+
Scribbler.respond_to?(method) || super
|
197
21
|
end
|
198
22
|
end
|
199
23
|
end
|