logstash-logger-yajl 0.27.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.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +1156 -0
  5. data/.travis.yml +26 -0
  6. data/Appraisals +23 -0
  7. data/CHANGELOG.md +203 -0
  8. data/Gemfile +6 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +880 -0
  11. data/Rakefile +23 -0
  12. data/gemfiles/rails_3.2.gemfile +9 -0
  13. data/gemfiles/rails_4.0.gemfile +9 -0
  14. data/gemfiles/rails_4.1.gemfile +9 -0
  15. data/gemfiles/rails_4.2.gemfile +9 -0
  16. data/gemfiles/rails_5.0.gemfile +9 -0
  17. data/gemfiles/rails_5.1.gemfile +9 -0
  18. data/lib/logstash-event.rb +1 -0
  19. data/lib/logstash-logger.rb +11 -0
  20. data/lib/logstash-logger/buffer.rb +336 -0
  21. data/lib/logstash-logger/configuration.rb +29 -0
  22. data/lib/logstash-logger/device.rb +67 -0
  23. data/lib/logstash-logger/device/aws_stream.rb +94 -0
  24. data/lib/logstash-logger/device/balancer.rb +40 -0
  25. data/lib/logstash-logger/device/base.rb +73 -0
  26. data/lib/logstash-logger/device/connectable.rb +131 -0
  27. data/lib/logstash-logger/device/file.rb +23 -0
  28. data/lib/logstash-logger/device/firehose.rb +42 -0
  29. data/lib/logstash-logger/device/io.rb +11 -0
  30. data/lib/logstash-logger/device/kafka.rb +57 -0
  31. data/lib/logstash-logger/device/kinesis.rb +44 -0
  32. data/lib/logstash-logger/device/multi_delegator.rb +36 -0
  33. data/lib/logstash-logger/device/redis.rb +69 -0
  34. data/lib/logstash-logger/device/socket.rb +21 -0
  35. data/lib/logstash-logger/device/stderr.rb +13 -0
  36. data/lib/logstash-logger/device/stdout.rb +14 -0
  37. data/lib/logstash-logger/device/tcp.rb +86 -0
  38. data/lib/logstash-logger/device/udp.rb +12 -0
  39. data/lib/logstash-logger/device/unix.rb +18 -0
  40. data/lib/logstash-logger/formatter.rb +51 -0
  41. data/lib/logstash-logger/formatter/base.rb +73 -0
  42. data/lib/logstash-logger/formatter/cee.rb +11 -0
  43. data/lib/logstash-logger/formatter/cee_syslog.rb +22 -0
  44. data/lib/logstash-logger/formatter/json.rb +11 -0
  45. data/lib/logstash-logger/formatter/json_lines.rb +11 -0
  46. data/lib/logstash-logger/formatter/logstash_event.rb +6 -0
  47. data/lib/logstash-logger/logger.rb +106 -0
  48. data/lib/logstash-logger/multi_logger.rb +153 -0
  49. data/lib/logstash-logger/railtie.rb +51 -0
  50. data/lib/logstash-logger/silenced_logging.rb +83 -0
  51. data/lib/logstash-logger/tagged_logging.rb +40 -0
  52. data/lib/logstash-logger/version.rb +3 -0
  53. data/lib/logstash/event.rb +272 -0
  54. data/lib/logstash/namespace.rb +15 -0
  55. data/lib/logstash/util.rb +105 -0
  56. data/lib/logstash/util/fieldreference.rb +49 -0
  57. data/logstash-logger.gemspec +42 -0
  58. data/samples/example.crt +16 -0
  59. data/samples/example.key +15 -0
  60. data/samples/file.conf +11 -0
  61. data/samples/redis.conf +12 -0
  62. data/samples/ssl.conf +15 -0
  63. data/samples/syslog.conf +10 -0
  64. data/samples/tcp.conf +11 -0
  65. data/samples/udp.conf +11 -0
  66. data/samples/unix.conf +11 -0
  67. data/spec/configuration_spec.rb +27 -0
  68. data/spec/constructor_spec.rb +30 -0
  69. data/spec/device/balancer_spec.rb +31 -0
  70. data/spec/device/connectable_spec.rb +74 -0
  71. data/spec/device/file_spec.rb +15 -0
  72. data/spec/device/firehose_spec.rb +41 -0
  73. data/spec/device/io_spec.rb +13 -0
  74. data/spec/device/kafka_spec.rb +32 -0
  75. data/spec/device/kinesis_spec.rb +41 -0
  76. data/spec/device/multi_delegator_spec.rb +31 -0
  77. data/spec/device/redis_spec.rb +52 -0
  78. data/spec/device/socket_spec.rb +15 -0
  79. data/spec/device/stderr_spec.rb +16 -0
  80. data/spec/device/stdout_spec.rb +31 -0
  81. data/spec/device/tcp_spec.rb +120 -0
  82. data/spec/device/udp_spec.rb +9 -0
  83. data/spec/device/unix_spec.rb +23 -0
  84. data/spec/device_spec.rb +97 -0
  85. data/spec/formatter/base_spec.rb +125 -0
  86. data/spec/formatter/cee_spec.rb +15 -0
  87. data/spec/formatter/cee_syslog_spec.rb +43 -0
  88. data/spec/formatter/json_lines_spec.rb +14 -0
  89. data/spec/formatter/json_spec.rb +10 -0
  90. data/spec/formatter/logstash_event_spec.rb +10 -0
  91. data/spec/formatter_spec.rb +79 -0
  92. data/spec/logger_spec.rb +128 -0
  93. data/spec/logstash_event_spec.rb +139 -0
  94. data/spec/multi_logger_spec.rb +59 -0
  95. data/spec/rails_spec.rb +91 -0
  96. data/spec/silenced_logging_spec.rb +31 -0
  97. data/spec/spec_helper.rb +111 -0
  98. data/spec/syslog_spec.rb +32 -0
  99. data/spec/tagged_logging_spec.rb +32 -0
  100. metadata +385 -0
@@ -0,0 +1,67 @@
1
+ require 'logstash-logger/device/base'
2
+
3
+ module LogStashLogger
4
+ module Device
5
+ DEFAULT_TYPE = :udp
6
+
7
+ autoload :Base, 'logstash-logger/device/base'
8
+ autoload :Connectable, 'logstash-logger/device/connectable'
9
+ autoload :Socket, 'logstash-logger/device/socket'
10
+ autoload :UDP, 'logstash-logger/device/udp'
11
+ autoload :TCP, 'logstash-logger/device/tcp'
12
+ autoload :Unix, 'logstash-logger/device/unix'
13
+ autoload :Redis, 'logstash-logger/device/redis'
14
+ autoload :Kafka, 'logstash-logger/device/kafka'
15
+ autoload :Kinesis, 'logstash-logger/device/kinesis'
16
+ autoload :Firehose, 'logstash-logger/device/firehose'
17
+ autoload :File, 'logstash-logger/device/file'
18
+ autoload :IO, 'logstash-logger/device/io'
19
+ autoload :Stdout, 'logstash-logger/device/stdout'
20
+ autoload :Stderr, 'logstash-logger/device/stderr'
21
+ autoload :Balancer, 'logstash-logger/device/balancer'
22
+ autoload :MultiDelegator, 'logstash-logger/device/multi_delegator'
23
+
24
+ def self.new(opts)
25
+ opts = opts.dup
26
+ build_device(opts)
27
+ end
28
+
29
+ def self.build_device(opts)
30
+ if parsed_uri_opts = parse_uri_config(opts)
31
+ opts.delete(:uri)
32
+ opts.merge!(parsed_uri_opts)
33
+ end
34
+
35
+ type = opts.delete(:type) || DEFAULT_TYPE
36
+
37
+ device_klass_for(type).new(opts)
38
+ end
39
+
40
+ def self.parse_uri_config(opts)
41
+ if uri = opts[:uri]
42
+ require 'uri'
43
+ parsed = ::URI.parse(uri)
44
+ {type: parsed.scheme, host: parsed.host, port: parsed.port, path: parsed.path}
45
+ end
46
+ end
47
+
48
+ def self.device_klass_for(type)
49
+ case type.to_sym
50
+ when :udp then UDP
51
+ when :tcp then TCP
52
+ when :unix then Unix
53
+ when :file then File
54
+ when :redis then Redis
55
+ when :kafka then Kafka
56
+ when :kinesis then Kinesis
57
+ when :firehose then Firehose
58
+ when :io then IO
59
+ when :stdout then Stdout
60
+ when :stderr then Stderr
61
+ when :multi_delegator then MultiDelegator
62
+ when :balancer then Balancer
63
+ else fail ArgumentError, 'Invalid device type'
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,94 @@
1
+ begin
2
+ require 'aws-sdk-core'
3
+ rescue LoadError
4
+ require 'aws-sdk'
5
+ end
6
+
7
+ module LogStashLogger
8
+ module Device
9
+ class AwsStream < Connectable
10
+
11
+ DEFAULT_STREAM = 'logstash'
12
+
13
+ @stream_class = nil
14
+ @recoverable_error_codes = []
15
+
16
+ class << self
17
+ attr_accessor :stream_class, :recoverable_error_codes
18
+ end
19
+
20
+ attr_accessor :aws_region, :stream
21
+
22
+ def initialize(opts)
23
+ super
24
+ @access_key_id = opts[:aws_access_key_id]
25
+ @secret_access_key = opts[:aws_secret_access_key]
26
+ @aws_region = opts[:aws_region]
27
+ @stream = opts[:stream] || DEFAULT_STREAM
28
+ end
29
+
30
+ def transform_message(message)
31
+ fail NotImplementedError
32
+ end
33
+
34
+ def put_records(records)
35
+ fail NotImplementedError
36
+ end
37
+
38
+ def is_successful_response(resp)
39
+ fail NotImplementedError
40
+ end
41
+
42
+ def get_response_records(resp)
43
+ fail NotImplementedError
44
+ end
45
+
46
+ def connect
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)
51
+ end
52
+
53
+ def with_connection
54
+ connect unless connected?
55
+ yield
56
+ rescue => e
57
+ log_error(e)
58
+ log_warning("giving up")
59
+ close(flush: false)
60
+ end
61
+
62
+ def write_batch(messages, group = nil)
63
+ records = messages.map{ |m| transform_message(m) }
64
+
65
+ with_connection do
66
+ resp = put_records(records)
67
+
68
+ # Put any failed records back into the buffer
69
+ if !is_successful_response(resp)
70
+ get_response_records(resp).each_with_index do |record, index|
71
+ if self.class.recoverable_error_codes.include?(record.error_code)
72
+ log_warning("Failed to post record using #{self.class.stream_class.name} with error: #{record.error_code} #{record.error_message}")
73
+ log_warning("Retrying")
74
+ write(records[index][:data])
75
+ elsif !record.error_code.nil? && record.error_code != ''
76
+ log_error("Failed to post record using #{self.class.stream_class.name} with error: #{record.error_code} #{record.error_message}")
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def write_one(message)
84
+ write_batch([message])
85
+ end
86
+
87
+ def close!
88
+ @io = nil
89
+ end
90
+
91
+ end
92
+ end
93
+ end
94
+
@@ -0,0 +1,40 @@
1
+ module LogStashLogger
2
+ module Device
3
+ class Balancer < Base
4
+ attr_reader :devices
5
+
6
+ def initialize(opts)
7
+ @io = self
8
+ @devices = create_devices(opts[:outputs])
9
+ self.class.delegate_to_all(:close, :close!, :flush)
10
+ self.class.delegate_to_one(:write)
11
+ end
12
+
13
+ private
14
+
15
+ def create_devices(opts)
16
+ opts.map { |device_opts| Device.new(device_opts) }
17
+ end
18
+
19
+ def self.delegate_to_all(*methods)
20
+ methods.each do |m|
21
+ define_method(m) do |*args|
22
+ devices.each { |device| device.send(m, *args) }
23
+ end
24
+ end
25
+ end
26
+
27
+ def self.delegate_to_one(*methods)
28
+ methods.each do |m|
29
+ define_method(m) do |*args|
30
+ select_device.send(m, *args)
31
+ end
32
+ end
33
+ end
34
+
35
+ def select_device
36
+ devices.sample
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,73 @@
1
+ module LogStashLogger
2
+ module Device
3
+ class Base
4
+ attr_reader :io
5
+ attr_accessor :sync
6
+ attr_accessor :error_logger
7
+
8
+ def initialize(opts={})
9
+ @sync = opts[:sync]
10
+ @error_logger = opts.fetch(:error_logger, LogStashLogger.configuration.default_error_logger)
11
+ end
12
+
13
+ def to_io
14
+ @io
15
+ end
16
+
17
+ def write(message)
18
+ write_one(message) unless message.nil?
19
+ end
20
+
21
+ def write_one(message)
22
+ @io.write(message)
23
+ rescue => e
24
+ if unrecoverable_error?(e)
25
+ log_error(e)
26
+ log_warning("unrecoverable error, aborting write")
27
+ else
28
+ raise
29
+ end
30
+ end
31
+
32
+ def write_batch(messages, group = nil)
33
+ messages.each do |message|
34
+ write_one(message)
35
+ end
36
+ end
37
+
38
+ def flush
39
+ @io && @io.flush
40
+ end
41
+
42
+ def reset
43
+ close
44
+ end
45
+
46
+ def close(opts = {})
47
+ close!
48
+ rescue => e
49
+ log_error(e)
50
+ end
51
+
52
+ def close!
53
+ @io && @io.close
54
+ ensure
55
+ @io = nil
56
+ end
57
+
58
+ def unrecoverable_error?(e)
59
+ e.is_a?(JSON::GeneratorError)
60
+ end
61
+
62
+ private
63
+
64
+ def log_error(e)
65
+ error_logger.error "[#{self.class}] #{e.class} - #{e.message}"
66
+ end
67
+
68
+ def log_warning(message)
69
+ error_logger.warn("[#{self.class}] #{message}")
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,131 @@
1
+ require 'logstash-logger/buffer'
2
+
3
+ module LogStashLogger
4
+ module Device
5
+ class Connectable < Base
6
+ include LogStashLogger::Buffer
7
+
8
+ attr_accessor :buffer_logger
9
+
10
+ def initialize(opts = {})
11
+ super
12
+
13
+ if opts[:batch_events]
14
+ warn "The :batch_events option is deprecated. Please use :buffer_max_items instead"
15
+ end
16
+
17
+ if opts[:batch_timeout]
18
+ warn "The :batch_timeout option is deprecated. Please use :buffer_max_interval instead"
19
+ end
20
+
21
+ @buffer_group = nil
22
+ @buffer_max_items = opts[:batch_events] || opts[:buffer_max_items]
23
+ @buffer_max_interval = opts[:batch_timeout] || opts[:buffer_max_interval]
24
+ @drop_messages_on_flush_error =
25
+ if opts.key?(:drop_messages_on_flush_error)
26
+ opts.delete(:drop_messages_on_flush_error)
27
+ else
28
+ false
29
+ end
30
+
31
+ @drop_messages_on_full_buffer =
32
+ if opts.key?(:drop_messages_on_full_buffer)
33
+ opts.delete(:drop_messages_on_full_buffer)
34
+ else
35
+ true
36
+ end
37
+
38
+ @buffer_flush_at_exit =
39
+ if opts.key?(:buffer_flush_at_exit)
40
+ opts.delete(:buffer_flush_at_exit)
41
+ else
42
+ true
43
+ end
44
+
45
+ @buffer_logger = opts[:buffer_logger]
46
+
47
+ buffer_initialize(
48
+ max_items: @buffer_max_items,
49
+ max_interval: @buffer_max_interval,
50
+ logger: buffer_logger,
51
+ autoflush: @sync,
52
+ drop_messages_on_flush_error: @drop_messages_on_flush_error,
53
+ drop_messages_on_full_buffer: @drop_messages_on_full_buffer,
54
+ flush_at_exit: @buffer_flush_at_exit
55
+ )
56
+ end
57
+
58
+ def write(message)
59
+ buffer_receive(message, @buffer_group) unless message.nil?
60
+ end
61
+
62
+ def flush(*args)
63
+ if args.empty?
64
+ buffer_flush
65
+ else
66
+ messages, group = *args
67
+ write_batch(messages, group)
68
+ end
69
+ end
70
+
71
+ def on_full_buffer_receive(data)
72
+ log_warning("Buffer Full - #{data}")
73
+ end
74
+
75
+ def close(opts = {})
76
+ if opts.fetch(:flush, true)
77
+ buffer_flush(final: true)
78
+ end
79
+
80
+ super
81
+ end
82
+
83
+ def to_io
84
+ with_connection do
85
+ super
86
+ end
87
+ end
88
+
89
+ def connected?
90
+ !!@io
91
+ end
92
+
93
+ def write_one(message)
94
+ with_connection do
95
+ super
96
+ end
97
+ end
98
+
99
+ def write_batch(messages, group = nil)
100
+ with_connection do
101
+ super
102
+ end
103
+ end
104
+
105
+ # Implemented by subclasses
106
+ def connect
107
+ fail NotImplementedError
108
+ end
109
+
110
+ def reset
111
+ reset_buffer
112
+ close(flush: false)
113
+ end
114
+
115
+ def reconnect
116
+ close(flush: false)
117
+ connect
118
+ end
119
+
120
+ # Ensure the block is executed with a valid connection
121
+ def with_connection(&block)
122
+ connect unless connected?
123
+ yield
124
+ rescue => e
125
+ log_error(e)
126
+ close(flush: false)
127
+ raise
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,23 @@
1
+ require 'fileutils'
2
+
3
+ module LogStashLogger
4
+ module Device
5
+ class File < Base
6
+ def initialize(opts)
7
+ super
8
+ @path = opts[:path] || fail(ArgumentError, "Path is required")
9
+ open
10
+ end
11
+
12
+ def open
13
+ unless ::File.exist? ::File.dirname @path
14
+ ::FileUtils.mkdir_p ::File.dirname @path
15
+ end
16
+
17
+ @io = ::File.open @path, ::File::WRONLY | ::File::APPEND | ::File::CREAT
18
+ @io.binmode
19
+ @io.sync = self.sync
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ begin
2
+ require 'aws-sdk-firehose'
3
+ rescue LoadError
4
+ require 'aws-sdk'
5
+ end
6
+
7
+ require 'logstash-logger/device/aws_stream'
8
+
9
+ module LogStashLogger
10
+ module Device
11
+ class Firehose < AwsStream
12
+ @stream_class = ::Aws::Firehose::Client
13
+ @recoverable_error_codes = [
14
+ "ServiceUnavailable",
15
+ "InternalFailure",
16
+ "ServiceUnavailableException"
17
+ ].freeze
18
+
19
+ def transform_message(message)
20
+ {
21
+ data: message
22
+ }
23
+ end
24
+
25
+ def put_records(records)
26
+ @io.put_record_batch({
27
+ records: records,
28
+ delivery_stream_name: @stream
29
+ })
30
+ end
31
+
32
+ def is_successful_response(resp)
33
+ resp.failed_put_count == 0
34
+ end
35
+
36
+ def get_response_records(resp)
37
+ resp.request_responses
38
+ end
39
+
40
+ end
41
+ end
42
+ end