sapience 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.simplecov +6 -2
- data/.travis.yml +8 -25
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +5 -5
- data/README.md +146 -15
- data/Rakefile +2 -1
- data/config/default.yml +29 -0
- data/dev-entrypoint.sh +10 -0
- data/docker-compose.yml +42 -0
- data/lib/sapience/appender/datadog.rb +100 -0
- data/lib/sapience/appender/file.rb +11 -22
- data/lib/sapience/appender/sentry.rb +61 -55
- data/lib/sapience/appender/wrapper.rb +5 -4
- data/lib/sapience/base.rb +21 -13
- data/lib/sapience/config_loader.rb +66 -0
- data/lib/sapience/configuration/grape.rb +9 -0
- data/lib/sapience/configuration.rb +32 -22
- data/lib/sapience/core_ext/hash.rb +25 -0
- data/lib/sapience/core_ext/thread.rb +2 -2
- data/lib/sapience/extensions/action_cable/tagged_logger_proxy.rb +6 -0
- data/lib/sapience/extensions/action_controller/live.rb +6 -0
- data/lib/sapience/extensions/action_controller/log_subscriber.rb +127 -0
- data/lib/sapience/extensions/action_controller/log_subscriber_processing.rb +24 -0
- data/lib/sapience/extensions/action_dispatch/debug_exceptions.rb +11 -0
- data/lib/sapience/extensions/action_view/log_subscriber.rb +9 -0
- data/lib/sapience/extensions/action_view/streaming_template_renderer.rb +11 -0
- data/lib/sapience/extensions/active_job/logging.rb +14 -0
- data/lib/sapience/extensions/active_model_serializers/logging.rb +14 -0
- data/lib/sapience/extensions/active_record/log_subscriber.rb +35 -0
- data/lib/sapience/extensions/grape/middleware/logging.rb +91 -0
- data/lib/sapience/extensions/grape/timings.rb +25 -0
- data/lib/sapience/extensions/rails/rack/logger.rb +11 -0
- data/lib/sapience/extensions/rails/rack/logger_info_as_debug.rb +24 -0
- data/lib/sapience/formatters/color.rb +3 -3
- data/lib/sapience/formatters/default.rb +1 -1
- data/lib/sapience/grape.rb +25 -0
- data/lib/sapience/log.rb +8 -6
- data/lib/sapience/loggable.rb +19 -17
- data/lib/sapience/logger.rb +46 -126
- data/lib/sapience/rails.rb +65 -8
- data/lib/sapience/sapience.rb +74 -73
- data/lib/sapience/subscriber.rb +5 -1
- data/lib/sapience/version.rb +1 -1
- data/lib/sapience.rb +4 -1
- data/sapience.gemspec +7 -4
- data/test_app/Gemfile +5 -1
- data/test_app/Rakefile +5 -1
- data/test_app/app/controllers/posts_controller.rb +12 -11
- data/test_app/config/application.rb +0 -1
- data/test_app/spec/controllers/posts_controller_spec.rb +1 -1
- data/test_app/spec/fixtures/sapience.yml +14 -0
- data/test_app/spec/helpers/posts_helper_spec.rb +1 -1
- data/test_app/spec/integration/sapience_spec.rb +14 -0
- data/test_app/spec/models/post_spec.rb +1 -1
- data/test_app/spec/models/user_spec.rb +1 -1
- data/test_app/spec/rails_helper.rb +15 -0
- data/test_app/spec/requests/posts_spec.rb +1 -1
- data/test_app/spec/routing/posts_routing_spec.rb +8 -10
- data/test_app/spec/spec_helper.rb +0 -44
- metadata +76 -11
- data/lib/sapience/appender/statsd.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f84d8de78da549a144e13e50a0f34efbd7e26db0
|
4
|
+
data.tar.gz: b48b0a0375b29077acf0d67641e635d9d61c92c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4dde48558b0a55c5206ac82c812cfa57ca564bb6ddd52bd995420d8de3b3052a0cc5b2bd6bc1240065495003f479900a7c7c2abbe9b571d75764041b9728f20
|
7
|
+
data.tar.gz: 758c6d40530957d4e0fa6448a0b2d827bca2f232a3f5eebefab4a73c86ced2406eebde5ea6b2981d13452a547ccfb3fc3f80383df78fbf9136c454542a123d24
|
data/.simplecov
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
require "simplecov-json"
|
2
|
+
require "codeclimate-test-reporter"
|
2
3
|
require "coveralls"
|
3
|
-
Coveralls.wear!
|
4
4
|
|
5
|
-
|
5
|
+
CodeClimate::TestReporter.start
|
6
|
+
SimpleCov.maximum_coverage_drop 1
|
6
7
|
|
7
8
|
SimpleCov.formatters = [
|
8
9
|
SimpleCov::Formatter::HTMLFormatter,
|
9
10
|
SimpleCov::Formatter::JSONFormatter,
|
11
|
+
CodeClimate::TestReporter::Formatter,
|
12
|
+
Coveralls::SimpleCov::Formatter,
|
10
13
|
]
|
14
|
+
|
11
15
|
SimpleCov.start do
|
12
16
|
add_filter "/spec/"
|
13
17
|
add_filter "/bin/"
|
data/.travis.yml
CHANGED
@@ -1,27 +1,10 @@
|
|
1
|
-
sudo:
|
1
|
+
sudo: required
|
2
2
|
language: ruby
|
3
|
-
|
4
|
-
|
5
|
-
- rvm get head
|
6
|
-
- gem update --system
|
7
|
-
- gem install bundler
|
8
|
-
install:
|
9
|
-
- bundle install -j8 -r3
|
3
|
+
services:
|
4
|
+
- docker
|
10
5
|
script:
|
11
|
-
-
|
12
|
-
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
- 2.2.4
|
17
|
-
env: STYLE=false
|
18
|
-
|
19
|
-
matrix:
|
20
|
-
fast_finish: true
|
21
|
-
include:
|
22
|
-
- rvm: 2.3.1
|
23
|
-
env: STYLE=true
|
24
|
-
|
25
|
-
addons:
|
26
|
-
code_climate:
|
27
|
-
repo_token:
|
6
|
+
- docker-compose run rspec
|
7
|
+
- docker-compose run test_app
|
8
|
+
notifications:
|
9
|
+
slack:
|
10
|
+
secure: apFwkfBQ+3NDJgcLNCHQori9qtr6ePaN3Xx7Sy7NVWwYm9BHNxoX/FN8/hxR63JjXrf1C0hK0FLQ0TiA0BN9PgEEIecg78BvWUwMClDDiwhyYN3H0Bbg35PUFtgDIrOGpu/TYlxNmdHEDYEAxaWsl9wSds8pAJsN6m7VTjGfBwJUDcOiM4L1eRpbp7smPqOjmuQFuOJnO8YkPb+6nUfz53cJrMRUdha89Vgmvnw6cP4/Ms1TsL3vKmMSVbGGh/6WNKPjU6IbuUjwlsh6a9xWxQOk6Wnis/Z+kA+T0XbLMuTLLmzRDuql1tjJeMPi+wukmK1a7GjpPkpkzAgwLQ/CkjTBfIRbMyaBYSuAciuOY8PDtCcT4WLwEvdZbkFmhAdSr1RYxIBpONVfZ/5DT3bpk71+O74OIBqxG6NmkiZ0B6u9/KxbnIINLVAcVaqsN8sdSqWlWKzPm45BfGPXGjmGGgIVFU31rs+W5Zs7IYMNUjZxabYKIv9TsBONbogfbcoGZA+rWWUnQdjypNWJS9wyQDvJ4btxqy8YhDfaV6gF30Un5JcAggMutzKJiYi+qAeh0uN3/9XoXV2N6XBnh58h8ny1NY+0vklWhtFGR1wfFAqkDskvCIZabSeJ5bFM6FtNbNKq9tYciS+eAO1vEYQVDFt9eY2uZF2mFDKRnEegHMU=
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -35,7 +35,7 @@ This code of conduct applies both within project spaces and in public spaces
|
|
35
35
|
when an individual is representing the project or its community.
|
36
36
|
|
37
37
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
-
reported by contacting a project maintainer at
|
38
|
+
reported by contacting a project maintainer at developers@reevoo.com. All
|
39
39
|
complaints will be reviewed and investigated and will result in a response that
|
40
40
|
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
41
|
obligated to maintain confidentiality with regard to the reporter of an
|
data/Gemfile
CHANGED
@@ -5,8 +5,8 @@ gemspec
|
|
5
5
|
|
6
6
|
gem "pry-nav"
|
7
7
|
gem "sentry-raven"
|
8
|
-
gem "
|
9
|
-
gem "
|
10
|
-
gem "
|
11
|
-
gem "
|
12
|
-
gem
|
8
|
+
gem "dogstatsd-ruby"
|
9
|
+
gem "rails", "~> 5.0.0.1"
|
10
|
+
gem "grape"
|
11
|
+
gem "active_model_serializers", "~> 0.10.0"
|
12
|
+
gem "rspec-wait"
|
data/README.md
CHANGED
@@ -1,36 +1,167 @@
|
|
1
1
|
# Sapience
|
2
2
|
|
3
|
-
|
3
|
+
**Hasslefree autoconfiguration for logging, metrics and exception collection.**
|
4
4
|
|
5
|
-
|
5
|
+
[![Build Status](https://travis-ci.org/reevoo/sapience-rb.svg?branch=TECH-4%2FConfiguration-DSL)](https://travis-ci.org/reevoo/sapience-rb)[![Code Climate](https://codeclimate.com/github/reevoo/sapience-rb/badges/gpa.svg)](https://codeclimate.com/github/reevoo/sapience-rb)[![Test Coverage](https://codeclimate.com/github/reevoo/sapience-rb/badges/coverage.svg)](https://codeclimate.com/github/reevoo/sapience-rb/coverage)[![Issue Count](https://codeclimate.com/github/reevoo/sapience-rb/badges/issue_count.svg)](https://codeclimate.com/github/reevoo/sapience-rb)
|
6
6
|
|
7
|
-
|
7
|
+
## Background
|
8
8
|
|
9
|
-
|
9
|
+
We searched long and hard for a way to control our logging, error collection and metrics from a single place. The closest we could find that does everything we need is [Semantic Logger](https://github.com/rocketjob/semantic_logger). Unfortunately we couldn't find a good way to control the settings for our projects and would have had to spread our configuration over different initializers and rails configurations for each project. There was no easy way to gain that top level control over the configuration.
|
10
10
|
|
11
|
-
|
11
|
+
This project aims to make it easier to centralize the configuration of these three areas by handling the configuration a little differently.
|
12
|
+
|
13
|
+
We have taken a hug deal of inspiration from the amazing [Semantic Logger](https://github.com/rocketjob/semantic_logger) and implemented something similar to [Rubocop](https://github.com/bbatsov/rubocop) for handling and overriding how to find configuration. If you want some inspiration for how we do something similar for our projects for Rubocop check: [Reevoocop](https://github.com/reevoo/reevoocop).
|
14
|
+
|
15
|
+
## Setup
|
16
|
+
|
17
|
+
First of all we need to require the right file for the project. There are currently two frameworks supported (rails and grape).
|
18
|
+
|
19
|
+
### Rails
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem "sapience-rb", require: "sapience/rails"
|
23
|
+
```
|
24
|
+
|
25
|
+
### Grape
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
gem "sapience-rb", require: "sapience/grape"
|
29
|
+
```
|
30
|
+
|
31
|
+
|
32
|
+
### Configuration
|
33
|
+
|
34
|
+
The sapience configuration can be controlled by a `config/sapience.yml` file or if you like us have many projects that use the same configuration you can create your own gem with a shared config. Have a look at [reevoo/reevoo_sapience-rb](https://github.com/reevoo/reevoo_sapience-rb)
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
Sapience.configure do |config|
|
38
|
+
config.default_level = :info
|
39
|
+
config.backtrace_level = :error
|
40
|
+
config.application = "my-app"
|
41
|
+
config.appenders = [
|
42
|
+
{ file: { io: STDOUT, formatter: :color } },
|
43
|
+
{ sentry: { dsn: "https://username:password@app.getsentry.com/00000" } },
|
44
|
+
{ datadog: { url: "udp://localhost:8125" } },
|
45
|
+
]
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
Sapience provides a default configuration that will be used unless another file or configuration is specified. You can provide a custom
|
50
|
+
|
51
|
+
```yaml
|
52
|
+
---
|
53
|
+
default:
|
54
|
+
log_level: info
|
55
|
+
appenders:
|
56
|
+
- file:
|
57
|
+
io: STDOUT
|
58
|
+
formatter: color
|
59
|
+
|
60
|
+
test:
|
61
|
+
log_level: warn
|
62
|
+
appenders:
|
63
|
+
- file:
|
64
|
+
file_name: log/test.log
|
65
|
+
formatter: color
|
66
|
+
|
67
|
+
development:
|
68
|
+
log_level: debug
|
69
|
+
appenders:
|
70
|
+
- file:
|
71
|
+
file_name: log/development.log
|
72
|
+
formatter: color
|
73
|
+
|
74
|
+
production:
|
75
|
+
log_level: warn
|
76
|
+
appenders:
|
77
|
+
- file:
|
78
|
+
file_name: log/production.log
|
79
|
+
formatter: json
|
80
|
+
```
|
81
|
+
|
82
|
+
## Appenders
|
83
|
+
|
84
|
+
One of the things that did not suite us so well with the Semantic Logger approach was that they made a distinction between metrics and appenders. In our view anything that should potentially log something somewhere should be treated as an appender.
|
85
|
+
|
86
|
+
There are a number of appenders that all listen to different events and act on its data. It is possible to specify the `level` and `backtrace_level` for each appender by providing (example) `level: :error` to the add_appender method.
|
87
|
+
|
88
|
+
|
89
|
+
### File
|
90
|
+
|
91
|
+
File appenders are basically a log stream. You can add as many file appenders as you like logging to different locations.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
Sapience.add_appender(:file, file_name: "log/sapience.log", formatter: :json)
|
95
|
+
Sapience.add_appender(:file, io: STDOUT, formatter: :color, level: :trace)
|
96
|
+
```
|
97
|
+
|
98
|
+
### Sentry
|
99
|
+
|
100
|
+
The sentry appender handles sending errors to sentry. It's backtrace and log level can be configured by for instance `level: :info` and `backtrace_level: :debug`. The `level` configuration tells sentry to log starting at that level while the `backtrace_level` tells sentry to only collect backtrace starting at that level.
|
12
101
|
|
13
102
|
```ruby
|
14
|
-
|
103
|
+
Sapience.add_appender(
|
104
|
+
:sentry,
|
105
|
+
dsn: "https://username:password@app.getsentry.com/00000",
|
106
|
+
level: :error,
|
107
|
+
backtrace_level: :error
|
108
|
+
)
|
15
109
|
```
|
16
110
|
|
17
|
-
|
111
|
+
### Datadog
|
112
|
+
|
113
|
+
Datadog is a slightly modified version of statsd. On top of the standard statsd API it has support for events.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
Sapience.add_appender(:datadog, url: "udp://localhost:8125")
|
117
|
+
```
|
118
|
+
|
119
|
+
The appender will then be listening to anything that is logged with a `metric: "company/project/metric-name"` key. Details about the API can be found in [dogstatsd-ruby](https://github.com/DataDog/dogstatsd-ruby).
|
120
|
+
|
121
|
+
The appender can also be used directly through: `Sapience.metrix`
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
metrix = Sapience.metrix
|
125
|
+
metrix.timing("company/project/metric-name", 100)
|
126
|
+
metrix.increment("company/project/metric-name", 10)
|
127
|
+
metrix.decrement("company/project/metric-name", 5)
|
128
|
+
metrix.histogram("company/project/metric-name", 2_500)
|
129
|
+
metrix.gauge("company/project/metric-name", 1_000, {})
|
130
|
+
metrix.event("company/project/metric-name", "description about event", {})
|
131
|
+
metrix.batch do
|
132
|
+
metrix.event("company/project/metric-name", "description about event", {})
|
133
|
+
metrix.increment("company/project/another-metric-name", 2)
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
137
|
+
|
138
|
+
### Wrapper
|
139
|
+
|
140
|
+
The wrapper is useful when you already have a logger you want to use but want to use Sapience. The wrapper appender will when called use the logger provided to store the log data.
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
Sapience.add_appender(:wrapper, logger: Logger.new(STDOUT))
|
144
|
+
```
|
145
|
+
|
146
|
+
## Formatters
|
147
|
+
|
148
|
+
Formatters can be specified by using the key `formatter: :camelized_formatter_name`. **Note**: Only the File appender supports custom formatters.
|
18
149
|
|
19
|
-
|
150
|
+
### Color
|
20
151
|
|
21
|
-
|
152
|
+
`formatter: :color` - gives colorized output. Useful for `test` and `development` environments.
|
22
153
|
|
23
|
-
|
154
|
+
### Default
|
24
155
|
|
25
|
-
|
156
|
+
`formatter: :default` - logs a string. Inspired by how access logs for Nginx are logged.
|
26
157
|
|
27
|
-
|
158
|
+
### JSON
|
28
159
|
|
29
|
-
|
160
|
+
`formatter: :json` - logs are saved as a single line json. Useful for production like environments.
|
30
161
|
|
31
|
-
|
162
|
+
### RAW
|
32
163
|
|
33
|
-
|
164
|
+
`formatter: :raw` - logs are saved as a single line ruby hash. Useful for production like environments and is used internally for the Sentry appender.
|
34
165
|
|
35
166
|
## Contributing
|
36
167
|
|
data/Rakefile
CHANGED
data/config/default.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
---
|
2
|
+
default:
|
3
|
+
log_level: info
|
4
|
+
appenders:
|
5
|
+
- file:
|
6
|
+
io: STDOUT
|
7
|
+
formatter: color
|
8
|
+
|
9
|
+
test:
|
10
|
+
log_level: warn
|
11
|
+
appenders:
|
12
|
+
- file:
|
13
|
+
file_name: log/test.log
|
14
|
+
formatter: color
|
15
|
+
|
16
|
+
development:
|
17
|
+
log_level: debug
|
18
|
+
appenders:
|
19
|
+
- file:
|
20
|
+
file_name: log/development.log
|
21
|
+
formatter: color
|
22
|
+
|
23
|
+
production:
|
24
|
+
log_level: warn
|
25
|
+
appenders:
|
26
|
+
- file:
|
27
|
+
file_name: log/production.log
|
28
|
+
formatter: json
|
29
|
+
|
data/dev-entrypoint.sh
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#! /bin/bash
|
2
|
+
|
3
|
+
# The Docker App Container's development entrypoint.
|
4
|
+
# This is a script used by the project's Docker development environment to
|
5
|
+
# setup the app containers and databases upon runnning.
|
6
|
+
set -e
|
7
|
+
|
8
|
+
# 5: Check or install the app dependencies via Bundler:
|
9
|
+
bundle check || bundle install --jobs 8 --retry 5
|
10
|
+
exec "$@"
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
version: '2'
|
2
|
+
volumes:
|
3
|
+
gems:
|
4
|
+
driver: local
|
5
|
+
|
6
|
+
services:
|
7
|
+
rails:
|
8
|
+
image: ruby:2.3
|
9
|
+
cpu_shares: 4
|
10
|
+
# Specify the directory from where all commands sent to the container will be
|
11
|
+
# issued to where the code is mounted:
|
12
|
+
working_dir: /usr/src/app
|
13
|
+
|
14
|
+
# Keep the stdin open, so we can attach to our app container's process
|
15
|
+
# and do things such as byebug, etc:
|
16
|
+
stdin_open: true
|
17
|
+
|
18
|
+
# Enable sending signals (CTRL+C, CTRL+P + CTRL+Q) into the container:
|
19
|
+
tty: true
|
20
|
+
volumes:
|
21
|
+
# Mount our app code directory (".") into our app containers at the
|
22
|
+
# "/usr/src/app" folder:
|
23
|
+
- .:/usr/src/app
|
24
|
+
|
25
|
+
# Mount the 'gems' volume on the folder that stores bundled gems:
|
26
|
+
- gems:/usr/local/bundle
|
27
|
+
rspec:
|
28
|
+
extends:
|
29
|
+
service: rails
|
30
|
+
entrypoint: /usr/src/app/dev-entrypoint.sh
|
31
|
+
command: bundle exec rake
|
32
|
+
environment:
|
33
|
+
PATH: /usr/src/app/bin:/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
34
|
+
|
35
|
+
test_app:
|
36
|
+
extends:
|
37
|
+
service: rails
|
38
|
+
working_dir: /usr/src/app/test_app
|
39
|
+
entrypoint: /usr/src/app/dev-entrypoint.sh
|
40
|
+
command: bundle exec rspec
|
41
|
+
environment:
|
42
|
+
PATH: /usr/src/app/bin:/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "uri"
|
2
|
+
begin
|
3
|
+
require "dogstatsd-ruby"
|
4
|
+
rescue LoadError
|
5
|
+
raise 'Gem dogstatsd-ruby is required for logging metrics. Please add the gem "dogstatsd-ruby" to your Gemfile.'
|
6
|
+
end
|
7
|
+
|
8
|
+
# Example:
|
9
|
+
# Sapience.add_appender(:datadog, {url: "udp://localhost:2222"})
|
10
|
+
#
|
11
|
+
module Sapience
|
12
|
+
module Appender
|
13
|
+
class Datadog < Sapience::Subscriber
|
14
|
+
# Create Appender
|
15
|
+
#
|
16
|
+
# Parameters:
|
17
|
+
# level: :trace
|
18
|
+
# url: [String]
|
19
|
+
# Valid URL to post to.
|
20
|
+
# Example:
|
21
|
+
# udp://localhost:8125
|
22
|
+
# Example, send all metrics to a particular namespace:
|
23
|
+
# udp://localhost:8125/namespace
|
24
|
+
# Default: udp://localhost:8125
|
25
|
+
# tags: [String]
|
26
|
+
# Example:
|
27
|
+
# tag1:true
|
28
|
+
# rubocop:disable AbcSize, CyclomaticComplexity, PerceivedComplexity
|
29
|
+
|
30
|
+
def initialize(options = {}, &block)
|
31
|
+
fail("Options should be a Hash") unless options.is_a?(Hash)
|
32
|
+
url = options.delete(:url) || "udp://localhost:8125"
|
33
|
+
@tags = options.delete(:tags)
|
34
|
+
@uri = URI.parse(url)
|
35
|
+
fail('Statsd only supports udp. Example: "udp://localhost:8125"') if @uri.scheme != "udp"
|
36
|
+
|
37
|
+
super(options, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def provider
|
41
|
+
@_provider ||= begin
|
42
|
+
statsd = ::Statsd.new(@uri.host, @uri.port, tags: @tags)
|
43
|
+
path = @uri.path.chomp("/")
|
44
|
+
statsd.namespace = path.sub("/", "") if path != ""
|
45
|
+
statsd
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Send an error notification to sentry
|
50
|
+
def log(log)
|
51
|
+
metric = log.metric
|
52
|
+
return false unless metric
|
53
|
+
|
54
|
+
if log.duration
|
55
|
+
timing(metric, log.duration)
|
56
|
+
else
|
57
|
+
amount = (log.metric_amount || 1).round
|
58
|
+
if amount < 0
|
59
|
+
decrement(metric, amount.abs)
|
60
|
+
else
|
61
|
+
increment(metric, amount)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
def timing(metric, duration)
|
68
|
+
provider.timing(metric, duration)
|
69
|
+
end
|
70
|
+
|
71
|
+
def increment(metric, amount = 1)
|
72
|
+
provider.batch do
|
73
|
+
amount.times { provider.increment(metric) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def decrement(metric, amount = 1)
|
78
|
+
provider.batch do
|
79
|
+
amount.times { provider.decrement(metric) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def histogram(metric, amount)
|
84
|
+
provider.histogram(metric, amount)
|
85
|
+
end
|
86
|
+
|
87
|
+
def gauge(metric, amount, hash)
|
88
|
+
provider.gauge(metric, amount, hash)
|
89
|
+
end
|
90
|
+
|
91
|
+
def batch
|
92
|
+
yield provider
|
93
|
+
end
|
94
|
+
|
95
|
+
def event(title, text, options = {})
|
96
|
+
provider.event(title, text, options)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -58,35 +58,24 @@ module Sapience
|
|
58
58
|
#
|
59
59
|
# logger = Sapience['test']
|
60
60
|
# logger.info 'Hello World'
|
61
|
-
|
62
|
-
|
63
|
-
options
|
64
|
-
|
65
|
-
|
66
|
-
else
|
67
|
-
file_name = options
|
68
|
-
opts = {}
|
69
|
-
if file_name.respond_to?(:write) && file_name.respond_to?(:close)
|
70
|
-
opts[:io] = file_name
|
71
|
-
else
|
72
|
-
opts[:file_name] = file_name
|
73
|
-
end
|
74
|
-
opts[:level] = deprecated_level if deprecated_level
|
75
|
-
opts[:filter] = deprecated_filter if deprecated_filter
|
76
|
-
opts
|
77
|
-
end
|
61
|
+
# rubocop:disable AbcSize, CyclomaticComplexity, PerceivedComplexity
|
62
|
+
def initialize(options = {}, &block)
|
63
|
+
unless options[:io] || options[:file_name]
|
64
|
+
fail "Sapience::Appender::File missing mandatory parameter :file_name or :io"
|
65
|
+
end
|
78
66
|
|
79
|
-
|
80
|
-
|
67
|
+
opts = options.dup
|
68
|
+
if (io = opts.delete(:io))
|
69
|
+
@log = Sapience.constantize(io)
|
81
70
|
else
|
82
|
-
@file_name =
|
83
|
-
fail "Sapience::Appender::File missing mandatory parameter :file_name or :io" unless @file_name
|
71
|
+
@file_name = opts.delete(:file_name)
|
84
72
|
reopen
|
85
73
|
end
|
86
74
|
|
87
75
|
# Set the log level and formatter if supplied
|
88
|
-
super(
|
76
|
+
super(opts, &block)
|
89
77
|
end
|
78
|
+
# rubocop:enable AbcSize, CyclomaticComplexity, PerceivedComplexity
|
90
79
|
|
91
80
|
# After forking an active process call #reopen to re-open
|
92
81
|
# open the file handles etc to resources
|
@@ -9,64 +9,70 @@ end
|
|
9
9
|
# Example:
|
10
10
|
# Sapience.add_appender(:sentry, {})
|
11
11
|
#
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
12
|
+
# rubocop:disable Style/ClassAndModuleChildren
|
13
|
+
module Sapience
|
14
|
+
module Appender
|
15
|
+
class Sentry < Sapience::Subscriber
|
16
|
+
# Create Appender
|
17
|
+
#
|
18
|
+
# Parameters
|
19
|
+
# level: [:trace | :debug | :info | :warn | :error | :fatal]
|
20
|
+
# Override the log level for this appender.
|
21
|
+
# Default: :error
|
22
|
+
#
|
23
|
+
# formatter: [Object|Proc|Symbol|Hash]
|
24
|
+
# An instance of a class that implements #call, or a Proc to be used to format
|
25
|
+
# the output from this appender
|
26
|
+
# Default: Use the built-in formatter (See: #call)
|
27
|
+
#
|
28
|
+
# filter: [Regexp|Proc]
|
29
|
+
# RegExp: Only include log messages where the class name matches the supplied.
|
30
|
+
# regular expression. All other messages will be ignored.
|
31
|
+
# Proc: Only include log messages where the supplied Proc returns true
|
32
|
+
# The Proc must return true or false.
|
33
|
+
#
|
34
|
+
# host: [String]
|
35
|
+
# Name of this host to appear in log messages.
|
36
|
+
# Default: Sapience.config.host
|
37
|
+
#
|
38
|
+
# application: [String]
|
39
|
+
# Name of this application to appear in log messages.
|
40
|
+
# Default: Sapience.config.application
|
41
|
+
def initialize(options = {}, &block)
|
42
|
+
fail("Options should be a Hash") unless options.is_a?(Hash)
|
43
|
+
options[:level] ||= :error
|
44
|
+
Raven.configure do |config|
|
45
|
+
config.dsn = options.delete(:dsn)
|
46
|
+
end
|
47
|
+
super(options, &block)
|
48
|
+
end
|
41
49
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# Send an error notification to sentry
|
46
|
-
def log(log)
|
47
|
-
return false unless should_log?(log)
|
50
|
+
# Send an error notification to sentry
|
51
|
+
def log(log)
|
52
|
+
return false unless should_log?(log)
|
48
53
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
54
|
+
context = formatter.call(log, self)
|
55
|
+
if log.exception
|
56
|
+
context.delete(:exception)
|
57
|
+
Raven.capture_exception(log.exception, context)
|
58
|
+
else
|
59
|
+
message = {
|
60
|
+
error_class: context.delete(:name),
|
61
|
+
error_message: context.delete(:message),
|
62
|
+
context: context,
|
63
|
+
}
|
64
|
+
message[:backtrace] = log.backtrace if log.backtrace
|
65
|
+
Raven.capture_message(message[:error_message], message)
|
66
|
+
end
|
67
|
+
true
|
68
|
+
end
|
64
69
|
|
65
|
-
|
70
|
+
private
|
66
71
|
|
67
|
-
|
68
|
-
|
69
|
-
|
72
|
+
# Use Raw Formatter by default
|
73
|
+
def default_formatter
|
74
|
+
Sapience::Formatters::Raw.new
|
75
|
+
end
|
76
|
+
end
|
70
77
|
end
|
71
|
-
|
72
78
|
end
|