timber 1.0.13 → 1.1.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/README.md +278 -121
- data/lib/timber.rb +1 -0
- data/lib/timber/context.rb +1 -1
- data/lib/timber/contexts.rb +29 -2
- data/lib/timber/contexts/runtime.rb +24 -0
- data/lib/timber/contexts/system.rb +19 -0
- data/lib/timber/current_context.rb +14 -5
- data/lib/timber/event.rb +1 -1
- data/lib/timber/events.rb +11 -6
- data/lib/timber/events/controller_call.rb +1 -1
- data/lib/timber/events/custom.rb +1 -1
- data/lib/timber/events/exception.rb +1 -1
- data/lib/timber/events/{http_request.rb → http_server_request.rb} +1 -1
- data/lib/timber/events/{http_response.rb → http_server_response.rb} +2 -1
- data/lib/timber/events/sql_query.rb +2 -1
- data/lib/timber/events/template_render.rb +2 -1
- data/lib/timber/frameworks/rails.rb +12 -1
- data/lib/timber/log_devices/http.rb +29 -24
- data/lib/timber/log_entry.rb +23 -9
- data/lib/timber/logger.rb +20 -6
- data/lib/timber/probes.rb +1 -3
- data/lib/timber/probes/active_support_tagged_logging.rb +0 -43
- data/lib/timber/probes/rails_rack_logger.rb +1 -1
- data/lib/timber/rack_middlewares.rb +12 -0
- data/lib/timber/rack_middlewares/http_context.rb +30 -0
- data/lib/timber/util.rb +1 -0
- data/lib/timber/util/struct.rb +16 -0
- data/lib/timber/version.rb +1 -1
- data/spec/README.md +23 -0
- data/spec/support/timber.rb +1 -1
- data/spec/timber/contexts_spec.rb +49 -0
- data/spec/timber/events_spec.rb +1 -1
- data/spec/timber/log_devices/http_spec.rb +7 -7
- data/spec/timber/log_entry_spec.rb +15 -0
- data/spec/timber/logger_spec.rb +14 -10
- data/spec/timber/probes/action_controller_log_subscriber_spec.rb +6 -7
- data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +1 -1
- data/spec/timber/probes/action_view_log_subscriber_spec.rb +2 -2
- data/spec/timber/probes/rails_rack_logger_spec.rb +3 -3
- data/spec/timber/rack_middlewares/http_context_spec.rb +47 -0
- data/timber.gemspec +1 -0
- metadata +31 -8
- data/lib/timber/contexts/tags.rb +0 -22
- data/lib/timber/probes/rack_http_context.rb +0 -51
- data/spec/timber/probes/rack_http_context_spec.rb +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a526175aa41bf2a0f6124b8081fa68dff14d79f
|
4
|
+
data.tar.gz: 85e34c100200bc0c61c576126cf1980d0ac576ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bbf7e0964fb175ced6f826ff852079373c138f97ee72f1cc8ae367c43c9d11bdd26d318ec365a801fd3657d5cd7d832cae8f6c836e09f93f16ab3f27665f5ee2
|
7
|
+
data.tar.gz: f001a84ee2a8d2df95dd339ca467d884b15e75a26b57fc3bce66ccd3b4234254025b2cf4fddb12c447768b483b869a3cc5d7fa99f2d823cf5d183d2ff54858de
|
data/README.md
CHANGED
@@ -1,200 +1,357 @@
|
|
1
|
-
# Timber
|
1
|
+
# 🌲 Timber - Master your Ruby apps with structured logging
|
2
2
|
|
3
3
|
<p align="center" style="background: #140f2a;">
|
4
4
|
<a href="http://github.com/timberio/timber-ruby"><img src="http://files.timber.io/images/ruby-library-readme-header.gif" height="469" /></a>
|
5
5
|
</p>
|
6
6
|
|
7
|
+
[](LICENSE.md)
|
7
8
|
[](https://circleci.com/gh/timberio/timber-ruby/tree/master)
|
8
9
|
[](https://coveralls.io/github/timberio/timber-ruby?branch=master)
|
9
10
|
[](https://codeclimate.com/github/timberio/timber-ruby)
|
10
11
|
[](http://www.rubydoc.info/github/timberio/timber-ruby)
|
11
12
|
|
12
13
|
|
13
|
-
|
14
|
+
---
|
15
|
+
|
16
|
+
👉 **Timber is in beta testing, if interested in joining, please email us at
|
17
|
+
[beta@timber.io](mailto:beta@timber.io)**
|
18
|
+
|
19
|
+
---
|
14
20
|
|
21
|
+
Still logging raw text? Timber is a complete *structured* logging solution that you can setup in
|
22
|
+
minutes. It goes beyond traditional log management by focusing on data quality and modern
|
23
|
+
developer standards.
|
24
|
+
|
25
|
+
High quality logs, [a modern UX-first interface](https://timber.io), simple setup,
|
26
|
+
zero-maintenance, 6-month retention, and sane prices are just a few of the benefits Timber
|
27
|
+
offers.
|
28
|
+
|
29
|
+
To learn more, checkout out [timber.io](https://timber.io) or the
|
30
|
+
["why we built Timber"](http://moss-ibex2.cloudvent.net/blog/why-were-building-timber/)
|
31
|
+
blog post.
|
32
|
+
|
33
|
+
|
34
|
+
## Overview
|
35
|
+
|
36
|
+
<details><summary><strong>What are the benefits of using Timber?</strong></summary><p>
|
37
|
+
|
38
|
+
1. **Data quality.** The usefulness of your logs starts here. This is why we ship libraries that
|
39
|
+
structure logs from *within* your application; a fundamental difference from parsing. Not only
|
40
|
+
is it much more stable, but we can include data you couldn't obtain otherwise.
|
41
|
+
2. **Human readability.** Structuring your logs doesn't mean they have to be unreadable. Timber
|
42
|
+
*augments* your logs with structured data. Meaning we do not alter the original log message,
|
43
|
+
we simply attach metadata to it. And our console is specifically designed to give you access
|
44
|
+
to this data, without compromising readability. 😮
|
45
|
+
3. **Reliable downstream consumption.** All log events adhere to a
|
46
|
+
[normalized, shared, schema](https://github.com/timberio/log-event-json-schema) that follows
|
47
|
+
[semantic versioning](http://semver.org/) and goes through a [standard release process](https://github.com/timberio/log-event-json-schema/releases).
|
48
|
+
This means you can *rely* on the structure of your logs and interact consistently with them
|
49
|
+
across apps of any language: queries, graphs, alerts, and other downstream consumers.
|
50
|
+
4. **Zero risk of code debt or lock-in.** Logging is a standard that has been around since the dawn
|
51
|
+
of computers. It's built into every language, framework, and library. Timber adheres strictly
|
52
|
+
to the default `Logger` interface. There are no special APIs, and no need to pepper your app
|
53
|
+
with Timber specific code. It's just better logging. If you choose to stop using Timber, you
|
54
|
+
can do so without consequence.
|
55
|
+
5. **Long term retention.** Timber is designed on modern big-data principles. As a result, we can
|
56
|
+
offer 6+ months of retention at prices cheaper than alternatives offering <1 month.
|
57
|
+
This allows you to unlock your logs for purposes beyond debugging.
|
58
|
+
---
|
15
59
|
|
16
|
-
|
17
|
-
2. [How it works](#how-it-works)
|
18
|
-
3. [Why timber?](#why-timber)
|
19
|
-
4. [Logging Custom Events](#logging-custom-events)
|
20
|
-
5. [The Timber Console / Pricing](#the-timber-console--pricing)
|
21
|
-
6. [Install](#install)
|
60
|
+
</p></details>
|
22
61
|
|
62
|
+
<details><summary><strong>What specifically does the Timber library do?</strong></summary><p>
|
23
63
|
|
24
|
-
|
64
|
+
1. Captures and structures your framework and 3rd party logs. (see next question)
|
65
|
+
2. Adds useful context to every log line. (see next question)
|
66
|
+
3. Provides a [framework for logging custom structured events](#what-about-custom-events).
|
67
|
+
4. Offers transport strategies to [send your logs](#send-your-logs) to the Timber service.
|
25
68
|
|
26
|
-
|
27
|
-
something like this:
|
69
|
+
---
|
28
70
|
|
29
|
-
>
|
30
|
-
> Wow, this is expensive. Why is searching so difficult and time consuming?
|
31
|
-
> Would structuring my logs help? Which format should I use? Will they still be human readable?
|
32
|
-
> What if the structure changes? What about logs from 3rd party libraries? Ahhh!!!
|
71
|
+
</p></details>
|
33
72
|
|
34
|
-
|
35
|
-
a beautiful, *fast*, console with libraries that automatically structure and enrich your logs.
|
73
|
+
<details><summary><strong>What events does Timber capture & structure for me?</strong></summary><p>
|
36
74
|
|
75
|
+
Out of the box you get everything in the [`Timber::Events`](lib/timber/events) namespace:
|
76
|
+
|
77
|
+
1. [Controller Call Event](lib/timber/events/controller_call.rb)
|
78
|
+
2. [Exception Event](lib/timber/events/exception.rb)
|
79
|
+
3. [HTTP Client Request Event (net/http outgoing)](lib/timber/events/http_client_request.rb)
|
80
|
+
4. [HTTP Client Response Event (resposne from net/http outgoing)](lib/timber/events/http_client_response.rb)
|
81
|
+
5. [HTTP Server Request Event (incoming client request)](lib/timber/events/http_server_request.rb)
|
82
|
+
6. [HTTP Server Response Event (response to incoming client request)](lib/timber/events/http_server_response.rb)
|
83
|
+
7. [SQL Query Event](lib/timber/events/sql_query.rb)
|
84
|
+
8. [Template Render Event](lib/timber/events/template_render.rb)
|
85
|
+
9. ...more coming soon, [file an issue](https://github.com/timberio/timber-ruby/issues) to request.
|
86
|
+
|
87
|
+
We also add context to every log, everything in the [`Timber::Contexts`](lib/timber/contexts)
|
88
|
+
namespace. Context is structured data representing the current environment when the log line was
|
89
|
+
written. It is included in every log line. Think of it like join data for your logs:
|
90
|
+
|
91
|
+
1. [HTTP Context](lib/timber/contexts/http.rb)
|
92
|
+
2. [Organization Context](lib/timber/contexts/organization.rb)
|
93
|
+
3. [Process Context](lib/timber/contexts/process.rb)
|
94
|
+
4. [Server Context](lib/timber/contexts/server.rb)
|
95
|
+
5. [Runtime Context](lib/timber/contexts/runtime.rb)
|
96
|
+
5. [User Context](lib/timber/contexts/user.rb)
|
97
|
+
6. ...more coming soon, [file an issue](https://github.com/timberio/timber-ruby/issues) to request.
|
98
|
+
|
99
|
+
---
|
37
100
|
|
38
|
-
|
101
|
+
</p></details>
|
39
102
|
|
40
|
-
|
41
|
-
it turns this Rails log line:
|
103
|
+
<details><summary><strong>What about my current log statements?</strong></summary><p>
|
42
104
|
|
105
|
+
They'll continue to work as expected. Timber adheres strictly to the default `::Logger` interface
|
106
|
+
and will never deviate in *any* way.
|
107
|
+
|
108
|
+
In fact, traditional log statements for non-meaningful events, debug statements, etc, are
|
109
|
+
encouraged. In cases where the data is meaningful, consider [logging a custom event](#usage).
|
110
|
+
|
111
|
+
</p></details>
|
112
|
+
|
113
|
+
## Usage
|
114
|
+
|
115
|
+
<details><summary><strong>Basic logging</strong></summary><p>
|
116
|
+
|
117
|
+
Use `Logger` as normal:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
logger.info("My log message")
|
121
|
+
|
122
|
+
# My log message @metadata {"level": "info", "context": {...}}
|
43
123
|
```
|
44
|
-
|
124
|
+
|
125
|
+
Timber will never deviate from the public `::Logger` interface in *any* way.
|
126
|
+
|
127
|
+
---
|
128
|
+
|
129
|
+
</p></details>
|
130
|
+
|
131
|
+
<details><summary><strong>Tagging logs</strong></summary><p>
|
132
|
+
|
133
|
+
Need a quick and easy way to identify a log? Use tags!:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
logger.info(message: "My log message", tag: "tag")
|
137
|
+
|
138
|
+
# My log message @metadata {"level": "info", "tags": ["tag"], "context": {...}}
|
139
|
+
```
|
140
|
+
|
141
|
+
Multiple tags:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
logger.info(message: "My log message", tags: ["tag1", "tag2"])
|
145
|
+
|
146
|
+
# My log message @metadata {"level": "info", "tags": ["tag1", "tag2"], "context": {...}}
|
45
147
|
```
|
46
148
|
|
47
|
-
|
48
|
-
|
49
|
-
```
|
50
|
-
|
51
|
-
"
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
"http": {
|
56
|
-
"method": "GET",
|
57
|
-
"path": "/checkout",
|
58
|
-
"remote_addr": "123.456.789.10",
|
59
|
-
"request_id": "abcd1234"
|
60
|
-
},
|
61
|
-
"user": { // <---- http://i.giphy.com/EldfH1VJdbrwY.gif
|
62
|
-
"id": 2,
|
63
|
-
"name": "Ben Johnson",
|
64
|
-
"email": "ben@johnson.com"
|
65
|
-
}
|
66
|
-
},
|
67
|
-
"event": {
|
68
|
-
"http_response": {
|
69
|
-
"status": 200,
|
70
|
-
"time_ms": 117
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}
|
149
|
+
Using `ActiveSupport::TaggedLogging`? It works with that as well:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
logger.tagged("tag") do
|
153
|
+
logger.info(message: "My log message", tags: ["important", "slow"])
|
154
|
+
end
|
155
|
+
|
156
|
+
# My log message @metadata {"level": "info", "tags": ["tag"], "context": {...}}
|
74
157
|
```
|
75
158
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
159
|
+
</p></details>
|
160
|
+
|
161
|
+
<details><summary><strong>Custom events</strong></summary><p>
|
162
|
+
|
163
|
+
1. Log a structured Hash (simplest)
|
80
164
|
|
81
|
-
|
165
|
+
```ruby
|
166
|
+
Logger.warn message: "Payment rejected", payment_rejected: {customer_id: "abcd1234", amount: 100, reason: "Card expired"}
|
82
167
|
|
168
|
+
# Payment rejected @metadata {"level": "warn", "event": {"payment_rejected": {"customer_id": "abcd1234", "amount": 100, "reason": "Card expired"}}, "context": {...}}
|
169
|
+
```
|
83
170
|
|
84
|
-
|
171
|
+
* The hash can *only* have a `:message` and "event type" key, where `:payment_rejected` is the event type in the above example.
|
85
172
|
|
86
|
-
|
173
|
+
2. Log a Struct (recommended)
|
87
174
|
|
88
|
-
|
89
|
-
|
90
|
-
3. Normalized log data. Timber enforces a strict schema, meaning your log data, across all apps
|
91
|
-
and languages will be normalized.
|
92
|
-
4. Absolutely no lock-in or risk of code debt. No fancy API, no proprietary data format locked
|
93
|
-
away in our servers, Timber is just good ol' loggin'.
|
94
|
-
5. Fully managed, all the way from the log messages to the console you use. No fragile parsing
|
95
|
-
rules or complicated interfaces.
|
175
|
+
Defining structs for your important events just feels oh so good :) It creates a strong contract
|
176
|
+
with down stream consumers and gives you compile time guarantees.
|
96
177
|
|
178
|
+
```ruby
|
179
|
+
PaymentRejectedEvent = Struct.new(:customer_id, :amount, :reason) do
|
180
|
+
def message; "Payment rejected for #{customer_id}"; end
|
181
|
+
def type; :payment_rejected; end
|
182
|
+
end
|
183
|
+
Logger.warn PaymentRejectedEvent.new("abcd1234", 100, "Card expired")
|
97
184
|
|
98
|
-
|
185
|
+
# Payment rejected @metadata {"level": "warn", "event": {"payment_rejected": {"customer_id": "abcd1234", "amount": 100, "reason": "Card expired"}}, "context": {...}}
|
186
|
+
```
|
99
187
|
|
100
|
-
|
188
|
+
* `:type` is how Timber classifies the event, it creates a namespace for the data you send.
|
189
|
+
* For more advanced examples see [`Timber::Logger`](lib/timber.logger.rb).
|
190
|
+
* Also, notice there is no mention of Timber in the above code. Just plain old logging.
|
101
191
|
|
102
|
-
|
192
|
+
#### What about regular Hashes, JSON, or logfmt?
|
193
|
+
|
194
|
+
Go for it! Timber will parse the data server side, but we *highly* recommend the above examples.
|
195
|
+
Providing a `:type` allows timber to classify the event, create a namespace for the data you
|
196
|
+
send, and make it easier to search, graph, alert, etc.
|
103
197
|
|
104
198
|
```ruby
|
105
|
-
|
106
|
-
|
199
|
+
logger.info({key: "value"})
|
200
|
+
# {"key": "value"} @metadata {"level": "info", "context": {...}}
|
107
201
|
|
108
|
-
|
109
|
-
|
110
|
-
data: {customer_id: "abcd1234", amount: 100, reason: "Card expired"}
|
202
|
+
logger.info('{"key": "value"}')
|
203
|
+
# {"key": "value"} @metadata {"level": "info", "context": {...}}
|
111
204
|
|
112
|
-
|
113
|
-
|
114
|
-
def message; "Payment rejected for #{customer_id}"; end
|
115
|
-
def type; :payment_rejected; end
|
116
|
-
end
|
117
|
-
Logger.warn PaymentRejectedEvent.new("abcd1234", 100, "Card expired")
|
205
|
+
logger.info('key=value')
|
206
|
+
# key=value @metadata {"level": "info", "context": {...}}
|
118
207
|
```
|
119
208
|
|
120
|
-
|
209
|
+
---
|
210
|
+
|
211
|
+
</p></details>
|
212
|
+
|
213
|
+
<details><summary><strong>Custom contexts</strong></summary><p>
|
121
214
|
|
122
|
-
|
215
|
+
Context is structured data representing the current environment when the log line was written.
|
216
|
+
It is included in every log line. Think of it like join data for your logs. For example, the
|
217
|
+
`http.request_id` field is included in the context, allowing you to find all log lines related
|
218
|
+
to that request ID, if desired. This is in contrast to *only* showing log lines that contain this
|
219
|
+
value.
|
123
220
|
|
221
|
+
1. Add a Hash (simplest)
|
124
222
|
|
125
|
-
|
223
|
+
```ruby
|
224
|
+
Timber::CurrentContext.with({build: {version: "1.0.0"}}) do
|
225
|
+
logger.info("My log message")
|
226
|
+
end
|
126
227
|
|
127
|
-
|
228
|
+
# My log message @metadata {"level": "info", "context": {"build": {"version": "1.0.0"}}}
|
229
|
+
```
|
128
230
|
|
129
|
-
|
130
|
-
specifically for this library.
|
231
|
+
This adds data to the context keyspaced by `build`.
|
131
232
|
|
132
|
-
|
233
|
+
2. Add a Struct (recommended)
|
133
234
|
|
134
|
-
|
135
|
-
|
136
|
-
3. `event.http_reponse.time_ms>3000` - Easily find outliers and have the proper context to resolve them!
|
137
|
-
4. `level:warn` - Log levels in your logs. Imagine that!
|
235
|
+
Just like events, we recommend defining your custom contexts. It makes a stronger contract
|
236
|
+
with downstream consumers.
|
138
237
|
|
139
|
-
|
238
|
+
```ruby
|
239
|
+
BuildContext = Struct.new(:version) do
|
240
|
+
def type; :build; end
|
241
|
+
end
|
242
|
+
build_context = BuildContext.new("1.0.0")
|
243
|
+
Timber::CurrentContext.with(build_context) do
|
244
|
+
logger.info("My log message")
|
245
|
+
end
|
140
246
|
|
141
|
-
|
142
|
-
|
143
|
-
stored at no cost to you. [Say wha?!](http://i.giphy.com/l0HlL2vlfpWI0meJi.gif). This ensures
|
144
|
-
pricing remains predictable. We charge per GB sent to us and retained. No user limits,
|
145
|
-
no weird feature matrixes, just data. Finally, the data is yours, in a simple
|
146
|
-
non-proprietary JSON format that you can export to S3, Redshift, or any of our other integrations.
|
247
|
+
# My log message @metadata {"level": "info", "context": {"build": {"version": "1.0.0"}}}
|
248
|
+
```
|
147
249
|
|
148
|
-
|
250
|
+
</p></details>
|
149
251
|
|
150
|
-
## Install
|
151
252
|
|
152
|
-
**Timber is in beta testing. If interested, please email beta@timber.io**
|
153
253
|
|
154
|
-
|
254
|
+
## Installation
|
155
255
|
|
156
256
|
```ruby
|
157
257
|
# Gemfile
|
158
258
|
gem 'timber'
|
159
259
|
```
|
160
260
|
|
161
|
-
### 2. Install the logger:
|
162
261
|
|
163
|
-
|
262
|
+
## Setup
|
263
|
+
|
264
|
+
<details><summary><strong>Rails >= 3.0</strong></summary><p>
|
265
|
+
|
266
|
+
*Replace* any existing `config.logger=` calls in `config/environments/production.rb` with:
|
164
267
|
|
165
268
|
```ruby
|
166
|
-
# config/environments/production.rb
|
167
|
-
|
269
|
+
# config/environments/production.rb
|
270
|
+
|
271
|
+
config.logger = ActiveSupport::TaggedLogging.new(Timber::Logger.new(STDOUT))
|
168
272
|
```
|
169
273
|
|
170
|
-
|
171
|
-
|
274
|
+
* Prefer examples? Checkout our [Ruby / Rails example app](https://github.com/timberio/ruby-rails-example-app),
|
275
|
+
you can see all changes by [search for "timber-change"](https://github.com/timberio/ruby-rails-example-app/search?utf8=%E2%9C%93&q=timber-change&type=Code).
|
172
276
|
|
173
|
-
|
277
|
+
---
|
174
278
|
|
175
|
-
|
176
|
-
# config/environments/production.rb (or staging, etc)
|
177
|
-
log_device = Timber::LogDevices::HTTP.new(ENV['TIMBER_KEY']) # key can be obtained by signing up at https://timber.io
|
178
|
-
config.logger = Timber::Logger.new(log_device)
|
179
|
-
```
|
279
|
+
</p></details>
|
180
280
|
|
181
|
-
|
182
|
-
after you add your application.
|
281
|
+
<details><summary><strong>Other</strong></summary><p>
|
183
282
|
|
283
|
+
1. *Insert* the Timber probes:
|
184
284
|
|
185
|
-
*
|
285
|
+
This should be executed *immediately after* you have required your dependencies.
|
186
286
|
|
287
|
+
```ruby
|
288
|
+
Timber::Probes.insert!
|
289
|
+
```
|
187
290
|
|
188
|
-
|
291
|
+
2. *Add* the Rack middlewares:
|
189
292
|
|
190
|
-
|
293
|
+
This should be included where you build your `Rack` application. Usually `config.ru`:
|
191
294
|
|
192
|
-
```ruby
|
193
|
-
|
194
|
-
|
295
|
+
```ruby
|
296
|
+
# Most likely config.ru
|
297
|
+
|
298
|
+
Timber::RackMiddlewares.middlewares.each do |m|
|
299
|
+
use m
|
300
|
+
end
|
301
|
+
```
|
302
|
+
|
303
|
+
2. *Instantiate* the Timber logger:
|
304
|
+
|
305
|
+
This should be *globally* available to your application:
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
logger = Timber::Logger.new(STDOUT)
|
309
|
+
```
|
310
|
+
|
311
|
+
</p></details>
|
312
|
+
|
313
|
+
|
314
|
+
## Send your logs
|
315
|
+
|
316
|
+
<details><summary><strong>Heroku (log drains)</strong></summary><p>
|
317
|
+
|
318
|
+
The recommended strategy for Heroku is to setup a
|
319
|
+
[log drain](https://devcenter.heroku.com/articles/log-drains). To get your Timber log drain URL:
|
320
|
+
|
321
|
+
👉 **[Add your app to Timber](https://app.timber.io)**
|
195
322
|
|
196
323
|
---
|
197
324
|
|
198
|
-
|
325
|
+
</p></details>
|
326
|
+
|
327
|
+
<details><summary><strong>All other platforms (Network / HTTP)</strong></summary><p>
|
328
|
+
|
329
|
+
1. *Specify* the Timber Network logger backend in `config/environments/production.rb`:
|
330
|
+
|
331
|
+
Replace any existing `config.logger =` calls with:
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
# config/environments/production.rb (or staging, etc)
|
335
|
+
|
336
|
+
network_log_device = Timber::LogDevices::Network.new(ENV['TIMBER_LOGS_KEY'])
|
337
|
+
config.logger = Timber::Logger.new(network_log_device) # <-- Use network_log_device instead of STDOUT
|
338
|
+
```
|
339
|
+
|
340
|
+
2. Obtain your Timber API :key: by **[adding your app in Timber](https://app.timber.io)**.
|
341
|
+
|
342
|
+
3. Assign your API key to the `TIMBER_LOGS_KEY` environment variable.
|
343
|
+
|
344
|
+
</p></details>
|
345
|
+
|
346
|
+
<details><summary><strong>Advanced setup (syslog, file tailing agent, etc)</strong></summary><p>
|
347
|
+
|
348
|
+
Checkout our [docs](https://timber.io/docs) for a comprehensive list of install instructions.
|
349
|
+
|
350
|
+
</p></details>
|
351
|
+
|
352
|
+
|
353
|
+
---
|
354
|
+
|
355
|
+
<p align="center" style="background: #221f40;">
|
199
356
|
<a href="http://github.com/timberio/timber-ruby"><img src="http://files.timber.io/images/ruby-library-readme-log-truth.png" height="947" /></a>
|
200
|
-
</p>
|
357
|
+
</p>
|