fluent-plugin-https-client 0.0.1

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
+ SHA1:
3
+ metadata.gz: 3b59b6107b871dd3b8d36e7df137961cd9f1a68e
4
+ data.tar.gz: 63f34236d611c5e7968e298a696a2d934b66aa88
5
+ SHA512:
6
+ metadata.gz: 3da69d57d183d3fac60a0f40e0388633c2efe78ffa525d6651e58dba39ac65a5c7724fc6b20f34346df1889e5fb1712465fdd2e60f86a37ca9d971369eafa1c6
7
+ data.tar.gz: 745b017399dc6383bc9669953cf9d0a5964926ef27fcb9414226f8fbd83280523d165e5d7705d5c9c5d31cba408f631286c4d237c80deccdbeaf9c9c528682cc
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ ## Fluent::Plugin::HTTPSClient
2
+
3
+ Output plugin for [Fluentd](http://fluentd.org), for sending records to an HTTP or HTTPS endpoint, with SSL, Proxy,
4
+ and Header implementation.
5
+
6
+ ## Configuration Guide
7
+
8
+ <match *>
9
+ type https_client
10
+ endpoint_url # endpoint_url
11
+ http_method # get / post / put / delete defaults to post
12
+ serializer # json / form defaults to form
13
+ include_timestamp # true / false defaults to false
14
+ rate_limit_msec # limit the rate in ms, defaults to 10 ms
15
+ auth # basic / none
16
+ use_ssl # true / false
17
+ proxy_addr # proxy url
18
+ proxy_port # proxy port
19
+ username # user name if auth is basic
20
+ password # password if auth is basic
21
+ <header> # HTTP headers (see examples below)
22
+ Accept application/json
23
+ auth_token my_secret
24
+ </header>
25
+ </match>
26
+
27
+
28
+ ### Use Cases
29
+ * send records to HTTP endpoints
30
+ * send records to HTTPS endpoints
31
+ * send events through proxy
32
+ * send events by setting custom headers (header-based authentication, etc)
33
+
34
+
35
+ ### Credits
36
+ * Majority of the code is cloned from [fluent-plugin-out-http][2]
37
+ * SSL implementation from [fluent-plugin-out-https][3]
38
+
39
+ ### Exception Handling
40
+ * For retries in case of exceptions, use
41
+ [fluent-plugin-bufferize](https://github.com/kazegusuri/fluent-plugin-bufferize) as a wrapper.
42
+
43
+
44
+
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'fluent-plugin-https-client'
5
+ gem.version = '0.0.1'
6
+ gem.authors = ['Arash Vatanpoor']
7
+ gem.email = ['arash@a-venture.org']
8
+ gem.summary = %q{A generic Fluentd output plugin to send records to HTTP / HTTPS endpoint}
9
+ gem.description = %q{A generic Fluentd output plugin to send records to HTTP / HTTPS endpoint, with SSL, Proxy, and Header implementation}
10
+ gem.homepage = 'https://github.com/a-venture/fluent-plugin-https-client'
11
+ gem.license = 'MIT'
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.require_paths = ['lib']
16
+ gem.required_ruby_version = '>= 2.1.2'
17
+
18
+ gem.add_runtime_dependency 'yajl-ruby', '~> 1.0'
19
+ gem.add_runtime_dependency 'fluentd', '~> 0.12'
20
+ end
@@ -0,0 +1,174 @@
1
+ class Fluent::HTTPSOutput < Fluent::Output
2
+ Fluent::Plugin.register_output('https_client', self)
3
+
4
+ def initialize
5
+ super
6
+ require 'net/https'
7
+ require 'openssl'
8
+ require 'uri'
9
+ require 'yajl'
10
+ end
11
+
12
+ config_param :use_ssl, :bool, :default => false
13
+ config_param :include_tag, :bool, :default => false
14
+ config_param :include_timestamp, :bool, :default => false
15
+ config_param :endpoint_url, :string
16
+ config_param :http_method, :string, :default => :post
17
+ config_param :serializer, :string, :default => :form
18
+ config_param :rate_limit_msec, :integer, :default => 10
19
+ config_param :auth, :string, :default => nil
20
+ config_param :username, :string, :default => ''
21
+ config_param :password, :string, :default => ''
22
+ config_param :proxy_addr, :string, :default => ''
23
+ config_param :proxy_port, :integer, :default => -1
24
+
25
+
26
+
27
+ def configure(conf)
28
+ super
29
+
30
+ @use_ssl = conf['use_ssl']
31
+ @include_tag = conf['include_tag']
32
+ @include_timestamp = conf['include_timestamp']
33
+
34
+
35
+ @use_proxy = false
36
+ if @proxy_port and @proxy_addr
37
+ # check for proxy settings
38
+ if @proxy_port > 0 and @proxy_addr.empty?
39
+ raise Fluent::ConfigError, 'HTTPS Output :: provide a valid proxy address'
40
+ elsif @proxy_port <= 0 and !@proxy_addr.empty?
41
+ raise Fluent::ConfigError, 'HTTPS Output :: provide a valid proxy port number'
42
+ elsif @proxy_port == 0
43
+ raise Fluent::ConfigError, 'HTTPS Output :: provide a valid proxy port number'
44
+ elsif @proxy_port > 0 and !@proxy_addr.empty?
45
+ @use_proxy = true
46
+ end
47
+ end
48
+
49
+ serializers = [:json, :form]
50
+ @serializer = if serializers.include? @serializer.intern
51
+ @serializer.intern
52
+ else
53
+ :form
54
+ end
55
+
56
+ http_methods = [:get, :put, :post, :delete]
57
+ @http_method = if http_methods.include? @http_method.intern
58
+ @http_method.intern
59
+ else
60
+ :post
61
+ end
62
+
63
+ @auth = case @auth
64
+ when 'basic' then :basic
65
+ else
66
+ :none
67
+ end
68
+
69
+ # create the headers hash
70
+ @headers = {}
71
+ conf.elements.each do |elem|
72
+ elem.keys.each do |key|
73
+ @headers[key] = elem[key]
74
+ end
75
+ end
76
+ end
77
+
78
+ def start
79
+ super
80
+ end
81
+
82
+ def shutdown
83
+ super
84
+ end
85
+
86
+ def format_url
87
+ @endpoint_url
88
+ end
89
+
90
+ def set_body(req, tag, record)
91
+ if @include_tag
92
+ record['tag'] = tag
93
+ end
94
+ if @include_timestamp
95
+ record['timestamp'] = Time.now.to_i
96
+ end
97
+ if @serializer == :json
98
+ set_json_body(req, record)
99
+ else
100
+ req.set_form_data(record)
101
+ end
102
+ req
103
+ end
104
+
105
+ def set_header(req)
106
+ @headers.each do |key, value|
107
+ req[key] = value
108
+ end
109
+ end
110
+
111
+ def set_json_body(req, data)
112
+ req.body = Yajl.dump(data)
113
+ req['Content-Type'] = 'application/json'
114
+ end
115
+
116
+ def create_request(tag, time, record)
117
+ url = format_url()
118
+ uri = URI.parse(url)
119
+ req = Net::HTTP.const_get(@http_method.to_s.capitalize).new(uri.path)
120
+ set_body(req, tag, record)
121
+ set_header(req)
122
+ return req, uri
123
+ end
124
+
125
+ def send_request(req, uri, record)
126
+ is_rate_limited = (@rate_limit_msec != 0 and not @last_request_time.nil?)
127
+ if is_rate_limited and ((Time.now.to_f - @last_request_time) * 1000.0 < @rate_limit_msec)
128
+ $log.info('Dropped request due to rate limiting')
129
+ return
130
+ end
131
+
132
+ res = nil
133
+ begin
134
+ if @auth and @auth == :basic
135
+ req.basic_auth(@username, @password)
136
+ end
137
+ @last_request_time = Time.now.to_f
138
+ if @use_proxy
139
+ https = Net::HTTP.new(uri.host, uri.port, @proxy_addr, @proxy_port)
140
+ else
141
+ https = Net::HTTP.new(uri.host, uri.port)
142
+ end
143
+ https.use_ssl = @use_ssl
144
+ https.ca_file = OpenSSL::X509::DEFAULT_CERT_FILE
145
+ https.verify_mode = OpenSSL::SSL::VERIFY_NONE
146
+ res = https.start {|http| http.request(req) }
147
+ rescue IOError, EOFError, SystemCallError
148
+ $log.warn "HTTPS Output :: Net::HTTP.#{req.method.capitalize} raises exception: #{$!.class}, '#{$!.message}'"
149
+ end
150
+ unless res and res.is_a?(Net::HTTPSuccess)
151
+ res_summary = if res
152
+ "#{res.code} #{res.message} #{res.body}"
153
+ else
154
+ "res=nil"
155
+ end
156
+ $log.warn "HTTPS Output :: failed to #{req.method} #{uri} (#{res_summary})"
157
+ $log.warn "HTTPS Output :: record failed to send : #{record}"
158
+ else
159
+ $log.info "HTTPS Output :: emitted record : #{record}"
160
+ end
161
+ end
162
+
163
+ def handle_record(tag, time, record)
164
+ req, uri = create_request(tag, time, record)
165
+ send_request(req, uri, record)
166
+ end
167
+
168
+ def emit(tag, es, chain)
169
+ es.each do |time, record|
170
+ handle_record(tag, time, record)
171
+ end
172
+ chain.next
173
+ end
174
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-https-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Arash Vatanpoor
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: yajl-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fluentd
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.12'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.12'
41
+ description: A generic Fluentd output plugin to send records to HTTP / HTTPS endpoint,
42
+ with SSL, Proxy, and Header implementation
43
+ email:
44
+ - arash@a-venture.org
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - README.md
50
+ - fluent-plugin-https-client.gemspec
51
+ - lib/fluent/plugin/out_https_client.rb
52
+ homepage: https://github.com/a-venture/fluent-plugin-https-client
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 2.1.2
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 2.6.8
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: A generic Fluentd output plugin to send records to HTTP / HTTPS endpoint
76
+ test_files: []