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.
- checksums.yaml +4 -4
- data/.gitignore +4 -2
- data/.travis.yml +47 -0
- data/Gemfile +1 -28
- data/README.md +83 -298
- data/bin/timber +13 -0
- data/gemfiles/rails-3.0.gemfile +5 -0
- data/gemfiles/rails-3.1.gemfile +5 -0
- data/gemfiles/rails-3.2.gemfile +5 -0
- data/gemfiles/rails-4.0.gemfile +9 -0
- data/gemfiles/rails-4.1.gemfile +9 -0
- data/gemfiles/rails-4.2.gemfile +9 -0
- data/gemfiles/rails-5.0.gemfile +9 -0
- data/gemfiles/rails-edge.gemfile +7 -0
- data/lib/timber.rb +7 -7
- data/lib/timber/cli.rb +72 -0
- data/lib/timber/cli/api.rb +104 -0
- data/lib/timber/cli/application.rb +28 -0
- data/lib/timber/cli/install.rb +186 -0
- data/lib/timber/cli/io_helper.rb +58 -0
- data/lib/timber/cli/messages.rb +170 -0
- data/lib/timber/config.rb +47 -6
- data/lib/timber/contexts/http.rb +2 -2
- data/lib/timber/current_context.rb +1 -1
- data/lib/timber/event.rb +8 -0
- data/lib/timber/events.rb +2 -0
- data/lib/timber/events/controller_call.rb +12 -3
- data/lib/timber/events/exception.rb +4 -3
- data/lib/timber/events/http_client_request.rb +61 -0
- data/lib/timber/events/http_client_response.rb +47 -0
- data/lib/timber/events/http_server_request.rb +15 -23
- data/lib/timber/events/http_server_response.rb +9 -9
- data/lib/timber/events/sql_query.rb +2 -2
- data/lib/timber/events/template_render.rb +2 -2
- data/lib/timber/frameworks/rails.rb +31 -6
- data/lib/timber/integrations.rb +22 -0
- data/lib/timber/integrations/action_controller/log_subscriber.rb +25 -0
- data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +40 -0
- data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +51 -0
- data/lib/timber/integrations/action_view/log_subscriber.rb +25 -0
- data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +73 -0
- data/lib/timber/integrations/active_record/log_subscriber.rb +25 -0
- data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +39 -0
- data/lib/timber/integrations/active_support/tagged_logging.rb +71 -0
- data/lib/timber/integrations/rack.rb +16 -0
- data/lib/timber/integrations/rack/exception_event.rb +28 -0
- data/lib/timber/integrations/rack/http_context.rb +25 -0
- data/lib/timber/integrations/rack/http_events.rb +46 -0
- data/lib/timber/integrations/rack/user_context.rb +59 -0
- data/lib/timber/integrations/rails/rack_logger.rb +49 -0
- data/lib/timber/integrator.rb +24 -0
- data/lib/timber/log_devices/http.rb +14 -21
- data/lib/timber/log_entry.rb +1 -1
- data/lib/timber/logger.rb +38 -12
- data/lib/timber/overrides.rb +9 -0
- data/lib/timber/overrides/lograge.rb +14 -0
- data/lib/timber/overrides/rails_server.rb +10 -0
- data/lib/timber/util.rb +2 -0
- data/lib/timber/util/active_support_log_subscriber.rb +13 -9
- data/lib/timber/util/http_event.rb +54 -0
- data/lib/timber/util/request.rb +44 -0
- data/lib/timber/version.rb +1 -1
- data/spec/README.md +5 -9
- data/spec/spec_helper.rb +1 -4
- data/spec/support/action_controller.rb +7 -3
- data/spec/support/active_record.rb +23 -19
- data/spec/support/rails.rb +56 -32
- data/spec/support/timber.rb +2 -3
- data/spec/support/webmock.rb +1 -0
- data/spec/timber/integrations/action_controller/log_subscriber_spec.rb +55 -0
- data/spec/timber/integrations/action_dispatch/debug_exceptions_spec.rb +53 -0
- data/spec/timber/integrations/action_view/log_subscriber_spec.rb +115 -0
- data/spec/timber/integrations/active_record/log_subscriber_spec.rb +46 -0
- data/spec/timber/integrations/rack/http_context_spec.rb +60 -0
- data/spec/timber/integrations/rails/rack_logger_spec.rb +58 -0
- data/spec/timber/logger_spec.rb +45 -9
- data/timber.gemspec +29 -3
- metadata +143 -46
- data/Appraisals +0 -41
- data/circle.yml +0 -33
- data/lib/timber/overrides/logger_add.rb +0 -38
- data/lib/timber/probe.rb +0 -23
- data/lib/timber/probes.rb +0 -23
- data/lib/timber/probes/action_controller_log_subscriber.rb +0 -20
- data/lib/timber/probes/action_controller_log_subscriber/log_subscriber.rb +0 -64
- data/lib/timber/probes/action_controller_user_context.rb +0 -52
- data/lib/timber/probes/action_dispatch_debug_exceptions.rb +0 -80
- data/lib/timber/probes/action_view_log_subscriber.rb +0 -20
- data/lib/timber/probes/action_view_log_subscriber/log_subscriber.rb +0 -69
- data/lib/timber/probes/active_record_log_subscriber.rb +0 -20
- data/lib/timber/probes/active_record_log_subscriber/log_subscriber.rb +0 -31
- data/lib/timber/probes/active_support_tagged_logging.rb +0 -63
- data/lib/timber/probes/rails_rack_logger.rb +0 -77
- data/lib/timber/rack_middlewares.rb +0 -12
- data/lib/timber/rack_middlewares/http_context.rb +0 -30
- data/spec/support/action_view.rb +0 -4
- data/spec/support/coveralls.rb +0 -2
- data/spec/support/simplecov.rb +0 -9
- data/spec/timber/overrides/logger_add_spec.rb +0 -26
- data/spec/timber/probes/action_controller_log_subscriber_spec.rb +0 -65
- data/spec/timber/probes/action_controller_user_context_spec.rb +0 -53
- data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +0 -48
- data/spec/timber/probes/action_view_log_subscriber_spec.rb +0 -107
- data/spec/timber/probes/active_record_log_subscriber_spec.rb +0 -47
- data/spec/timber/probes/rails_rack_logger_spec.rb +0 -46
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eab99caab83ef2be6496c0ad1db6d736cf54817f
|
|
4
|
+
data.tar.gz: dfdd212606d1ff42d908401e073ecf94a2cc2f72
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b7e9143deab1f3d58076b7c55600f8ee72d7a11f3d659c1494f6bef053d03e444555564e1a7a7977fc1ed8bfab8b2c5d53bd1d238d2934b5d23537e6f23da2e5
|
|
7
|
+
data.tar.gz: bb07cec849ea6a95a6480711b123612b1db91d6f4a59c23aac8c01b5f0b6ee921fc52ff43147a8123d9ad341b934055676e594cbc5ab4d1082268f423cd7d4f4
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
|
@@ -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
|
-
|
|
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 -
|
|
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
|
[](LICENSE.md)
|
|
8
4
|
[](https://circleci.com/gh/timberio/timber-ruby/tree/master)
|
|
9
|
-
[](https://coveralls.io/github/timberio/timber-ruby?branch=master)
|
|
10
5
|
[](https://codeclimate.com/github/timberio/timber-ruby)
|
|
11
6
|
[](http://www.rubydoc.info/github/timberio/timber-ruby)
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
32
|
-
# config/environments/production.rb
|
|
14
|
+
## Overview
|
|
33
15
|
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
38
|
-
```
|
|
21
|
+
For example, Timber turns this:
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
27
|
+
Into this:
|
|
103
28
|
|
|
104
|
-
|
|
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
|
-
|
|
107
|
-
# config/environments/production.rb (or staging, etc)
|
|
33
|
+
Allowing you to run queries like:
|
|
108
34
|
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
42
|
+
## Installation
|
|
116
43
|
|
|
117
|
-
|
|
44
|
+
1. In `Gemfile`, add the `timber` gem:
|
|
118
45
|
|
|
119
|
-
|
|
46
|
+
```ruby
|
|
47
|
+
gem 'timber', '~> 2.0'
|
|
48
|
+
```
|
|
120
49
|
|
|
121
|
-
|
|
50
|
+
2. In your `shell`, run `bundle install`
|
|
122
51
|
|
|
123
|
-
|
|
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>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
81
|
+
# => Payment rejected @metadata {"level": "warn", "event": {"payment_rejected": {"customer_id": "abcd1234", "amount": 100, "reason": "Card expired"}}, "context": {...}}
|
|
192
82
|
```
|
|
193
83
|
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
|
|
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
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
|
|
247
|
-
|
|
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
|
-
|
|
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>
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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>
|
|
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
|
-
|
|
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
|
|
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
|
|
374
|
-
|
|
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-
|
|
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>
|