sapience 1.0.1 → 1.0.2
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/CHANGELOG.md +5 -0
- data/README.md +8 -1
- data/docker-compose.yml +2 -0
- data/lib/sapience/appender/datadog.rb +14 -6
- data/lib/sapience/appender/sentry.rb +4 -4
- data/lib/sapience/base.rb +2 -3
- data/lib/sapience/configuration.rb +2 -3
- data/lib/sapience/formatters/raw.rb +1 -1
- data/lib/sapience/log.rb +4 -4
- data/lib/sapience/sapience.rb +57 -12
- data/lib/sapience/subscriber.rb +14 -14
- data/lib/sapience/version.rb +1 -1
- data/test_apps/grape/gemfiles/grape_0.16.2.gemfile.lock +3 -3
- data/test_apps/grape/gemfiles/grape_0.17.0.gemfile.lock +3 -3
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bbf1f419c40131407dc53eccc467636462c6627
|
4
|
+
data.tar.gz: 2556a1353dfc63228882845c6515b186ef9c7fb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2cbd70840bd75008f69b8501dc12dd1dc4b64f7fc338beff143a2ea4bba3f9358a298e1b84d34bc32124b38a8b7f84e3f5b0ca6230a772ebb5d1a51332ecfde7
|
7
|
+
data.tar.gz: 9101d5a36a37c8061eea06d930c2a55161ca2d44d75c687d7e5a9d48127dd81ceeebac358e8d0859db9887455da361adc71daac6af5111621cd877fc1e3132b0
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## v1.0.2
|
2
|
+
|
3
|
+
- Require `app_name` to be configured. Either set it with the environment variable `SAPIENCE_APP_NAME` or provided it when configuring the application.
|
4
|
+
- Fixes problems with Datadog namespace always being nil.
|
5
|
+
|
1
6
|
## v1.0.1
|
2
7
|
|
3
8
|
- Fix loading configuration outside of Rack application
|
data/README.md
CHANGED
@@ -52,11 +52,13 @@ end
|
|
52
52
|
|
53
53
|
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)
|
54
54
|
|
55
|
+
The `app_name` is required to be configured. Sapience will fail on startup if app_name isn't configured properly.
|
56
|
+
|
55
57
|
```ruby
|
56
58
|
Sapience.configure do |config|
|
57
59
|
config.default_level = :info
|
58
60
|
config.backtrace_level = :error
|
59
|
-
config.
|
61
|
+
config.app_name = "my_app"
|
60
62
|
config.appenders = [
|
61
63
|
{ stream: { io: STDOUT, formatter: :color } },
|
62
64
|
{ sentry: { dsn: "https://username:password@app.getsentry.com/00000" } },
|
@@ -200,6 +202,11 @@ Formatters can be specified by using the key `formatter: :camelized_formatter_na
|
|
200
202
|
|
201
203
|
`bin/tests`
|
202
204
|
|
205
|
+
## Environment variables
|
206
|
+
|
207
|
+
`SAPIENCE_APP_NAME` - If you want to provide an application name for sapience
|
208
|
+
`SAPIENCE_ENV` - For applications that don't use rack or rails
|
209
|
+
|
203
210
|
## Contributing
|
204
211
|
|
205
212
|
Bug reports and pull requests are welcome on GitHub at https://github.com/reevoo/sapience. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
data/docker-compose.yml
CHANGED
@@ -56,6 +56,7 @@ services:
|
|
56
56
|
depends_on:
|
57
57
|
- rabbitmq
|
58
58
|
environment:
|
59
|
+
SAPIENCE_APP_NAME: rails_app
|
59
60
|
AMQP: amqp://sapience:tests@rabbitmq:5672
|
60
61
|
PATH: /usr/src/app/bin:/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
61
62
|
|
@@ -68,4 +69,5 @@ services:
|
|
68
69
|
entrypoint: /usr/src/app/dev-entrypoint.sh
|
69
70
|
command: bundle exec rspec
|
70
71
|
environment:
|
72
|
+
SAPIENCE_APP_NAME: grape_app
|
71
73
|
PATH: /usr/src/app/bin:/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
@@ -38,12 +38,7 @@ module Sapience
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def provider
|
41
|
-
@_provider ||=
|
42
|
-
statsd = ::Datadog::Statsd.new(@uri.host, @uri.port, tags: @tags)
|
43
|
-
path = @uri.path.chomp("/")
|
44
|
-
statsd.namespace = path.sub("/", "") if path != ""
|
45
|
-
statsd
|
46
|
-
end
|
41
|
+
@_provider ||= ::Datadog::Statsd.new(@uri.host, @uri.port, dog_options)
|
47
42
|
end
|
48
43
|
|
49
44
|
# Send an error notification to sentry
|
@@ -109,6 +104,19 @@ module Sapience
|
|
109
104
|
def event(title, text, options = {})
|
110
105
|
provider.event(title, text, options)
|
111
106
|
end
|
107
|
+
|
108
|
+
def namespace
|
109
|
+
ns = Sapience.app_name
|
110
|
+
ns << ".#{Sapience.environment}" if Sapience.environment
|
111
|
+
ns
|
112
|
+
end
|
113
|
+
|
114
|
+
def dog_options
|
115
|
+
{
|
116
|
+
namespace: namespace,
|
117
|
+
tags: @tags,
|
118
|
+
}
|
119
|
+
end
|
112
120
|
end
|
113
121
|
end
|
114
122
|
end
|
@@ -35,9 +35,9 @@ module Sapience
|
|
35
35
|
# Name of this host to appear in log messages.
|
36
36
|
# Default: Sapience.config.host
|
37
37
|
#
|
38
|
-
#
|
38
|
+
# app_name: [String]
|
39
39
|
# Name of this application to appear in log messages.
|
40
|
-
# Default: Sapience.
|
40
|
+
# Default: Sapience.app_name
|
41
41
|
def initialize(options = {}, &block)
|
42
42
|
validate_options!(options)
|
43
43
|
|
@@ -46,7 +46,6 @@ module Sapience
|
|
46
46
|
config.dsn = options.delete(:dsn)
|
47
47
|
config.tags = { environment: Sapience.environment }
|
48
48
|
end
|
49
|
-
|
50
49
|
super(options, &block)
|
51
50
|
end
|
52
51
|
|
@@ -57,10 +56,11 @@ module Sapience
|
|
57
56
|
end
|
58
57
|
|
59
58
|
# Send an error notification to sentry
|
60
|
-
def log(log)
|
59
|
+
def log(log) # rubocop:disable AbcSize
|
61
60
|
return false unless should_log?(log)
|
62
61
|
|
63
62
|
context = formatter.call(log, self)
|
63
|
+
|
64
64
|
if log.exception
|
65
65
|
context.delete(:exception)
|
66
66
|
Raven.capture_exception(log.exception, context)
|
data/lib/sapience/base.rb
CHANGED
@@ -150,9 +150,8 @@ module Sapience
|
|
150
150
|
Sapience::Formatters::Default.new
|
151
151
|
end
|
152
152
|
|
153
|
-
|
154
|
-
|
155
|
-
Sapience.config.application
|
153
|
+
def app_name
|
154
|
+
Sapience.app_name
|
156
155
|
end
|
157
156
|
|
158
157
|
# Allow host name to be set globally or per subscriber
|
@@ -8,12 +8,11 @@ module Sapience
|
|
8
8
|
class Configuration
|
9
9
|
attr_reader :default_level, :backtrace_level, :backtrace_level_index
|
10
10
|
attr_writer :host
|
11
|
-
attr_accessor :
|
11
|
+
attr_accessor :app_name, :ap_options, :appenders, :log_executor
|
12
12
|
|
13
13
|
SUPPORTED_EXECUTORS = %i(single_thread_executor immediate_executor).freeze
|
14
14
|
DEFAULT = {
|
15
15
|
log_level: :info,
|
16
|
-
application: "Sapience",
|
17
16
|
host: nil,
|
18
17
|
ap_options: { multiline: false },
|
19
18
|
appenders: [{ stream: { io: STDOUT, formatter: :color } }],
|
@@ -28,8 +27,8 @@ module Sapience
|
|
28
27
|
validate_log_executor!(@options[:log_executor])
|
29
28
|
self.default_level = @options[:log_level].to_sym
|
30
29
|
self.backtrace_level = @options[:log_level].to_sym
|
31
|
-
self.application = @options[:application]
|
32
30
|
self.host = @options[:host]
|
31
|
+
self.app_name = @options[:app_name]
|
33
32
|
self.ap_options = @options[:ap_options]
|
34
33
|
self.appenders = @options[:appenders]
|
35
34
|
self.log_executor = @options[:log_executor]
|
@@ -4,7 +4,7 @@ module Sapience
|
|
4
4
|
class Raw < Base
|
5
5
|
# Returns log messages in Hash format
|
6
6
|
def call(log, logger)
|
7
|
-
log.to_h(log_host ? logger.host : nil, log_application ? logger.
|
7
|
+
log.to_h(log_host ? logger.host : nil, log_application ? logger.app_name : nil)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
data/lib/sapience/log.rb
CHANGED
@@ -153,7 +153,7 @@ module Sapience
|
|
153
153
|
end
|
154
154
|
|
155
155
|
# Returns [Hash] representation of this log entry
|
156
|
-
def to_h(host = Sapience.config.host,
|
156
|
+
def to_h(host = Sapience.config.host, app_name = Sapience.app_name) # rubocop:disable AbcSize, CyclomaticComplexity, PerceivedComplexity, LineLength
|
157
157
|
# Header
|
158
158
|
h = {
|
159
159
|
name: name,
|
@@ -163,9 +163,9 @@ module Sapience
|
|
163
163
|
level: level,
|
164
164
|
level_index: level_index,
|
165
165
|
}
|
166
|
-
h[:host]
|
167
|
-
h[:
|
168
|
-
file, line
|
166
|
+
h[:host] = host if host
|
167
|
+
h[:app_name] = app_name if app_name
|
168
|
+
file, line = file_name_and_line
|
169
169
|
if file
|
170
170
|
h[:file] = file
|
171
171
|
h[:line] = line.to_i
|
data/lib/sapience/sapience.rb
CHANGED
@@ -8,7 +8,7 @@ require "English"
|
|
8
8
|
# Sapience.configure do |config|
|
9
9
|
# config.default_level = ENV.fetch('SAPIENCE_DEFAULT_LEVEL') { :info }.to_sym
|
10
10
|
# config.backtrace_level = ENV.fetch('SAPIENCE_BACKTRACE_LEVEL') { :info }.to_sym
|
11
|
-
# config.
|
11
|
+
# config.app_name = 'TestApplication'
|
12
12
|
# config.host = ENV.fetch('SAPIENCE_HOST', nil)
|
13
13
|
# config.ap_options = { multiline: false }
|
14
14
|
# config.appenders = [
|
@@ -20,12 +20,18 @@ require "English"
|
|
20
20
|
|
21
21
|
# rubocop:disable ClassVars
|
22
22
|
module Sapience
|
23
|
-
UnknownClass
|
23
|
+
UnknownClass = Class.new(NameError)
|
24
|
+
AppNameMissing = Class.new(NameError)
|
25
|
+
TestException = Class.new(StandardError)
|
24
26
|
@@configured = false
|
25
27
|
|
26
28
|
# Logging levels in order of most detailed to most severe
|
27
29
|
LEVELS = [:trace, :debug, :info, :warn, :error, :fatal].freeze
|
28
|
-
DEFAULT_ENV
|
30
|
+
DEFAULT_ENV = "default".freeze
|
31
|
+
RACK_ENV = "RACK_ENV".freeze
|
32
|
+
RAILS_ENV = "RAILS_ENV".freeze
|
33
|
+
SAPIENCE_APP_NAME = "SAPIENCE_APP_NAME".freeze
|
34
|
+
SAPIENCE_ENV = "SAPIENCE_ENV".freeze
|
29
35
|
|
30
36
|
# TODO: Should we really always read from file?
|
31
37
|
# What if someone wants to configure sapience with a block
|
@@ -44,7 +50,9 @@ module Sapience
|
|
44
50
|
end
|
45
51
|
|
46
52
|
def self.default_options(options = {})
|
47
|
-
|
53
|
+
unless environment =~ /default|rspec/
|
54
|
+
warn "No configuration for environment #{environment}. Using 'default'"
|
55
|
+
end
|
48
56
|
options[DEFAULT_ENV]
|
49
57
|
end
|
50
58
|
|
@@ -52,6 +60,8 @@ module Sapience
|
|
52
60
|
@@config = nil
|
53
61
|
@@logger = nil
|
54
62
|
@@metrics = nil
|
63
|
+
@@environment = nil
|
64
|
+
@@app_name = nil
|
55
65
|
@@configured = false
|
56
66
|
clear_tags!
|
57
67
|
reset_appenders!
|
@@ -61,23 +71,56 @@ module Sapience
|
|
61
71
|
@@appenders = Concurrent::Array.new
|
62
72
|
end
|
63
73
|
|
74
|
+
# TODO: Default to SAPIENCE_ENV (if present it should be returned first)
|
64
75
|
def self.environment
|
65
|
-
|
66
|
-
ENV.fetch(
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
76
|
+
@@environment ||=
|
77
|
+
ENV.fetch(SAPIENCE_ENV) do
|
78
|
+
ENV.fetch(RAILS_ENV) do
|
79
|
+
ENV.fetch(RACK_ENV) do
|
80
|
+
if defined?(::Rails) && ::Rails.respond_to?(:env)
|
81
|
+
::Rails.env
|
82
|
+
else
|
83
|
+
warn "Sapience is going to use default configuration"
|
84
|
+
DEFAULT_ENV
|
85
|
+
end
|
86
|
+
end
|
72
87
|
end
|
73
88
|
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.app_name
|
92
|
+
@@app_name ||= begin
|
93
|
+
appname = ENV.fetch(SAPIENCE_APP_NAME) do
|
94
|
+
config.app_name
|
95
|
+
end
|
96
|
+
namify(appname)
|
74
97
|
end
|
75
98
|
end
|
76
99
|
|
100
|
+
def self.namify(appname, sep = "_")
|
101
|
+
return unless appname.is_a?(String)
|
102
|
+
return unless appname.length > 0
|
103
|
+
|
104
|
+
# Turn unwanted chars into the separator
|
105
|
+
appname = appname.dup
|
106
|
+
appname.gsub!(/[^a-z0-9\-_]+/i, sep)
|
107
|
+
unless sep.nil? || sep.empty?
|
108
|
+
re_sep = Regexp.escape(sep)
|
109
|
+
# No more than one of the separator in a row.
|
110
|
+
appname.gsub!(/#{re_sep}{2,}/, sep)
|
111
|
+
# Remove leading/trailing separator.
|
112
|
+
appname.gsub!(/^#{re_sep}|#{re_sep}$/, "")
|
113
|
+
end
|
114
|
+
appname.downcase
|
115
|
+
end
|
116
|
+
private_class_method :namify
|
117
|
+
|
118
|
+
|
77
119
|
# TODO: Maybe when configuring with a block we should create a new config?
|
78
120
|
# See the TODO note on .config for more information
|
79
121
|
def self.configure(force: false)
|
80
122
|
yield config if block_given?
|
123
|
+
fail AppNameMissing, "app_name is not configured. See documentation for more information" unless app_name
|
81
124
|
return config if configured? && force == false
|
82
125
|
reset_appenders!
|
83
126
|
add_appenders(*config.appenders)
|
@@ -249,7 +292,9 @@ module Sapience
|
|
249
292
|
end
|
250
293
|
|
251
294
|
def self.test_exception(level = :error)
|
252
|
-
Sapience
|
295
|
+
fail Sapience::TestException, "Sapience Test Exception"
|
296
|
+
rescue Sapience::TestException => ex
|
297
|
+
Sapience[self].public_send(level, ex)
|
253
298
|
end
|
254
299
|
|
255
300
|
# Wait until all queued log messages have been written and flush all active
|
data/lib/sapience/subscriber.rb
CHANGED
@@ -5,7 +5,7 @@ module Sapience
|
|
5
5
|
class Subscriber < Sapience::Base
|
6
6
|
# Every logger has its own formatter
|
7
7
|
attr_accessor :formatter
|
8
|
-
attr_writer :
|
8
|
+
attr_writer :app_name, :host
|
9
9
|
|
10
10
|
extend Sapience::Descendants
|
11
11
|
|
@@ -33,9 +33,9 @@ module Sapience
|
|
33
33
|
Sapience::Formatters::Default.new
|
34
34
|
end
|
35
35
|
|
36
|
-
# Allow
|
37
|
-
def
|
38
|
-
@
|
36
|
+
# Allow app_name to be set globally or per subscriber
|
37
|
+
def app_name
|
38
|
+
@app_name || Sapience.app_name
|
39
39
|
end
|
40
40
|
|
41
41
|
# Allow host name to be set globally or per subscriber
|
@@ -67,18 +67,18 @@ module Sapience
|
|
67
67
|
# Name of this host to appear in log messages.
|
68
68
|
# Default: Sapience.config.host
|
69
69
|
#
|
70
|
-
#
|
71
|
-
# Name of this
|
72
|
-
# Default: Sapience.
|
70
|
+
# app_name: [String]
|
71
|
+
# Name of this app_name to appear in log messages.
|
72
|
+
# Default: Sapience.app_name
|
73
73
|
def initialize(options = {}, &block)
|
74
74
|
# Backward compatibility
|
75
|
-
options
|
76
|
-
options
|
77
|
-
level
|
78
|
-
filter
|
79
|
-
@formatter
|
80
|
-
@
|
81
|
-
@host
|
75
|
+
options = { level: options } unless options.is_a?(Hash)
|
76
|
+
options = options.dup
|
77
|
+
level = options.delete(:level)
|
78
|
+
filter = options.delete(:filter)
|
79
|
+
@formatter = extract_formatter(options.delete(:formatter), &block)
|
80
|
+
@app_name = options.delete(:app_name)
|
81
|
+
@host = options.delete(:host)
|
82
82
|
fail(ArgumentError, "Unknown options: #{options.inspect}") if options.size > 0
|
83
83
|
|
84
84
|
# Subscribers don't take a class name, so use this class name if an subscriber
|
data/lib/sapience/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../../..
|
3
3
|
specs:
|
4
|
-
sapience (1.0.
|
4
|
+
sapience (1.0.1)
|
5
5
|
concurrent-ruby (~> 1.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -54,7 +54,7 @@ GEM
|
|
54
54
|
ice_nine (0.11.2)
|
55
55
|
json (1.8.3)
|
56
56
|
method_source (0.8.2)
|
57
|
-
minitest (5.9.
|
57
|
+
minitest (5.9.1)
|
58
58
|
multi_json (1.12.1)
|
59
59
|
multi_xml (0.5.5)
|
60
60
|
multipart-post (2.0.0)
|
@@ -137,4 +137,4 @@ DEPENDENCIES
|
|
137
137
|
simplecov-json
|
138
138
|
|
139
139
|
BUNDLED WITH
|
140
|
-
1.
|
140
|
+
1.13.1
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../../..
|
3
3
|
specs:
|
4
|
-
sapience (1.0.
|
4
|
+
sapience (1.0.1)
|
5
5
|
concurrent-ruby (~> 1.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -53,7 +53,7 @@ GEM
|
|
53
53
|
ice_nine (0.11.2)
|
54
54
|
json (2.0.2)
|
55
55
|
method_source (0.8.2)
|
56
|
-
minitest (5.9.
|
56
|
+
minitest (5.9.1)
|
57
57
|
multi_json (1.12.1)
|
58
58
|
multi_xml (0.5.5)
|
59
59
|
multipart-post (2.0.0)
|
@@ -134,4 +134,4 @@ DEPENDENCIES
|
|
134
134
|
simplecov-json
|
135
135
|
|
136
136
|
BUNDLED WITH
|
137
|
-
1.
|
137
|
+
1.13.1
|