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 CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+
19
+ coverage
data/.irbrc ADDED
@@ -0,0 +1,2 @@
1
+ $:<< "./lib"
2
+ require 'scribbler'
data/.rvmrc CHANGED
@@ -1,4 +1,4 @@
1
- rvm --create ruby-1.9.3-p125@scribbler
1
+ rvm --create ruby-1.9.3-p327-turbo@scribbler
2
2
  # Ensure that Bundler is installed, install it if it is not.
3
3
  if ! command -v bundle > /dev/null; then
4
4
  gem install bundler
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Scribbler
2
2
 
3
3
  [![TravisCI](https://secure.travis-ci.org/jphenow/scribbler.png "TravisCI")](http://travis-ci.org/jphenow/scribbler "Travis-CI Scribbler")
4
+ [![Code Climate](https://codeclimate.com/badge.png)](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
- gem 'scribbler'
48
+ ```ruby
49
+ gem 'scribbler'
50
+ ```
19
51
 
20
52
  to your Gemfile and
21
53
 
22
- bundle install
54
+ ```bash
55
+ bundle install
56
+ ```
23
57
 
24
58
  Then
25
59
 
26
- scribbler install # For options do `scribbler` first
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
- Scribbler::Base.configure do
33
- config.application_include = true
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
- config.logs = %w[production delayed_job]
72
+ # config.log_directory = File.new '/a/better/path'
38
73
 
39
- config.use_template_by_default = true # Default: false
74
+ config.use_template_by_default = true # Default: false
40
75
 
41
- # config.template = proc do |options|
42
- # <<-MSG
43
- # ##########
44
- # Cool template bro!
45
- # Message: #{options[:message]}
46
- # MSG
47
- # end
48
- end
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
- Blogger.production_log_location
53
- # => <#Path: Rails.root.join('log', 'production.log')>
88
+ ```ruby
89
+ Blogger.production_log_location
90
+ # => <#Path: Rails.root.join('log', 'production.log')>
91
+ ```
54
92
 
55
93
  or
56
94
 
57
- Scribbler::Base.production_log_location
58
- # => <#Path: Rails.root.join('log', 'production.log')>
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
- # Notifies NewRelic and drops the message in log found at Blogger.production_log_location
63
- Blogger.log :production, :error => e, :message => "#{e} broke stuff"
64
- Scribbler::Base.log :production, :error => e, :message => "#{e} broke stuff"
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
- # Only logs to log/delayed_job.log and doesn't notify NewRelic
67
- Blogger.log :delayed_job, :message => "Successfully executed Delayed Job"
68
- Scribbler::Base.log :delayed_job, :message => "Successfully executed Delayed Job"
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
- # Doesn't notify NewRelic but gives the method access to the error and logs the message
71
- # to the given logfile
72
- Blogger.log 'production', :new_relic => false, :error => e, :message => "#{e} broke stuff"
73
- Scribbler::Base.log 'production', :new_relic => false, :error => e, :message => "#{e} broke stuff"
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
- # Logs to given file without using the fancy log methods
76
- Blogger.log File.expand_path(File.join(File.dirname(__FILE__), 'logfile.log')), :message => "#{e} broke stuff"
77
- Scribbler::Base.log File.expand_path(File.join(File.dirname(__FILE__), 'logfile.log')), :message => "#{e} broke stuff"
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
- options - Hash of options for logging on Ngin
82
- :error - Error object, mostly for passing to NewRelic
83
- :message - Message to log in the actual file [REQUIRED]
84
- :custom_fields - Custom fields dropped into the default template
85
- :template - Whether or not to use the template at this log
86
- :new_relic - Notify NewRelic of the error (default: true)
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)
@@ -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
 
@@ -1,7 +1,68 @@
1
1
  require 'active_support/all'
2
2
  require 'scribbler/version'
3
3
  require 'scribbler/configurator'
4
- require 'scribbler/base'
4
+ require 'scribbler/log_location'
5
+ require 'scribbler/logger'
5
6
  require 'scribbler/includeables'
6
- require 'scribbler/cli'
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'
@@ -1,199 +1,23 @@
1
1
  module Scribbler
2
- class Base
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
- class_eval(&block)
65
- Base.include_in_application
66
- BaseIncluder.include_includeables
67
- end
68
-
69
- # Simply returns the configurator class.
70
- #
71
- # Examples:
72
- #
73
- # Base.config
74
- # # => Scribbler::Configurator
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
- # TODO: Fix to work with any template
171
- def self.can_apply_to_log?(location, options)
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