fluent-plugin-sumologic_output 0.0.7 → 1.0.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: 49e311e7b4512f25f99942f69fdf4c90405d2351
4
- data.tar.gz: ff095f8c1176898c8a7f97c65abc5a0c816f88db
3
+ metadata.gz: 5db25c9b7ac9e0a3c59424d7f3fc5c4bb1d53d27
4
+ data.tar.gz: fa733ca4ed03b66a475e8c06201e38584b50f5c1
5
5
  SHA512:
6
- metadata.gz: 7c2c9c4a24a557cecb6e426b5069d5dfa6f6750996a262f8448cd5d79ec7192836ee1c9a0c332c93b2cd54596d48f01e0d032c8ff9b7777ca2ba939d7ba1c20e
7
- data.tar.gz: 472fb4fa5312d2734704164e49b073a1b44e378690c9471c95be6f7696103f4e1daf6304c124353c6de128cd46986eda808fa91e41cecab154da1ceab5efc76c
6
+ metadata.gz: 36721ceacc453015d0f819c1337061d9e92c3de065f030e02f1af0802b016a6d82caa1dbb65c58bcd25e3bbcff84c8723df9c0d647cb12932b1c1cf44de994e0
7
+ data.tar.gz: 1dc18e8b3686efcf69794f0bf0ab55751ca89f72fc220254c4bf52279dadb066a571417b94985dd833edfc8240621061ebd03601dd2b6f0d9db6ee748828f916
data/README.md CHANGED
@@ -42,6 +42,7 @@ Reading from the JSON formatted log files with `in_tail` and wildcard filenames:
42
42
  log_format json
43
43
  source_category prod/someapp/logs
44
44
  source_name AppA
45
+ open_timeout 10
45
46
  </match>
46
47
  ```
47
48
 
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |gem|
6
6
  gem.name = "fluent-plugin-sumologic_output"
7
- gem.version = "0.0.7"
7
+ gem.version = "1.0.0"
8
8
  gem.authors = ["Steven Adams"]
9
9
  gem.email = ["stevezau@gmail.com"]
10
10
  gem.description = %q{Output plugin to SumoLogic HTTP Endpoint}
@@ -24,4 +24,6 @@ Gem::Specification.new do |gem|
24
24
  gem.add_development_dependency "rake"
25
25
  gem.add_runtime_dependency "fluentd"
26
26
  gem.add_development_dependency 'test-unit', '~> 3.1.0'
27
+
28
+ gem.add_runtime_dependency 'httpclient', '~> 2.8.0'
27
29
  end
@@ -1,46 +1,53 @@
1
- require 'fluent/output'
1
+ require 'fluent/plugin/output'
2
2
  require 'net/https'
3
3
  require 'yajl'
4
+ require 'httpclient'
4
5
 
5
6
  class SumologicConnection
6
- def initialize(endpoint, verify_ssl, open_timeout)
7
- @endpoint_uri = URI.parse(endpoint.strip)
8
- @verify_ssl = verify_ssl
9
- @open_timeout = open_timeout
7
+
8
+ attr_reader :http
9
+
10
+ def initialize(endpoint, verify_ssl, connect_timeout)
11
+ @endpoint = endpoint
12
+ create_http_client(verify_ssl, connect_timeout)
10
13
  end
11
14
 
12
15
  def publish(raw_data, source_host=nil, source_category=nil, source_name=nil)
13
- response = http.request(request_for(raw_data, source_host, source_category, source_name))
14
- unless response.is_a?(Net::HTTPSuccess)
15
- raise "Failed to send data to HTTP Source. #{response.code} - #{response.message}"
16
+ response = http.post(@endpoint, raw_data, request_headers(source_host, source_category, source_name))
17
+ unless response.ok?
18
+ raise "Failed to send data to HTTP Source. #{response.code} - #{response.body}"
16
19
  end
17
20
  end
18
21
 
19
22
  private
20
- def request_for(raw_data, source_host, source_category, source_name)
21
- request = Net::HTTP::Post.new(@endpoint_uri.request_uri)
22
- request.body = raw_data
23
- request['X-Sumo-Name'] = source_name
24
- request['X-Sumo-Category'] = source_category
25
- request['X-Sumo-Host'] = source_host
26
- request
27
- end
28
-
29
- def http
30
- # Rubys HTTP is not thread safe, so we need a new instance for each request
31
- client = Net::HTTP.new(@endpoint_uri.host, @endpoint_uri.port)
32
- client.use_ssl = true
33
- client.verify_mode = @verify_ssl ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
34
- client.open_timeout = @open_timeout
35
- client
23
+
24
+ def request_headers(source_host, source_category, source_name)
25
+ {
26
+ 'X-Sumo-Name' => source_name,
27
+ 'X-Sumo-Category' => source_category,
28
+ 'X-Sumo-Host' => source_host
29
+ }
30
+ end
31
+
32
+ def ssl_options(verify_ssl)
33
+ verify_ssl ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
34
+ end
35
+
36
+ def create_http_client(verify_ssl, connect_timeout)
37
+ @http = HTTPClient.new
38
+ @http.ssl_config.verify_mode = ssl_options(verify_ssl)
39
+ @http.connect_timeout = connect_timeout
36
40
  end
37
41
  end
38
42
 
39
- class Sumologic < Fluent::BufferedOutput
43
+ class Fluent::Plugin::Sumologic < Fluent::Plugin::Output
40
44
  # First, register the plugin. NAME is the name of this plugin
41
45
  # and identifies the plugin in the configuration file.
42
46
  Fluent::Plugin.register_output('sumologic', self)
43
47
 
48
+ helpers :compat_parameters
49
+ DEFAULT_BUFFER_TYPE = "memory"
50
+
44
51
  config_param :endpoint, :string
45
52
  config_param :log_format, :string, :default => 'json'
46
53
  config_param :log_key, :string, :default => 'message'
@@ -52,8 +59,20 @@ class Sumologic < Fluent::BufferedOutput
52
59
  config_param :delimiter, :string, :default => "."
53
60
  config_param :open_timeout, :integer, :default => 60
54
61
 
62
+ config_section :buffer do
63
+ config_set_default :@type, DEFAULT_BUFFER_TYPE
64
+ config_set_default :chunk_keys, ['tag']
65
+ end
66
+
67
+ def initialize
68
+ super
69
+ end
70
+
55
71
  # This method is called before starting.
56
72
  def configure(conf)
73
+
74
+ compat_parameters_convert(conf, :buffer)
75
+
57
76
  unless conf['endpoint'] =~ URI::regexp
58
77
  raise Fluent::ConfigError, "Invalid SumoLogic endpoint url: #{conf['endpoint']}"
59
78
  end
@@ -99,7 +118,16 @@ class Sumologic < Fluent::BufferedOutput
99
118
  end
100
119
 
101
120
  def format(tag, time, record)
102
- [tag, time, record].to_msgpack
121
+ if defined? time.nsec
122
+ mstime = time * 1000 + (time.nsec / 1000000)
123
+ [mstime, record].to_msgpack
124
+ else
125
+ [time, record].to_msgpack
126
+ end
127
+ end
128
+
129
+ def formatted_to_msgpack_binary
130
+ true
103
131
  end
104
132
 
105
133
  def sumo_key(sumo_metadata, record, tag)
@@ -128,13 +156,13 @@ class Sumologic < Fluent::BufferedOutput
128
156
  return param if (param =~ /\${.+}/).nil?
129
157
 
130
158
  # check for 'tag_parts[]'
131
- # separated by a delimiter (default '.')
159
+ # separated by a delimiter (default '.')
132
160
  tag_parts = tag.split(@delimiter) unless (param =~ /tag_parts\[.+\]/).nil? || tag.nil?
133
161
 
134
162
  # pull out section between ${} then eval
135
163
  inner = param.clone
136
164
  while inner.match(/\${.+}/)
137
- to_eval = inner.match(/\${(.+?)}/){$1}
165
+ to_eval = inner.match(/\${(.+?)}/) { $1 }
138
166
 
139
167
  if !(to_eval =~ /record\[.+\]/).nil? && record.nil?
140
168
  return to_eval
@@ -143,7 +171,7 @@ class Sumologic < Fluent::BufferedOutput
143
171
  elsif !(to_eval =~/time/).nil? && time.nil?
144
172
  return to_eval
145
173
  else
146
- inner.sub!(/\${.+?}/, eval( to_eval ))
174
+ inner.sub!(/\${.+?}/, eval(to_eval))
147
175
  end
148
176
  end
149
177
  inner
@@ -151,16 +179,17 @@ class Sumologic < Fluent::BufferedOutput
151
179
 
152
180
  # This method is called every flush interval. Write the buffer chunk
153
181
  def write(chunk)
182
+ tag = chunk.metadata.tag
154
183
  messages_list = {}
155
184
 
156
185
  # Sort messages
157
- chunk.msgpack_each do |tag, time, record|
186
+ chunk.msgpack_each do |time, record|
158
187
  # plugin dies randomly
159
188
  # https://github.com/uken/fluent-plugin-elasticsearch/commit/8597b5d1faf34dd1f1523bfec45852d380b26601#diff-ae62a005780cc730c558e3e4f47cc544R94
160
189
  next unless record.is_a? Hash
161
- sumo_metadata = record.fetch('_sumo_metadata', {'source' => record[@source_name_key]})
162
- key = sumo_key(sumo_metadata, record, tag)
163
- log_format = sumo_metadata['log_format'] || @log_format
190
+ sumo_metadata = record.fetch('_sumo_metadata', { 'source' => record[@source_name_key] })
191
+ key = sumo_key(sumo_metadata, record, tag)
192
+ log_format = sumo_metadata['log_format'] || @log_format
164
193
 
165
194
  # Strip any unwanted newlines
166
195
  record[@log_key].chomp! if record[@log_key]
@@ -172,9 +201,9 @@ class Sumologic < Fluent::BufferedOutput
172
201
  log.strip!
173
202
  end
174
203
  when 'json_merge'
175
- log = dump_log(merge_json({:timestamp => sumo_timestamp(time)}.merge(record)))
204
+ log = dump_log(merge_json({ :timestamp => sumo_timestamp(time) }.merge(record)))
176
205
  else
177
- log = dump_log({:timestamp => sumo_timestamp(time)}.merge(record))
206
+ log = dump_log({ :timestamp => sumo_timestamp(time) }.merge(record))
178
207
  end
179
208
 
180
209
  unless log.nil?
@@ -192,9 +221,9 @@ class Sumologic < Fluent::BufferedOutput
192
221
  source_name, source_category, source_host = key.split(':')
193
222
  @sumo_conn.publish(
194
223
  messages.join("\n"),
195
- source_host=source_host,
224
+ source_host =source_host,
196
225
  source_category=source_category,
197
- source_name=source_name
226
+ source_name =source_name
198
227
  )
199
228
  end
200
229
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-sumologic_output
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Adams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-26 00:00:00.000000000 Z
11
+ date: 2017-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: 3.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: httpclient
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.8.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.8.0
69
83
  description: Output plugin to SumoLogic HTTP Endpoint
70
84
  email:
71
85
  - stevezau@gmail.com