fluent-plugin-splunk-ex-logentries 1.0.1.logentries

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: df18337f5895e02bcafd8d9926082575d6ba5234a4b343db4da3bff10efa7678
4
+ data.tar.gz: 6f7e8e2b4c06a27e04c7fc7bb0d62a6c4fab71b483cfa72663b2e12c5f418440
5
+ SHA512:
6
+ metadata.gz: 591ca52932934d84a350f5b90f3a358e6250777ea798b79cc15107a81d1146de283419d89243c64a2428c78c85f0e813748a88e25b3e86327d552586658ac4f1
7
+ data.tar.gz: cac585a169d1b687e96914dbe320e65106814637681ea78d6a2199b8996e95208790f0cbef3d7c41d3cb3591730b4b64b8ad7cd99a202eb64f2def2630943189
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1.*
5
+ gemfile:
6
+ - Gemfile
7
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'coveralls', require: false
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ [![Build Status](https://travis-ci.org/gtrevg/fluent-plugin-splunk-ex.svg?branch=master)](https://travis-ci.org/gtrevg/fluent-plugin-splunk-ex) [![Code Climate](https://codeclimate.com/github/gtrevg/fluent-plugin-splunk-ex.png)](https://codeclimate.com/github/gtrevg/fluent-plugin-splunk-ex) [![Coverage Status](https://coveralls.io/repos/gtrevg/fluent-plugin-splunk-ex/badge.png)](https://coveralls.io/r/gtrevg/fluent-plugin-splunk-ex)
2
+
3
+ ## Overview
4
+
5
+ This plugin will send your fluentd logs to a splunk server. It can send the data in either
6
+ key/value (k1=v1 k2=v2) or json format for easy splunk parsing.
7
+
8
+
9
+ ## Installation
10
+
11
+ gem install fluent-plugin-splunk-ex
12
+
13
+ ## Configuration
14
+
15
+ ### Plugin
16
+
17
+ <match pattern>
18
+ type splunk_ex
19
+ host <splunk_host> # default: localhost
20
+ port <splunk_port> # default: 9997 - but you'll want to change this
21
+ output_format json|kv # default: json
22
+ </match>
23
+
24
+ ### Splunk
25
+
26
+ You may need to open up a special TCP port just for the fluentd logs. To do that, go to
27
+ `Manager -> Data Inputs -> TCP -> New`. Then decide the following:
28
+
29
+ * Port
30
+ * Source Name
31
+ * Source Type
32
+ * Index ( default works well )
33
+
34
+ After enabling these settings, you'll be able to see your fluentd logs appear in your Splunk search interface.
35
+ The JSON format will be automagically parsed and indexed based on the keys passed in.
36
+
37
+ Because the plugin batch sends data to Splunk, you'll want to update your `apps/search/local/props.conf`
38
+ file to specify that Splunk should split on newlines. If you do not update this setting, you find that
39
+ all logs from a similar time slice will be stacked upon each other. Because the kv & json formats do
40
+ not contain any newline characters, splitting on the newline will solve this problem. The values to
41
+ add to this file are:
42
+
43
+ [<source_type_here>]
44
+ SHOULD_LINEMERGE = false
45
+
46
+ This will make sure that the new source type you just set up for fluentd will always split on the newline character.
47
+
48
+ ## Copyright
49
+
50
+ Copyright (c) 2014 Trevor Gattis
51
+
52
+ ## License
53
+
54
+ Apache License, Version 2.0
55
+
56
+
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+ task :default => :spec
10
+
11
+ desc 'Open an irb session preloaded with the gem library'
12
+ task :console do
13
+ sh 'irb -rubygems -I lib'
14
+ end
15
+ task :c => :console
16
+
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = "fluent-plugin-splunk-ex-logentries"
5
+ gem.version = "1.0.1.logentries"
6
+
7
+ gem.authors = ["Trevor Gattis"]
8
+ gem.email = "github@trevorgattis.com"
9
+ gem.description = "Splunk output plugin for Fluent event collector. It supports reconnecting on socket failure as well as exporting the data as json or in key/value pairs. Modified to produce output format fit for Logentries."
10
+ gem.homepage = "https://github.com/Indrius/fluent-plugin-splunk-ex"
11
+ gem.summary = gem.description
12
+ gem.license = "APLv2"
13
+ gem.has_rdoc = false
14
+
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency "fluentd", "~> 0.10.17"
21
+ gem.add_runtime_dependency "json"
22
+
23
+ gem.add_development_dependency "rake"
24
+ gem.add_development_dependency "rspec"
25
+ gem.add_development_dependency "pry"
26
+ gem.add_development_dependency "pry-nav"
27
+ end
28
+
@@ -0,0 +1,145 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+ require 'open-uri'
15
+ require 'json'
16
+
17
+ class Fluent::SplunkExOutput < Fluent::Output
18
+
19
+ SOCKET_TRY_MAX = 3
20
+
21
+ Fluent::Plugin.register_output('splunk_ex', self)
22
+
23
+ include Fluent::SetTagKeyMixin
24
+ config_set_default :include_tag_key, false
25
+
26
+ include Fluent::SetTimeKeyMixin
27
+ config_set_default :include_time_key, false
28
+
29
+ config_param :host, :string, :default => 'localhost'
30
+ config_param :port, :string, :default => 9997
31
+ config_param :output_format, :string, :default => 'json'
32
+
33
+ config_param :test_mode, :bool, :default => false
34
+
35
+ # To support log_level option implemented by Fluentd v0.10.43
36
+ unless method_defined?(:log)
37
+ define_method(:log) { $log }
38
+ end
39
+
40
+
41
+ def configure(conf)
42
+ super
43
+ end
44
+
45
+ def start
46
+ super
47
+
48
+ if @output_format == 'kv'
49
+ @format_fn = self.class.method(:format_kv)
50
+ elsif @output_format == 'logentries'
51
+ @format_fn = self.class.method(:format_logentries)
52
+ else
53
+ @format_fn = self.class.method(:format_json)
54
+ end
55
+
56
+ if @test_mode
57
+ @send_data = proc { |text| log.trace("test mode text: #{text}") }
58
+ else
59
+ begin
60
+ @splunk_connection = TCPSocket.open(@host, @port)
61
+ rescue Errno::ECONNREFUSED
62
+ # we'll try again when data is sent
63
+ end
64
+ @send_data = self.method(:splunk_send)
65
+ end
66
+
67
+ end
68
+
69
+
70
+ def shutdown
71
+ super
72
+ if !@test_mode && @splunk_connection.respond_to?(:close)
73
+ @splunk_connection.close
74
+ end
75
+ end
76
+
77
+
78
+ def emit(tag, es, chain)
79
+ chain.next
80
+ es.each {|time,record|
81
+ @send_data.call( @format_fn.call(record) )
82
+ }
83
+ end
84
+
85
+ # =================================================================
86
+
87
+ protected
88
+
89
+ def self.format_kv(record)
90
+ kv_out_str = ''
91
+ record.each { |k, v|
92
+ kv_out_str << sprintf('%s=%s ', URI::encode(k), URI::encode(v.to_s))
93
+ }
94
+ kv_out_str
95
+ end
96
+
97
+ def self.format_logentries(record)
98
+ label = record["kubernetes"]["labels"]["logentries"]
99
+ message = record["message"]
100
+ le_out_str = label + " " + message
101
+ end
102
+
103
+ def self.format_json(record)
104
+ json_str = record.to_json
105
+ end
106
+
107
+ def splunk_send(text, try_count=0)
108
+ log.debug("splunk_send: #{text}")
109
+
110
+ successful_send = false
111
+ try_count = 0
112
+
113
+ while (!successful_send && try_count < SOCKET_TRY_MAX)
114
+ begin
115
+ @splunk_connection.puts(text)
116
+ successful_send = true
117
+
118
+ rescue NoMethodError, Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EPIPE => se
119
+ log.error("splunk_send - socket send retry (#{try_count}) failed: #{se}")
120
+ try_count = try_count + 1
121
+
122
+ successful_reopen = false
123
+ while (!successful_reopen && try_count < SOCKET_TRY_MAX)
124
+ begin
125
+ # Try reopening
126
+ @splunk_connection = TCPSocket.open(@host, @port)
127
+ successful_reopen = true
128
+ rescue Errno::ECONNRESET, Errno::ECONNREFUSED, Errno::EPIPE => se
129
+ log.error("splunk_send - socket open retry (#{try_count}) failed: #{se}")
130
+ try_count = try_count + 1
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ if !successful_send
137
+ log.fatal("splunk_send - retry of sending data failed after #{SOCKET_TRY_MAX} chances.")
138
+ log.warn(text)
139
+ end
140
+
141
+ end
142
+
143
+
144
+ end
145
+
@@ -0,0 +1,74 @@
1
+ # encoding: UTF-8
2
+ require_relative 'spec_helper'
3
+ require 'benchmark'
4
+ Fluent::Test.setup
5
+
6
+ def create_driver(config, tag = 'foo.bar')
7
+ Fluent::Test::OutputTestDriver.new(Fluent::SplunkExOutput, tag).configure(config)
8
+ end
9
+
10
+ # setup
11
+ single_key_message = {
12
+ 'msg' => 'testing some data'
13
+ }
14
+
15
+ multi_key_message = {
16
+ 'msg' => 'testing some data',
17
+ 'chars' => 'let"s put !@#$%^&*()-= some weird :\'?><,./ characters',
18
+ 'dt' => '2014/04/03T07:02:11.124202',
19
+ 'debug_line' => 24,
20
+ 'debug_file' => '/some/path/to/myFile.py',
21
+ 'statsd_key' => 'fluent_plugin_splunk_ex',
22
+ 'statsd_timing' => 0.234,
23
+ 'statsd_type' => 'timing',
24
+ 'tx' => '280c3e80-bb6c-11e3-a5e2-0800200c9a66',
25
+ 'host' => 'my01.cool.server.com'
26
+ }
27
+
28
+ time = Time.now.to_i
29
+
30
+ driver_kv = create_driver(%[
31
+ log_level fatal
32
+ test_mode true
33
+ output_format kv
34
+ ])
35
+
36
+ driver_json = create_driver(%[
37
+ log_level fatal
38
+ test_mode true
39
+ output_format json
40
+ ])
41
+
42
+ driver_kv_time = create_driver(%[
43
+ log_level fatal
44
+ test_mode true
45
+ output_format kv
46
+ time_key myKey
47
+ include_time_key true
48
+ ])
49
+
50
+ driver_json_time = create_driver(%[
51
+ log_level fatal
52
+ test_mode true
53
+ output_format json
54
+ time_key myKey
55
+ include_time_key true
56
+ ])
57
+
58
+
59
+
60
+ # bench
61
+ n = 10000
62
+ Benchmark.bm(7) do |x|
63
+ x.report("single_kv ") { driver_kv.run { n.times { driver_kv.emit( single_key_message, time) } } }
64
+ x.report("single_kv_time ") { driver_kv_time.run { n.times { driver_kv_time.emit( single_key_message, time) } } }
65
+ x.report("single_json ") { driver_json.run { n.times { driver_json.emit( single_key_message, time) } } }
66
+ x.report("single_json_time") { driver_json_time.run { n.times { driver_json_time.emit(single_key_message, time) } } }
67
+
68
+ x.report("multi_kv ") { driver_kv.run { n.times { driver_kv.emit( multi_key_message, time ) } } }
69
+ x.report("multi_kv_time ") { driver_kv_time.run { n.times { driver_kv_time.emit( multi_key_message, time ) } } }
70
+ x.report("multi_json ") { driver_json.run { n.times { driver_json.emit( multi_key_message, time ) } } }
71
+ x.report("multi_json_time ") { driver_json_time.run { n.times { driver_json_time.emit(multi_key_message, time ) } } }
72
+
73
+ end
74
+
@@ -0,0 +1,25 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ # This file was generated by the `rspec --init` command. Conventionally, all
5
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
+ # Require this file using `require "spec_helper"` to ensure that it is only
7
+ # loaded once.
8
+ #
9
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
21
+
22
+ require 'fluent/test'
23
+
24
+ require 'fluent/plugin/out_splunk_ex'
25
+
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-splunk-ex-logentries
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1.logentries
5
+ platform: ruby
6
+ authors:
7
+ - Trevor Gattis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.17
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.17
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-nav
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Splunk output plugin for Fluent event collector. It supports reconnecting
98
+ on socket failure as well as exporting the data as json or in key/value pairs. Modified
99
+ to produce output format fit for Logentries.
100
+ email: github@trevorgattis.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".travis.yml"
106
+ - Gemfile
107
+ - README.md
108
+ - Rakefile
109
+ - fluent-plugin-splunk-ex.gemspec
110
+ - lib/fluent/plugin/out_splunk_ex.rb
111
+ - spec/out_splunk_ex_spec.rb
112
+ - spec/spec_helper.rb
113
+ homepage: https://github.com/Indrius/fluent-plugin-splunk-ex
114
+ licenses:
115
+ - APLv2
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">"
129
+ - !ruby/object:Gem::Version
130
+ version: 1.3.1
131
+ requirements: []
132
+ rubyforge_project:
133
+ rubygems_version: 2.7.3
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: Splunk output plugin for Fluent event collector. It supports reconnecting
137
+ on socket failure as well as exporting the data as json or in key/value pairs. Modified
138
+ to produce output format fit for Logentries.
139
+ test_files: []