rails_semantic_logger 1.0.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/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
+