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,11 @@
1
+ module LogStashLogger
2
+ module Device
3
+ class IO < Base
4
+ def initialize(opts)
5
+ super
6
+ @io = opts[:io] || fail(ArgumentError, 'IO is required')
7
+ @io.sync = sync unless sync.nil?
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ require 'poseidon'
2
+
3
+ module LogStashLogger
4
+ module Device
5
+ class Kafka < Connectable
6
+
7
+ DEFAULT_HOST = 'localhost'
8
+ DEFAULT_PORT = 9092
9
+ DEFAULT_TOPIC = 'logstash'
10
+ DEFAULT_PRODUCER = 'logstash-logger'
11
+ DEFAULT_BACKOFF = 1
12
+
13
+ attr_accessor :hosts, :topic, :producer, :backoff
14
+
15
+ def initialize(opts)
16
+ super
17
+ host = opts[:host] || DEFAULT_HOST
18
+ port = opts[:port] || DEFAULT_PORT
19
+ @hosts = opts[:hosts] || host.split(',').map { |h| "#{h}:#{port}" }
20
+ @topic = opts[:path] || DEFAULT_TOPIC
21
+ @producer = opts[:producer] || DEFAULT_PRODUCER
22
+ @backoff = opts[:backoff] || DEFAULT_BACKOFF
23
+ @buffer_group = @topic
24
+ end
25
+
26
+ def connect
27
+ @io = ::Poseidon::Producer.new(@hosts, @producer)
28
+ end
29
+
30
+ def with_connection
31
+ connect unless connected?
32
+ yield
33
+ rescue ::Poseidon::Errors::ChecksumError, Poseidon::Errors::UnableToFetchMetadata => e
34
+ log_error(e)
35
+ log_warning("reconnect/retry")
36
+ sleep backoff if backoff
37
+ reconnect
38
+ retry
39
+ rescue => e
40
+ log_error(e)
41
+ log_warning("giving up")
42
+ close(flush: false)
43
+ end
44
+
45
+ def write_batch(messages, topic = nil)
46
+ topic ||= @topic
47
+ with_connection do
48
+ @io.send_messages messages.map { |message| Poseidon::MessageToSend.new(topic, message) }
49
+ end
50
+ end
51
+
52
+ def write_one(message, topic = nil)
53
+ write_batch([message], topic)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,44 @@
1
+ begin
2
+ require 'aws-sdk-kinesis'
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 Kinesis < AwsStream
12
+ @stream_class = ::Aws::Kinesis::Client
13
+ @recoverable_error_codes = [
14
+ "ServiceUnavailable",
15
+ "Throttling",
16
+ "RequestExpired",
17
+ "ProvisionedThroughputExceededException"
18
+ ].freeze
19
+
20
+ def transform_message(message)
21
+ {
22
+ data: message,
23
+ partition_key: SecureRandom.uuid
24
+ }
25
+ end
26
+
27
+ def put_records(records)
28
+ @io.put_records({
29
+ records: records,
30
+ stream_name: @stream
31
+ })
32
+ end
33
+
34
+ def is_successful_response(resp)
35
+ resp.failed_record_count == 0
36
+ end
37
+
38
+ def get_response_records(resp)
39
+ resp.records
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,36 @@
1
+ # Container to allow writes to multiple devices
2
+
3
+ # Code originally from:
4
+ # http://stackoverflow.com/a/6410202
5
+
6
+ module LogStashLogger
7
+ module Device
8
+ class MultiDelegator < Base
9
+ attr_reader :devices
10
+
11
+ def initialize(opts)
12
+ @io = self
13
+ @devices = create_devices(opts)
14
+ self.class.delegate(:write, :close, :close!, :flush)
15
+ end
16
+
17
+ private
18
+
19
+ def create_devices(opts)
20
+ output_configurations = opts.delete(:outputs)
21
+ output_configurations.map do |device_opts|
22
+ device_opts = opts.merge(device_opts)
23
+ Device.new(device_opts)
24
+ end
25
+ end
26
+
27
+ def self.delegate(*methods)
28
+ methods.each do |m|
29
+ define_method(m) do |*args|
30
+ @devices.each { |device| device.send(m, *args) }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,69 @@
1
+ require 'redis'
2
+
3
+ module LogStashLogger
4
+ module Device
5
+ class Redis < Connectable
6
+ DEFAULT_LIST = 'logstash'
7
+
8
+ attr_accessor :list
9
+
10
+ def initialize(opts)
11
+ super
12
+ @list = opts.delete(:list) || DEFAULT_LIST
13
+ @buffer_group = @list
14
+
15
+ normalize_path(opts)
16
+
17
+ @redis_options = opts
18
+ end
19
+
20
+ def connect
21
+ @io = ::Redis.new(@redis_options)
22
+ end
23
+
24
+ def reconnect
25
+ @io.client.reconnect
26
+ rescue => e
27
+ log_error(e)
28
+ end
29
+
30
+ def with_connection
31
+ connect unless connected?
32
+ yield
33
+ rescue ::Redis::InheritedError
34
+ reconnect
35
+ retry
36
+ rescue => e
37
+ log_error(e)
38
+ close(flush: false)
39
+ raise
40
+ end
41
+
42
+ def write_batch(messages, list = nil)
43
+ list ||= @list
44
+ with_connection do
45
+ @io.rpush(list, messages)
46
+ end
47
+ end
48
+
49
+ def write_one(message, list = nil)
50
+ write_batch(message, list)
51
+ end
52
+
53
+ def close!
54
+ @io && @io.quit
55
+ end
56
+
57
+ private
58
+
59
+ def normalize_path(opts)
60
+ path = opts.fetch(:path, nil)
61
+ if path
62
+ opts[:db] = path.gsub("/", "").to_i unless path.empty?
63
+ opts.delete(:path)
64
+ end
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,21 @@
1
+ require 'socket'
2
+
3
+ module LogStashLogger
4
+ module Device
5
+ class Socket < Connectable
6
+ DEFAULT_HOST = '0.0.0.0'
7
+
8
+ attr_reader :host, :port
9
+
10
+ def initialize(opts)
11
+ super
12
+ @port = opts[:port] || fail(ArgumentError, "Port is required")
13
+ @host = opts[:host] || DEFAULT_HOST
14
+ end
15
+
16
+ def unrecoverable_error?(e)
17
+ e.is_a?(Errno::EMSGSIZE) || super
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module LogStashLogger
2
+ module Device
3
+ class Stderr < IO
4
+ def initialize(opts={})
5
+ super({io: $stderr}.merge(opts))
6
+ end
7
+
8
+ def close!
9
+ # no-op
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module LogStashLogger
2
+ module Device
3
+ class Stdout < IO
4
+ def initialize(opts={})
5
+ super({io: $stdout}.merge(opts))
6
+ end
7
+
8
+ def close!
9
+ # no-op
10
+ # Calling $stdout.close would be a bad idea
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,86 @@
1
+ require 'openssl'
2
+
3
+ module LogStashLogger
4
+ module Device
5
+ class TCP < Socket
6
+ attr_reader :ssl_certificate
7
+
8
+ def initialize(opts)
9
+ super
10
+
11
+ @ssl_certificate = opts[:ssl_certificate]
12
+ @ssl_context = opts[:ssl_context]
13
+ @use_ssl = !!(@ssl_certificate || opts[:ssl_context])
14
+ @use_ssl = opts[:ssl_enable] if opts.has_key? :ssl_enable
15
+ if opts.has_key?(:use_ssl)
16
+ @use_ssl = opts[:use_ssl]
17
+ warn "[LogStashLogger] The use_ssl option is deprecated. Use ssl_enable instead."
18
+ end
19
+ @verify_hostname = opts.fetch(:verify_hostname, true)
20
+ end
21
+
22
+ def ssl_context
23
+ return unless use_ssl?
24
+ @ssl_context || certificate_context
25
+ end
26
+
27
+ def use_ssl?
28
+ @use_ssl
29
+ end
30
+
31
+ def connect
32
+ if use_ssl?
33
+ io.connect
34
+ verify_hostname!
35
+ end
36
+ io
37
+ end
38
+
39
+ def io
40
+ @io ||= if use_ssl?
41
+ ssl_io
42
+ else
43
+ tcp_io
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def tcp_io
50
+ TCPSocket.new(@host, @port).tap do |socket|
51
+ socket.sync = sync unless sync.nil?
52
+ end
53
+ end
54
+
55
+ def ssl_io
56
+ ssl_context ?
57
+ OpenSSL::SSL::SSLSocket.new(tcp_io, ssl_context) :
58
+ OpenSSL::SSL::SSLSocket.new(tcp_io)
59
+ end
60
+
61
+ def certificate_context
62
+ return unless @ssl_certificate
63
+ @certificate_context ||= OpenSSL::SSL::SSLContext.new.tap do |ctx|
64
+ ctx.set_params(cert: @ssl_certificate)
65
+ end
66
+ end
67
+
68
+ def verify_hostname?
69
+ return false unless ssl_context
70
+ !! @verify_hostname
71
+ end
72
+
73
+ def verify_hostname!
74
+ @io.post_connection_check(hostname) if verify_hostname?
75
+ end
76
+
77
+ def hostname
78
+ if String === @verify_hostname
79
+ @verify_hostname
80
+ else
81
+ @host
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,12 @@
1
+ module LogStashLogger
2
+ module Device
3
+ class UDP < Socket
4
+ def connect
5
+ @io = UDPSocket.new.tap do |socket|
6
+ socket.connect(@host, @port)
7
+ socket.sync = sync unless sync.nil?
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ require 'socket'
2
+
3
+ module LogStashLogger
4
+ module Device
5
+ class Unix < Connectable
6
+ def initialize(opts={})
7
+ super
8
+ @path = opts[:path] || fail(ArgumentError, "Path is required")
9
+ end
10
+
11
+ def connect
12
+ @io = ::UNIXSocket.new(@path).tap do |socket|
13
+ socket.sync = sync unless sync.nil?
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,51 @@
1
+ require 'logstash-logger/formatter/base'
2
+
3
+ module LogStashLogger
4
+ module Formatter
5
+ DEFAULT_FORMATTER = :json_lines
6
+
7
+ autoload :LogStashEvent, 'logstash-logger/formatter/logstash_event'
8
+ autoload :Json, 'logstash-logger/formatter/json'
9
+ autoload :JsonLines, 'logstash-logger/formatter/json_lines'
10
+ autoload :Cee, 'logstash-logger/formatter/cee'
11
+ autoload :CeeSyslog, 'logstash-logger/formatter/cee_syslog'
12
+
13
+ def self.new(formatter_type, customize_event: nil)
14
+ build_formatter(formatter_type, customize_event)
15
+ end
16
+
17
+ def self.build_formatter(formatter_type, customize_event)
18
+ formatter_type ||= DEFAULT_FORMATTER
19
+
20
+ formatter = if custom_formatter_instance?(formatter_type)
21
+ formatter_type
22
+ elsif custom_formatter_class?(formatter_type)
23
+ formatter_type.new
24
+ else
25
+ formatter_klass(formatter_type).new(customize_event: customize_event)
26
+ end
27
+
28
+ formatter.send(:extend, ::LogStashLogger::TaggedLogging::Formatter)
29
+ formatter
30
+ end
31
+
32
+ def self.formatter_klass(formatter_type)
33
+ case formatter_type.to_sym
34
+ when :json_lines then JsonLines
35
+ when :json then Json
36
+ when :logstash_event then LogStashEvent
37
+ when :cee then Cee
38
+ when :cee_syslog then CeeSyslog
39
+ else fail ArgumentError, 'Invalid formatter'
40
+ end
41
+ end
42
+
43
+ def self.custom_formatter_instance?(formatter_type)
44
+ formatter_type.respond_to?(:call)
45
+ end
46
+
47
+ def self.custom_formatter_class?(formatter_type)
48
+ formatter_type.is_a?(Class) && formatter_type.method_defined?(:call)
49
+ end
50
+ end
51
+ end