timber 2.0.24 → 2.1.0.rc1

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.
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>