slack_log_device 3.0.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.mdown +24 -1
- data/VERSION +1 -1
- data/lib/slack_log_device.rb +24 -23
- data/lib/slack_log_device/{rails_exceptions_logging.rb → debug_exceptions.rb} +1 -1
- data/lib/slack_log_device/formatter.rb +1 -1
- data/lib/slack_log_device/set_request_in_thread.rb +18 -0
- data/spec/slack_log_device/formatter_spec.rb +10 -2
- data/spec/slack_log_device_spec.rb +15 -28
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b8c2c4a011a4ba09610beb398cfb992ed65a2f7
|
4
|
+
data.tar.gz: 9499a0f40302d799977eeca879cdc1746cb557b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 517127197dfe3563a572c58c3b5ad7a628c8773fd29baada89188d6b0a37ebbe0ed80a6e9728881216801de9868dcc4746766fbcab54d9b442065a04c172f35e
|
7
|
+
data.tar.gz: b89dfd5dfca5b6fbcc1549a7527f7e5f763b228c6cf9db86221e93674043f0a078ed2a13323d44cfecf6405acc7fb4045343d5fa179fa0d3de1cdd13a338f47f
|
data/README.mdown
CHANGED
@@ -35,7 +35,8 @@ by default).
|
|
35
35
|
default). It can be a channel (if starting with `#`) or a specific user (if
|
36
36
|
starting with a `@`).
|
37
37
|
- `flush_delay`: The delay in seconds to send buffered messages (1 by default).
|
38
|
-
- `max_buffer_size`: The max
|
38
|
+
- `max_buffer_size`: The max messages count to flush them (10 messages by
|
39
|
+
default).
|
39
40
|
- `timeout`: The timeout in seconds to send message to slack (5 by default).
|
40
41
|
- `username`: The username to post message as (nil by default).
|
41
42
|
- `webhook_url`: The URL of the webhook (mandatory).
|
@@ -56,17 +57,39 @@ message, example:
|
|
56
57
|
logger.formatter = SlackLogDevice.formatter { |message| message.reverse }
|
57
58
|
```
|
58
59
|
|
60
|
+
You can also add custom metadata to message sent to slack, here is how to do
|
61
|
+
it:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
logger.formatter = SlackLogDevice.formatter(extra_metadata: {
|
65
|
+
'User' => -> (options) { ENV['USER'] },
|
66
|
+
'Machine' => `uname -a`,
|
67
|
+
})
|
68
|
+
```
|
69
|
+
|
70
|
+
If you use [Ruby on Rails](http://rubyonrails.org/), you will get some
|
71
|
+
metadata like current HTTP method, URL, remote address and User-Agent (see
|
72
|
+
Rails configuration section).
|
73
|
+
|
74
|
+
If you need more, use `:extra_metadata` option. Note that blocks specified
|
75
|
+
with `:extra_metadata` option are invoked with options that may contains
|
76
|
+
`:request` option (if present).
|
77
|
+
|
59
78
|
## Rails configuration
|
60
79
|
|
61
80
|
For a rails application, it is recommanded to use following configuration into
|
62
81
|
`config/environments/production.rb` file:
|
63
82
|
|
64
83
|
```ruby
|
84
|
+
SlackLogDevice.enable_rails_logging!
|
65
85
|
config.logger = ActiveSupport::Logger.new(SlackLogDevice.new(webhook_url: 'https://hooks.slack.com/services/...', username: 'MyRailsApp'))
|
66
86
|
config.logger.formatter = SlackLogDevice::FORMATTER
|
67
87
|
config.log_level = :warn
|
68
88
|
```
|
69
89
|
|
90
|
+
`SlackLogDevice.enable_rails_logging!` instruction put current request into
|
91
|
+
thread in order to make it available by slack formatter.
|
92
|
+
|
70
93
|
## Executing test suite
|
71
94
|
|
72
95
|
This project is fully tested with [Rspec 3](http://github.com/rspec/rspec).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4.0.0
|
data/lib/slack_log_device.rb
CHANGED
@@ -7,19 +7,26 @@ class SlackLogDevice
|
|
7
7
|
|
8
8
|
attr_reader :channel, :flush_delay, :max_buffer_size, :timeout, :username, :webhook_url
|
9
9
|
|
10
|
+
def self.enable_rails_logging!
|
11
|
+
require 'slack_log_device/debug_exceptions'
|
12
|
+
require 'slack_log_device/set_request_in_thread'
|
13
|
+
ActionDispatch::DebugExceptions.prepend(SlackLogDevice::DebugExceptions)
|
14
|
+
Rails.application.config.middleware.insert_before(Rails::Rack::Logger, SlackLogDevice::SetRequestInThread)
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
10
18
|
def self.formatter(options = {}, &block)
|
11
19
|
Formatter.new(options, &block)
|
12
20
|
end
|
13
21
|
|
14
22
|
def initialize(options = {})
|
15
23
|
options.assert_valid_keys(:auto_flush, :channel, :flush_delay, :max_buffer_size, :timeout, :username, :webhook_url)
|
16
|
-
@buffer =
|
24
|
+
@buffer = []
|
17
25
|
@mutex = Mutex.new
|
18
|
-
@flush_thread
|
19
26
|
self.auto_flush = options[:auto_flush]
|
20
27
|
self.channel = options[:channel]
|
21
28
|
self.flush_delay = options.key?(:flush_delay) ? options[:flush_delay] : 1
|
22
|
-
self.max_buffer_size = options.key?(:max_buffer_size) ? options[:max_buffer_size] :
|
29
|
+
self.max_buffer_size = options.key?(:max_buffer_size) ? options[:max_buffer_size] : 10
|
23
30
|
self.timeout = options.key?(:timeout) ? options[:timeout] : 5
|
24
31
|
self.username = options[:username]
|
25
32
|
self.webhook_url = options[:webhook_url]
|
@@ -44,25 +51,25 @@ class SlackLogDevice
|
|
44
51
|
end
|
45
52
|
|
46
53
|
def flush
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
54
|
+
while !@buffer.empty? do
|
55
|
+
message = ''
|
56
|
+
@mutex.synchronize do
|
57
|
+
message = @buffer.pop
|
58
|
+
end
|
59
|
+
data = { 'text' => message.to_s }
|
60
|
+
data['channel'] = channel if channel.present?
|
61
|
+
data['username'] = username if username.present?
|
62
|
+
begin
|
63
|
+
HTTParty.post(webhook_url, body: data.to_json, headers: { 'Content-Type' => 'application/json' }, timeout: timeout)
|
64
|
+
rescue Exception => e
|
65
|
+
STDERR.puts(e)
|
66
|
+
end
|
60
67
|
end
|
61
68
|
nil
|
62
69
|
end
|
63
70
|
|
64
71
|
def flush?
|
65
|
-
auto_flush? || flush_delay.zero? || @buffer.
|
72
|
+
auto_flush? || flush_delay.zero? || @buffer.size > max_buffer_size
|
66
73
|
end
|
67
74
|
|
68
75
|
def flush_delay=(value)
|
@@ -98,7 +105,6 @@ class SlackLogDevice
|
|
98
105
|
message = message.to_s.try(:strip)
|
99
106
|
return if message.blank?
|
100
107
|
@mutex.synchronize do
|
101
|
-
@buffer << "\n" unless @buffer.empty?
|
102
108
|
@buffer << message
|
103
109
|
end
|
104
110
|
@flush_thread.kill if @flush_thread
|
@@ -115,9 +121,4 @@ class SlackLogDevice
|
|
115
121
|
|
116
122
|
end
|
117
123
|
|
118
|
-
require 'slack_log_device/rails_exceptions_logging'
|
119
124
|
require 'slack_log_device/formatter'
|
120
|
-
|
121
|
-
if defined?(ActionDispatch::DebugExceptions)
|
122
|
-
ActionDispatch::DebugExceptions.prepend(SlackLogDevice::RailsExceptionsLogging)
|
123
|
-
end
|
@@ -72,7 +72,7 @@ class SlackLogDevice
|
|
72
72
|
return nil if size_available < 11
|
73
73
|
options = {}
|
74
74
|
options[:exception] = message if message.is_a?(Exception)
|
75
|
-
request =
|
75
|
+
request = Thread.current[:slack_log_device_request]
|
76
76
|
options[:request] = request if request.present?
|
77
77
|
text = default_metadata(request).merge(extra_metadata).map do |name, value|
|
78
78
|
value = value.call(options) if value.respond_to?(:call)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'action_dispatch/http/request'
|
2
|
+
|
3
|
+
class SlackLogDevice
|
4
|
+
|
5
|
+
class SetRequestInThread
|
6
|
+
|
7
|
+
def initialize(app)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
Thread.current[:slack_log_device_request] = ActionDispatch::Request.new(env)
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -237,12 +237,20 @@ describe SlackLogDevice::Formatter do
|
|
237
237
|
|
238
238
|
end
|
239
239
|
|
240
|
-
context 'with
|
240
|
+
context 'with request set in current thread' do
|
241
241
|
|
242
|
-
let(:exception) { RuntimeError.new('BAM!')
|
242
|
+
let(:exception) { RuntimeError.new('BAM!') }
|
243
243
|
let(:formatter) { SlackLogDevice::Formatter.new }
|
244
244
|
let(:request) { double(remote_addr: '127.0.0.1', user_agent: 'Mozilla', method: 'GET', url: 'http://google.com') }
|
245
245
|
|
246
|
+
before :each do
|
247
|
+
Thread.current[:slack_log_device_request] = request
|
248
|
+
end
|
249
|
+
|
250
|
+
after :each do
|
251
|
+
Thread.current[:slack_log_device_request] = nil
|
252
|
+
end
|
253
|
+
|
246
254
|
it 'logs metadata' do
|
247
255
|
expect(formatter.call('DEBUG', Time.now, nil, exception)).to eq("*`DEBUG`*: A `RuntimeError` occurred: BAM!\n\n• *Method*: `GET`\n• *URL*: `http://google.com`\n• *Remote address*: `127.0.0.1`\n• *User-Agent*: `Mozilla`")
|
248
256
|
end
|
@@ -146,7 +146,7 @@ describe SlackLogDevice do
|
|
146
146
|
it 'flushes all message writen separated by a new line' do
|
147
147
|
device.write('BAM!')
|
148
148
|
device.write('BIM!')
|
149
|
-
expect(HTTParty).to receive(:post).
|
149
|
+
expect(HTTParty).to receive(:post).twice
|
150
150
|
device.flush
|
151
151
|
end
|
152
152
|
|
@@ -160,7 +160,7 @@ describe SlackLogDevice do
|
|
160
160
|
device.write('BIM!')
|
161
161
|
expect {
|
162
162
|
device.flush
|
163
|
-
}.to change { device.instance_variable_get(:@buffer) }.to(
|
163
|
+
}.to change { device.instance_variable_get(:@buffer) }.to([])
|
164
164
|
expect(HTTParty).not_to receive(:post)
|
165
165
|
device.flush
|
166
166
|
end
|
@@ -170,18 +170,11 @@ describe SlackLogDevice do
|
|
170
170
|
describe '#flush?' do
|
171
171
|
|
172
172
|
it 'is true if max_buffer_size is reached' do
|
173
|
-
options[:max_buffer_size] =
|
174
|
-
device.write('
|
173
|
+
options[:max_buffer_size] = 2
|
174
|
+
device.write('hello')
|
175
|
+
device.write('world')
|
175
176
|
expect {
|
176
|
-
device.instance_variable_get(:@buffer).send(:<<, '
|
177
|
-
}.to change { device.flush? }.from(false).to(true)
|
178
|
-
end
|
179
|
-
|
180
|
-
it 'use byte size to compare max_buffer_size' do
|
181
|
-
options[:max_buffer_size] = 10
|
182
|
-
device.write('01234567é')
|
183
|
-
expect {
|
184
|
-
device.instance_variable_get(:@buffer).send(:<<, 'a')
|
177
|
+
device.instance_variable_get(:@buffer).send(:<<, 'foo')
|
185
178
|
}.to change { device.flush? }.from(false).to(true)
|
186
179
|
end
|
187
180
|
|
@@ -197,12 +190,6 @@ describe SlackLogDevice do
|
|
197
190
|
}.to change { device.flush? }.from(false).to(true)
|
198
191
|
end
|
199
192
|
|
200
|
-
it 'is true if it contains markdown code block' do
|
201
|
-
expect {
|
202
|
-
device.instance_variable_get(:@buffer).send(:<<, '```hello world```')
|
203
|
-
}.to change { device.flush? }.from(false).to(true)
|
204
|
-
end
|
205
|
-
|
206
193
|
end
|
207
194
|
|
208
195
|
describe '#flush_delay' do
|
@@ -279,8 +266,8 @@ describe SlackLogDevice do
|
|
279
266
|
|
280
267
|
describe '#max_buffer_size' do
|
281
268
|
|
282
|
-
it 'is
|
283
|
-
expect(device.max_buffer_size).to eq(
|
269
|
+
it 'is 10 by default' do
|
270
|
+
expect(device.max_buffer_size).to eq(10)
|
284
271
|
end
|
285
272
|
|
286
273
|
it 'can be specified' do
|
@@ -327,8 +314,8 @@ describe SlackLogDevice do
|
|
327
314
|
|
328
315
|
it 'can be set' do
|
329
316
|
expect {
|
330
|
-
device.max_buffer_size =
|
331
|
-
}.to change { device.max_buffer_size }.from(
|
317
|
+
device.max_buffer_size = 42
|
318
|
+
}.to change { device.max_buffer_size }.from(10).to(42)
|
332
319
|
end
|
333
320
|
|
334
321
|
end
|
@@ -466,19 +453,19 @@ describe SlackLogDevice do
|
|
466
453
|
|
467
454
|
it 'strips message' do
|
468
455
|
device.write(" BAM !\n")
|
469
|
-
expect(device.instance_variable_get(:@buffer)).to eq('BAM !')
|
456
|
+
expect(device.instance_variable_get(:@buffer)).to eq(['BAM !'])
|
470
457
|
end
|
471
458
|
|
472
459
|
it 'converts message to string' do
|
473
460
|
device.write(42)
|
474
|
-
expect(device.instance_variable_get(:@buffer)).to eq('42')
|
461
|
+
expect(device.instance_variable_get(:@buffer)).to eq(['42'])
|
475
462
|
end
|
476
463
|
|
477
|
-
it 'adds given string to existing buffer with a \n' do
|
464
|
+
it 'adds given string to existing buffer with a two \n' do
|
478
465
|
device.write('BAM!')
|
479
466
|
expect {
|
480
467
|
device.write('BIM!')
|
481
|
-
}.to change { device.instance_variable_get(:@buffer) }.from('BAM!').to(
|
468
|
+
}.to change { device.instance_variable_get(:@buffer) }.from(['BAM!']).to(['BAM!', 'BIM!'])
|
482
469
|
end
|
483
470
|
|
484
471
|
it 'does nothing if message is blank' do
|
@@ -491,7 +478,7 @@ describe SlackLogDevice do
|
|
491
478
|
it 'does nothing if message is nil' do
|
492
479
|
expect(HTTParty).not_to receive(:post)
|
493
480
|
expect(device.write(nil)).to be_nil
|
494
|
-
expect(device.instance_variable_get(:@buffer)).to eq(
|
481
|
+
expect(device.instance_variable_get(:@buffer)).to eq([])
|
495
482
|
end
|
496
483
|
|
497
484
|
it 'does not post HTTP message if auto flush is false' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slack_log_device
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Toulotte
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -124,8 +124,9 @@ files:
|
|
124
124
|
- Rakefile
|
125
125
|
- VERSION
|
126
126
|
- lib/slack_log_device.rb
|
127
|
+
- lib/slack_log_device/debug_exceptions.rb
|
127
128
|
- lib/slack_log_device/formatter.rb
|
128
|
-
- lib/slack_log_device/
|
129
|
+
- lib/slack_log_device/set_request_in_thread.rb
|
129
130
|
- slack_log_device.gemspec
|
130
131
|
- spec/slack_log_device/formatter_spec.rb
|
131
132
|
- spec/slack_log_device_spec.rb
|