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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7da84e6d177382ef3698ba25b1cafddfd7e41e9d
4
- data.tar.gz: 9643a365bff66ea7ea8219d38c73dcad7166185e
3
+ metadata.gz: 2b8c2c4a011a4ba09610beb398cfb992ed65a2f7
4
+ data.tar.gz: 9499a0f40302d799977eeca879cdc1746cb557b5
5
5
  SHA512:
6
- metadata.gz: a25cdda1fa68d846b11405ade1d656b0b0d349db2faa3c798290643ae58e78cd878e81eec53cfb204ceececdfc2a31a75b1561d8394d1450cf29f05e0e552f32
7
- data.tar.gz: 44c2fda8c1c618aee82cd46fc6a6bf48445826290048fd269817da57daa34ddbc54a9e4a954e99069f35c794f628a111e86b26a0a120b2b6cadd4eaf4c751aaa
6
+ metadata.gz: 517127197dfe3563a572c58c3b5ad7a628c8773fd29baada89188d6b0a37ebbe0ed80a6e9728881216801de9868dcc4746766fbcab54d9b442065a04c172f35e
7
+ data.tar.gz: b89dfd5dfca5b6fbcc1549a7527f7e5f763b228c6cf9db86221e93674043f0a078ed2a13323d44cfecf6405acc7fb4045343d5fa179fa0d3de1cdd13a338f47f
@@ -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 buffer size to flush messages (8192 by default).
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
- 3.0.0
1
+ 4.0.0
@@ -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] : 1024 * 128
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
- return if @buffer.empty?
48
- message = ''
49
- @mutex.synchronize do
50
- message = @buffer
51
- @buffer = ''
52
- end
53
- data = { 'text' => message.to_s }
54
- data['channel'] = channel if channel.present?
55
- data['username'] = username if username.present?
56
- begin
57
- HTTParty.post(webhook_url, body: data.to_json, headers: { 'Content-Type' => 'application/json' }, timeout: timeout)
58
- rescue Exception => e
59
- STDERR.puts(e)
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.bytesize > max_buffer_size || @buffer.include?('```')
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
@@ -1,6 +1,6 @@
1
1
  class SlackLogDevice
2
2
 
3
- module RailsExceptionsLogging
3
+ module DebugExceptions
4
4
 
5
5
  def log_error(request, wrapper)
6
6
  logger = logger(request)
@@ -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 = options[:exception].present? ? options[:exception].instance_variable_get(:@__slack_log_device_request) : nil
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 an exception with @__slack_log_device_request set' do
240
+ context 'with request set in current thread' do
241
241
 
242
- let(:exception) { RuntimeError.new('BAM!').tap { |e| e.instance_variable_set(:@__slack_log_device_request, request) } }
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).with(options[:webhook_url], body: { 'text' => "BAM!\nBIM!", 'username' => options[:username] }.to_json, headers: { 'Content-Type' => 'application/json' }, timeout: 5)
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] = 10
174
- device.write('0123456789')
173
+ options[:max_buffer_size] = 2
174
+ device.write('hello')
175
+ device.write('world')
175
176
  expect {
176
- device.instance_variable_get(:@buffer).send(:<<, 'a')
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 128 kilobytes by default' do
283
- expect(device.max_buffer_size).to eq(1024 * 128)
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 = 1024
331
- }.to change { device.max_buffer_size }.from(1024 * 128).to(1024)
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("BAM!\nBIM!")
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: 3.0.0
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-26 00:00:00.000000000 Z
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/rails_exceptions_logging.rb
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