logstash-logger 0.25.1 → 0.26.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: '02946cc68ecd472a33ee4e20c8b0f9676a35c31e'
4
- data.tar.gz: 22ebacf159993cebd61ec2f2069c5d35ccb5949e
3
+ metadata.gz: 2f81edad89b077de5fa36b1b1291f6b0d1c66761
4
+ data.tar.gz: 9834bb9837f9b9d6672f6a24b0325e3d2d9098ef
5
5
  SHA512:
6
- metadata.gz: d19465ebd83bb4a0710eac75face6c11287c5737fc8683e79e5b725cd81933082d123d0bcf220ab49b267c693b98f6bffc5300c7c6ceae7a0ad7b350654c3fe6
7
- data.tar.gz: f1be1a3735cd768d7c53b5d9cdddb34a3fde4e76d0cc6b770f731a70cd5129d1278bd21017634c9af25c99593d7f006d3d9ed2646a4faf7c84e8e454b85a00d8
6
+ metadata.gz: 49afad48b880a4c98156de108ad9f3105ed3ecf72e38d24987d08027d56ecdc2147c4b46fe0fb9d59799fdfbf44af7218e70e9185470f0f046e89921976afed1
7
+ data.tar.gz: 7274f69bc942ee4c2597682cde7f818c6da371bc58108ef56b2e3002b854e7142f241529003f5ed4f7c2001b35364e23f62572b70430ef9971131088c44a7b71
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 0.26.0
2
+
3
+ - Allow user configuration of the logger class. [#129](https://github.com/dwbutler/logstash-logger/pull/129)
4
+ - Fix: Allow type to be a string for multi_logger and syslog. [#131](https://github.com/dwbutler/logstash-logger/pull/131)
5
+ - Fix: Cancelled events are being logged. [#133](https://github.com/dwbutler/logstash-logger/issues/133)
6
+ - Fix: Expose method to reset logger state. [#138](https://github.com/dwbutler/logstash-logger/pull/138)
7
+ - Use specific AWS SDK gems. [#136](https://github.com/dwbutler/logstash-logger/pull/136)
8
+ - Adds support for using the default AWS credential provider chain. [#141](https://github.com/dwbutler/logstash-logger/pull/141)
9
+
1
10
  ## 0.25.1
2
11
 
3
12
  - Skip message truncating when there is no message field. [#130](https://github.com/dwbutler/logstash-logger/pull/130)
data/README.md CHANGED
@@ -399,6 +399,15 @@ logger.silence(temporary_level) do
399
399
  end
400
400
  ```
401
401
 
402
+ ## Custom Logger Class
403
+
404
+ By default, LogStashLogger creates a logger that extends Ruby's built in `Logger` class.
405
+ If you require a different logger implementation, you can use a different class
406
+ by passing in the class with the `logger_class` option.
407
+
408
+ Note that for syslog, the `Syslog::Logger` class is required and cannot be
409
+ changed.
410
+
402
411
  ## Rails Integration
403
412
 
404
413
  Supports Rails 4 and 5.
@@ -559,6 +568,10 @@ config.logstash.backoff = 1
559
568
 
560
569
  Add the aws-sdk gem to your Gemfile:
561
570
 
571
+ # aws-sdk >= 3.0
572
+ gem 'aws-sdk-kinesis'
573
+
574
+ # aws-sdk < 3.0
562
575
  gem 'aws-sdk'
563
576
 
564
577
  ```ruby
@@ -583,6 +596,10 @@ config.logstash.aws_secret_access_key = 'ASKASKHLD1234123412341234'
583
596
 
584
597
  Add the aws-sdk gem to your Gemfile:
585
598
 
599
+ # aws-sdk >= 3.0
600
+ gem 'aws-sdk-firehose'
601
+
602
+ # aws-sdk < 3.0
586
603
  gem 'aws-sdk'
587
604
 
588
605
  ```ruby
@@ -592,13 +609,13 @@ config.logstash.type = :firehose
592
609
  # Optional, will default to the 'logstash' delivery stream
593
610
  config.logstash.stream = 'my-stream-name'
594
611
 
595
- # Optional, will default to 'us-east-1'
612
+ # Optional, will default to AWS default region config chain
596
613
  config.logstash.aws_region = 'us-west-2'
597
614
 
598
- # Optional, will default to the AWS_ACCESS_KEY_ID environment variable
615
+ # Optional, will default to AWS default credential provider chain
599
616
  config.logstash.aws_access_key_id = 'ASKASKHLD12341'
600
617
 
601
- # Optional, will default to the AWS_SECRET_ACCESS_KEY environment variable
618
+ # Optional, will default to AWS default credential provider chain
602
619
  config.logstash.aws_secret_access_key = 'ASKASKHLD1234123412341234'
603
620
 
604
621
  ```
@@ -693,6 +710,36 @@ def track_load_balancer_session_id
693
710
  end
694
711
  ```
695
712
 
713
+ ## Cleaning up resources when forking
714
+
715
+ If your application forks (as is common with many web servers) you will need to
716
+ manage cleaning up resources on your LogStashLogger instances. The instance method
717
+ `#reset` is available for this purpose. Here is sample configuration for
718
+ several common web servers used with Rails:
719
+
720
+ Passenger:
721
+ ```ruby
722
+ ::PhusionPassenger.on_event(:starting_worker_process) do |forked|
723
+ Rails.logger.reset
724
+ end
725
+ ```
726
+
727
+ Puma:
728
+ ```ruby
729
+ # In config/puma.rb
730
+ on_worker_boot do
731
+ Rails.logger.reset
732
+ end
733
+ ```
734
+
735
+ Unicorn
736
+ ```ruby
737
+ # In config/unicorn.rb
738
+ after_fork do |server, worker|
739
+ Rails.logger.reset
740
+ end
741
+ ```
742
+
696
743
  ## Ruby Compatibility
697
744
 
698
745
  Verified to work with:
@@ -818,6 +865,11 @@ logger = LogStashLogger.new('localhost', 5228, :tcp)
818
865
  * [Joao Fernandes](https://github.com/jcmfernandes)
819
866
  * [CoolElvis](https://github.com/coolelvis)
820
867
  * [Sergey Pyankov](https://github.com/esergion)
868
+ * [Alec Hoey](https://github.com/alechoey)
869
+ * [Alexey Krasnoperov](https://github.com/AlexeyKrasnoperov)
870
+ * [Gabriel de Oliveira](https://github.com/gdeoliveira)
871
+ * [Vladislav Syabruk](https://github.com/SeTeM)
872
+ * [Matus Vacula](https://github.com/matus-vacula)
821
873
 
822
874
  ## Contributing
823
875
 
@@ -107,6 +107,8 @@ module LogStashLogger
107
107
  end
108
108
 
109
109
  def reset_buffer
110
+ reset_flush_timer_thread
111
+
110
112
  @buffer_state = {
111
113
  # items accepted from including class
112
114
  :pending_items => {},
@@ -127,7 +129,6 @@ module LogStashLogger
127
129
  :timer => flush_timer_thread
128
130
  }
129
131
 
130
-
131
132
  # events we've accumulated
132
133
  buffer_clear_pending
133
134
  end
@@ -305,6 +306,13 @@ module LogStashLogger
305
306
  end
306
307
  end
307
308
 
309
+ def reset_flush_timer_thread
310
+ unless @flush_timer_thread.nil?
311
+ @flush_timer_thread.kill
312
+ @flush_timer_thread = nil
313
+ end
314
+ end
315
+
308
316
  def buffer_clear_pending
309
317
  @buffer_state[:pending_items] = Hash.new { |h, k| h[k] = [] }
310
318
  @buffer_state[:pending_count] = 0
@@ -1,10 +1,13 @@
1
- require 'aws-sdk'
1
+ begin
2
+ require 'aws-sdk-core'
3
+ rescue LoadError
4
+ require 'aws-sdk'
5
+ end
2
6
 
3
7
  module LogStashLogger
4
8
  module Device
5
9
  class AwsStream < Connectable
6
10
 
7
- DEFAULT_REGION = 'us-east-1'
8
11
  DEFAULT_STREAM = 'logstash'
9
12
 
10
13
  @stream_class = nil
@@ -18,9 +21,9 @@ module LogStashLogger
18
21
 
19
22
  def initialize(opts)
20
23
  super
21
- @access_key_id = opts[:aws_access_key_id] || ENV['AWS_ACCESS_KEY_ID']
22
- @secret_access_key = opts[:aws_secret_access_key] || ENV['AWS_SECRET_ACCESS_KEY']
23
- @aws_region = opts[:aws_region] || DEFAULT_REGION
24
+ @access_key_id = opts[:aws_access_key_id]
25
+ @secret_access_key = opts[:aws_secret_access_key]
26
+ @aws_region = opts[:aws_region]
24
27
  @stream = opts[:stream] || DEFAULT_STREAM
25
28
  end
26
29
 
@@ -41,10 +44,10 @@ module LogStashLogger
41
44
  end
42
45
 
43
46
  def connect
44
- @io = self.class.stream_class.new(
45
- region: @aws_region,
46
- credentials: ::Aws::Credentials.new(@access_key_id, @secret_access_key)
47
- )
47
+ client_opts = {}
48
+ client_opts[:credentials] = Aws::Credentials.new(@access_key_id, @secret_access_key) unless @access_key_id == nil || @secret_access_key == nil
49
+ client_opts[:region] = @aws_region unless @aws_region == nil
50
+ @io = self.class.stream_class.new(client_opts)
48
51
  end
49
52
 
50
53
  def with_connection
@@ -15,7 +15,7 @@ module LogStashLogger
15
15
  end
16
16
 
17
17
  def write(message)
18
- write_one(message)
18
+ write_one(message) unless message.nil?
19
19
  end
20
20
 
21
21
  def write_one(message)
@@ -39,6 +39,10 @@ module LogStashLogger
39
39
  @io && @io.flush
40
40
  end
41
41
 
42
+ def reset
43
+ close
44
+ end
45
+
42
46
  def close(opts = {})
43
47
  close!
44
48
  rescue => e
@@ -56,7 +56,7 @@ module LogStashLogger
56
56
  end
57
57
 
58
58
  def write(message)
59
- buffer_receive message, @buffer_group
59
+ buffer_receive(message, @buffer_group) unless message.nil?
60
60
  end
61
61
 
62
62
  def flush(*args)
@@ -107,6 +107,11 @@ module LogStashLogger
107
107
  fail NotImplementedError
108
108
  end
109
109
 
110
+ def reset
111
+ reset_buffer
112
+ close(flush: false)
113
+ end
114
+
110
115
  def reconnect
111
116
  close(flush: false)
112
117
  connect
@@ -1,4 +1,9 @@
1
- require 'aws-sdk'
1
+ begin
2
+ require 'aws-sdk-firehose'
3
+ rescue LoadError
4
+ require 'aws-sdk'
5
+ end
6
+
2
7
  require 'logstash-logger/device/aws_stream'
3
8
 
4
9
  module LogStashLogger
@@ -1,4 +1,9 @@
1
- require 'aws-sdk'
1
+ begin
2
+ require 'aws-sdk-kinesis'
3
+ rescue LoadError
4
+ require 'aws-sdk'
5
+ end
6
+
2
7
  require 'logstash-logger/device/aws_stream'
3
8
 
4
9
  module LogStashLogger
@@ -14,11 +14,12 @@ module LogStashLogger
14
14
  super()
15
15
  end
16
16
 
17
- def call(severity, time, progname, message)
18
- @event = build_event(message, severity, time)
17
+ def call(severity, time, _progname, message)
18
+ event = build_event(message, severity, time)
19
+ format_event(event) unless event.cancelled?
19
20
  end
20
21
 
21
- protected
22
+ private
22
23
 
23
24
  def build_event(message, severity, time)
24
25
  data = message
@@ -63,6 +64,10 @@ module LogStashLogger
63
64
 
64
65
  event
65
66
  end
67
+
68
+ def format_event(event)
69
+ event
70
+ end
66
71
  end
67
72
  end
68
73
  end
@@ -1,9 +1,10 @@
1
1
  module LogStashLogger
2
2
  module Formatter
3
3
  class Cee < Base
4
- def call(severity, time, progname, message)
5
- super
6
- "@cee:#{@event.to_json}"
4
+ private
5
+
6
+ def format_event(event)
7
+ "@cee:#{event.to_json}"
7
8
  end
8
9
  end
9
10
  end
@@ -2,18 +2,20 @@ module LogStashLogger
2
2
  module Formatter
3
3
  class CeeSyslog < Cee
4
4
  def call(severity, time, progname, message)
5
- @cee = super
6
5
  @progname = progname
7
-
8
- "#{facility}:#{@cee}\n"
6
+ super
9
7
  end
10
8
 
11
- protected
9
+ private
10
+
11
+ def build_facility(host)
12
+ facility = host.dup
13
+ facility << " #{@progname}" if @progname
14
+ facility
15
+ end
12
16
 
13
- def facility
14
- @facility = "#{@event['host']}"
15
- @facility << " #{@progname}" if @progname
16
- @facility
17
+ def format_event(event)
18
+ "#{build_facility(event["host".freeze])}:#{super}\n"
17
19
  end
18
20
  end
19
21
  end
@@ -1,9 +1,10 @@
1
1
  module LogStashLogger
2
2
  module Formatter
3
3
  class Json < Base
4
- def call(severity, time, progname, message)
5
- super
6
- @event.to_json
4
+ private
5
+
6
+ def format_event(event)
7
+ event.to_json
7
8
  end
8
9
  end
9
10
  end
@@ -1,9 +1,10 @@
1
1
  module LogStashLogger
2
2
  module Formatter
3
3
  class JsonLines < Base
4
- def call(severity, time, progname, message)
5
- super
6
- "#{@event.to_json}\n"
4
+ private
5
+
6
+ def format_event(event)
7
+ "#{event.to_json}\n"
7
8
  end
8
9
  end
9
10
  end
@@ -1,9 +1,6 @@
1
1
  module LogStashLogger
2
2
  module Formatter
3
3
  class LogStashEvent < Base
4
- def call(severity, time, progname, message)
5
- super
6
- end
7
4
  end
8
5
  end
9
6
  end
@@ -19,6 +19,10 @@ module LogStashLogger
19
19
  def flush
20
20
  !!(@device.flush if @device.respond_to?(:flush))
21
21
  end
22
+
23
+ def reset
24
+ @device.reset if @device.respond_to?(:reset)
25
+ end
22
26
  end
23
27
  end
24
28
 
@@ -48,7 +52,8 @@ module LogStashLogger
48
52
  def self.build_logger(opts)
49
53
  formatter = Formatter.new(opts.delete(:formatter), customize_event: opts.delete(:customize_event))
50
54
 
51
- logger = case opts[:type]
55
+ logger_type = opts[:type].to_s.to_sym
56
+ logger = case logger_type
52
57
  when :multi_logger
53
58
  build_multi_logger(opts)
54
59
  when :syslog
@@ -64,8 +69,9 @@ module LogStashLogger
64
69
  private
65
70
 
66
71
  def self.build_default_logger(opts)
72
+ logger_class = opts.delete(:logger_class) || ::Logger
67
73
  device = Device.new(opts)
68
- ::Logger.new(device).tap do |logger|
74
+ logger_class.new(device).tap do |logger|
69
75
  logger.instance_variable_set(:@device, device)
70
76
  extend_logger(logger)
71
77
  end
@@ -1,3 +1,3 @@
1
1
  module LogStashLogger
2
- VERSION = "0.25.1"
2
+ VERSION = "0.26.0"
3
3
  end
@@ -34,4 +34,5 @@ Gem::Specification.new do |gem|
34
34
  gem.add_development_dependency 'pry'
35
35
  gem.add_development_dependency 'wwtd'
36
36
  gem.add_development_dependency 'appraisal'
37
+ gem.add_development_dependency 'rubocop'
37
38
  end
@@ -1,22 +1,30 @@
1
1
  require 'logstash-logger'
2
2
 
3
3
  describe LogStashLogger do
4
- describe ".new" do
5
- it "returns a Logger instance" do
4
+ describe '.new' do
5
+ it 'returns a Logger instance' do
6
6
  expect(LogStashLogger.new(type: :stdout)).to be_a ::Logger
7
7
  end
8
8
 
9
- context "type: :multi_logger" do
9
+ context 'type: :multi_logger' do
10
10
  it "returns an instance of LogStashLogger::MultiLogger" do
11
11
  expect(LogStashLogger.new(type: :multi_logger)).to be_a LogStashLogger::MultiLogger
12
12
  end
13
13
 
14
- it "merges top level configuration into each logger" do
14
+ it 'merges top level configuration into each logger' do
15
15
  logger = LogStashLogger.new(type: :multi_logger, port: 1234, outputs: [ { type: :tcp }, { type: :udp } ])
16
16
  logger.loggers.each do |logger|
17
17
  expect(logger.device.port).to eq(1234)
18
18
  end
19
19
  end
20
20
  end
21
+
22
+ context 'logger_class: CustomLogger' do
23
+ class CustomLogger < Logger; end
24
+
25
+ it 'should create a logger of the specified class' do
26
+ expect(LogStashLogger.new(type: :stdout, :logger_class => CustomLogger)).to be_a CustomLogger
27
+ end
28
+ end
21
29
  end
22
30
  end
@@ -1,6 +1,6 @@
1
1
  require 'logstash-logger'
2
2
 
3
- describe LogStashLogger::Device::Kinesis do
3
+ describe LogStashLogger::Device::Firehose do
4
4
  include_context 'device'
5
5
 
6
6
  let(:client) { double("Aws::Firehose::Client") }
@@ -35,10 +35,6 @@ describe LogStashLogger::Device::Kinesis do
35
35
  firehose_device.write_one "foo"
36
36
  end
37
37
 
38
- it "defaults the AWS region to us-east-1" do
39
- expect(firehose_device.aws_region).to eq('us-east-1')
40
- end
41
-
42
38
  it "defaults the Firehose stream to logstash" do
43
39
  expect(firehose_device.stream).to eq('logstash')
44
40
  end
@@ -35,10 +35,6 @@ describe LogStashLogger::Device::Kinesis do
35
35
  kinesis_device.write_one "foo"
36
36
  end
37
37
 
38
- it "defaults the AWS region to us-east-1" do
39
- expect(kinesis_device.aws_region).to eq('us-east-1')
40
- end
41
-
42
38
  it "defaults the kinesis stream to logstash" do
43
39
  expect(kinesis_device.stream).to eq('logstash')
44
40
  end
@@ -3,6 +3,28 @@ require 'logstash-logger'
3
3
  describe LogStashLogger::Formatter::Base do
4
4
  include_context "formatter"
5
5
 
6
+ describe "#call" do
7
+ context "when event is not cancelled" do
8
+ it "returns a formatted message" do
9
+ expect(subject).to receive(:format_event).once.with(instance_of(LogStash::Event)).and_call_original
10
+ expect(subject.call(severity, time, progname, message)).to be_a(LogStash::Event)
11
+ end
12
+ end
13
+
14
+ context "when event is cancelled" do
15
+ before(:each) do
16
+ LogStashLogger.configure do |config|
17
+ config.customize_event(&:cancel)
18
+ end
19
+ end
20
+
21
+ it "returns `nil`" do
22
+ expect(subject).not_to receive(:format_event)
23
+ expect(subject.call(severity, time, progname, message)).to be_nil
24
+ end
25
+ end
26
+ end
27
+
6
28
  describe "#build_event" do
7
29
  let(:event) { formatted_message }
8
30
 
@@ -7,7 +7,7 @@ describe LogStashLogger::Formatter::CeeSyslog do
7
7
  let(:facility) { "facility" }
8
8
 
9
9
  before do
10
- allow(subject).to receive(:facility).and_return(facility)
10
+ allow(subject).to receive(:build_facility).and_return(facility)
11
11
  end
12
12
 
13
13
  it "outputs a facility before the @cee" do
@@ -21,7 +21,7 @@ describe LogStashLogger::Formatter::CeeSyslog do
21
21
  end
22
22
  end
23
23
 
24
- describe "#facility" do
24
+ describe "#build_facility" do
25
25
  let(:host) { Socket.gethostname }
26
26
 
27
27
  before do
@@ -29,14 +29,14 @@ describe LogStashLogger::Formatter::CeeSyslog do
29
29
  end
30
30
 
31
31
  it "includes hostname and progname" do
32
- expect(subject.send(:facility)).to match(/\A#{host}\s#{progname}\z/)
32
+ expect(subject.send(:build_facility, host)).to match(/\A#{host}\s#{progname}\z/)
33
33
  end
34
34
 
35
35
  context "without progname" do
36
36
  let(:progname) { nil }
37
37
 
38
38
  it "only includes hostname" do
39
- expect(subject.send(:facility)).to match(/\A#{host}\z/)
39
+ expect(subject.send(:build_facility, host)).to match(/\A#{host}\z/)
40
40
  end
41
41
  end
42
42
  end
data/spec/syslog_spec.rb CHANGED
@@ -1,25 +1,32 @@
1
1
  require 'logstash-logger'
2
2
 
3
3
  describe LogStashLogger do
4
- context "Syslog" do
5
- let(:program_name) { "MyApp" }
6
- let(:facility) { 128 } #Syslog::LOG_LOCAL0 }
4
+ let(:program_name) { 'MyApp' }
5
+ let(:facility) { 128 } #Syslog::LOG_LOCAL0 }
6
+
7
+ context 'Syslog' do
7
8
  subject { LogStashLogger.new(type: :syslog, program_name: program_name, facility: facility) }
8
9
  let(:syslog) { subject.class.class_variable_get(:@@syslog) }
9
10
 
10
11
  it { is_expected.to be_a Syslog::Logger }
11
12
 
12
- it "writes formatted messages to syslog" do
13
+ it 'writes formatted messages to syslog' do
13
14
  expect(syslog).to receive(:log)
14
- subject.info("test")
15
+ subject.info('test')
15
16
  end
16
17
 
17
- it "sets the syslog identity" do
18
+ it 'sets the syslog identity' do
18
19
  expect(syslog.ident).to eq(program_name)
19
20
  end
20
21
 
21
- it "sets the default facility if supported" do
22
+ it 'sets the default facility if supported' do
22
23
  expect(subject.facility).to eq(facility) if subject.respond_to?(:facility)
23
24
  end
24
25
  end
26
+
27
+ context 'when logger type is a string' do
28
+ subject { LogStashLogger.new(type: 'syslog', program_name: program_name, facility: facility) }
29
+
30
+ it { is_expected.to be_a Syslog::Logger }
31
+ end
25
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.1
4
+ version: 0.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Butler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-08 00:00:00.000000000 Z
11
+ date: 2018-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-event
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
153
167
  description: Ruby logger that writes directly to LogStash
154
168
  email:
155
169
  - dwbutler@ucla.edu
@@ -157,7 +171,6 @@ executables: []
157
171
  extensions: []
158
172
  extra_rdoc_files: []
159
173
  files:
160
- - ".codeclimate.yml"
161
174
  - ".gitignore"
162
175
  - ".rspec"
163
176
  - ".rubocop.yml"
data/.codeclimate.yml DELETED
@@ -1,16 +0,0 @@
1
- ---
2
- engines:
3
- duplication:
4
- enabled: true
5
- config:
6
- languages:
7
- - ruby
8
- fixme:
9
- enabled: true
10
- rubocop:
11
- enabled: true
12
- ratings:
13
- paths:
14
- - "**.rb"
15
- exclude_paths:
16
- - spec/