logstash-logger-yajl 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
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