slack_log_device 3.0.0 → 4.0.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.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
|