timberio 1.0.0.beta1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -2
- data/.rspec +2 -0
- data/.yardopts +6 -0
- data/Appraisals +4 -0
- data/Gemfile +9 -1
- data/LICENSE.md +15 -0
- data/README.md +170 -8
- data/circle.yml +11 -8
- data/lib/timber/config.rb +11 -18
- data/lib/timber/context.rb +9 -68
- data/lib/timber/contexts/custom.rb +27 -0
- data/lib/timber/contexts/http.rb +28 -0
- data/lib/timber/contexts/organization.rb +24 -22
- data/lib/timber/contexts/user.rb +25 -28
- data/lib/timber/contexts.rb +7 -20
- data/lib/timber/current_context.rb +26 -41
- data/lib/timber/event.rb +13 -0
- data/lib/timber/events/controller_call.rb +40 -0
- data/lib/timber/events/custom.rb +42 -0
- data/lib/timber/events/exception.rb +35 -0
- data/lib/timber/events/http_request.rb +50 -0
- data/lib/timber/events/http_response.rb +36 -0
- data/lib/timber/events/sql_query.rb +26 -0
- data/lib/timber/events/template_render.rb +26 -0
- data/lib/timber/events.rb +37 -0
- data/lib/timber/frameworks/rails.rb +3 -14
- data/lib/timber/frameworks.rb +8 -10
- data/lib/timber/log_devices/http.rb +72 -13
- data/lib/timber/log_devices.rb +8 -4
- data/lib/timber/log_entry.rb +59 -0
- data/lib/timber/logger.rb +136 -13
- data/lib/timber/probe.rb +6 -4
- data/lib/timber/probes/action_controller_log_subscriber/log_subscriber.rb +64 -0
- data/lib/timber/probes/action_controller_log_subscriber.rb +20 -0
- data/lib/timber/probes/action_dispatch_debug_exceptions.rb +59 -35
- data/lib/timber/probes/action_view_log_subscriber/log_subscriber.rb +62 -0
- data/lib/timber/probes/action_view_log_subscriber.rb +20 -0
- data/lib/timber/probes/active_record_log_subscriber/log_subscriber.rb +72 -0
- data/lib/timber/probes/active_record_log_subscriber.rb +20 -0
- data/lib/timber/probes/rack_http_context.rb +51 -0
- data/lib/timber/probes/rails_rack_logger.rb +76 -0
- data/lib/timber/probes.rb +13 -16
- data/lib/timber/util/active_support_log_subscriber.rb +33 -0
- data/lib/timber/util/hash.rb +14 -0
- data/lib/timber/util.rb +8 -0
- data/lib/timber/version.rb +2 -2
- data/lib/timber.rb +6 -11
- data/spec/spec_helper.rb +7 -4
- data/spec/support/rails.rb +9 -5
- data/spec/support/timber.rb +1 -20
- data/spec/timber/events_spec.rb +55 -0
- data/spec/timber/log_devices/http_spec.rb +62 -0
- data/spec/timber/logger_spec.rb +68 -0
- data/spec/timber/probes/action_controller_log_subscriber_spec.rb +70 -0
- data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +24 -18
- data/spec/timber/probes/action_view_log_subscriber_spec.rb +61 -0
- data/spec/timber/probes/active_record_log_subscriber_spec.rb +49 -0
- data/spec/timber/probes/rack_http_context_spec.rb +54 -0
- data/spec/timber/probes/rails_rack_logger_spec.rb +46 -0
- data/timberio.gemspec +2 -0
- metadata +62 -123
- data/.codeclimate.yml +0 -34
- data/LICENSE +0 -38
- data/Rakefile +0 -4
- data/TODO +0 -4
- data/benchmark/README.md +0 -26
- data/benchmark/rails_request.rb +0 -68
- data/benchmark/support/rails.rb +0 -69
- data/docs/installation/rails_on_heroku.md +0 -31
- data/docs/installation/rails_over_http.md +0 -22
- data/gemfiles/rails_3.0.X.gemfile +0 -25
- data/gemfiles/rails_3.1.X.gemfile +0 -25
- data/gemfiles/rails_3.2.X.gemfile +0 -25
- data/gemfiles/rails_4.0.X.gemfile +0 -26
- data/gemfiles/rails_4.1.X.gemfile +0 -26
- data/gemfiles/rails_4.2.X.gemfile +0 -26
- data/gemfiles/rails_5.0.X.gemfile +0 -26
- data/gemfiles/rails_edge.gemfile +0 -27
- data/lib/timber/api_settings.rb +0 -17
- data/lib/timber/bootstrap.rb +0 -45
- data/lib/timber/context_snapshot.rb +0 -64
- data/lib/timber/contexts/dynamic_values.rb +0 -59
- data/lib/timber/contexts/exception.rb +0 -40
- data/lib/timber/contexts/http_request.rb +0 -22
- data/lib/timber/contexts/http_requests/action_controller_specific.rb +0 -48
- data/lib/timber/contexts/http_requests/rack/params.rb +0 -26
- data/lib/timber/contexts/http_requests/rack.rb +0 -105
- data/lib/timber/contexts/http_response.rb +0 -19
- data/lib/timber/contexts/http_responses/action_controller.rb +0 -76
- data/lib/timber/contexts/logger.rb +0 -33
- data/lib/timber/contexts/organizations/action_controller.rb +0 -34
- data/lib/timber/contexts/server.rb +0 -21
- data/lib/timber/contexts/servers/heroku_specific.rb +0 -48
- data/lib/timber/contexts/sql_queries/active_record.rb +0 -30
- data/lib/timber/contexts/sql_queries/active_record_specific/binds.rb +0 -37
- data/lib/timber/contexts/sql_queries/active_record_specific.rb +0 -59
- data/lib/timber/contexts/sql_query.rb +0 -18
- data/lib/timber/contexts/template_render.rb +0 -17
- data/lib/timber/contexts/template_renders/action_view.rb +0 -29
- data/lib/timber/contexts/template_renders/action_view_specific.rb +0 -51
- data/lib/timber/contexts/users/action_controller.rb +0 -34
- data/lib/timber/current_line_indexes.rb +0 -35
- data/lib/timber/internal_logger.rb +0 -35
- data/lib/timber/log_device.rb +0 -40
- data/lib/timber/log_devices/heroku_logplex/hybrid_formatter.rb +0 -14
- data/lib/timber/log_devices/heroku_logplex.rb +0 -14
- data/lib/timber/log_devices/http/log_pile.rb +0 -86
- data/lib/timber/log_devices/http/log_truck/delivery.rb +0 -116
- data/lib/timber/log_devices/http/log_truck.rb +0 -87
- data/lib/timber/log_devices/io/formatter.rb +0 -46
- data/lib/timber/log_devices/io/hybrid_formatter.rb +0 -41
- data/lib/timber/log_devices/io/hybrid_hidden_formatter.rb +0 -36
- data/lib/timber/log_devices/io/json_formatter.rb +0 -11
- data/lib/timber/log_devices/io/logfmt_formatter.rb +0 -11
- data/lib/timber/log_devices/io.rb +0 -41
- data/lib/timber/log_line.rb +0 -33
- data/lib/timber/macros/compactor.rb +0 -16
- data/lib/timber/macros/date_formatter.rb +0 -9
- data/lib/timber/macros/deep_merger.rb +0 -11
- data/lib/timber/macros/logfmt_encoder.rb +0 -77
- data/lib/timber/macros.rb +0 -4
- data/lib/timber/patterns/delegated_singleton.rb +0 -21
- data/lib/timber/patterns/to_json.rb +0 -22
- data/lib/timber/patterns/to_logfmt.rb +0 -9
- data/lib/timber/patterns.rb +0 -3
- data/lib/timber/probes/action_controller_base.rb +0 -31
- data/lib/timber/probes/active_support_log_subscriber/action_controller.rb +0 -15
- data/lib/timber/probes/active_support_log_subscriber/action_view.rb +0 -26
- data/lib/timber/probes/active_support_log_subscriber/active_record.rb +0 -13
- data/lib/timber/probes/active_support_log_subscriber.rb +0 -62
- data/lib/timber/probes/heroku.rb +0 -30
- data/lib/timber/probes/logger.rb +0 -31
- data/lib/timber/probes/rack.rb +0 -36
- data/lib/timber/probes/server.rb +0 -18
- data/spec/timber/bootstrap_spec.rb +0 -31
- data/spec/timber/context_snapshot_spec.rb +0 -10
- data/spec/timber/context_spec.rb +0 -4
- data/spec/timber/contexts/exception_spec.rb +0 -34
- data/spec/timber/contexts/organizations/action_controller_spec.rb +0 -49
- data/spec/timber/contexts/users/action_controller_spec.rb +0 -65
- data/spec/timber/current_line_indexes_spec.rb +0 -40
- data/spec/timber/frameworks/rails_spec.rb +0 -9
- data/spec/timber/log_devices/heroku_logplex_spec.rb +0 -45
- data/spec/timber/log_devices/http/log_truck/delivery_spec.rb +0 -66
- data/spec/timber/log_devices/http/log_truck_spec.rb +0 -65
- data/spec/timber/log_devices/io/hybrid_hidden_formatter_spec.rb +0 -28
- data/spec/timber/log_line_spec.rb +0 -49
- data/spec/timber/macros/compactor_spec.rb +0 -19
- data/spec/timber/macros/logfmt_encoder_spec.rb +0 -89
- data/spec/timber/patterns/to_json_spec.rb +0 -40
- data/spec/timber/probes/action_controller_base_spec.rb +0 -43
- data/spec/timber/probes/action_controller_log_subscriber/action_controller_spec.rb +0 -35
- data/spec/timber/probes/action_controller_log_subscriber/action_view_spec.rb +0 -44
- data/spec/timber/probes/action_controller_log_subscriber/active_record_spec.rb +0 -26
- data/spec/timber/probes/logger_spec.rb +0 -20
- data/spec/timber/probes/rack_spec.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7561d4af5b30a06c3964a04ff0ff21d3f36bca31
|
4
|
+
data.tar.gz: 5072e0329ba5799c2c73622b483f2301d2055797
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 977a6aff51b60657619677e63892a129fbe43fe90cdbffcb1678a3c19434676b264b79853a046a9e1aa3596f2d66d09cc6185d9755bc48a3499409a3670269e8
|
7
|
+
data.tar.gz: f17d76bef300091e365087f7c8c892f0ef5407fdee4fc12b7f739c23fc0255386636c21e6d636e324b5fb183ddf60ff32c3f07628345602505b458ebe39dc40b
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.yardopts
ADDED
data/Appraisals
CHANGED
data/Gemfile
CHANGED
@@ -14,7 +14,15 @@ group :test do
|
|
14
14
|
gem 'sqlite3'
|
15
15
|
gem 'terminal-table'
|
16
16
|
gem 'timecop'
|
17
|
-
|
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
|
18
26
|
|
19
27
|
# for coveralls
|
20
28
|
gem 'rest-client', '~> 1.8' # >= 2.0 requires ruby 2+, we have tests for 1.9
|
data/LICENSE.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# License
|
2
|
+
|
3
|
+
Copyright (c) 2016, Timber Technologies, Inc.
|
4
|
+
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose
|
6
|
+
with or without fee is hereby granted, provided that the above copyright notice
|
7
|
+
and this permission notice appear in all copies.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
11
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
13
|
+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
14
|
+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
15
|
+
THIS SOFTWARE.
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# Timber
|
1
|
+
# Timber
|
2
2
|
|
3
3
|
<p align="center" style="background: #140f2a;">
|
4
|
-
<a href="http://github.com/timberio/timber-ruby"><img src="http://
|
4
|
+
<a href="http://github.com/timberio/timber-ruby"><img src="http://files.timber.io/images/ruby-library-readme-header.gif" height="370" /></a>
|
5
5
|
</p>
|
6
6
|
|
7
7
|
[![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,14 +9,176 @@
|
|
9
9
|
[![Code Climate](https://codeclimate.com/github/timberio/timber-ruby/badges/gpa.svg)](https://codeclimate.com/github/timberio/timber-ruby)
|
10
10
|
[![View docs](https://img.shields.io/badge/docs-viewdocs-blue.svg?style=flat-square "Viewdocs")](http://www.rubydoc.info/github/timberio/timber-ruby)
|
11
11
|
|
12
|
-
**Note: Timber is in alpha testing, if interested in joining, please visit http://timber.io**
|
13
12
|
|
14
|
-
|
13
|
+
1. [What is timber?](#what-is-timber)
|
14
|
+
2. [Examples](#examples)
|
15
|
+
3. [Pricing](#pricing)
|
16
|
+
2. [Install](#install)
|
17
|
+
|
18
|
+
|
19
|
+
## What is Timber?
|
20
|
+
|
21
|
+
Glad you asked :) Timber tames the crazy world that is logging. First, it *automatically*
|
22
|
+
augments your logs with structured data. Second, it provides a transparent, no lock-in, API
|
23
|
+
for logging your own events. Lastly, it can be paired with a [simple modern console](https://timber.io) for querying.
|
24
|
+
|
25
|
+
For example, it automatically turns this:
|
26
|
+
|
27
|
+
```
|
28
|
+
Completed 200 OK in 117ms (Views: 85.2ms | ActiveRecord: 25.3ms)
|
29
|
+
```
|
30
|
+
|
31
|
+
Into this:
|
32
|
+
|
33
|
+
```json
|
34
|
+
{
|
35
|
+
"dt": "2016-12-01T02:23:12.236543Z",
|
36
|
+
"level": "info",
|
37
|
+
"message": "Completed 200 OK in 117ms (Views: 85.2ms | ActiveRecord: 25.3ms)",
|
38
|
+
"context": {
|
39
|
+
"http": {
|
40
|
+
"method": "GET",
|
41
|
+
"path": "/checkout",
|
42
|
+
"remote_addr": "123.456.789.10",
|
43
|
+
"request_id": "abcd1234"
|
44
|
+
},
|
45
|
+
"user": {
|
46
|
+
"id": 2,
|
47
|
+
"name": "Ben Johnson",
|
48
|
+
"email": "ben@johnson.com"
|
49
|
+
}
|
50
|
+
},
|
51
|
+
"event": {
|
52
|
+
"http_response": {
|
53
|
+
"status": 200,
|
54
|
+
"time_ms": 117
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
```
|
59
|
+
|
60
|
+
It does the same for `http requests`, `sql queries`, `exceptions`, `template renderings`,
|
61
|
+
and any other event your framework logs. (for a full list see `Timber::Events`)
|
62
|
+
|
63
|
+
This enables you to query your logs in a way that
|
64
|
+
[even your mother would get excited about](http://i.giphy.com/7JYWGKgwxga5i.gif)!
|
65
|
+
|
66
|
+
1. `context.user.email:ben@johnson.com` - Tail a specific user!
|
67
|
+
2. `context.http.request_id:1234` - View *all* logs for a given HTTP request!
|
68
|
+
3. `event.http_reponse.time_ms>3000` - Easily find outliers and have the proper context to resolve them!
|
69
|
+
4. `level:warn` - Log levels in your logs. Imagine that!
|
70
|
+
|
71
|
+
|
72
|
+
## Examples
|
73
|
+
|
74
|
+
> Another service? More lock-in? More code debt? More sadness? :*(
|
75
|
+
|
76
|
+
Nope! This is exactly why we created Timber. Timber is Just Logging™. No special API, no risk
|
77
|
+
of code debt, no weird proprietary data format locked away in our servers. Absolutely no lock-in!
|
78
|
+
|
79
|
+
Besides automatically capturing known events, you can also log custom events. Check it out:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# Simple string (original Logger interface remains untouched)
|
83
|
+
Logger.warn "Payment rejected for customer abcd1234, reason: Card expired"
|
84
|
+
|
85
|
+
# Structured hash
|
86
|
+
Logger.warn message: "Payment rejected", type: :payment_rejected,
|
87
|
+
data: %{customer_id: "abcd1234", amount: 100, reason: "Card expired"}
|
88
|
+
|
89
|
+
# Using a Struct
|
90
|
+
PaymentRejectedEvent = Struct.new(:customer_id, :amount, :reason) do
|
91
|
+
def message; "Payment rejected for #{customer_id}"; end
|
92
|
+
def type; :payment_rejected; end
|
93
|
+
end
|
94
|
+
Logger.warn PaymentRejectedEvent.new("abcd1234", 100, "Card expired")
|
95
|
+
```
|
96
|
+
|
97
|
+
(for more examples, see the `Timber::Logger` docs)
|
98
|
+
|
99
|
+
No Timber specific code anywhere! In fact, this approach pushes things the opposite way. What if,
|
100
|
+
as a result of structured logging, you could start decoupling other services from your application?
|
101
|
+
|
102
|
+
Before:
|
103
|
+
|
104
|
+
```
|
105
|
+
|---[HTTP]---> sentry / bugsnag / etc
|
106
|
+
My Application |---[HTTP]---> librato / graphite / etc
|
107
|
+
|---[HTTP]---> new relic / etc
|
108
|
+
|--[STDOUT]--> logs
|
109
|
+
|---> Logging service
|
110
|
+
|---> S3
|
111
|
+
|---> RedShift
|
112
|
+
```
|
113
|
+
|
114
|
+
|
115
|
+
After:
|
116
|
+
|
117
|
+
```
|
118
|
+
|-- sentry / bugsnag / etc
|
119
|
+
|-- librato / graphite / etc
|
120
|
+
My Application |--[STDOUT]--> logs ---> Timber ---> |-- new relic / etc
|
121
|
+
^ |-- S3
|
122
|
+
| |-- RedShift
|
123
|
+
| ^
|
124
|
+
fast, efficient, durable, |
|
125
|
+
replayable, auditable, change any of these without
|
126
|
+
just logging touching your code
|
127
|
+
*and* backfill them!
|
128
|
+
```
|
129
|
+
|
130
|
+
|
131
|
+
## Pricing
|
132
|
+
|
133
|
+
> This is all gravy, but wouldn't it get expensive?
|
134
|
+
|
135
|
+
If you opt to send your data to the [Timber service](https://timber.io), we only charge for
|
136
|
+
the size of the `message`, `dt`, and `event.custom` attributes. Everything else is
|
137
|
+
stored at no cost to you. [Say wha?!](http://i.giphy.com/l0HlL2vlfpWI0meJi.gif). This ensures
|
138
|
+
pricing remains predictable. And our pricing is simple, we charge per GB transferred to us and
|
139
|
+
retained, no user limits, and no weird feature matrixes. Lastly, the data is yours, in a simple
|
140
|
+
non-proprietary JSON format.
|
141
|
+
|
142
|
+
For more details checkout our [timber.io](https://timber.io).
|
15
143
|
|
16
144
|
## Install
|
17
145
|
|
18
|
-
|
146
|
+
### 1. Install the gem:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
# Gemfile
|
150
|
+
gem 'timberio', require: "timber"
|
151
|
+
```
|
152
|
+
|
153
|
+
### 2. Install the logger:
|
154
|
+
|
155
|
+
#### Heroku:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
# config/environments/production.rb (or staging, etc)
|
159
|
+
config.logger = ActiveSupport::TaggedLogging.new(Timber::Logger.new(STDOUT))
|
160
|
+
```
|
161
|
+
|
162
|
+
The command to add your log drain will be displayed in the [Timber app](https://app.timber.io)
|
163
|
+
after you add your application.
|
164
|
+
|
165
|
+
#### Non-Heroku:
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
# config/environments/production.rb (or staging, etc)
|
169
|
+
log_device = Timber::LogDevices::HTTP.new(ENV['TIMBER_KEY']) # key can be obtained by signing up at https://timber.io
|
170
|
+
config.logger = ActiveSupport::TaggedLogging.new(Timber::Logger.new(log_device))
|
171
|
+
```
|
172
|
+
|
173
|
+
Your Timber application key will be displayed in the [Timber app](https://app.timber.io)
|
174
|
+
after you add your application.
|
175
|
+
|
176
|
+
|
177
|
+
*Other transport methods coming soon!*
|
178
|
+
|
179
|
+
---
|
180
|
+
|
181
|
+
That's it! Log to your heart's content.
|
19
182
|
|
20
|
-
|
21
|
-
|
22
|
-
3. ...more coming soon!
|
183
|
+
For documentation on logging structured events, and other features,
|
184
|
+
checkout [the docs](http://thedocs.com/). For more information on Timber visit [timber.io](https://timber.io).
|
data/circle.yml
CHANGED
@@ -5,6 +5,8 @@ machine:
|
|
5
5
|
dependencies:
|
6
6
|
override:
|
7
7
|
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 bundle install
|
8
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal generate
|
9
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-2.3.X bundle install
|
8
10
|
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.0.X bundle install
|
9
11
|
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.1.X bundle install
|
10
12
|
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.2.X bundle install
|
@@ -17,11 +19,12 @@ dependencies:
|
|
17
19
|
|
18
20
|
test:
|
19
21
|
override:
|
20
|
-
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.
|
21
|
-
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.
|
22
|
-
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.
|
23
|
-
- PATH=/home/ubuntu/.rvm/gems/ruby-
|
24
|
-
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-4.
|
25
|
-
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-4.
|
26
|
-
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-
|
27
|
-
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-
|
22
|
+
- RAILS_23=true PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-2.3.X rspec --tag rails_23
|
23
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.0.X rspec
|
24
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.1.X rspec
|
25
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-1.9.3-p448/bin:$PATH rvm-exec 1.9.3 appraisal rails-3.2.X rspec
|
26
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-4.0.X rspec
|
27
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-4.1.X rspec
|
28
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-4.2.X rspec
|
29
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-5.0.X rspec
|
30
|
+
- PATH=/home/ubuntu/.rvm/gems/ruby-2.3.0/bin:$PATH rvm-exec 2.3.0 appraisal rails-edge rspec
|
data/lib/timber/config.rb
CHANGED
@@ -1,25 +1,18 @@
|
|
1
|
+
require "singleton"
|
2
|
+
|
1
3
|
module Timber
|
4
|
+
# Interface for configuring Timber.
|
5
|
+
#
|
6
|
+
# @note If using rails this will be installed in the `config` object via `config.timber`.
|
2
7
|
class Config
|
3
|
-
include
|
4
|
-
|
5
|
-
attr_writer :application_key, :enabled, :logger
|
6
|
-
|
7
|
-
def application_key
|
8
|
-
@application_key ||= ENV['TIMBER_KEY']
|
9
|
-
end
|
8
|
+
include Singleton
|
10
9
|
|
11
|
-
|
12
|
-
return @enabled if defined?(@enabled)
|
13
|
-
@enabled = true
|
14
|
-
end
|
15
|
-
|
16
|
-
def enabled?
|
17
|
-
enabled == true
|
18
|
-
end
|
10
|
+
attr_writer :logger
|
19
11
|
|
20
|
-
#
|
12
|
+
# Set a logger to view internal Timber library log message.
|
13
|
+
# Useful for debugging. Defaults to `::Logger.new(nil)`.
|
21
14
|
def logger
|
22
|
-
@logger ||=
|
15
|
+
@logger ||= Logger.new(nil)
|
23
16
|
end
|
24
17
|
end
|
25
|
-
end
|
18
|
+
end
|
data/lib/timber/context.rb
CHANGED
@@ -1,76 +1,17 @@
|
|
1
|
-
require "securerandom"
|
2
|
-
|
3
1
|
module Timber
|
2
|
+
# Base class for all `Timber::Contexts::*` classes.
|
3
|
+
# @private
|
4
4
|
class Context
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
PATH_DELIMITER = ".".freeze
|
9
|
-
SECURE_RANDOM_LENGTH = 16.freeze
|
10
|
-
|
11
|
-
class << self
|
12
|
-
def json_shell(&_block)
|
13
|
-
{_root_key => yield}
|
14
|
-
end
|
15
|
-
|
16
|
-
def _path
|
17
|
-
@path ||= Macros::LogfmtEncoder.encode(json_shell { 1 }).split("=").first
|
18
|
-
end
|
19
|
-
|
20
|
-
def _root_key
|
21
|
-
@_root_key ||= const_get(:ROOT_KEY)
|
22
|
-
end
|
23
|
-
|
24
|
-
def _version
|
25
|
-
@_version ||= const_get(:VERSION)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def _dt
|
30
|
-
@_dt ||= Time.now.utc
|
31
|
-
end
|
32
|
-
|
33
|
-
def _path
|
34
|
-
self.class._path
|
5
|
+
def keyspace
|
6
|
+
raise NoImplementedError.new
|
35
7
|
end
|
36
8
|
|
37
|
-
def
|
38
|
-
|
9
|
+
def as_json(options = {})
|
10
|
+
raise NotImplementedError.new
|
39
11
|
end
|
40
12
|
|
41
|
-
def
|
42
|
-
|
13
|
+
def to_json(options = {})
|
14
|
+
Util::Hash.compact(as_json).to_json(options)
|
43
15
|
end
|
44
|
-
|
45
|
-
def as_json(*args)
|
46
|
-
@as_json ||= json_shell { super }
|
47
|
-
end
|
48
|
-
|
49
|
-
def json_shell(&block)
|
50
|
-
self.class.json_shell(&block)
|
51
|
-
end
|
52
|
-
|
53
|
-
def inspect(*_args)
|
54
|
-
"#<#{self.class.name}:#{object_id} ...>"
|
55
|
-
end
|
56
|
-
|
57
|
-
# Some contexts hold mutable object that change as the context block
|
58
|
-
# executes. This method checks the state of that object to ensure
|
59
|
-
# that the context is valid and ready to be copied for each log line.
|
60
|
-
def valid?
|
61
|
-
true
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
def json_payload
|
66
|
-
@json_payload ||= {
|
67
|
-
:_dt => Macros::DateFormatter.format(_dt),
|
68
|
-
:_version => _version
|
69
|
-
}
|
70
|
-
end
|
71
|
-
|
72
|
-
def generate_secure_random
|
73
|
-
SecureRandom.urlsafe_base64(SECURE_RANDOM_LENGTH)
|
74
|
-
end
|
75
16
|
end
|
76
|
-
end
|
17
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Timber
|
2
|
+
module Contexts
|
3
|
+
# Custom contexts allow you to add application specific context not covered elsewhere.
|
4
|
+
#
|
5
|
+
# @example Adding a context
|
6
|
+
# custom_context = Timber::Contexts::Custom.new(type: :keyspace, data: %{my: "data"})
|
7
|
+
# Timber::CurrentContext.with(custom_context) do
|
8
|
+
# # ... anything logged here will have the context ...
|
9
|
+
# end
|
10
|
+
class Custom < Context
|
11
|
+
attr_reader :type, :data
|
12
|
+
|
13
|
+
def initialize(attributes)
|
14
|
+
@type = attributes[:type] || raise(ArgumentError.new(":type is required"))
|
15
|
+
@data = attributes[:data] || raise(ArgumentError.new(":data is required"))
|
16
|
+
end
|
17
|
+
|
18
|
+
def keyspace
|
19
|
+
:custom
|
20
|
+
end
|
21
|
+
|
22
|
+
def as_json(_options = {})
|
23
|
+
{type => data}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Timber
|
2
|
+
module Contexts
|
3
|
+
# The HTTP content tracks the current HTTP request being processed. This serves
|
4
|
+
# as join data across your logs, allowing you to query all logs for any attribute
|
5
|
+
# presented here. For example, viewing all logs for a given request_id.
|
6
|
+
#
|
7
|
+
# @note This context should be installed automatically through probes,
|
8
|
+
# such as the {Probes::RackHTTPContext} probe.
|
9
|
+
class HTTP < Context
|
10
|
+
attr_reader :method, :path, :remote_addr, :request_id
|
11
|
+
|
12
|
+
def initialize(attributes)
|
13
|
+
@method = attributes[:method] || raise(ArgumentError.new(":method is required"))
|
14
|
+
@path = attributes[:path] || raise(ArgumentError.new(":path is required"))
|
15
|
+
@remote_addr = attributes[:remote_addr]
|
16
|
+
@request_id = attributes[:request_id]
|
17
|
+
end
|
18
|
+
|
19
|
+
def keyspace
|
20
|
+
:http
|
21
|
+
end
|
22
|
+
|
23
|
+
def as_json(_options = {})
|
24
|
+
{:method => method, :path => path, :remote_addr => remote_addr, :request_id => request_id}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,33 +1,35 @@
|
|
1
1
|
module Timber
|
2
2
|
module Contexts
|
3
|
+
# The organization context tracks the organization of the currently
|
4
|
+
# authenticated user.
|
5
|
+
#
|
6
|
+
# You will want to add this context at the time you determine
|
7
|
+
# the organization a user belongs to, typically in the authentication
|
8
|
+
# flow.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
#
|
12
|
+
# organization_context = Timber::Contexts::Organization.new(id: "abc1234", name: "Timber Inc")
|
13
|
+
# Timber::CurrentContext.with(organization_context) do
|
14
|
+
# # Logging will automatically include this context
|
15
|
+
# logger.info("This is a log message")
|
16
|
+
# end
|
17
|
+
#
|
3
18
|
class Organization < Context
|
4
|
-
|
5
|
-
VERSION = 1.freeze
|
19
|
+
attr_reader :id, :name
|
6
20
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
return @id if defined?(@id)
|
11
|
-
@id = organization.respond_to?(:id) ? organization.id : nil
|
21
|
+
def initialize(attributes)
|
22
|
+
@id = attributes[:id]
|
23
|
+
@name = attributes[:name]
|
12
24
|
end
|
13
25
|
|
14
|
-
def
|
15
|
-
|
16
|
-
@name = organization.respond_to?(:name) ? organization.name : nil
|
26
|
+
def keyspace
|
27
|
+
:organization
|
17
28
|
end
|
18
29
|
|
19
|
-
def
|
20
|
-
|
30
|
+
def as_json(_options = {})
|
31
|
+
{id: id, name: name}
|
21
32
|
end
|
22
|
-
|
23
|
-
private
|
24
|
-
def json_payload
|
25
|
-
@json_payload ||= Macros::DeepMerger.merge({
|
26
|
-
# order is relevant for logfmt styling
|
27
|
-
:id => id,
|
28
|
-
:name => name
|
29
|
-
}, super).freeze
|
30
|
-
end
|
31
33
|
end
|
32
34
|
end
|
33
|
-
end
|
35
|
+
end
|
data/lib/timber/contexts/user.rb
CHANGED
@@ -1,39 +1,36 @@
|
|
1
1
|
module Timber
|
2
2
|
module Contexts
|
3
|
+
# The user context tracks the currently authenticated user.
|
4
|
+
#
|
5
|
+
# You will want to add this context at the time log the user in, typically
|
6
|
+
# during the authentication flow.
|
7
|
+
#
|
8
|
+
# Note: Timber will attempt to automatically add this if you add a #current_user
|
9
|
+
# method to your controllers. Most authentication solutions do this for you automatically.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# user_context = Timber::Contexts::User.new(id: "abc1234", name: "Ben Johnson")
|
14
|
+
# Timber::CurrentContext.with(user_context) do
|
15
|
+
# # Logging will automatically include this context
|
16
|
+
# logger.info("This is a log message")
|
17
|
+
# end
|
18
|
+
#
|
3
19
|
class User < Context
|
4
|
-
|
5
|
-
VERSION = 1.freeze
|
20
|
+
attr_reader :id, :name
|
6
21
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
return @email if defined?(@email)
|
11
|
-
@email = user.respond_to?(:email) ? user.email : nil
|
12
|
-
end
|
13
|
-
|
14
|
-
def id
|
15
|
-
return @id if defined?(@id)
|
16
|
-
@id = user.respond_to?(:id) ? user.id : nil
|
22
|
+
def initialize(attributes)
|
23
|
+
@id = attributes[:id]
|
24
|
+
@name = attributes[:name]
|
17
25
|
end
|
18
26
|
|
19
|
-
def
|
20
|
-
|
21
|
-
@name = user.respond_to?(:name) ? user.name : nil
|
27
|
+
def keyspace
|
28
|
+
:user
|
22
29
|
end
|
23
30
|
|
24
|
-
def
|
25
|
-
|
31
|
+
def as_json(_options = {})
|
32
|
+
{id: id, name: name}
|
26
33
|
end
|
27
|
-
|
28
|
-
private
|
29
|
-
def json_payload
|
30
|
-
@json_payload ||= Macros::DeepMerger.merge({
|
31
|
-
# order is relevant for logfmt styling
|
32
|
-
:id => id,
|
33
|
-
:name => name,
|
34
|
-
:email => email
|
35
|
-
}, super).freeze
|
36
|
-
end
|
37
34
|
end
|
38
35
|
end
|
39
|
-
end
|
36
|
+
end
|
data/lib/timber/contexts.rb
CHANGED
@@ -1,23 +1,10 @@
|
|
1
|
-
|
2
|
-
require "timber/contexts/
|
3
|
-
require "timber/contexts/exception"
|
4
|
-
require "timber/contexts/http_request"
|
5
|
-
require "timber/contexts/http_response"
|
6
|
-
require "timber/contexts/logger"
|
1
|
+
require "timber/contexts/custom"
|
2
|
+
require "timber/contexts/http"
|
7
3
|
require "timber/contexts/organization"
|
8
|
-
require "timber/contexts/server"
|
9
|
-
require "timber/contexts/sql_query"
|
10
|
-
require "timber/contexts/template_render"
|
11
4
|
require "timber/contexts/user"
|
12
5
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
require "timber/contexts/servers/heroku_specific"
|
19
|
-
require "timber/contexts/sql_queries/active_record"
|
20
|
-
require "timber/contexts/sql_queries/active_record_specific"
|
21
|
-
require "timber/contexts/template_renders/action_view"
|
22
|
-
require "timber/contexts/template_renders/action_view_specific"
|
23
|
-
require "timber/contexts/users/action_controller"
|
6
|
+
module Timber
|
7
|
+
# @private
|
8
|
+
module Contexts
|
9
|
+
end
|
10
|
+
end
|