timber 2.0.24 → 2.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/CHANGELOG +3 -0
  4. data/README.md +314 -59
  5. data/bin/timber +11 -2
  6. data/lib/timber.rb +2 -7
  7. data/lib/timber/cli.rb +16 -28
  8. data/lib/timber/cli/api.rb +80 -14
  9. data/lib/timber/cli/api/application.rb +30 -0
  10. data/lib/timber/cli/config_file.rb +66 -0
  11. data/lib/timber/cli/file_helper.rb +43 -0
  12. data/lib/timber/cli/installer.rb +58 -0
  13. data/lib/timber/cli/installers.rb +37 -0
  14. data/lib/timber/cli/installers/other.rb +47 -0
  15. data/lib/timber/cli/installers/rails.rb +255 -0
  16. data/lib/timber/cli/installers/root.rb +189 -0
  17. data/lib/timber/cli/io.rb +97 -0
  18. data/lib/timber/cli/io/ansi.rb +22 -0
  19. data/lib/timber/cli/io/messages.rb +213 -0
  20. data/lib/timber/cli/os_helper.rb +53 -0
  21. data/lib/timber/config.rb +97 -43
  22. data/lib/timber/config/integrations.rb +63 -0
  23. data/lib/timber/config/integrations/rack.rb +74 -0
  24. data/lib/timber/context.rb +13 -10
  25. data/lib/timber/contexts.rb +1 -0
  26. data/lib/timber/contexts/custom.rb +16 -3
  27. data/lib/timber/contexts/http.rb +10 -3
  28. data/lib/timber/contexts/organization.rb +4 -0
  29. data/lib/timber/contexts/release.rb +46 -0
  30. data/lib/timber/contexts/runtime.rb +7 -1
  31. data/lib/timber/contexts/session.rb +8 -1
  32. data/lib/timber/contexts/system.rb +5 -1
  33. data/lib/timber/contexts/user.rb +9 -2
  34. data/lib/timber/current_context.rb +43 -11
  35. data/lib/timber/events/controller_call.rb +4 -0
  36. data/lib/timber/events/custom.rb +13 -5
  37. data/lib/timber/events/exception.rb +4 -0
  38. data/lib/timber/events/http_client_request.rb +4 -0
  39. data/lib/timber/events/http_client_response.rb +4 -0
  40. data/lib/timber/events/http_server_request.rb +5 -0
  41. data/lib/timber/events/http_server_response.rb +15 -3
  42. data/lib/timber/events/sql_query.rb +3 -0
  43. data/lib/timber/events/template_render.rb +3 -0
  44. data/lib/timber/integration.rb +40 -0
  45. data/lib/timber/integrations.rb +21 -14
  46. data/lib/timber/integrations/action_controller.rb +18 -0
  47. data/lib/timber/integrations/action_controller/log_subscriber.rb +2 -0
  48. data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +6 -0
  49. data/lib/timber/integrations/action_dispatch.rb +23 -0
  50. data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +2 -0
  51. data/lib/timber/integrations/action_view.rb +18 -0
  52. data/lib/timber/integrations/action_view/log_subscriber.rb +2 -0
  53. data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +10 -0
  54. data/lib/timber/integrations/active_record.rb +18 -0
  55. data/lib/timber/integrations/active_record/log_subscriber.rb +2 -0
  56. data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +8 -0
  57. data/lib/timber/integrations/rack.rb +12 -2
  58. data/lib/timber/integrations/rack/exception_event.rb +38 -5
  59. data/lib/timber/integrations/rack/http_context.rb +4 -6
  60. data/lib/timber/integrations/rack/http_events.rb +177 -27
  61. data/lib/timber/integrations/rack/middleware.rb +28 -0
  62. data/lib/timber/integrations/rack/session_context.rb +5 -6
  63. data/lib/timber/integrations/rack/user_context.rb +90 -43
  64. data/lib/timber/integrations/rails.rb +22 -0
  65. data/lib/timber/integrations/rails/rack_logger.rb +2 -0
  66. data/lib/timber/integrator.rb +18 -3
  67. data/lib/timber/log_devices/http.rb +107 -99
  68. data/lib/timber/log_devices/http/dropping_sized_queue.rb +26 -0
  69. data/lib/timber/log_devices/http/flushable_sized_queue.rb +42 -0
  70. data/lib/timber/log_entry.rb +14 -2
  71. data/lib/timber/logger.rb +51 -36
  72. data/lib/timber/overrides.rb +2 -0
  73. data/lib/timber/overrides/active_support_3_tagged_logging.rb +103 -0
  74. data/lib/timber/overrides/active_support_tagged_logging.rb +53 -90
  75. data/lib/timber/timer.rb +21 -0
  76. data/lib/timber/util/hash.rb +1 -1
  77. data/lib/timber/util/http_event.rb +16 -3
  78. data/lib/timber/version.rb +1 -1
  79. data/spec/support/timber.rb +2 -3
  80. data/spec/timber/cli/installers/rails_spec.rb +160 -0
  81. data/spec/timber/cli/installers/root_spec.rb +100 -0
  82. data/spec/timber/config_spec.rb +28 -0
  83. data/spec/timber/current_context_spec.rb +61 -12
  84. data/spec/timber/events/custom_spec.rb +13 -2
  85. data/spec/timber/events/exception_spec.rb +15 -0
  86. data/spec/timber/events/http_server_request_spec.rb +3 -3
  87. data/spec/timber/integrations/rack/http_events_spec.rb +101 -0
  88. data/spec/timber/log_devices/http_spec.rb +20 -4
  89. data/spec/timber/log_entry_spec.rb +2 -1
  90. data/spec/timber/logger_spec.rb +8 -8
  91. metadata +40 -9
  92. data/benchmarks/rails.rb +0 -122
  93. data/lib/timber/cli/application.rb +0 -28
  94. data/lib/timber/cli/install.rb +0 -196
  95. data/lib/timber/cli/io_helper.rb +0 -65
  96. data/lib/timber/cli/messages.rb +0 -180
  97. data/lib/timber/integrations/active_support/tagged_logging.rb +0 -71
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c631daf0393857de501da9e12c1087f4f6cceda
4
- data.tar.gz: 55b336aec1471657a0358d80e7bfabdd1c6a7a1b
3
+ metadata.gz: 3db79522e2f956e63a0d0954deecd94ed23ed105
4
+ data.tar.gz: 745fcb202414db0fd5db648b906499aadf832665
5
5
  SHA512:
6
- metadata.gz: 706a67aec83bf76c5a2089c3d7ca14b15226a05fd3113a4896cc0faec27ba7976c439783e7a3f50367ec38e7cbacf9c7611a8e493a4faadfcdc3356610df5634
7
- data.tar.gz: c4e70b7199e075ce052593fe0a4d9c12cb83e2ecd0599fbb3188f939d6b234517e07f50d32f7c0daaf0f5a92a635b355830560044d7407de45e57fdf9511bd56
6
+ metadata.gz: fcf7dcefee624791ceac83ed31d016b3429dcc261e51eddb3305f66038f1eb065c73388b6daedee06d0a89fd1ebea068941535b0f76e65967af1a40f9e1c60df
7
+ data.tar.gz: 4a2549874d1b67f31333665a37043bda838375c6043041221ae744b5e94d0e3669341ce78b3992b47f3b43b588aaced3e4315434bfd8369d710a6627d9433029
data/.travis.yml CHANGED
@@ -5,7 +5,7 @@ rvm:
5
5
  - 1.9.3
6
6
  - 2.2.6
7
7
  - 2.3.3
8
- - 2.4.0
8
+ - 2.4.1
9
9
  - jruby
10
10
  gemfile:
11
11
  - gemfiles/rails-3.0.gemfile
@@ -36,7 +36,7 @@ matrix:
36
36
  - rvm: "1.9.3"
37
37
  gemfile: "gemfiles/rails-3.2.gemfile"
38
38
  allow_failures:
39
- - rvm: 2.4.0
39
+ - rvm: 2.4.1
40
40
  - rvm: jruby
41
41
  gemfile: gemfiles/rails-5.0.gemfile
42
42
  - rvm: jruby
data/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ Please see https://github.com/timberio/timber-ruby/releases for library specific changes.
2
+
3
+ For all Timber changes see https://timber.io/changelog.
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
- # 🌲 Timber - Log Better. Solve Problems Faster.
1
+ # 🌲 Timber - Automatic Ruby Structured Logging
2
2
 
3
3
  [![ISC License](https://img.shields.io/badge/license-ISC-ff69b4.svg)](LICENSE.md)
4
- [![CircleCI](https://circleci.com/gh/timberio/timber-ruby.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/timberio/timber-ruby/tree/master)
4
+ [![Build Status](https://travis-ci.org/timberio/timber-ruby.svg?branch=master)](https://travis-ci.org/timberio/timber-ruby)
5
+ [![Build Status](https://travis-ci.org/timberio/timber-ruby.svg?branch=master)](https://travis-ci.org/timberio/timber-ruby)
5
6
  [![Code Climate](https://codeclimate.com/github/timberio/timber-ruby/badges/gpa.svg)](https://codeclimate.com/github/timberio/timber-ruby)
6
7
  [![View docs](https://img.shields.io/badge/docs-viewdocs-blue.svg?style=flat-square "Viewdocs")](http://www.rubydoc.info/github/timberio/timber-ruby)
7
8
 
@@ -13,62 +14,129 @@
13
14
 
14
15
  ## Overview
15
16
 
16
- Timber for Ruby is an optional upgrade you can install for Ruby apps on the
17
- [Timber.io logging platform](https://timber.io). Instead of completely replacing your log messages,
18
- Timber efficiently augments your logs with critical metadata. Turning them into
19
- [rich events with context](https://timber.io/docs/ruby/events-and-context). This preserves the
20
- readability of your logs while still adding the critical context needed to properly analyze your
21
- logs.
17
+ Timber solves ruby structured logging so you don't have to. Go from raw text logs to rich
18
+ structured events in seconds. Spend more time focusing on your app and less time
19
+ focusing on logging.
20
+
21
+ 1. **Easy setup.** - `bundle exec timber install`, [get setup in seconds](#installation).
22
+
23
+ 2. **Automatically structures yours logs.** - Third-party and in-app logs are all structured
24
+ in a consistent format. See [how it works](#how-it-works) below.
25
+
26
+ 3. **Seamlessly integrates with popular libraries and frameworks.** - Rails, Rack, Devise,
27
+ Omniauth, etc. [Automatically captures user context, HTTP context, and event data.](#third-party-support)
28
+
29
+ 4. **Pairs with a modern console.** - Designed specifically for this librariy, instantly
30
+ usable, zero configuration.
31
+
32
+
33
+ ## Installation
34
+
35
+ 1. In `Gemfile`, add the `timber` gem:
36
+
37
+ ```ruby
38
+ gem 'timber', '~> 2.0'
39
+ ```
40
+
41
+ 2. In your `shell`, run `bundle install`
42
+
43
+ 3. In your `shell`, run `bundle exec timber install`
22
44
 
23
45
 
24
46
  ## How it works
25
47
 
26
- For example, Timber turns this familiar raw text log:
48
+ Let's start with an example. Timber turns this familiar raw text log line:
27
49
 
28
50
  ```
29
- Sent 200 in 45.ms
51
+ Sent 200 in 45.2ms
30
52
  ```
31
53
 
32
54
  Into a rich [`http_server_response` event](https://timber.io/docs/ruby/events-and-context/http-server-response-event/).
33
55
 
34
56
  ```
35
- Sent 200 in 45.2ms @metadata {"dt": "2017-02-02T01:33:21.154345Z", "level": "info", "context": {"user": {"id": 1, "name": "Ben Johnson"}, "http": {"method": "GET", "host": "timber.io", "path": "/path", "request_id": "abcd1234"}}, "event": {"http_server_response": {"status": 200, "time_ms": 45.2}}}
57
+ Sent 200 in 45.2ms @metadata {"dt": "2017-02-02T01:33:21.154345Z", "level": "info", "context": {"user": {"id": 1, "name": "Ben Johnson"}, "http": {"method": "GET", "host": "timber.io", "path": "/path", "request_id": "abcd1234"}, "system": {"hostname": "1.server.com", "pid": "254354"}}, "event": {"http_server_response": {"status": 200, "time_ms": 45.2}}}
36
58
  ```
37
59
 
38
- In the [Timber console](https://app.timber.io) simply
39
- [click the line to view this metdata](https://timber.io/docs/app/tutorials/view-metadata/).
40
- Moreover, this data allows you to run powerful queries like:
60
+ Notice that instead of completely replacing your log messages,
61
+ Timber _augments_ your logs with structured metadata. Turning them into
62
+ [rich events with context](https://timber.io/docs/ruby/events-and-context) without sacrificing
63
+ readability.
41
64
 
42
- 1. `context.request_id:abcd1234` - View all logs generated for a specific request.
43
- 2. `context.user.id:1` - View logs generated by a specific user.
44
- 3. `type:http_server_response` - View specific events (exceptions, sql queries, etc)
45
- 4. `http_server_response.time_ms:>=1000` - View slow responses with the ability to zoom out and view them in context (request, user, etc).
46
- 5. `level:info` - Levels in your logs!
65
+ This is all accomplished by using the
66
+ [Timber::Logger](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Logger):
47
67
 
48
- For a complete overview, see the [Timber for Ruby docs](https://timber.io/docs/ruby/overview/).
68
+ ```ruby
69
+ logger = Timber::Logger.new(STDOUT)
70
+ logger.info("Sent 200 in 45.2ms")
71
+ ```
49
72
 
73
+ Here's a better look at the metadata:
74
+
75
+ ```json
76
+ {
77
+ "dt": "2017-02-02T01:33:21.154345Z",
78
+ "level": "info",
79
+ "context": {
80
+ "user": {
81
+ "id": 1,
82
+ "name": "Ben Johnson"
83
+ },
84
+ "http": {
85
+ "method": "GET",
86
+ "host": "timber.io",
87
+ "path": "/path",
88
+ "request_id": "abcd1234"
89
+ },
90
+ "system": {
91
+ "hostname": "1.server.com",
92
+ "pid": "254354"
93
+ }
94
+ },
95
+ "event": {
96
+ "http_server_response": {
97
+ "status": 200,
98
+ "time_ms": 45.2
99
+ }
100
+ }
101
+ }
102
+ ```
50
103
 
51
- ## Installation
104
+ This structure isn't arbitrary either, it follows the
105
+ [simple log event JSON schema](https://github.com/timberio/log-event-json-schema), which
106
+ formalizes the data structure, creates a contract with downstream consumers, and
107
+ improves stability.
52
108
 
53
- 1. In `Gemfile`, add the `timber` gem:
109
+ So what can you do with this data?
54
110
 
55
- ```ruby
56
- gem 'timber', '~> 2.0'
57
- ```
111
+ 1. [**Tail a user** - `user.id:1`](https://timber.io/docs/app/tutorials/tail-a-user/)
112
+ 2. [**Trace a request** - `http.request_id:abcd1234`](https://timber.io/docs/app/tutorials/view-in-request-context/)
113
+ 3. **Narrow by host** - `system.hostname:1.server.com`
114
+ 4. **View slow responses** - `http_server_response.time_ms:>=1000`
115
+ 5. **Filter by log level** - `level:error`
116
+ 6. **Quickly find exceptions** - `is:exception`
58
117
 
59
- 2. In your `shell`, run `bundle install`
118
+ For a complete overview, see the [Timber for Ruby docs](https://timber.io/docs/ruby/overview/).
60
119
 
61
- 3. In your `shell`, run `bundle exec timber install`
120
+
121
+ ## Third-party support
122
+
123
+ 1. **Rails**: Structures ([HTTP requests](https://timber.io/docs/ruby/events-and-context/http-server-request-event/), [HTTP respones](https://timber.io/docs/ruby/events-and-context/http-server-response-event/), [controller calls](https://timber.io/docs/ruby/events-and-context/controller-call-event/), [template renders](https://timber.io/docs/ruby/events-and-context/template-render-event/), and [sql queries](https://timber.io/docs/ruby/events-and-context/sql-query-event/)).
124
+ 2. **Rack**: Structures [exceptions](https://timber.io/docs/ruby/events-and-context/exception-event/), captures [HTTP context](https://timber.io/docs/ruby/events-and-context/http-context/), captures [user context](https://timber.io/docs/ruby/events-and-context/user-context/), captures [session context](https://timber.io/docs/ruby/events-and-context/session-context/).
125
+ 3. **Devise, Omniauth, Clearance**: captures [user context](https://timber.io/docs/ruby/events-and-context/user-context/)
126
+ 5. **Heroku**: Captures [release context](https://timber.io/docs/ruby/events-and-context/release-context/) via [Heroku dyno metadata](https://devcenter.heroku.com/articles/dyno-metadata).
127
+
128
+ ...and more. Timber will continue to evolve and support more libraries.
62
129
 
63
130
 
64
131
  ## Usage
65
132
 
66
133
  <details><summary><strong>Basic logging</strong></summary><p>
67
134
 
68
- Use `Logger` as normal:
135
+ Use the `Timber::Logger` just like you would `::Logger`:
69
136
 
70
137
  ```ruby
71
- logger.info("My log message")
138
+ logger = Timber::Logger.new(STDOUT)
139
+ logger.info("My log message") # use warn, error, debug, etc.
72
140
 
73
141
  # => My log message @metadata {"level": "info", "context": {...}}
74
142
  ```
@@ -83,6 +151,7 @@ Custom events allow you to extend beyond events already defined in
83
151
  the [`Timber::Events`](lib/timber/events) namespace.
84
152
 
85
153
  ```ruby
154
+ logger = Timber::Logger.new(STDOUT)
86
155
  logger.warn "Payment rejected", payment_rejected: {customer_id: "abcd1234", amount: 100, reason: "Card expired"}
87
156
 
88
157
  # => Payment rejected @metadata {"level": "warn", "event": {"payment_rejected": {"customer_id": "abcd1234", "amount": 100, "reason": "Card expired"}}, "context": {...}}
@@ -99,10 +168,12 @@ logger.warn "Payment rejected", payment_rejected: {customer_id: "abcd1234", amou
99
168
  <details><summary><strong>Custom contexts</strong></summary><p>
100
169
 
101
170
  Context is additional data shared across log lines. Think of it like log join data.
171
+ This is how a query like `context.user.id:1` can show you all logs generated by that user.
102
172
  Custom contexts allow you to extend beyond contexts already defined in
103
173
  the [`Timber::Contexts`](lib/timber/contexts) namespace.
104
174
 
105
175
  ```ruby
176
+ logger = Timber::Logger.new(STDOUT)
106
177
  logger.with_context(build: {version: "1.0.0"}) do
107
178
  logger.info("My log message")
108
179
  end
@@ -114,26 +185,229 @@ end
114
185
  * In the [Timber console](https://app.timber.io) use queries like: `build.version:1.0.0`
115
186
  * See more details on our [custom contexts docs page](https://timber.io/docs/ruby/custom-contexts/)
116
187
 
188
+ ---
189
+
190
+ </p></details>
191
+
192
+ <details><summary><strong>Metrics & Timings</strong></summary><p>
193
+
194
+ Aggregates destroy details, and with Timber capturing metrics and timings is just logging events.
195
+ Timber is built on modern big-data principles, it can calculate aggregates across terrabytes of
196
+ data in seconds. Don't reduce the quality of your data because the system processing
197
+ your data is limited.
198
+
199
+ Here's a timing example. Notice how Timber automatically calculates the time and adds the timing
200
+ to the message.
201
+
202
+ ```ruby
203
+ logger = Timber::Logger.new(STDOUT)
204
+ timer = Timber::Timer.start
205
+ # ... code to time ...
206
+ logger.info("Processed background job", background_job: {time_ms: timer})
207
+
208
+ # => Processed background job in 54.2ms @metadata {"level": "info", "event": {"background_job": {"time_ms": 54.2}}}
209
+ ```
210
+
211
+ Or capture any metric you want:
212
+
213
+ ```ruby
214
+ logger = Timber::Logger.new(STDOUT)
215
+ logger.info("Credit card charged", credit_card_charge: {amount: 123.23})
216
+
217
+ # => Credit card charged @metadata {"level": "info", "event": {"credit_card_charge": {"amount": 123.23}}}
218
+ ```
219
+
220
+ In Timber you can easily sum, average, min, and max the `amount` attribute across any interval
221
+ you desire.
222
+
223
+ </p></details>
224
+
225
+
226
+ ## Configuration
227
+
228
+ Below are a few popular configuration options, for a comprehensive list, see
229
+ [Timber::Config](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Config).
230
+
231
+ <details><summary><strong>Logrageify. Silence noisy logs (sql query, template renders)</strong></summary><p>
232
+
233
+ Timber allows you to silence noisy logs that aren't of value to you, just like
234
+ [lograge](https://github.com/roidrage/lograge). In fact, we've provided a convenience method
235
+ for anyone transitioning from lograge:
236
+
237
+ ```ruby
238
+ # config/initializers/timber.rb
239
+
240
+ config = Timber::Config.instance
241
+ config.logrageify!()
242
+ ```
243
+
244
+ It turns this:
245
+
246
+ ```
247
+ Started GET "/" for 127.0.0.1 at 2012-03-10 14:28:14 +0100
248
+ Processing by HomeController#index as HTML
249
+ Rendered text template within layouts/application (0.0ms)
250
+ Rendered layouts/_assets.html.erb (2.0ms)
251
+ Rendered layouts/_top.html.erb (2.6ms)
252
+ Rendered layouts/_about.html.erb (0.3ms)
253
+ Rendered layouts/_google_analytics.html.erb (0.4ms)
254
+ Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)
255
+ ```
256
+
257
+ Into this:
258
+
259
+ ```
260
+ Get "/" sent 200 OK in 79ms @metadata {...}
261
+ ```
262
+
263
+ Internally this is equivalent to:
264
+
265
+ ```ruby
266
+ # config/initializers/timber.rb
267
+
268
+ config = Timber::Config.instance
269
+ config.integrations.action_controller.silence = true
270
+ config.integrations.action_view.silence = true
271
+ config.integrations.active_record.silence = true
272
+ config.integrations.rack.http_events.collapse_into_single_event = true
273
+ ```
274
+
275
+ Feel free to deviate and customize which logs you silence. We recommend a slight deviation
276
+ from lograge with the following settings:
277
+
278
+ ```ruby
279
+ # config/initializers/timber.rb
280
+
281
+ config = Timber::Config.instance
282
+ config.integrations.action_view.silence = true
283
+ config.integrations.active_record.silence = true
284
+ config.integrations.rack.http_events.collapse_into_single_event = true
285
+ ```
286
+
287
+ This does _not_ silence the controller call log event. This is because Timber captures the
288
+ parameters passed to the controller, which is very valuable when debugging.
289
+
290
+ For a full list of integrations and settings, see
291
+ [Timber::Integrations](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Integrations)
292
+
293
+ ---
294
+
117
295
  </p></details>
118
296
 
119
- <details><summary><strong>Metrics</strong></summary><p>
297
+ <details><summary><strong>Silence specific requests (LB health checks, etc)</strong></summary><p>
298
+
299
+ The following will silence all `[GET] /_health` requests:
300
+
301
+ ```ruby
302
+ # config/initializers/timber.rb
303
+
304
+ config = Timber::Config.instance
305
+ config.integrations.rack.http_events.silence_request = lambda do |rack_env, rack_request|
306
+ rack_request.path == "/_health"
307
+ end
308
+ ```
309
+
310
+ We require a block because it gives you complete control over how you want to silence requests.
311
+ The first parameter being the traditional Rack env hash, the second being a
312
+ [Rack Request](http://www.rubydoc.info/gems/rack/Rack/Request) object.
120
313
 
121
- Logging metrics is accomplished by logging custom events. Please see our
122
- [metrics docs page](https://timber.io/docs/ruby/metrics/) for a more detailed explanation
123
- with examples.
314
+ ---
315
+
316
+ </p></details>
317
+
318
+ <details><summary><strong>Change log formats</strong></summary><p>
319
+
320
+ Simply set the formatter like you would with any other logger:
321
+
322
+ ```ruby
323
+ # This is set in your various environment files
324
+ logger = Timber::Logger.new(STDOUT)
325
+ logger.formatter = Timber::Logger::JSONFormatter.new
326
+ ```
327
+
328
+ Your options are:
329
+
330
+ 1. [`Timber::Logger::AugmentedFormatter`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Logger/AugmentedFormatter) -
331
+ (default) A human readable format that _appends_ metadata to the original log line.
332
+ Ex: `My log message @metadata {"level":"info","dt":"2017-01-01T01:02:23.234321Z"}`
333
+
334
+ 2. [`Timber::Logger::JSONFormatter`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Logger/JSONFormatter) -
335
+ Ex: `{"level":"info","message":"My log message","dt":"2017-01-01T01:02:23.234321Z"}`
336
+
337
+ 3. [`Timber::Logger::MessageOnlyFormatter`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Logger/MessageOnlyFormatter) -
338
+ For use in development / test. Prints logs as strings with no metadata attached.
339
+ Ex: `My log message`
340
+
341
+ ---
342
+
343
+ </p></details>
344
+
345
+ <details><summary><strong>Capture custom user context</strong></summary><p>
346
+
347
+ By default Timber automatically captures user context for most of the popular authentication
348
+ libraries (Devise, Omniauth, and Clearance). See
349
+ [Timber::Integrations::Rack::UserContext](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Integrations/Rack/UserContext)
350
+ for a complete list.
351
+
352
+ In cases where you Timber doesn't support your strategy, or you want to customize it further,
353
+ you can do so like:
354
+
355
+ ```ruby
356
+ # config/initializers/timber.rb
357
+
358
+ config = Timber::Config.instance
359
+ config.integrations.rack.user_context.custom_user_hash = lambda do |rack_env|
360
+ user = rack_env['warden'].user
361
+ if user
362
+ {
363
+ id: user.id, # unique identifier for the user, can be an integer or string,
364
+ name: user.name, # identifiable name for the user,
365
+ email: user.email, # user's email address
366
+ }
367
+ else
368
+ nil
369
+ end
370
+ end
371
+ ```
372
+
373
+ *All* of the user hash keys are optional, but you must provide at least one.
374
+
375
+ ---
376
+
377
+ </p></details>
378
+
379
+ <details><summary><strong>Capture release / deploy context</strong></summary><p>
380
+
381
+ [Timber::Contexts::Release](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Contexts/Release)
382
+ tracks the current application release and version. If you are on Heroku, simply enable the
383
+ [dyno metadata](https://devcenter.heroku.com/articles/dyno-metadata) feature to get this
384
+ automatically. If you are not, simply add the follow environment variables to have the context
385
+ set automatically.
386
+
387
+ 1. `RELEASE_COMMIT` - `2c3a0b24069af49b3de35b8e8c26765c1dba9ff0`
388
+ 2. `RELEASE_CREATED_AT` - `2015-04-02T18:00:42Z`
389
+ 3. `RELEASE_VERSION` - `v2.3.1`
390
+
391
+ ---
124
392
 
125
393
  </p></details>
126
394
 
127
395
 
128
396
  ## Jibber-Jabber
129
397
 
130
- <details><summary><strong>Which log events does Timber structure for me?</strong></summary><p>
398
+ <details><summary><strong>Which events and context does Timber capture for me?</strong></summary><p>
131
399
 
132
- Out of the box you get everything in the [`Timber::Events`](lib/timber/events) namespace.
400
+ Out of the box you get everything in the
401
+ [`Timber::Events`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Events) namespace.
133
402
 
134
- We also add context to every log, everything in the [`Timber::Contexts`](lib/timber/contexts)
403
+ We also add context to every log, everything in the
404
+ [`Timber::Contexts`](http://www.rubydoc.info/github/timberio/timber-ruby/Timber/Contexts)
135
405
  namespace. Context is structured data representing the current environment when the log line
136
- was written. It is included in every log line. Think of it like join data for your logs.
406
+ was written. It is included in every log line. Think of it like join data for your logs. It's
407
+ how Timber is able to accomplished tailing users (`context.user.id:1`).
408
+
409
+ Lastly, you can checkout the specific integrations in
410
+ [`Timber::Integrations`](lib/timber/integrations).
137
411
 
138
412
  ---
139
413
 
@@ -141,32 +415,13 @@ was written. It is included in every log line. Think of it like join data for yo
141
415
 
142
416
  <details><summary><strong>What about my current log statements?</strong></summary><p>
143
417
 
144
- They'll continue to work as expected. Timber adheres to the default `Logger` interface.
145
- Your previous logger calls will work as they always do.
418
+ They'll continue to work as expected. Timber adheres to the default `::Logger` interface.
419
+ Your previous logger calls will work as they always do. Just swap in `Timber::Logger` and
420
+ you're good to go.
146
421
 
147
422
  In fact, traditional log statements for non-meaningful events, debug statements, etc, are
148
423
  encouraged. In cases where the data is meaningful, consider [logging a custom event](#usage).
149
424
 
150
- </p></details>
151
-
152
- <details><summary><strong>How is Timber different?</strong></summary><p>
153
-
154
- 1. **It's just _better_ logging**. Nothing beats well structured raw data. And that's exactly
155
- what Timber aims to provide. There are no agents, special APIs, or proprietary data
156
- sets that you can't access.
157
- 2. **Improved log data quality.** Instead of relying on parsing alone, Timber ships libraries that
158
- structure and augment your logs from _within_ your application. Improving your log data at the
159
- source.
160
- 3. **Human readability.** Timber _augments_ your logs without sacrificing human readability. For
161
- example: `log message @metadata {...}`. And when you view your logs in the
162
- [Timber console](https://app.timber.io), you'll see the human friendly messages
163
- with the ability to view the associated metadata.
164
- 4. **Long retention**. Logging is notoriously expensive with low retention. Timber
165
- offers _6 months_ of retention by default with sane prices.
166
- 5. **Normalized schema.** Have multiple apps? All of Timber's libraries adhere to our
167
- [JSON schema](https://github.com/timberio/log-event-json-schema). This means queries, alerts,
168
- and graphs for your ruby app can also be applied to your elixir app (for example).
169
-
170
425
  ---
171
426
 
172
427
  </p></details>