rails_semantic_logger 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ group :test do
4
+ gem "shoulda"
5
+ end
6
+
7
+ gem 'semantic_logger', '>= 2.0.0'
8
+ gem 'rails', '>= 3.0.10'
data/LICENSE.txt ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2012 Clarity Services, Inc.
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,476 @@
1
+ rails_semantic_logger
2
+ =====================
3
+
4
+ Improved logging for Ruby on Rails
5
+
6
+ * http://github.com/ClarityServices/rails_semantic_logger
7
+
8
+ ### Overview
9
+
10
+ Rails Semantic Logger replaces the Rails default logger with [Semantic Logger](http://github.com/ClarityServices/semantic_logger)
11
+
12
+ [Semantic Logger](http://github.com/ClarityServices/semantic_logger) takes
13
+ logging in Ruby to a new level by adding several new capabilities to the
14
+ commonly used Logging API:
15
+
16
+ Dynamic
17
+
18
+ * Increase the log level at runtime for just one class
19
+ * For example enable debug level logging for a single class (logging instance)
20
+ while the program is running to get more detailed logging in production for just that class
21
+
22
+ Tagged Logging
23
+
24
+ * Supply custom data to be added to every log entry within a block of code,
25
+ including libraries and existing gems
26
+ * Tagged logging is critical for any high traffic site so that one can narrow
27
+ down log entries for a single call that is mixed in with log entries
28
+ from hundreds of other log entries
29
+
30
+ High Performance
31
+
32
+ * Logging is performed in a separate thread so as not to impact performance of
33
+ running code
34
+
35
+ Customizable
36
+
37
+ * Custom formatting by destination
38
+ * Easy to "roll your own" destination (Appender).
39
+ For example to log to Hadoop, Redis, etc..
40
+
41
+ Payload support
42
+
43
+ * Aside from the regular log message, a hash payload can also be supplied with
44
+ every log entry
45
+ * Very powerful when logging to NOSQL destinations that allow queries against
46
+ any data in the payload
47
+
48
+ Exceptions
49
+
50
+ * Directly log exceptions
51
+ * Semantic Logger standardizes the logging of exceptions with their backtraces
52
+ to text destinations and writes the exception elements as a hash to NOSQL
53
+ destinations
54
+
55
+ Drop-in Replacement
56
+
57
+ * Simple drop-in replacement for the Ruby, or the Rails loggers
58
+ * Supports current common logging interface
59
+ * No changes to existing to code to use new logger ( other than replacing the logger )
60
+
61
+ Rails 2 & 3 Support
62
+
63
+ * Just include the semantic_logger gem into Rails and it will immediately
64
+ replace the existing loggers to improve performance and information
65
+ in the log files
66
+ * The Rails 3 Tagged logging feature is already available for Rails 2 by using Semantic Logger
67
+
68
+ Thread Aware
69
+
70
+ * Includes the process and thread id information in every log entry
71
+ * If running JRuby it will also include the name of the thread for every log entry
72
+
73
+ Trace Level
74
+
75
+ * :trace is a new level common in other languages and is commonly used for
76
+ logging trace level detail. It is intended for logging data at level below
77
+ :debug.
78
+ * :trace can be used for logging the actual data sent or received over the network
79
+ that is rarely needed but is critical when things are not working as expected.
80
+ * Since :trace can be enabled on a per class basis it can even be turned on
81
+ in production to resolve what was actually sent to an external vendor
82
+
83
+ Multiple Destinations
84
+
85
+ * Log to multiple destinations at the same time ( File and MongoDB, etc.. )
86
+ * Each destination can also have its own log level.
87
+ For example, only log :info and above to MongoDB, or :warn and above to a
88
+ second log file
89
+
90
+ Benchmarking
91
+
92
+ * The performance of any block of code can be measured and logged at the same time
93
+ depending on the active log level
94
+
95
+ Semantic Capabilities
96
+
97
+ * With Semantic Logger it is simple to mix-in additional semantic information with
98
+ every log entry
99
+ * The application or class name is automatically included for every log entry under
100
+ a specific logging instance
101
+ * Includes the duration of blocks of code
102
+ * Any hash containing context specific information such as user_id or location information
103
+
104
+ Beyond Tagged Logging
105
+
106
+ * Supply entire hash of custom data to be added to the payload of every log entry
107
+ within a block of code, including libraries and existing gems
108
+
109
+ NOSQL Destinations
110
+
111
+ * Every log entry is broken down into elements that NOSQL data stores can understand:
112
+
113
+ ```json
114
+ {
115
+ "_id" : ObjectId("5034fa48e3f3fea945e83ef2"),
116
+ "time" : ISODate("2012-08-22T15:27:04.409Z"),
117
+ "host_name" : "release",
118
+ "pid" : 16112,
119
+ "thread_name" : "main",
120
+ "name" : "UserLocator",
121
+ "level" : "debug",
122
+ "message" : "Fetch user information",
123
+ "duration" : 12,
124
+ "payload" : {
125
+ "user" : "Jack",
126
+ "zip_code" : 12345,
127
+ "location" : "US"
128
+ }
129
+ }
130
+ ```
131
+
132
+ Thread Safe
133
+
134
+ * Semantic Logger is completely thread safe and all methods can be called
135
+ concurrently from any thread
136
+ * Tagged logging keeps any tagging data on a per-thread basis to ensure that
137
+ tags from different threads are not inter-mingled
138
+
139
+ ### Introduction
140
+
141
+ Just by including the rails_semantic_logger gem, Rails Semantic Logger will
142
+ replace the default Rails logger with Semantic Logger. Without further
143
+ configuration it will log to the existing Rails log file in a more efficient
144
+ multi-threaded way.
145
+
146
+ Extract from a Rails log file after adding the semantic_logger gem:
147
+
148
+ ```
149
+ 2012-10-19 12:05:46.736 I [35940:JRubyWorker-10] Rails --
150
+
151
+ Started GET "/" for 127.0.0.1 at 2012-10-19 12:05:46 +0000
152
+ 2012-10-19 12:05:47.318 I [35940:JRubyWorker-10] ActionController -- Processing by AdminController#index as HTML
153
+ 2012-10-19 12:05:47.633 D [35940:JRubyWorker-10] ActiveRecord -- User Load (2.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
154
+ 2012-10-19 12:05:49.833 D [35940:JRubyWorker-10] ActiveRecord -- Role Load (2.0ms) SELECT `roles`.* FROM `roles`
155
+ 2012-10-19 12:05:49.868 D [35940:JRubyWorker-10] ActiveRecord -- Role Load (1.0ms) SELECT * FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE (`roles_users`.user_id = 1 )
156
+ 2012-10-19 12:05:49.885 I [35940:JRubyWorker-10] ActionController -- Rendered menus/_control_system.html.erb (98.0ms)
157
+ 2012-10-19 12:05:51.014 I [35940:JRubyWorker-10] ActionController -- Rendered layouts/_top_bar.html.erb (386.0ms)
158
+ 2012-10-19 12:05:51.071 D [35940:JRubyWorker-10] ActiveRecord -- Announcement Load (20.0ms) SELECT `announcements`.* FROM `announcements` WHERE `announcements`.`active` = 1 ORDER BY created_at desc
159
+ 2012-10-19 12:05:51.072 I [35940:JRubyWorker-10] ActionController -- Rendered layouts/_announcement.html.erb (26.0ms)
160
+ 2012-10-19 12:05:51.083 I [35940:JRubyWorker-10] ActionController -- Rendered layouts/_flash.html.erb (4.0ms)
161
+ 2012-10-19 12:05:51.109 I [35940:JRubyWorker-10] ActionController -- Rendered layouts/_footer.html.erb (16.0ms)
162
+ 2012-10-19 12:05:51.109 I [35940:JRubyWorker-10] ActionController -- Rendered admin/index.html.erb within layouts/base (1329.0ms)
163
+ 2012-10-19 12:05:51.113 I [35940:JRubyWorker-10] ActionController -- Completed 200 OK in 3795ms (Views: 1349.0ms | ActiveRecord: 88.0ms | Mongo: 0.0ms)
164
+ ```
165
+
166
+ ### Logging API
167
+
168
+ #### Standard Logging methods
169
+
170
+ The Semantic Logger logging API supports the existing logging interface for
171
+ the Rails and Ruby Loggers. For example:
172
+
173
+ ```ruby
174
+ logger.info("Hello World")
175
+ ```
176
+
177
+ Or to query whether a specific log level is set
178
+
179
+ ```ruby
180
+ logger.info?
181
+ ```
182
+
183
+ The following logging methods are available
184
+
185
+ ```ruby
186
+ trace(message, payload=nil, exception=nil, &block)
187
+ debug(message, payload=nil, exception=nil, &block)
188
+ info(message, payload=nil, exception=nil, &block)
189
+ warn(message, payload=nil, exception=nil, &block)
190
+ error(message, payload=nil, exception=nil, &block)
191
+ fatal(message, payload=nil, exception=nil, &block)
192
+ ```
193
+
194
+ Parameters
195
+
196
+ - message: The text message to log.
197
+ Mandatory only if no block is supplied
198
+ - payload: Optional, either a Ruby Exception object or a Hash
199
+ - exception: Optional, Ruby Exception object. Allows both an exception and a payload to be logged
200
+ - block: The optional block is executed only if the corresponding log level
201
+ is active. Can be used to prevent unnecessary calculations of debug data in
202
+ production.
203
+
204
+ Examples:
205
+
206
+ ```ruby
207
+ logger.debug("Calling Supplier")
208
+
209
+ logger.debug("Calling Supplier", :request => 'update', :user => 'Jack')
210
+
211
+ logger.debug { "A total of #{result.inject(0) {|sum, i| i+sum }} were processed" }
212
+ ```
213
+
214
+ ### Exceptions
215
+
216
+ The Semantic Logger adds an optional parameter to the existing log methods so that
217
+ a corresponding Exception can be logged in a standard way
218
+
219
+ ```ruby
220
+ begin
221
+ # ... Code that can raise an exception
222
+ rescue Exception => exception
223
+ logger.error("Oops external call failed", exception)
224
+ # Re-raise or handle the exception
225
+ raise exception
226
+ end
227
+ ```
228
+
229
+ #### Payload
230
+
231
+ The Semantic Logger adds an extra parameter to the existing log methods so that
232
+ additional payload can be logged, such as a Hash or a Ruby Exception object.
233
+
234
+ ```ruby
235
+ logger.info("Oops external call failed", :result => :failed, :reason_code => -10)
236
+ ```
237
+
238
+ The additional payload is machine readable so that we don't have to write complex
239
+ regular expressions so that a program can analyze log output. With the MongoDB
240
+ appender the payload is written directly to MongoDB as part of the document and
241
+ is therefore fully searchable
242
+
243
+ #### Benchmarking
244
+
245
+ Another common logging requirement is to measure the time it takes to execute a block
246
+ of code based on the log level. For example:
247
+
248
+ ```ruby
249
+ Rails.logger.benchmark_info "Calling external interface" do
250
+ # Code to call external service ...
251
+ end
252
+ ```
253
+
254
+ The following output will be written to file:
255
+
256
+ 2012-08-30 15:37:29.474 I [48308:ScriptThreadProcess: script/rails] (5.2ms) Rails -- Calling external interface
257
+
258
+ If an exception is raised during the block the exception is logged
259
+ at the same log level as the benchmark along with the duration and message.
260
+ The exception will flow through to the caller unchanged
261
+
262
+ The following benchmarking methods are available
263
+
264
+ ```ruby
265
+ benchmark_trace(message, params=nil, &block)
266
+ benchmark_debug(message, params=nil, &block)
267
+ benchmark_info(message, params=nil, &block)
268
+ benchmark_warn(message, params=nil, &block)
269
+ benchmark_error(message, params=nil, &block)
270
+ benchmark_fatal(message, params=nil, &block)
271
+ ```
272
+
273
+ Parameters
274
+
275
+ - message: The mandatory text message to log.
276
+ - params:
277
+ ```
278
+ :log_exception
279
+ Control whether or how an exception thrown in the block is
280
+ reported by Semantic Logger. Values:
281
+ :full
282
+ Log the exception class, message, and backtrace
283
+ :partial
284
+ Log the exception class and messag
285
+ The backtrace will not be logged
286
+ :off
287
+ Any unhandled exception from the block will not be logged
288
+
289
+ :min_duration
290
+ Only log if the block takes longer than this duration in ms
291
+ Default: 0.0
292
+
293
+ :payload
294
+ Optional, Hash payload
295
+
296
+ :exception
297
+ Optional, Ruby Exception object to log along with the duration of the supplied block
298
+ ```
299
+
300
+ #### Logging levels
301
+
302
+ The following logging levels are available through Semantic Logger
303
+
304
+ :trace, :debug, :info, :warn, :error, :fatal
305
+
306
+ The log levels are listed above in the order of precedence with the most detail to the least.
307
+ For example :debug would include :info, :warn, :error, :fatal levels but not :trace
308
+ And :fatal would only log :fatal error messages and nothing else
309
+
310
+ :unknown has been mapped to :fatal for Rails and Ruby Logger
311
+
312
+ :trace is a new level that is often used for tracing low level calls such
313
+ as the data sent or received to external web services. It is also commonly used
314
+ in the development environment for low level trace logging of methods calls etc.
315
+
316
+ If only the rails logger is being used, then :trace level calls will be logged
317
+ as debug calls only if the log level is set to trace
318
+
319
+ #### Changing the Class name for Log Entries
320
+
321
+ When Semantic Logger is included in a Rails project it automatically replaces the
322
+ loggers for Rails, ActiveRecord::Base, ActionController::Base, and ActiveResource::Base
323
+ with wrappers that set their Class name. For example:
324
+
325
+ ```ruby
326
+ ActiveRecord::Base.logger = SemanticLogger::Logger.new(ActiveRecord)
327
+ ```
328
+
329
+ By replacing their loggers we now get the class name in the text logging output:
330
+
331
+ 2012-08-30 15:24:13.439 D [47900:main] ActiveRecord -- SQL (12.0ms) SELECT `schema_migrations`.`version` FROM `schema_migrations`
332
+
333
+ It is recommended to include a class specific logger for all major classes that will
334
+ be logging using the SemanticLogger::Loggable mix-in. For Example:
335
+
336
+ ```ruby
337
+ require 'semantic_logger'
338
+
339
+ class ExternalSupplier
340
+ # Lazy load logger class variable on first use
341
+ include SemanticLogger::Loggable
342
+
343
+ def call_supplier(amount, name)
344
+ logger.debug "Calculating with amount", { :amount => amount, :name => name }
345
+
346
+ # Measure and log on completion how long the call took to the external supplier
347
+ logger.benchmark_info "Calling external interface" do
348
+ # Code to call the external supplier ...
349
+ end
350
+ end
351
+ end
352
+ ```
353
+
354
+ This will result in the log output identifying the log entry as from the ExternalSupplier class
355
+
356
+ 2012-08-30 15:37:29.474 I [48308:ScriptThreadProcess: script/rails] (5.2ms) ExternalSupplier -- Calling external interface
357
+
358
+ #### Tagged Logging
359
+
360
+ Semantic Logger allows any Ruby or Rails program to also include tagged logging.
361
+
362
+ This means that any logging performed within a block, including any called
363
+ libraries or gems to include the specified tag with every log entry.
364
+
365
+ Using Tagged logging is critical in any highly concurrent environment so that
366
+ one can quickly find all related log entries across all levels of code, and even
367
+ across threads
368
+
369
+ ```ruby
370
+ logger.tagged(tracking_number) do
371
+ logger.debug("Hello World")
372
+ # ...
373
+ end
374
+ ```
375
+
376
+ #### Beyond Tagged Logging
377
+
378
+ Blocks of code can be tagged with not only values, but can be tagged with
379
+ entire hashes of data. The additional hash of data will be merged into
380
+ the payload of every log entry
381
+
382
+ For example every corresponding log entry could include a hash containing
383
+ a user_id, name, region, zip_code, tracking_number, etc...
384
+
385
+ ```ruby
386
+ logger.with_payload(:user => 'Jack', :zip_code => 12345) do
387
+ logger.debug("Hello World")
388
+ # ...
389
+ end
390
+ ```
391
+
392
+ #### Installation
393
+
394
+ Add the following line to Gemfile
395
+
396
+ ```ruby
397
+ gem 'rails_semantic_logger'
398
+ ```
399
+
400
+ Install required gems with bundler
401
+
402
+ bundle install
403
+
404
+ This will automatically replace the standard Rails logger with Semantic Logger
405
+ which will write all log data to the configured Rails logger.
406
+
407
+ #### Configuration
408
+
409
+ By default Semantic Logger will detect the log level from Rails. To set the
410
+ log level explicitly, add the following line to
411
+ config/environments/production.rb inside the Application.configure block
412
+
413
+ ```ruby
414
+ config.log_level = :trace
415
+ ```
416
+
417
+ To log to both the Rails log file and MongoDB add the following lines to
418
+ config/environments/production.rb inside the Application.configure block
419
+
420
+ ```ruby
421
+ config.after_initialize do
422
+ # Re-use the existing MongoDB connection, or create a new one here
423
+ db = Mongo::Connection.new['production_logging']
424
+
425
+ # Besides logging to the standard Rails logger, also log to MongoDB
426
+ config.semantic_logger.appenders << SemanticLogger::Appender::MongoDB.new(
427
+ :db => db,
428
+ :collection_size => 25.gigabytes
429
+ )
430
+ end
431
+ ```
432
+ ### Custom Appenders and Formatters
433
+
434
+ To write your own appenders or formatting, see [SemanticLogger](http://github.com/ClarityServices/semantic_logger)
435
+
436
+ ### Log Rotation
437
+
438
+ Since the log file is not re-opened with every call, when the log file needs
439
+ to be rotated, use a copy-truncate operation rather than deleting the file.
440
+
441
+ ### Dependencies
442
+
443
+ - Ruby MRI 1.8.7, 1.9.3 (or above) Or, JRuby 1.6.3 (or above)
444
+ - Rails 2 or above
445
+
446
+ Meta
447
+ ----
448
+
449
+ * Code: `git clone git://github.com/ClarityServices/rails_semantic_logger.git`
450
+ * Home: <https://github.com/ClarityServices/rails_semantic_logger>
451
+ * Bugs: <http://github.com/ClarityServices/rails_semantic_logger/issues>
452
+ * Gems: <http://rubygems.org/gems/rails_semantic_logger>
453
+
454
+ This project uses [Semantic Versioning](http://semver.org/).
455
+
456
+ Authors
457
+ -------
458
+
459
+ Reid Morrison :: reidmo@gmail.com :: @reidmorrison
460
+
461
+ License
462
+ -------
463
+
464
+ Copyright 2012 Clarity Services, Inc.
465
+
466
+ Licensed under the Apache License, Version 2.0 (the "License");
467
+ you may not use this file except in compliance with the License.
468
+ You may obtain a copy of the License at
469
+
470
+ http://www.apache.org/licenses/LICENSE-2.0
471
+
472
+ Unless required by applicable law or agreed to in writing, software
473
+ distributed under the License is distributed on an "AS IS" BASIS,
474
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
475
+ See the License for the specific language governing permissions and
476
+ limitations under the License.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ require 'rubygems'
5
+ require 'rake/clean'
6
+ require 'rake/testtask'
7
+ require 'date'
8
+ require 'rails_semantic_logger/version'
9
+
10
+ desc "Build gem"
11
+ task :gem do |t|
12
+ gemspec = Gem::Specification.new do |spec|
13
+ spec.name = 'rails_semantic_logger'
14
+ spec.version = RailsSemanticLogger::VERSION
15
+ spec.platform = Gem::Platform::RUBY
16
+ spec.authors = ['Reid Morrison']
17
+ spec.email = ['reidmo@gmail.com']
18
+ spec.homepage = 'https://github.com/ClarityServices/rails_semantic_logger'
19
+ spec.date = Date.today.to_s
20
+ spec.summary = "Improved logging for Ruby on Rails"
21
+ spec.description = "Replaces the default Rails logger with SemanticLogger"
22
+ spec.files = FileList["./**/*"].exclude(/.gem$/, /.log$/,/^nbproject/).map{|f| f.sub(/^\.\//, '')}
23
+ spec.has_rdoc = true
24
+ spec.add_dependency 'semantic_logger', '>= 2'
25
+ spec.add_dependency 'rails', '>= 2'
26
+ end
27
+ Gem::Builder.new(gemspec).build
28
+ end
29
+
@@ -0,0 +1,2 @@
1
+ require 'semantic_logger'
2
+ require 'rails_semantic_logger/railtie'
@@ -0,0 +1,73 @@
1
+ require 'logger'
2
+ module RailsSemanticLogger #:nodoc:
3
+ class Railtie < Rails::Railtie #:nodoc:
4
+ # Make the SemanticLogger config available in the Rails application config
5
+ #
6
+ # Example: Add the MongoDB logging appender in the Rails environment
7
+ # initializer in file config/environments/development.rb
8
+ #
9
+ # Claritybase::Application.configure do
10
+ # # Add the MongoDB logger appender only once Rails is initialized
11
+ # config.after_initialize do
12
+ # config.semantic_logger.appenders << SemanticLogger::Appender::Mongo.new(
13
+ # :db => Mongo::Connection.new['development_development']
14
+ # )
15
+ # end
16
+ # end
17
+ config.semantic_logger = ::SemanticLogger::Logger
18
+
19
+ # Initialize SemanticLogger. In a Rails environment it will automatically
20
+ # insert itself above the configured rails logger to add support for its
21
+ # additional features
22
+ #
23
+ # Also, if Mongoid is installed it will automatically start logging to Mongoid
24
+ #
25
+ # Loaded after Rails logging is initialized since SemanticLogger will continue
26
+ # to forward logging to the Rails Logger
27
+ initializer :initialize_semantic_logger, :before => :initialize_logger do
28
+ config = Rails.application.config
29
+
30
+ # Set the default log level based on the Rails config
31
+ SemanticLogger::Logger.default_level = config.log_level
32
+
33
+ # Existing loggers are ignored because servers like trinidad supply their
34
+ # own file loggers which would result in duplicate logging to the same log file
35
+ Rails.logger = config.logger = begin
36
+ # First check for Rails 3.2 path, then fallback to pre-3.2
37
+ path = ((config.paths.log.to_a rescue nil) || config.paths['log']).first
38
+ unless File.exist? File.dirname path
39
+ FileUtils.mkdir_p File.dirname path
40
+ end
41
+
42
+ # Set internal logger to log to file only, in case another appender
43
+ # experiences errors during writes
44
+ appender = SemanticLogger::Appender::File.new(path, config.log_level)
45
+ appender.name = "SemanticLogger::Logger"
46
+ SemanticLogger::Logger.logger = appender
47
+
48
+ # Add the log file to the list of appenders
49
+ SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new(path)
50
+ SemanticLogger::Logger.new(Rails)
51
+ rescue StandardError
52
+ # If not able to log to file, log to standard error with warning level only
53
+ SemanticLogger::Logger.default_level = :warn
54
+
55
+ SemanticLogger::Logger.logger = SemanticLogger::Appender::File.new(STDERR)
56
+ SemanticLogger::Logger.appenders << SemanticLogger::Appender::File.new(STDERR)
57
+
58
+ logger = SemanticLogger::Logger.new(Rails)
59
+ logger.warn(
60
+ "Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " +
61
+ "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
62
+ )
63
+ logger
64
+ end
65
+
66
+ # Replace the default Rails loggers
67
+ ActiveSupport.on_load(:active_record) { self.logger = SemanticLogger::Logger.new('ActiveRecord') }
68
+ ActiveSupport.on_load(:action_controller) { self.logger = SemanticLogger::Logger.new('ActionController') }
69
+ ActiveSupport.on_load(:action_mailer) { self.logger = SemanticLogger::Logger.new('ActionMailer') }
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module RailsSemanticLogger #:nodoc
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1 @@
1
+ file.reference.rails_semantic_logger-lib=/Users/rmorrison/Sandbox/rails_semantic_logger/lib
@@ -0,0 +1,5 @@
1
+ file.reference.rails_semantic_logger-lib=lib
2
+ main.file=
3
+ platform.active=Ruby_0
4
+ source.encoding=UTF-8
5
+ src.dir=${file.reference.rails_semantic_logger-lib}
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://www.netbeans.org/ns/project/1">
3
+ <type>org.netbeans.modules.ruby.rubyproject</type>
4
+ <configuration>
5
+ <data xmlns="http://www.netbeans.org/ns/ruby-project/1">
6
+ <name>rails_semantic_logger</name>
7
+ <source-roots>
8
+ <root id="src.dir"/>
9
+ </source-roots>
10
+ <test-roots/>
11
+ </data>
12
+ </configuration>
13
+ </project>
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_semantic_logger
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Reid Morrison
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-12-20 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: semantic_logger
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ version: "2"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: rails
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 2
41
+ version: "2"
42
+ type: :runtime
43
+ version_requirements: *id002
44
+ description: Replaces the default Rails logger with SemanticLogger
45
+ email:
46
+ - reidmo@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files: []
52
+
53
+ files:
54
+ - Gemfile
55
+ - lib/rails_semantic_logger/railtie.rb
56
+ - lib/rails_semantic_logger/version.rb
57
+ - lib/rails_semantic_logger.rb
58
+ - LICENSE.txt
59
+ - nbproject/private/private.properties
60
+ - nbproject/project.properties
61
+ - nbproject/project.xml
62
+ - Rakefile
63
+ - README.md
64
+ has_rdoc: true
65
+ homepage: https://github.com/ClarityServices/rails_semantic_logger
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.3.6
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Improved logging for Ruby on Rails
94
+ test_files: []
95
+