timber 1.1.14 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -2
  3. data/.travis.yml +47 -0
  4. data/Gemfile +1 -28
  5. data/README.md +83 -298
  6. data/bin/timber +13 -0
  7. data/gemfiles/rails-3.0.gemfile +5 -0
  8. data/gemfiles/rails-3.1.gemfile +5 -0
  9. data/gemfiles/rails-3.2.gemfile +5 -0
  10. data/gemfiles/rails-4.0.gemfile +9 -0
  11. data/gemfiles/rails-4.1.gemfile +9 -0
  12. data/gemfiles/rails-4.2.gemfile +9 -0
  13. data/gemfiles/rails-5.0.gemfile +9 -0
  14. data/gemfiles/rails-edge.gemfile +7 -0
  15. data/lib/timber.rb +7 -7
  16. data/lib/timber/cli.rb +72 -0
  17. data/lib/timber/cli/api.rb +104 -0
  18. data/lib/timber/cli/application.rb +28 -0
  19. data/lib/timber/cli/install.rb +186 -0
  20. data/lib/timber/cli/io_helper.rb +58 -0
  21. data/lib/timber/cli/messages.rb +170 -0
  22. data/lib/timber/config.rb +47 -6
  23. data/lib/timber/contexts/http.rb +2 -2
  24. data/lib/timber/current_context.rb +1 -1
  25. data/lib/timber/event.rb +8 -0
  26. data/lib/timber/events.rb +2 -0
  27. data/lib/timber/events/controller_call.rb +12 -3
  28. data/lib/timber/events/exception.rb +4 -3
  29. data/lib/timber/events/http_client_request.rb +61 -0
  30. data/lib/timber/events/http_client_response.rb +47 -0
  31. data/lib/timber/events/http_server_request.rb +15 -23
  32. data/lib/timber/events/http_server_response.rb +9 -9
  33. data/lib/timber/events/sql_query.rb +2 -2
  34. data/lib/timber/events/template_render.rb +2 -2
  35. data/lib/timber/frameworks/rails.rb +31 -6
  36. data/lib/timber/integrations.rb +22 -0
  37. data/lib/timber/integrations/action_controller/log_subscriber.rb +25 -0
  38. data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +40 -0
  39. data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +51 -0
  40. data/lib/timber/integrations/action_view/log_subscriber.rb +25 -0
  41. data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +73 -0
  42. data/lib/timber/integrations/active_record/log_subscriber.rb +25 -0
  43. data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +39 -0
  44. data/lib/timber/integrations/active_support/tagged_logging.rb +71 -0
  45. data/lib/timber/integrations/rack.rb +16 -0
  46. data/lib/timber/integrations/rack/exception_event.rb +28 -0
  47. data/lib/timber/integrations/rack/http_context.rb +25 -0
  48. data/lib/timber/integrations/rack/http_events.rb +46 -0
  49. data/lib/timber/integrations/rack/user_context.rb +59 -0
  50. data/lib/timber/integrations/rails/rack_logger.rb +49 -0
  51. data/lib/timber/integrator.rb +24 -0
  52. data/lib/timber/log_devices/http.rb +14 -21
  53. data/lib/timber/log_entry.rb +1 -1
  54. data/lib/timber/logger.rb +38 -12
  55. data/lib/timber/overrides.rb +9 -0
  56. data/lib/timber/overrides/lograge.rb +14 -0
  57. data/lib/timber/overrides/rails_server.rb +10 -0
  58. data/lib/timber/util.rb +2 -0
  59. data/lib/timber/util/active_support_log_subscriber.rb +13 -9
  60. data/lib/timber/util/http_event.rb +54 -0
  61. data/lib/timber/util/request.rb +44 -0
  62. data/lib/timber/version.rb +1 -1
  63. data/spec/README.md +5 -9
  64. data/spec/spec_helper.rb +1 -4
  65. data/spec/support/action_controller.rb +7 -3
  66. data/spec/support/active_record.rb +23 -19
  67. data/spec/support/rails.rb +56 -32
  68. data/spec/support/timber.rb +2 -3
  69. data/spec/support/webmock.rb +1 -0
  70. data/spec/timber/integrations/action_controller/log_subscriber_spec.rb +55 -0
  71. data/spec/timber/integrations/action_dispatch/debug_exceptions_spec.rb +53 -0
  72. data/spec/timber/integrations/action_view/log_subscriber_spec.rb +115 -0
  73. data/spec/timber/integrations/active_record/log_subscriber_spec.rb +46 -0
  74. data/spec/timber/integrations/rack/http_context_spec.rb +60 -0
  75. data/spec/timber/integrations/rails/rack_logger_spec.rb +58 -0
  76. data/spec/timber/logger_spec.rb +45 -9
  77. data/timber.gemspec +29 -3
  78. metadata +143 -46
  79. data/Appraisals +0 -41
  80. data/circle.yml +0 -33
  81. data/lib/timber/overrides/logger_add.rb +0 -38
  82. data/lib/timber/probe.rb +0 -23
  83. data/lib/timber/probes.rb +0 -23
  84. data/lib/timber/probes/action_controller_log_subscriber.rb +0 -20
  85. data/lib/timber/probes/action_controller_log_subscriber/log_subscriber.rb +0 -64
  86. data/lib/timber/probes/action_controller_user_context.rb +0 -52
  87. data/lib/timber/probes/action_dispatch_debug_exceptions.rb +0 -80
  88. data/lib/timber/probes/action_view_log_subscriber.rb +0 -20
  89. data/lib/timber/probes/action_view_log_subscriber/log_subscriber.rb +0 -69
  90. data/lib/timber/probes/active_record_log_subscriber.rb +0 -20
  91. data/lib/timber/probes/active_record_log_subscriber/log_subscriber.rb +0 -31
  92. data/lib/timber/probes/active_support_tagged_logging.rb +0 -63
  93. data/lib/timber/probes/rails_rack_logger.rb +0 -77
  94. data/lib/timber/rack_middlewares.rb +0 -12
  95. data/lib/timber/rack_middlewares/http_context.rb +0 -30
  96. data/spec/support/action_view.rb +0 -4
  97. data/spec/support/coveralls.rb +0 -2
  98. data/spec/support/simplecov.rb +0 -9
  99. data/spec/timber/overrides/logger_add_spec.rb +0 -26
  100. data/spec/timber/probes/action_controller_log_subscriber_spec.rb +0 -65
  101. data/spec/timber/probes/action_controller_user_context_spec.rb +0 -53
  102. data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +0 -48
  103. data/spec/timber/probes/action_view_log_subscriber_spec.rb +0 -107
  104. data/spec/timber/probes/active_record_log_subscriber_spec.rb +0 -47
  105. data/spec/timber/probes/rails_rack_logger_spec.rb +0 -46
  106. data/spec/timber/rack_middlewares/http_context_spec.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 423710eb07f5ddad12eebd5cdb105a4557aba07e
4
- data.tar.gz: 5c4c3c0303a09157b032b3d8fccc1fd86fe72814
3
+ metadata.gz: eab99caab83ef2be6496c0ad1db6d736cf54817f
4
+ data.tar.gz: dfdd212606d1ff42d908401e073ecf94a2cc2f72
5
5
  SHA512:
6
- metadata.gz: 88662c0e6a31886e9a20f4782db1b2bca3b44ae0d8ad501fb4457f1ec8a7aaaf67fd756c25486dfd722a93726153119abba56ca99edbdec5bb9b50db45a574ac
7
- data.tar.gz: 676c3525de6505c9e9e514508c10113d27950dc0d597a4a29b78bafe2bc2d546c5456077aa558a62cf3727c0bc31c95f9fa15a9f707a74a86a37096bc850bbce
6
+ metadata.gz: b7e9143deab1f3d58076b7c55600f8ee72d7a11f3d659c1494f6bef053d03e444555564e1a7a7977fc1ed8bfab8b2c5d53bd1d238d2934b5d23537e6f23da2e5
7
+ data.tar.gz: bb07cec849ea6a95a6480711b123612b1db91d6f4a59c23aac8c01b5f0b6ee921fc52ff43147a8123d9ad341b934055676e594cbc5ab4d1082268f423cd7d4f4
data/.gitignore CHANGED
@@ -6,10 +6,12 @@ Gemfile.lock
6
6
  *.swp
7
7
  *.gem
8
8
 
9
+ Gemfile.lock
10
+ gemfiles/*.lock
11
+
9
12
  /.bundle
10
13
  /.yardoc
11
14
  /doc
12
- /gemfiles
13
15
  /log
14
16
  /tmp
15
- /pkg
17
+ /pkg
@@ -0,0 +1,47 @@
1
+ sudo: false
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.2.6
7
+ - 2.3.3
8
+ - 2.4.0
9
+ - jruby
10
+ gemfile:
11
+ - gemfiles/rails-3.0.gemfile
12
+ - gemfiles/rails-3.1.gemfile
13
+ - gemfiles/rails-3.2.gemfile
14
+ - gemfiles/rails-4.0.gemfile
15
+ - gemfiles/rails-4.1.gemfile
16
+ - gemfiles/rails-4.2.gemfile
17
+ - gemfiles/rails-4.2.gemfile
18
+ - gemfiles/rails-5.0.gemfile
19
+ - gemfiles/rails-edge.gemfile
20
+ env:
21
+ global: RAILS_ENV=test
22
+ before_script:
23
+ - echo $BUNDLE_GEMFILE
24
+ - bundle install
25
+ script: bundle exec rspec
26
+ matrix:
27
+ fast_finish: true
28
+ exclude:
29
+ - rvm: "1.9.3"
30
+ include:
31
+ - rvm: "1.9.3"
32
+ gemfile: "gemfiles/rails-3.0.gemfile"
33
+ - rvm: "1.9.3"
34
+ gemfile: "gemfiles/rails-3.1.gemfile"
35
+ - rvm: "1.9.3"
36
+ gemfile: "gemfiles/rails-3.2.gemfile"
37
+ allow_failures:
38
+ - rvm: 2.4.0
39
+ - rvm: jruby
40
+ gemfile: gemfiles/rails-5.0.gemfile
41
+ - rvm: jruby
42
+ gemfile: gemfiles/rails-edge.gemfile
43
+ notifications:
44
+ email: false
45
+ slack:
46
+ rooms:
47
+ secure: F4BGVLUnaDqJ3YXfuIwx+m6047E8YstCUXs33Tfcs7SUlSuOSChuXqvCfVtnfNy2muF7xgB6VRL3xpFIRm7qNStqGUWCQJXmKq2OEgq1DYGkhAVle4d/LBtVcfBgeLelsoi+1TI9MrUtpZDHPl0li3PLoC+dq7rzSuhrxQ9EOhZlZGVn6LTeVcgNw6cLNzHSWJJ8zpYWLjBWUXgJ75MQvo5qaNbQxyfzm7GzEgRNfSzabFBwpKwB1Tog9X9TKTtPrn30O9Ur9+wmTu6EnwaDWZjaTK6I+AbxE8huIfUGvSrq1aV2JaDIra6zHEQ+d4j0oRYutgFM4YfyN9124MbPE2yH/5lXNQHMpUOsP0bl2U+KGDzq/V5APyrZ6irsvwGYpo3fSXrW8nDIAK4Mh8KB+Ta0zN5H8PmIRK76wJ+wG2zAtrfl+ailxMrdpK6J04fl3pCBuO6eW+AKEJ7Wfi5GiE7a9lk/YewAeDHyyLSnUNFIP0/iFAbTtRh5denCk0ZUS1XyfZNQuFoku7jk5lpe41SNItqOO0jv/jXPF+wensNa2UgMBIP0XkRw55LKn9eY0MKm9P+zp9ePaXs0T0Ttv4e0T4Jxrgf5QBynefgHwAsOI1nHr7GhlPaFQ6u8iNmjNYLB9v1JZMlO08LkytzZFpUuJoHbYYoBaRtUtEosBHg=
data/Gemfile CHANGED
@@ -1,30 +1,3 @@
1
1
  source 'https://rubygems.org'
2
- gemspec
3
2
 
4
- group :test do
5
- gem 'appraisal'
6
- gem 'coveralls', require: false
7
- gem 'json', '~> 1'
8
- gem 'pry'
9
- gem 'rails_stdout_logging'
10
- gem 'rake'
11
- gem 'rspec', '~> 3.4'
12
- gem 'rspec-its'
13
- gem 'simplecov', require: false
14
- gem 'sqlite3'
15
- gem 'terminal-table'
16
- gem 'timecop'
17
-
18
- ruby_version = Gem::Version.new("#{RUBY_VERSION}")
19
- if ruby_version < Gem::Version.new("2.0.0")
20
- gem 'public_suffix', '~> 1.4.6'
21
- gem 'term-ansicolor', '~> 1.3.2'
22
- gem 'webmock', '~> 2.2.0'
23
- else
24
- gem 'webmock'
25
- end
26
-
27
- # for coveralls
28
- gem 'rest-client', '~> 1.8' # >= 2.0 requires ruby 2+, we have tests for 1.9
29
- gem 'tins', '~> 1.6.0' # > 1.6 requires ruby 2+, we have tests for 1.9
30
- end
3
+ gemspec
data/README.md CHANGED
@@ -1,126 +1,55 @@
1
- # 🌲 Timber - Master your Ruby apps with structured logging
2
-
3
- <p align="center" style="background: #140f2a;">
4
- <a href="http://files.timber.io/images/readme-interface.gif"><img src="http://files.timber.io/images/readme-interface.gif" width="100%" /></a>
5
- </p>
1
+ # 🌲 Timber - Log Better. Solve Problems Faster.
6
2
 
7
3
  [![ISC License](https://img.shields.io/badge/license-ISC-ff69b4.svg)](LICENSE.md)
8
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)
9
- [![Coverage Status](https://coveralls.io/repos/github/timberio/timber-ruby/badge.svg?branch=master)](https://coveralls.io/github/timberio/timber-ruby?branch=master)
10
5
  [![Code Climate](https://codeclimate.com/github/timberio/timber-ruby/badges/gpa.svg)](https://codeclimate.com/github/timberio/timber-ruby)
11
6
  [![View docs](https://img.shields.io/badge/docs-viewdocs-blue.svg?style=flat-square "Viewdocs")](http://www.rubydoc.info/github/timberio/timber-ruby)
12
7
 
13
- Still logging raw text? Timber is a complete *structured* logging solution that you can setup in
14
- minutes. It solves logging so you don't have to!
15
-
16
- To learn more, checkout out [timber.io](https://timber.io).
17
-
18
-
19
- ## Installation
20
-
21
- 1. *Add* the `timber` gem in `Gemfile`:
22
-
23
- ```ruby
24
- # Gemfile
25
-
26
- gem 'timber'
27
- ```
8
+ * [Timber website](https://timber.io)
9
+ * [Timber docs](https://timber.io/docs)
10
+ * [Library docs](http://www.rubydoc.info/github/timberio/timber-ruby)
11
+ * [Support](mailto:support@timber.io)
28
12
 
29
- 2. *Install* the `Timber::Logger` in `config/environments/production.rb`:
30
13
 
31
- ```ruby
32
- # config/environments/production.rb
14
+ ## Overview
33
15
 
34
- # config.log_formatter = ::Logger::Formatter.new # <--------------------------- REMOVE ME
35
- # config.logger = ActiveSupport::TaggedLogging.new(logger) # <----------------- REMOVE ME
16
+ Timber turns your raw text logs into rich JSON events that can be consumed by the
17
+ [Timber.io service](https://timber.io). It improves log data quality at the source, adding
18
+ critical event and context data to your logs so that you can filter out the noise and
19
+ solve problems faster.
36
20
 
37
- config.logger = ActiveSupport::TaggedLogging.new(Timber::Logger.new(STDOUT)) # <-- ADD ME
38
- ```
21
+ For example, Timber turns this:
39
22
 
40
- ---
41
-
42
- <details><summary><strong>Prefer to see an example pull request?</strong></summary><p>
43
-
44
- Checkout our the [Timber install example pull request](https://github.com/timberio/ruby-rails-example-app/pull/1/files)
45
-
46
- ---
47
-
48
- </p></details>
49
-
50
- <details><summary><strong>Not using Rails?</strong></summary><p>
51
-
52
- No problem! You can easily install Timber following these steps:
53
-
54
- 1. *Insert* the Timber probes:
55
-
56
- This should be executed *immediately after* you have required your dependencies.
57
-
58
- ```ruby
59
- Timber::Probes.insert!
60
- ```
61
-
62
- 2. *Add* the Rack middlewares:
63
-
64
- This should be included where you build your `Rack` application. Usually `config.ru`:
65
-
66
- ```ruby
67
- # Most likely config.ru
68
-
69
- Timber::RackMiddlewares.middlewares.each do |m|
70
- use m
71
- end
72
- ```
73
-
74
- 2. *Instantiate* the Timber logger:
75
-
76
- This should be *globally* available to your application:
77
-
78
- ```ruby
79
- logger = Timber::Logger.new(STDOUT)
80
- ```
81
-
82
- ---
83
-
84
- </p></details>
85
-
86
-
87
- ## Send your logs (choose one)
88
-
89
- <details><summary><strong>Heroku (log drains)</strong></summary><p>
90
-
91
- The recommended strategy for Heroku is to setup a
92
- [log drain](https://devcenter.heroku.com/articles/log-drains). To get your Timber log drain URL:
93
-
94
- 👉 **[Add your app to Timber](https://app.timber.io)**
95
-
96
- ---
97
-
98
- </p></details>
99
-
100
- <details><summary><strong>Or, all other platforms (Network / HTTP)</strong></summary><p>
23
+ ```
24
+ Sent 200 in 45.ms
25
+ ```
101
26
 
102
- 1. *Specify* the Timber HTTP logger backend in `config/environments/production.rb`:
27
+ Into this:
103
28
 
104
- Replace any existing `config.logger =` calls with:
29
+ ```
30
+ 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}}}
31
+ ```
105
32
 
106
- ```ruby
107
- # config/environments/production.rb (or staging, etc)
33
+ Allowing you to run queries like:
108
34
 
109
- http_log_device = Timber::LogDevices::HTTP.new(ENV['TIMBER_LOGS_KEY'])
110
- config.logger = ActiveSupport::TaggedLogging.new(Timber::Logger.new(http_log_device))
111
- ```
35
+ 1. `context.request_id:abcd1234` - View all logs generated for a specific request.
36
+ 2. `context.user.id:1` - View logs generated by a specific user.
37
+ 3. `type:http_response` - View specific events (exceptions, sql queries, etc)
38
+ 4. `http_server_response.time_ms:>=1000` - View slow responses with the ability to zoom out and view them in context (request, user, etc).
39
+ 5. `level:error` - Levels in your logs!
112
40
 
113
- 2. Obtain your Timber API :key: by **[adding your app in Timber](https://app.timber.io)**.
114
41
 
115
- 3. Assign your API key to the `TIMBER_LOGS_KEY` environment variable.
42
+ ## Installation
116
43
 
117
- </p></details>
44
+ 1. In `Gemfile`, add the `timber` gem:
118
45
 
119
- <details><summary><strong>Or, advanced setup (syslog, file tailing agent, etc)</strong></summary><p>
46
+ ```ruby
47
+ gem 'timber', '~> 2.0'
48
+ ```
120
49
 
121
- Checkout our [docs](https://timber.io/docs) for a comprehensive list of install instructions.
50
+ 2. In your `shell`, run `bundle install`
122
51
 
123
- </p></details>
52
+ 3. In your `shell`, run `bundle exec timber install`
124
53
 
125
54
 
126
55
  ## Usage
@@ -132,7 +61,7 @@ Use `Logger` as normal:
132
61
  ```ruby
133
62
  logger.info("My log message")
134
63
 
135
- # My log message @metadata {"level": "info", "context": {...}}
64
+ # => My log message @metadata {"level": "info", "context": {...}}
136
65
  ```
137
66
 
138
67
  Timber will *never* deviate from the public `::Logger` interface in *any* way.
@@ -141,228 +70,63 @@ Timber will *never* deviate from the public `::Logger` interface in *any* way.
141
70
 
142
71
  </p></details>
143
72
 
144
- <details><summary><strong>Tagging logs</strong></summary><p>
145
-
146
- Tags provide a quick way to identify logs. They work just like any tagging system.
147
- In the context of logging, they prevent obstructing the log message to
148
- accomplish the same thing, while also being a step down from creating a classified custom
149
- event. If the event is meaningful in any way, we recommend creating a custom event.
150
-
151
- ```ruby
152
- logger.info(message: "My log message", tag: "tag")
153
-
154
- # My log message @metadata {"level": "info", "tags": ["tag"], "context": {...}}
155
- ```
156
-
157
- Multiple tags:
158
-
159
- ```ruby
160
- logger.info(message: "My log message", tags: ["tag1", "tag2"])
161
-
162
- # My log message @metadata {"level": "info", "tags": ["tag1", "tag2"], "context": {...}}
163
- ```
164
-
165
- Using `ActiveSupport::TaggedLogging`? It works with that as well:
166
-
167
- ```ruby
168
- logger.tagged("tag") do
169
- logger.info(message: "My log message", tags: ["important", "slow"])
170
- end
171
-
172
- # My log message @metadata {"level": "info", "tags": ["tag"], "context": {...}}
173
- ```
174
-
175
- * In the Timber console use the query: `tags:tag`.
176
-
177
- ---
178
-
179
- </p></details>
180
-
181
- <details><summary><strong>Timing events</strong></summary><p>
73
+ <details><summary><strong>Custom events</strong></summary><p>
182
74
 
183
- Timings provid a simple way to time code execution:
75
+ Custom events allow you to extend beyond events already defined in
76
+ the [`Timber::Events`](lib/timber/events) namespace.
184
77
 
185
78
  ```ruby
186
- start = Time.now
187
- # ...my code to time...
188
- time_ms = (Time.now - start) * 1000
189
- logger.info(message: "Task complete", tag: "my_task", time_ms: time_ms)
79
+ Logger.warn "Payment rejected", payment_rejected: {customer_id: "abcd1234", amount: 100, reason: "Card expired"}
190
80
 
191
- # My log message @metadata {"level": "info", tags: ["my_task"], "time_ms": 54.2132, "context": {...}}
81
+ # => Payment rejected @metadata {"level": "warn", "event": {"payment_rejected": {"customer_id": "abcd1234", "amount": 100, "reason": "Card expired"}}, "context": {...}}
192
82
  ```
193
83
 
194
- * In the Timber console use the query: `tags:my_task time_ms>500`
195
- * The Timber console will also display this value inline with your logs. No need to include it
196
- in the log message, but you certainly can if you'd prefer.
84
+ * Notice the `:payment_rejected` root key. Timber will classify this event as such.
85
+ * In the [Timber console](https://app.timber.io) use the query: `type:payment_rejected` or `payment_rejected.amount:>100`.
86
+ * See more details on our [custom events docs page](https://timber.io/docs/ruby/custom-events/)
197
87
 
198
88
  ---
199
89
 
200
90
  </p></details>
201
91
 
92
+ <details><summary><strong>Custom contexts</strong></summary><p>
202
93
 
203
- <details><summary><strong>Custom events</strong></summary><p>
204
-
205
- Custom events can be used to structure information about events that are central
206
- to your line of business like receiving credit card payments, saving a draft of a post,
207
- or changing a user's password. You have 2 options to do this:
208
-
209
- 1. Log a structured Hash (simplest)
210
-
211
- ```ruby
212
- Logger.warn message: "Payment rejected", payment_rejected: {customer_id: "abcd1234", amount: 100, reason: "Card expired"}
213
-
214
- # Payment rejected @metadata {"level": "warn", "event": {"payment_rejected": {"customer_id": "abcd1234", "amount": 100, "reason": "Card expired"}}, "context": {...}}
215
- ```
216
-
217
- * The hash can *only* have 2 keys: `:message` and "event type" key; `:payment_rejected` in this example.
218
- * Timber will keyspace your event data by the event type key passed.
219
-
220
- 2. Log a Struct (recommended)
221
-
222
- Defining structs for your important events just feels oh so good :) It creates a strong contract
223
- with down stream consumers and gives you compile time guarantees.
224
-
225
- ```ruby
226
- PaymentRejectedEvent = Struct.new(:customer_id, :amount, :reason) do
227
- def message; "Payment rejected for #{customer_id}"; end
228
- def type; :payment_rejected; end
229
- end
230
- Logger.warn PaymentRejectedEvent.new("abcd1234", 100, "Card expired")
231
-
232
- # Payment rejected @metadata {"level": "warn", "event": {"payment_rejected": {"customer_id": "abcd1234", "amount": 100, "reason": "Card expired"}}, "context": {...}}
233
- ```
234
-
235
- * In the Timber console use queries like: `payment_rejected.customer_id:xiaus1934` or `payment_rejected.amount>100`
236
- * For more advanced examples see [`Timber::Logger`](lib/timber.logger.rb).
237
- * Also, notice there is no mention of Timber in the above code. Just plain old logging.
238
-
239
- #### What about regular Hashes, JSON, or logfmt?
240
-
241
- Go for it! Timber will parse the data server side, but we *highly* recommend the above examples.
242
- Providing a `:type` allows timber to classify the event, create a namespace for the data you
243
- send, and make it easier to search, graph, alert, etc.
94
+ Context is additional data shared across log lines. Think of it like log join data.
95
+ Custom contexts allow you to extend beyond contexts already defined in
96
+ the [`Timber::Contexts`](lib/timber/contexts) namespace.
244
97
 
245
98
  ```ruby
246
- logger.info({key: "value"})
247
- # {"key": "value"} @metadata {"level": "info", "context": {...}}
248
-
249
- logger.info('{"key": "value"}')
250
- # {"key": "value"} @metadata {"level": "info", "context": {...}}
99
+ Timber::CurrentContext.with({build: {version: "1.0.0"}}) do
100
+ logger.info("My log message")
101
+ end
251
102
 
252
- logger.info('key=value')
253
- # key=value @metadata {"level": "info", "context": {...}}
103
+ # => My log message @metadata {"level": "info", "context": {"build": {"version": "1.0.0"}}}
254
104
  ```
255
105
 
256
- ---
106
+ * Notice the `:build` root key. Timber will classify this context as such.
107
+ * In the [Timber console](https://app.timber.io) use queries like: `build.version:1.0.0`
108
+ * See more details on our [custom contexts docs page](https://timber.io/docs/ruby/custom-contexts/)
257
109
 
258
110
  </p></details>
259
111
 
260
- <details><summary><strong>Custom contexts</strong></summary><p>
261
-
262
- Context is structured data representing the current environment when the log line was written.
263
- It is included in every log line. Think of it like join data for your logs. For example, the
264
- `http.request_id` field is included in the context, allowing you to find all log lines related
265
- to that request ID, if desired. This is in contrast to *only* showing log lines that contain this
266
- value.
267
-
268
- 1. Add a Hash (simplest)
269
-
270
- ```ruby
271
- Timber::CurrentContext.with({build: {version: "1.0.0"}}) do
272
- logger.info("My log message")
273
- end
274
-
275
- # My log message @metadata {"level": "info", "context": {"build": {"version": "1.0.0"}}}
276
- ```
112
+ <details><summary><strong>Metrics</strong></summary><p>
277
113
 
278
- This adds data to the context keyspaced by `build`.
279
-
280
- 2. Add a Struct (recommended)
281
-
282
- Just like events, we recommend defining your custom contexts. It makes a stronger contract
283
- with downstream consumers.
284
-
285
- ```ruby
286
- BuildContext = Struct.new(:version) do
287
- def type; :build; end
288
- end
289
- build_context = BuildContext.new("1.0.0")
290
- Timber::CurrentContext.with(build_context) do
291
- logger.info("My log message")
292
- end
293
-
294
- # My log message @metadata {"level": "info", "context": {"build": {"version": "1.0.0"}}}
295
- ```
114
+ Logging metrics is accomplished by logging custom events. Please see our
115
+ [metrics docs page](https://timber.io/docs/ruby/metrics/) for a more detailed explanation
116
+ with examples.
296
117
 
297
118
  </p></details>
298
119
 
299
120
 
300
121
  ## Jibber-Jabber
301
122
 
302
- <details><summary><strong>What specifically does the Timber library do?</strong></summary><p>
303
-
304
- 1. Captures and structures your framework and 3rd party logs. (see next question)
305
- 2. Adds useful context to every log line. (see next question)
306
- 3. Allows you to easily add tags and timings to log. (see [Usage](#usage))
307
- 4. Provides a framework for logging custom structured events. (see [Usage](#usage))
308
- 5. Offers transport strategies to [send your logs](#send-your-logs) to the Timber service.
309
-
310
- ---
311
-
312
- </p></details>
313
-
314
- <details><summary><strong>What are the benefits of using Timber?</strong></summary><p>
315
-
316
- 1. **Data quality.** The usefulness of your logs starts here. This is why we ship libraries that
317
- structure logs from *within* your application; a fundamental difference from parsing. Not only
318
- is it much more stable, but we can include data you couldn't obtain otherwise.
319
- 2. **Human readability.** Structuring your logs doesn't mean they have to be unreadable. Timber
320
- *augments* your logs with structured data. Meaning we do not alter the original log message,
321
- we simply attach metadata to it. And our console is specifically designed to give you access
322
- to this data, without compromising readability. 😮
323
- 3. **Reliable downstream consumption.** All log events adhere to a
324
- [normalized, shared, schema](https://github.com/timberio/log-event-json-schema) that follows
325
- [semantic versioning](http://semver.org/) and goes through a [standard release process](https://github.com/timberio/log-event-json-schema/releases).
326
- This means you can *rely* on the structure of your logs and interact consistently with them
327
- across apps of any language: queries, graphs, alerts, and other downstream consumers.
328
- 4. **Zero risk of code debt or lock-in.** Logging is a standard that has been around since the dawn
329
- of computers. It's built into every language, framework, and library. Timber adheres strictly
330
- to the default `Logger` interface. There are no special APIs, and no need to pepper your app
331
- with Timber specific code. It's just better logging. If you choose to stop using Timber, you
332
- can do so without consequence.
333
- 5. **Long term retention.** Timber is designed on modern big-data principles. As a result, we can
334
- offer 6+ months of retention at prices cheaper than alternatives offering <1 month.
335
- This allows you to unlock your logs for purposes beyond debugging.
336
-
337
- ---
338
-
339
- </p></details>
340
-
341
- <details><summary><strong>What events does Timber capture & structure for me?</strong></summary><p>
342
-
343
- Out of the box you get everything in the [`Timber::Events`](lib/timber/events) namespace:
123
+ <details><summary><strong>Which log events does Timber structure for me?</strong></summary><p>
344
124
 
345
- 1. [Controller Call Event](lib/timber/events/controller_call.rb)
346
- 2. [Exception Event](lib/timber/events/exception.rb)
347
- 3. [HTTP Client Request Event (net/http outgoing)](lib/timber/events/http_client_request.rb)
348
- 4. [HTTP Client Response Event (resposne from net/http outgoing)](lib/timber/events/http_client_response.rb)
349
- 5. [HTTP Server Request Event (incoming client request)](lib/timber/events/http_server_request.rb)
350
- 6. [HTTP Server Response Event (response to incoming client request)](lib/timber/events/http_server_response.rb)
351
- 7. [SQL Query Event](lib/timber/events/sql_query.rb)
352
- 8. [Template Render Event](lib/timber/events/template_render.rb)
353
- 9. ...more coming soon, [file an issue](https://github.com/timberio/timber-ruby/issues) to request.
125
+ Out of the box you get everything in the [`Timber::Events`](lib/timber/events) namespace.
354
126
 
355
127
  We also add context to every log, everything in the [`Timber::Contexts`](lib/timber/contexts)
356
- namespace. Context is structured data representing the current environment when the log line was
357
- written. It is included in every log line. Think of it like join data for your logs:
358
-
359
- 1. [HTTP Context](lib/timber/contexts/http.rb)
360
- 2. [Organization Context](lib/timber/contexts/organization.rb)
361
- 3. [Process Context](lib/timber/contexts/process.rb)
362
- 4. [Server Context](lib/timber/contexts/server.rb)
363
- 5. [Runtime Context](lib/timber/contexts/runtime.rb)
364
- 5. [User Context](lib/timber/contexts/user.rb)
365
- 6. ...more coming soon, [file an issue](https://github.com/timberio/timber-ruby/issues) to request.
128
+ namespace. Context is structured data representing the current environment when the log line
129
+ was written. It is included in every log line. Think of it like join data for your logs.
366
130
 
367
131
  ---
368
132
 
@@ -370,17 +134,38 @@ written. It is included in every log line. Think of it like join data for your l
370
134
 
371
135
  <details><summary><strong>What about my current log statements?</strong></summary><p>
372
136
 
373
- They'll continue to work as expected. Timber adheres strictly to the default `::Logger` interface
374
- and will never deviate in *any* way.
137
+ They'll continue to work as expected. Timber adheres to the default `Logger` interface.
138
+ Your previous logger calls will work as they always do.
375
139
 
376
140
  In fact, traditional log statements for non-meaningful events, debug statements, etc, are
377
141
  encouraged. In cases where the data is meaningful, consider [logging a custom event](#usage).
378
142
 
379
143
  </p></details>
380
144
 
145
+ <details><summary><strong>How is Timber different?</strong></summary><p>
146
+
147
+ 1. **It's just _better_ logging**. Nothing beats well structured raw data. And that's exactly
148
+ what Timber aims to provide. There are no agents, special APIs, or proprietary data
149
+ sets that you can't access.
150
+ 2. **Improved log data quality.** Instead of relying on parsing alone, Timber ships libraries that
151
+ structure and augment your logs from _within_ your application. Improving your log data at the
152
+ source.
153
+ 3. **Human readability.** Timber _augments_ your logs without sacrificing human readability. For
154
+ example: `log message @metadata {...}`. And when you view your logs in the
155
+ [Timber console](https://app.timber.io), you'll see the human friendly messages
156
+ with the ability to view the associated metadata.
157
+ 4. **Long retention**. Logging is notoriously expensive with low retention. Timber
158
+ offers _6 months_ of retention by default with sane prices.
159
+ 5. **Normalized schema.** Have multiple apps? All of Timber's libraries adhere to our
160
+ [JSON schema](https://github.com/timberio/log-event-json-schema). This means queries, alerts,
161
+ and graphs for your ruby app can also be applied to your elixir app (for example).
162
+
163
+ ---
164
+
165
+ </p></details>
381
166
 
382
167
  ---
383
168
 
384
169
  <p align="center" style="background: #221f40;">
385
- <a href="http://github.com/timberio/timber-ruby"><img src="http://files.timber.io/images/ruby-library-readme-log-truth.png" height="947" /></a>
170
+ <a href="http://github.com/timberio/timber-elixir"><img src="http://files.timber.io/images/ruby-library-readme-log-truth.png" height="947" /></a>
386
171
  </p>