lumberjack 1.0.13 → 1.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +129 -0
- data/{MIT_LICENSE → MIT_LICENSE.txt} +0 -0
- data/README.md +142 -23
- data/VERSION +1 -1
- data/lib/lumberjack.rb +70 -22
- data/lib/lumberjack/context.rb +35 -0
- data/lib/lumberjack/device.rb +22 -8
- data/lib/lumberjack/device/date_rolling_log_file.rb +9 -9
- data/lib/lumberjack/device/log_file.rb +14 -3
- data/lib/lumberjack/device/multi.rb +46 -0
- data/lib/lumberjack/device/null.rb +1 -3
- data/lib/lumberjack/device/rolling_log_file.rb +45 -21
- data/lib/lumberjack/device/size_rolling_log_file.rb +10 -10
- data/lib/lumberjack/device/writer.rb +92 -61
- data/lib/lumberjack/formatter.rb +97 -28
- data/lib/lumberjack/formatter/date_time_formatter.rb +25 -0
- data/lib/lumberjack/formatter/exception_formatter.rb +25 -2
- data/lib/lumberjack/formatter/id_formatter.rb +23 -0
- data/lib/lumberjack/formatter/object_formatter.rb +12 -0
- data/lib/lumberjack/formatter/pretty_print_formatter.rb +4 -4
- data/lib/lumberjack/formatter/string_formatter.rb +1 -1
- data/lib/lumberjack/formatter/strip_formatter.rb +12 -0
- data/lib/lumberjack/formatter/structured_formatter.rb +63 -0
- data/lib/lumberjack/log_entry.rb +44 -16
- data/lib/lumberjack/logger.rb +275 -69
- data/lib/lumberjack/rack.rb +3 -2
- data/lib/lumberjack/rack/context.rb +18 -0
- data/lib/lumberjack/rack/request_id.rb +4 -4
- data/lib/lumberjack/rack/unit_of_work.rb +1 -1
- data/lib/lumberjack/severity.rb +11 -10
- data/lib/lumberjack/tag_formatter.rb +96 -0
- data/lib/lumberjack/tagged_logger_support.rb +66 -0
- data/lib/lumberjack/tagged_logging.rb +29 -0
- data/lib/lumberjack/tags.rb +42 -0
- data/lib/lumberjack/template.rb +81 -33
- data/lumberjack.gemspec +31 -0
- metadata +26 -53
- data/Rakefile +0 -40
- data/spec/device/date_rolling_log_file_spec.rb +0 -73
- data/spec/device/log_file_spec.rb +0 -48
- data/spec/device/null_spec.rb +0 -12
- data/spec/device/rolling_log_file_spec.rb +0 -151
- data/spec/device/size_rolling_log_file_spec.rb +0 -58
- data/spec/device/writer_spec.rb +0 -118
- data/spec/formatter/exception_formatter_spec.rb +0 -20
- data/spec/formatter/inspect_formatter_spec.rb +0 -13
- data/spec/formatter/pretty_print_formatter_spec.rb +0 -14
- data/spec/formatter/string_formatter_spec.rb +0 -12
- data/spec/formatter_spec.rb +0 -45
- data/spec/log_entry_spec.rb +0 -69
- data/spec/logger_spec.rb +0 -411
- data/spec/lumberjack_spec.rb +0 -29
- data/spec/rack/request_id_spec.rb +0 -48
- data/spec/rack/unit_of_work_spec.rb +0 -26
- data/spec/severity_spec.rb +0 -23
- data/spec/spec_helper.rb +0 -32
- data/spec/template_spec.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c7912cf1bfe32dcaa911a6a65a0b755fb3051eebc2a7e4a65ff5d422f2f61ad7
|
4
|
+
data.tar.gz: b4077d2ef97be7169ed0e7bca7d107ec3f42372dde45cae1e7cdcedae1fb4e61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a092775aec0c7670eda8ff4959a7cc928a57b0934ecc8a1190efe395b437bc0a681bdbd2f3455b98f3cf757904f5f39b31c96e24e9c8bcd7a481b806027e92c8
|
7
|
+
data.tar.gz: 885f76da2738f3f6236a363d9a7dea68f83a80a03e123a3c52c578984f963e959de6fd60d0fd222d9a9933c22ed959181538abb4118163c8fd6528292e88673c
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
## 1.2.8
|
2
|
+
|
3
|
+
* Add `Logger#untagged` to remove previously set logging tags from a block.
|
4
|
+
* Return result of the block when a block is passed to `Logger#tag`.
|
5
|
+
|
6
|
+
## 1.2.7
|
7
|
+
|
8
|
+
* Allow passing frozen hashes to `Logger#tag`. Tags passed to this method are now duplicated so the logger maintains it's own copy of the hash.
|
9
|
+
|
10
|
+
## 1.2.6
|
11
|
+
|
12
|
+
* Fix `Logger#tag` so it only ads to the current block's logger tags instead of the global tags if called inside a `Logger#tag` block.
|
13
|
+
* Add Logger#remove_tag
|
14
|
+
|
15
|
+
## 1.2.5
|
16
|
+
|
17
|
+
* Fix logic with recursive reference guard in StructuredFormatter so it only suppresses Enumerable references.
|
18
|
+
* Add support for bang methods (error!) for setting the log level.
|
19
|
+
|
20
|
+
## 1.2.4
|
21
|
+
|
22
|
+
* Enhance `ActiveSupport::TaggedLogging` support so code that Lumberjack loggers can be wrapped with a tagged logger.
|
23
|
+
|
24
|
+
## 1.2.3
|
25
|
+
|
26
|
+
* Fix structured formatter so no-recursive, duplicate references are allowed.
|
27
|
+
|
28
|
+
## 1.2.2
|
29
|
+
|
30
|
+
* Prevent infinite loops in the structured formatter where objects have backreferences to each other.
|
31
|
+
|
32
|
+
## 1.2.1
|
33
|
+
|
34
|
+
* Prevent infinite loops where logging a statement triggers the logger.
|
35
|
+
|
36
|
+
## 1.2.0
|
37
|
+
|
38
|
+
* Enable compatibility with `ActiveSupport::TaggedLogger` by calling `tagged_logger!` on a logger.
|
39
|
+
* Add `tag_formatter` to logger to specify formatting of tags for output.
|
40
|
+
* Allow adding and removing classes by name to formatters.
|
41
|
+
* Allow adding and removing multiple classes in a single call to a formatter.
|
42
|
+
* Allow using symbols and strings as log level for silencing a logger.
|
43
|
+
* Ensure flusher thread gets stopped when logger is closed.
|
44
|
+
* Add writer for logger device attribute.
|
45
|
+
* Handle passing an array of devices to a multi device.
|
46
|
+
* Helper method to get a tag with a specified name.
|
47
|
+
* Add strip formatter to strip whitespace from strings.
|
48
|
+
* Support non-alpha numeric characters in template variables.
|
49
|
+
* Add backtrace cleaner to ExceptionFormatter.
|
50
|
+
|
51
|
+
## 1.1.1
|
52
|
+
|
53
|
+
* Replace Procs in tag values with the value of calling the Proc in log entries.
|
54
|
+
|
55
|
+
## 1.1.0
|
56
|
+
|
57
|
+
* Change `Lumberjack::Logger` to inherit from ::Logger
|
58
|
+
* Add support for tags on log messages
|
59
|
+
* Add global tag context for all loggers
|
60
|
+
* Add per logger tags and tag contexts
|
61
|
+
* Reimplement unit of work id as a tag on log entries
|
62
|
+
* Add support for setting datetime format on log devices
|
63
|
+
* Performance optimizations
|
64
|
+
* Add Multi device to output to multiple devices
|
65
|
+
* Add `DateTimeFormatter`, `IdFormatter`, `ObjectFormatter`, and `StructuredFormatter`
|
66
|
+
* Add rack `Context` middleware for setting thread global context
|
67
|
+
* End support for ruby versions < 2.3
|
68
|
+
* Add support for modules in formatters
|
69
|
+
|
70
|
+
## 1.0.13
|
71
|
+
|
72
|
+
* Reduce amount of code executed inside a mutex lock when writing to the logger stream.
|
73
|
+
* Added `:min_roll_check` option to `Lumberjack::Device::RollingLogFile` to reduce file system checks. Default is now to only check if a file needs to be rolled at most once per second.
|
74
|
+
* Force immutable strings for Ruby versions that support them.
|
75
|
+
|
76
|
+
## 1.0.12
|
77
|
+
|
78
|
+
* Add support for `ActionDispatch` request id for better Rails compatibility.
|
79
|
+
|
80
|
+
## 1.0.11
|
81
|
+
|
82
|
+
* Fix Ruby 2.4 deprecation warning on Fixnum (thanks koic).
|
83
|
+
* Fix gemspec files to be flat array (thanks e2).
|
84
|
+
|
85
|
+
## 1.0.10
|
86
|
+
|
87
|
+
* Expose option to manually roll log files.
|
88
|
+
* Minor code cleanup.
|
89
|
+
|
90
|
+
## 1.0.9
|
91
|
+
|
92
|
+
* Add method so Formatter is compatible with `ActiveSupport` logging extensions.
|
93
|
+
|
94
|
+
## 1.0.8
|
95
|
+
|
96
|
+
* Fix another internal variable name conflict with `ActiveSupport` logging extensions.
|
97
|
+
|
98
|
+
## 1.0.7
|
99
|
+
|
100
|
+
* Fix broken formatter attribute method.
|
101
|
+
|
102
|
+
## 1.0.6
|
103
|
+
|
104
|
+
* Fix internal variable name conflict with `ActiveSupport` logging extensions.
|
105
|
+
|
106
|
+
## 1.0.5
|
107
|
+
|
108
|
+
* Update docs.
|
109
|
+
* Remove autoload calls to make thread safe.
|
110
|
+
* Make compatible with Ruby 2.1.1 Pathname.
|
111
|
+
* Make compatible with standard library Logger's use of progname as default message.
|
112
|
+
|
113
|
+
## 1.0.4
|
114
|
+
|
115
|
+
* Add ability to supply a unit of work id for a block instead of having one generated every time.
|
116
|
+
|
117
|
+
## 1.0.3
|
118
|
+
|
119
|
+
* Change log file output format to binary to avoid encoding warnings.
|
120
|
+
* Fixed bug in log file rolling that left the file locked.
|
121
|
+
|
122
|
+
## 1.0.2
|
123
|
+
|
124
|
+
* Remove deprecation warnings under ruby 1.9.3.
|
125
|
+
* Add more error checking around file rolling.
|
126
|
+
|
127
|
+
## 1.0.1
|
128
|
+
|
129
|
+
* Writes are no longer buffered by default.
|
File without changes
|
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
![Continuous Integration](https://github.com/bdurand/lumberjack/workflows/Continuous%20Integration/badge.svg)
|
2
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/a0abc03721fff9b0cde1/maintainability)](https://codeclimate.com/github/bdurand/lumberjack/maintainability)
|
3
|
+
[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
|
4
|
+
|
1
5
|
# Lumberjack
|
2
6
|
|
3
7
|
Lumberjack is a simple, powerful, and fast logging implementation in Ruby. It uses nearly the same API as the Logger class in the Ruby standard library and as ActiveSupport::BufferedLogger in Rails.
|
@@ -33,21 +37,77 @@ The following information is recorded for each message:
|
|
33
37
|
* time - The time at which the message was recorded.
|
34
38
|
* program name - The name of the program logging the message. This can be either set for all messages or customized with each message.
|
35
39
|
* process id - The process id (pid) of the process that logged the message.
|
36
|
-
*
|
40
|
+
* tags - An map of name value pairs for addition information about the log context.
|
41
|
+
|
42
|
+
### Tags
|
37
43
|
|
38
|
-
|
44
|
+
You can use tags to provide additional meta data about a log message or the context that the log message is being made in. Using tags can keep you log messages clean. You can avoid string interoplation to add additional meta data.
|
39
45
|
|
40
|
-
|
46
|
+
Each of the logger methods includes an additional argument that can be used to specify tags on a messsage:
|
41
47
|
|
42
48
|
```ruby
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
logger.info("request completed", duration: elapsed_time, status: response.status)
|
50
|
+
```
|
51
|
+
|
52
|
+
You can also specify tags on a logger that will be included with every log message.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
logger.tag(host: Socket.gethostname)
|
56
|
+
```
|
57
|
+
|
58
|
+
You can specify tags that will only be applied to the logger in a block as well.
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
logger.tag(thread_id: Thread.current.object_id) do
|
62
|
+
logger.info("here") # Will include the `thread_id` tag
|
63
|
+
logger.tag(count: 15)
|
64
|
+
logger.info("with count") # Will include the `count` tag
|
65
|
+
end
|
66
|
+
logger.info("there") # Will not include the `thread_id` or `count` tag
|
67
|
+
```
|
68
|
+
|
69
|
+
You can also set tags to `Proc` objects that will be evaluated when creating a log entry.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
logger.tag(thread_id: lambda { Thread.current.object_id })
|
73
|
+
Thread.new do
|
74
|
+
logger.info("inside thread") # Will include the `thread_id` tag with id of the spawned thread
|
75
|
+
end
|
76
|
+
logger.info("outside thread") # Will include the `thread_id` tag with id of the main thread
|
77
|
+
```
|
78
|
+
|
79
|
+
Finally, you can specify a logging context with tags that apply within a block to all loggers.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
Lumberjack.context do
|
83
|
+
Lumberjack.tag(request_id: SecureRandom.hex)
|
84
|
+
logger.info("begin request") # Will include the `request_id` tag
|
85
|
+
end
|
86
|
+
logger.info("no requests") # Will not include the `request_id` tag
|
87
|
+
```
|
88
|
+
|
89
|
+
Tag keys are always converted to strings. Tags are inherited so that message tags take precedence over block tags which take precedence over global tags.
|
90
|
+
|
91
|
+
#### Compatibility with ActiveSupport::TaggedLogging
|
92
|
+
|
93
|
+
`Lumberjack::Logger` version 1.1.2 or greater is compatible with `ActiveSupport::TaggedLogging`. This is so that other code that expect to have a logger that responds to the `tagged` method will work. Any tags added with the `tagged` method will be appended to an array in the the "tagged" tag.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
logger.tagged("foo", "bar=1", "other") do
|
97
|
+
logger.info("here") # will include tags: {"tagged" => ["foo", "bar=1", "other"]}
|
98
|
+
end
|
49
99
|
```
|
50
100
|
|
101
|
+
#### Templates
|
102
|
+
|
103
|
+
The built in `Lumberjack::Device::Writer` class has built in support for including tags in the output using the `Lumberjack::Template` class.
|
104
|
+
|
105
|
+
You can specify any tag name you want in a template as well as the `:tags` macro for all tags. If a tag name has been used as it's own macro, it will not be included in the `:tags` macro.
|
106
|
+
|
107
|
+
#### Unit Of Work
|
108
|
+
|
109
|
+
Lumberjack 1.0 had a concept of a unit of work id that could be used to tie log messages together. This has been replaced by tags. There is still an implementation of `Lumberjack.unit_of_work`, but it is just a wrapper on the tag implementation.
|
110
|
+
|
51
111
|
### Pluggable Devices
|
52
112
|
|
53
113
|
When a Logger logs a LogEntry, it sends it to a Lumberjack::Device. Lumberjack comes with a variety of devices for logging to IO streams or files.
|
@@ -56,27 +116,74 @@ When a Logger logs a LogEntry, it sends it to a Lumberjack::Device. Lumberjack c
|
|
56
116
|
* Lumberjack::Device::LogFile - Writes log entries to a file.
|
57
117
|
* Lumberjack::Device::DateRollingLogFile - Writes log entries to a file that will automatically roll itself based on date.
|
58
118
|
* Lumberjack::Device::SizeRollingLogFile - Writes log entries to a file that will automatically roll itself based on size.
|
119
|
+
* Lumberjack::Device::Multi - This device wraps mulitiple other devices and will write log entries to each of them.
|
59
120
|
* Lumberjack::Device::Null - This device produces no output and is intended for testing environments.
|
60
121
|
|
61
122
|
If you'd like to send you log to a different kind of output, you just need to extend the Device class and implement the +write+ method. Or check out these plugins:
|
62
123
|
|
63
124
|
* [lumberjack_syslog_device](https://github.com/bdurand/lumberjack_syslog_device) - send your log messages to the system wide syslog service
|
64
|
-
* [lumberjack_multi-device](https://github.com/astevens/lumberjack_multi-device) - send log messages to multiple devices
|
65
125
|
* [lumberjack_mongo_device](https://github.com/bdurand/lumberjack_mongo_device) - store your log messages to a [MongoDB](http://www.mongodb.org/) NoSQL data store
|
66
126
|
* [lumberjack-couchdb-driver](https://github.com/narkisr/lumberjack-couchdb-driver) - store your log messages to a [CouchDB](http://couchdb.apache.org/) NoSQL data store
|
67
127
|
* [lumberjack_heroku_device](https://github.com/tonycoco/lumberjack_heroku_device) - log to Heroku's logging system
|
68
128
|
|
69
129
|
### Customize Formatting
|
70
130
|
|
71
|
-
|
131
|
+
#### Formatters
|
132
|
+
|
133
|
+
The message you send to the logger can be any object type and does not need to be a string. You can specify a `Lumberjack::Formatter` to instruct the logger how to format objects before outputting them to the device. You do this by mapping classes or modules to formatter code. This code can be either a block or an object that responds to the `call` method. The formatter will be called with the object logged as the message and the returned value will be what is sent to the device.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
# Format all floating point number with three significant digits.
|
137
|
+
logger.formatter.add(Float) { |value| value.round(3) }
|
138
|
+
|
139
|
+
# Format all enumerable objects as a comma delimited string.
|
140
|
+
logger.formatter.add(Enumerable) { |value| value.join(", ") }
|
141
|
+
```
|
142
|
+
|
143
|
+
There are several built in classes you can add as formatters. You can use a symbol to reference built in formatters.
|
72
144
|
|
73
145
|
```ruby
|
74
146
|
logger.formatter.add(Hash, :pretty_print) # use the Formatter::PrettyPrintFormatter for all Hashes
|
75
|
-
logger.formatter.add(
|
147
|
+
logger.formatter.add(Hash, Lumberjack::Formatter::PrettyPrintFormatter.new) # alternative using a formatter instance
|
148
|
+
```
|
149
|
+
|
150
|
+
* `:object` - `Lumberjack::Formatter::ObjectFormatter` - no op conversion that returns the object itself.
|
151
|
+
* `:string` - `Lumberjack::Formatter::StringFormatter` - calls `to_s` on the object.
|
152
|
+
* `:strip` - `Lumberjack::Formatter::StripFormatter` - calls `to_s.strip` on the object.
|
153
|
+
* `:inspect` - `Lumberjack::Formatter::InspectFormatter` - calls `inspect` on the object.
|
154
|
+
* `:exception` - `Lumberjack::Formatter::ExceptionFormatter` - special formatter for exceptions which logs them as multi line statements with the message and backtrace.
|
155
|
+
* `:date_time` - `Lumberjack::Formatter::DateTimeFormatter` - special formatter for dates and times to format them using `strftime`.
|
156
|
+
* `:pretty_print` - `Lumberjack::Formatter::PrettyPrintFormatter` - returns the pretty print format of the object.
|
157
|
+
* `:id` - `Lumberjack::Formatter::IdFormatter` - returns a hash of the object with keys for the id attribute and class.
|
158
|
+
* `:structured` - `Lumberjack::Formatter::StructuredFormatter` - crawls the object and applies the formatter recursively to Enumerable objects found in it (arrays, hashes, etc.).
|
159
|
+
|
160
|
+
To define your own formatter, either provide a block or an object that responds to `call` with a single argument.
|
161
|
+
|
162
|
+
The default formatter will pass through values for strings, numbers, and booleans, and use the `:inspect` formatter for all objects except for exceptions which will be formatted with the `:exception` formatter.
|
163
|
+
|
164
|
+
#### Tag Formatters
|
165
|
+
|
166
|
+
The `logger.formatter` will only apply to log messages. You can use `logger.tag_formatter` to register formatters for tags. You can register both default formatters that will apply to all tag values, as well as tag specifice formatters that will apply only to objects with a specific tag name.
|
167
|
+
|
168
|
+
The fomatter values can be either a `Lumberjack::Formatter` or a block or an object that responds to `call`. If you supply a `Lumberjack::Formatter`, the tag value will be passed through the rules for that formatter. If you supply a block or other object, it will be called with the tag value.
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
# These will all do the same thing formatting all tag values with `inspect`
|
172
|
+
logger.tag_formatter.default(Lumberjack::Formatter.new.clear.add(Object, :inspect))
|
173
|
+
logger.tag_formatter.default(Lumberjack::Formatter::InspectFormatter.new)
|
174
|
+
logger.tag_formatter.default { |value| value.inspect }
|
175
|
+
|
176
|
+
# This will register formatters only on specific tag names
|
177
|
+
logger.tag_formatter.add(:thread) { |thread| "Thread(#{thread.name})" }
|
178
|
+
logger.tag_formatter.add(:current_user, Lumberjack::Formatter::IdFormatter.new)
|
76
179
|
```
|
77
180
|
|
78
|
-
|
79
|
-
|
181
|
+
#### Templates
|
182
|
+
|
183
|
+
If you use the built in `Lumberjack::Writer` derived devices, you can also customize the Template used to format the LogEntry.
|
184
|
+
|
185
|
+
See `Lumberjack::Template` for a complete list of macros you can use in the template. You can also use a block that receives a `Lumberjack::LogEntry` as a template.
|
186
|
+
|
80
187
|
```ruby
|
81
188
|
# Change the format of the time in the log
|
82
189
|
Lumberjack::Logger.new("application.log", :time_format => "%m/%d/%Y %H:%M:%S")
|
@@ -84,23 +191,27 @@ If you use the built in devices, you can also customize the Template used to for
|
|
84
191
|
# Use a simple template that only includes the time and the message
|
85
192
|
Lumberjack::Logger.new("application.log", :template => ":time - :message")
|
86
193
|
|
194
|
+
# Use a simple template that includes tags, but handles the `duration` tag separately.
|
195
|
+
# All tags will appear at the end of the message except for `duration` which will be at the beginning.
|
196
|
+
Lumberjack::Logger.new("application.log", :template => ":time (:duration) - :message - :tags")
|
197
|
+
|
87
198
|
# Use a custom template as a block that only includes the first character of the severity
|
88
199
|
template = lambda{|e| "#{e.severity_label[0, 1]} #{e.time} - #{e.message}"}
|
89
200
|
Lumberjack::Logger.new("application.log", :template => template)
|
90
201
|
```
|
91
202
|
|
92
|
-
### Buffered
|
203
|
+
### Buffered Logging
|
93
204
|
|
94
|
-
The logger has hooks for devices that support buffering to increase performance by batching physical writes. Log entries are not guaranteed to be written until the Lumberjack::Logger#flush method is called.
|
205
|
+
The logger has hooks for devices that support buffering to potentially increase performance by batching physical writes. Log entries are not guaranteed to be written until the Lumberjack::Logger#flush method is called. Buffering can improve performance if I/O is slow or there high overhead writing to the log device.
|
95
206
|
|
96
|
-
You can use the
|
207
|
+
You can use the `:flush_seconds` option on the logger to periodically flush the log. This is usually a good idea so you can more easily debug hung processes. Without periodic flushing, a process that hangs may never write anything to the log because the messages are sitting in a buffer. By turning on periodic flushing, the logged messages will be written which can greatly aid in debugging the problem.
|
97
208
|
|
98
|
-
The built in stream based logging devices use an internal buffer. The size of the buffer (in bytes) can be set with the
|
209
|
+
The built in stream based logging devices use an internal buffer. The size of the buffer (in bytes) can be set with the `:buffer_size` options when initializing a logger. The default behavior is to not to buffer.
|
99
210
|
|
100
211
|
```ruby
|
101
212
|
# Set buffer to flush after 8K has been written to the log.
|
102
213
|
logger = Lumberjack::Logger.new("application.log", :buffer_size => 8192)
|
103
|
-
|
214
|
+
|
104
215
|
# Turn off buffering so entries are immediately written to disk.
|
105
216
|
logger = Lumberjack::Logger.new("application.log", :buffer_size => 0)
|
106
217
|
```
|
@@ -111,6 +222,14 @@ The built in devices include two that can automatically roll log files based eit
|
|
111
222
|
|
112
223
|
There is a similar feature in the standard library Logger class, but the implementation here is safe to use with multiple processes writing to the same log file.
|
113
224
|
|
225
|
+
## Difference Standard Library Logger
|
226
|
+
|
227
|
+
`Lumberjack::Logger` does not extend from the `Logger` class in the standard library, but it does implement a compantible API. The main difference is in the flow of how messages are ultimately sent to devices for output.
|
228
|
+
|
229
|
+
The standard library Logger logic converts the log entries to strings and then sends the string to the device to be written to a stream. Lumberjack, on the other hand, sends structured data in the form of a `Lumberjack::LogEntry` to the device and lets the device worry about how to format it. The reason for this flip is to better support structured data logging. Devices (even ones that write to streams) can format the entire payload including non-string objects and tags however they need to.
|
230
|
+
|
231
|
+
The logging methods (`debug`, 'info', 'warn', 'error', 'fatal') are overloaded with an additional argument for setting tags on the log entry.
|
232
|
+
|
114
233
|
## Examples
|
115
234
|
|
116
235
|
These example are for Rails applications, but there is no dependency on Rails for using this gem. Most of the examples are applicable to any Ruby application.
|
@@ -139,17 +258,17 @@ To set up a logger to roll log files when they get to 100Mb, you could use this:
|
|
139
258
|
```ruby
|
140
259
|
config.logger = Lumberjack::Logger.new(log_file_path, :max_size => 100.megabytes)
|
141
260
|
```
|
142
|
-
|
261
|
+
|
143
262
|
To change the log message format, you could use this code:
|
144
263
|
|
145
264
|
```ruby
|
146
265
|
config.logger = Lumberjack::Logger.new(log_file_path, :template => ":time - :message")
|
147
266
|
```
|
148
267
|
|
149
|
-
To change the log message format to output JSON, you could use this code
|
150
|
-
|
268
|
+
To change the log message format to output JSON, you could use this code:
|
269
|
+
|
151
270
|
```ruby
|
152
|
-
config.logger = Lumberjack::Logger.new(log_file_path, :template => lambda{|e|
|
271
|
+
config.logger = Lumberjack::Logger.new(log_file_path, :template => lambda{|e| JSON.dump(time: e.time, level: e.severity_label, message: e.message)})
|
153
272
|
```
|
154
273
|
|
155
274
|
To send log messages to syslog instead of to a file, you could use this (require the lumberjack_syslog_device gem):
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.8
|
data/lib/lumberjack.rb
CHANGED
@@ -1,21 +1,27 @@
|
|
1
1
|
# frozen_string_literals: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "rbconfig"
|
4
|
+
require "time"
|
5
|
+
require "securerandom"
|
6
|
+
require "logger"
|
7
7
|
|
8
8
|
module Lumberjack
|
9
|
-
LINE_SEPARATOR = (RbConfig::CONFIG[
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
LINE_SEPARATOR = (RbConfig::CONFIG["host_os"] =~ /mswin/i ? "\r\n" : "\n")
|
10
|
+
|
11
|
+
require_relative "lumberjack/severity"
|
12
|
+
require_relative "lumberjack/formatter"
|
13
|
+
|
14
|
+
require_relative "lumberjack/context"
|
15
|
+
require_relative "lumberjack/log_entry"
|
16
|
+
require_relative "lumberjack/device"
|
17
|
+
require_relative "lumberjack/logger"
|
18
|
+
require_relative "lumberjack/tags"
|
19
|
+
require_relative "lumberjack/tag_formatter"
|
20
|
+
require_relative "lumberjack/tagged_logger_support"
|
21
|
+
require_relative "lumberjack/tagged_logging"
|
22
|
+
require_relative "lumberjack/template"
|
23
|
+
require_relative "lumberjack/rack"
|
24
|
+
|
19
25
|
class << self
|
20
26
|
# Define a unit of work within a block. Within the block supplied to this
|
21
27
|
# method, calling +unit_of_work_id+ will return the same value that can
|
@@ -27,19 +33,61 @@ module Lumberjack
|
|
27
33
|
# For the common use case of treating a single web request as a unit of work, see the
|
28
34
|
# Lumberjack::Rack::UnitOfWork class.
|
29
35
|
def unit_of_work(id = nil)
|
30
|
-
save_val = Thread.current[:lumberjack_logger_unit_of_work_id]
|
31
36
|
id ||= SecureRandom.hex(6)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
ensure
|
36
|
-
Thread.current[:lumberjack_logger_unit_of_work_id] = save_val
|
37
|
+
context do
|
38
|
+
context[:unit_of_work_id] = id
|
39
|
+
yield
|
37
40
|
end
|
38
41
|
end
|
39
|
-
|
42
|
+
|
40
43
|
# Get the UniqueIdentifier for the current unit of work.
|
41
44
|
def unit_of_work_id
|
42
|
-
|
45
|
+
context[:unit_of_work_id]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Contexts can be used to store tags that will be attached to all log entries in the block.
|
49
|
+
#
|
50
|
+
# If this method is called with a block, it will set a logging context for the scope of a block.
|
51
|
+
# If there is already a context in scope, a new one will be created that inherits
|
52
|
+
# all the tags of the parent context.
|
53
|
+
#
|
54
|
+
# Otherwise, it will return the current context. If one doesn't exist, it will return a new one
|
55
|
+
# but that context will not be in any scope.
|
56
|
+
def context(&block)
|
57
|
+
current_context = Thread.current[:lumberjack_context]
|
58
|
+
if block
|
59
|
+
use_context(Context.new(current_context), &block)
|
60
|
+
else
|
61
|
+
current_context || Context.new
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set the context to use within a block.
|
66
|
+
def use_context(context, &block)
|
67
|
+
current_context = Thread.current[:lumberjack_context]
|
68
|
+
begin
|
69
|
+
Thread.current[:lumberjack_context] = (context || Context.new)
|
70
|
+
yield
|
71
|
+
ensure
|
72
|
+
Thread.current[:lumberjack_context] = current_context
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Return true if inside a context block.
|
77
|
+
def context?
|
78
|
+
!!Thread.current[:lumberjack_context]
|
79
|
+
end
|
80
|
+
|
81
|
+
# Return the tags from the current context or nil if there are no tags.
|
82
|
+
def context_tags
|
83
|
+
context = Thread.current[:lumberjack_context]
|
84
|
+
context&.tags
|
85
|
+
end
|
86
|
+
|
87
|
+
# Set tags on the current context
|
88
|
+
def tag(tags)
|
89
|
+
context = Thread.current[:lumberjack_context]
|
90
|
+
context&.tag(tags)
|
43
91
|
end
|
44
92
|
end
|
45
93
|
end
|