timber 1.1.14 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>