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 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