fluent-plugin-http-status 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-http-response.gemspec
4
+ gemspec
5
+ gem 'mocha'
6
+ gem 'webmock'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 sugimoto hiroshi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # Fluent::Plugin::Http::Status
2
+
3
+ Fluentd input plugin for to get the http status.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'fluent-plugin-http-status'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install fluent-plugin-http-status
18
+
19
+ ## Usage
20
+
21
+ Config
22
+
23
+ <source>
24
+ type http_status
25
+ tag http.status
26
+ url https://rubygems.org
27
+ polling_time 1m
28
+
29
+ #=== options ===
30
+ #port 80
31
+ #basic_user user
32
+ #basic_password pass
33
+ #proxy_address proxy.test.jp
34
+ #proxy_port 8080
35
+ #proxy_user user
36
+ #proxy_password pass
37
+ #params server,date
38
+ #open_timeout 10
39
+ #read_timeout 20
40
+ </source>
41
+
42
+ <match http.status>
43
+ type stdout
44
+ </match>
45
+
46
+ Result
47
+
48
+ Time : 2012-11-19 03:29:29 +0900
49
+ Tag : http.status
50
+ Record : {"url":"https://rubygems.org","host":"rubygems.org","port":443,"request_uri":"/","code":200,"message":"OK","class_name":"Net::HTTPOK","ipaddress":"204.232.149.25","headers":{"server":"nginx/1.2.2", ...
51
+
52
+ ## Copyright
53
+ Copyright (c) 2012 hiro-su
54
+ Apache Licence, Version 2.0
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+ Rake::TestTask.new(:test) do |test|
4
+ test.libs << 'lib' << 'test'
5
+ test.pattern = 'test/**/test_*.rb'
6
+ test.verbose = false
7
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "fluent-plugin-http-status"
7
+ gem.version = "0.0.1"
8
+ gem.authors = ["hiro-su"]
9
+ gem.email = ["h.sugipon@gmail.com"]
10
+ gem.description = %q{Fluentd input plugin for to get the http status}
11
+ gem.summary = %q{Fluentd input plugin for to get the http status}
12
+ gem.homepage = ""
13
+
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.add_development_dependency "fluentd"
20
+ gem.add_development_dependency "polling"
21
+ gem.add_runtime_dependency "fluentd"
22
+ gem.add_runtime_dependency "polling"
23
+ end
data/http.conf.sample ADDED
@@ -0,0 +1,21 @@
1
+ <source>
2
+ type http_status
3
+ tag http.status
4
+ url https://rubygems.org
5
+ polling_time 1m
6
+
7
+ #port 80
8
+ #basic_user user
9
+ #basic_password pass
10
+ #proxy_address proxy.test.jp
11
+ #proxy_port 8080
12
+ #proxy_user user
13
+ #proxy_password pass
14
+ #params server,date
15
+ #open_timeout 10
16
+ #read_timeout 20
17
+ </source>
18
+
19
+ <match http.*>
20
+ type stdout
21
+ </match>
@@ -0,0 +1,139 @@
1
+ require "polling"
2
+ require "net/http"
3
+ require "net/https"
4
+ require "uri"
5
+ require "socket"
6
+
7
+ module Fluent
8
+ class HttpStatusInput < Input
9
+ Plugin.register_input('http_status',self)
10
+
11
+ config_param :tag, :string
12
+ config_param :url, :string
13
+ config_param :port, :integer, :default => nil
14
+ config_param :proxy_address, :string, :default => nil
15
+ config_param :proxy_port, :integer, :default => nil
16
+ config_param :proxy_user, :string, :default => nil
17
+ config_param :proxy_password, :string, :default => nil
18
+ config_param :open_timeout, :integer, :default => 10
19
+ config_param :read_timeout, :integer, :default => 20
20
+ config_param :params, :string, :default => nil
21
+ config_param :polling_time, :string
22
+ config_param :basic_user, :string, :default => nil
23
+ config_param :basic_password, :string, :default => nil
24
+
25
+ def configure(conf)
26
+ super
27
+ @params = @params.split(',').map{|str| str.strip} unless @params.nil?
28
+ @polling_time = @polling_time.split(',').map{|str| str.strip} unless @polling_time.nil?
29
+ raise ConfigError, "snmp: 'polling_time' parameter is required on snmp input" if !@polling_time.nil? && @polling_time.empty?
30
+ @retry_count = 0
31
+ end
32
+
33
+ def starter
34
+ Net::HTTP.version_1_2
35
+ @starter=Thread.new{yield}
36
+ end
37
+
38
+ def start
39
+ starter{@thread=Thread.new(&method(:run))}
40
+ end
41
+
42
+ def run
43
+ Polling::run(@polling_time) do
44
+ record = Hash.new
45
+ args = {
46
+ :url => @url,
47
+ :port => @port,
48
+ :proxy_address => @proxy_address,
49
+ :proxy_port => @proxy_port,
50
+ :proxy_user => @proxy_user,
51
+ :proxy_password => @proxy_password,
52
+ :params => @params
53
+ }
54
+ Engine.emit(@tag, Engine.now, get_status(record,args))
55
+ break if @end_flag
56
+ end
57
+ rescue TypeError => ex
58
+ $log.error "run TypeError", :error=>ex.message
59
+ exit
60
+ rescue => ex
61
+ $log.error "run failed", :error=>ex.message
62
+ sleep(10)
63
+ @retry_count += 1
64
+ retry if @retry_count < 30
65
+ end
66
+
67
+ def shutdown
68
+ @end_flag ||= true
69
+ @thread.run
70
+ @thread.join
71
+ @starter.join
72
+ end
73
+
74
+ private
75
+
76
+ def get_status(hash,*args)
77
+ args.each do |arg|
78
+ @url = arg[:url]
79
+ @port = arg[:port]
80
+ @proxy_address = arg[:proxy_address]
81
+ @proxy_port = arg[:proxy_port]
82
+ @proxy_user = arg[:proxy_user]
83
+ @proxy_password = arg[:proxy_password]
84
+ @params = arg[:params]
85
+ end
86
+
87
+ start = Time.now
88
+
89
+ uri = URI.parse("#{@url}:#{@port}")
90
+ host = uri.host
91
+ port = uri.port
92
+ request_uri = uri.request_uri
93
+
94
+ http = Net::HTTP.new(host,port,@proxy_address,@proxy_port,@proxy_user,@proxy_password)
95
+ http.open_timeout = @open_timeout
96
+ http.read_timeout = @read_timeout
97
+
98
+ if uri.port == 443
99
+ http.use_ssl = true
100
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
101
+ http.verify_depth = 5
102
+ end
103
+
104
+ req = Net::HTTP::Head.new(request_uri)
105
+ req.basic_auth @basic_user, @basic_password
106
+ response = http.request(req)
107
+
108
+ hash[:url] = url
109
+ hash[:host] = host
110
+ hash[:port] = port
111
+ hash[:request_uri] = request_uri
112
+ hash[:proxy_address] = @proxy_address if @proxy_address
113
+ hash[:proxy_port] = @proxy_port if @proxy_port
114
+ hash[:code] = response.code.to_i
115
+ hash[:message] = response.message
116
+ hash[:class_name] = response.class.name
117
+ hostent = Socket.gethostbyname(host)
118
+ hash[:ipaddress] = hostent[3].unpack("C4").join('.')
119
+ hash[:headers] = Hash.new
120
+
121
+ response.each_key{|name|
122
+ if @params
123
+ @params.each{|param| hash[:headers][param] = response[param] =~ /^-?\d+$/ ? response[param].to_i : response[param]}
124
+ else
125
+ hash[:headers][name] = response[name] =~ /^-?\d+$/ ? response[name].to_i : response[name]
126
+ end
127
+ }
128
+
129
+ hash[:response_time] = Time.now - start
130
+
131
+ return hash
132
+ rescue Timeout::Error => ex
133
+ return "Timeout Error : #{ex}"
134
+ rescue => ex
135
+ return ex.message
136
+ end
137
+
138
+ end
139
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'test/unit'
5
+ require 'fluent/test'
6
+
7
+ unless ENV.has_key?('VERBOSE')
8
+ nulllogger = Object.new
9
+ nulllogger.instance_eval {|obj|
10
+ def method_missing(method, *args)
11
+ # pass
12
+ end
13
+ }
14
+ $log = nulllogger
15
+ end
16
+
17
+ require 'fluent/plugin/in_http_status'
18
+
19
+ class Test::Unit::TestCase
20
+ end
@@ -0,0 +1,105 @@
1
+ require 'helper'
2
+ require 'mocha/setup'
3
+ require 'webmock/test_unit'
4
+ require 'socket'
5
+
6
+ class HttpStatusInputTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ Fluent::Test.setup
10
+ @obj = Fluent::HttpStatusInput.new
11
+ @hash = Hash.new
12
+ end
13
+
14
+ CONFIG = %[
15
+ tag http.status
16
+ url http://www.test.ad.jp
17
+ port 80
18
+ basic_user user
19
+ basic_password password
20
+ proxy_address proxy.test.jp
21
+ proxy_port 8080
22
+ proxy_user proxy_user
23
+ proxy_password proxy_password
24
+ polling_time 10s
25
+ #params server,date
26
+ ]
27
+
28
+ def create_driver(conf=CONFIG)
29
+ Fluent::Test::InputTestDriver.new(Fluent::HttpStatusInput).configure(conf)
30
+ end
31
+
32
+ def test_configure
33
+ d = create_driver
34
+
35
+ assert_equal "http.status", d.instance.tag
36
+ assert_equal "http://www.test.ad.jp", d.instance.url
37
+ assert_equal 80, d.instance.port
38
+ assert_equal "user", d.instance.basic_user
39
+ assert_equal "password", d.instance.basic_password
40
+ assert_equal "proxy.test.jp", d.instance.proxy_address
41
+ assert_equal "proxy_user", d.instance.proxy_user
42
+ assert_equal "proxy_password", d.instance.proxy_password
43
+ assert_equal 8080, d.instance.proxy_port
44
+ assert_equal ["10s"], d.instance.polling_time
45
+ #assert_equal ["server","date"], d.instance.params
46
+ end
47
+
48
+ def test_get_status
49
+ d = create_driver
50
+ args = {
51
+ :url => d.instance.url,
52
+ :port => d.instance.port,
53
+ :proxy_address => d.instance.proxy_address,
54
+ :proxy_port => d.instance.proxy_port,
55
+ :proxy_user => d.instance.proxy_user,
56
+ :proxy_password => d.instance.proxy_password,
57
+ :params => d.instance.params
58
+ }
59
+
60
+ headers = {}
61
+ headers[:headers] = {
62
+ "server" => "Apache",
63
+ "date" => "Sun, 18 Nov 2012 17:12:09 GMT",
64
+ "last-modified" => "Thu, 15 Nov 2012 02:00:30 GMT",
65
+ "etag" => "\"68c9e3-4356-3fe2b80\"",
66
+ "accept-ranges" => "bytes",
67
+ "content-length" => "17238",
68
+ "content-type" => "text/html",
69
+ "via" => "1.1 www.test.ad.jp",
70
+ "connection" => "close"
71
+ }
72
+
73
+ Socket.stubs(:gethostbyname).returns(["www.test.ad.jp", [], 0, "\xC0\xA8\x00\x01"])
74
+ WebMock.stub_request(:head, "www.test.ad.jp").to_return(:status => 200, :headers => headers[:headers])
75
+ res_data = @obj.__send__(:get_status,@hash,args)
76
+ res_data[:response_time] = 0.001239
77
+
78
+ result_hash = {
79
+ :url=>"http://www.test.ad.jp",
80
+ :host=>"www.test.ad.jp",
81
+ :port=>80, :request_uri=>"/",
82
+ :proxy_address=>"proxy.test.jp",
83
+ :proxy_port=>8080,
84
+ :code=>200,
85
+ :message=>"",
86
+ :class_name=>"Net::HTTPOK",
87
+ :ipaddress=>"192.168.0.1",
88
+ :response_time=>0.001239,
89
+ :headers=>{
90
+ "server"=>"Apache",
91
+ "date"=>"Sun, 18 Nov 2012 17:12:09 GMT",
92
+ "last-modified"=>"Thu, 15 Nov 2012 02:00:30 GMT",
93
+ "etag"=>"\"68c9e3-4356-3fe2b80\"",
94
+ "accept-ranges"=>"bytes",
95
+ "content-length"=>17238,
96
+ "content-type"=>"text/html",
97
+ "via"=>"1.1 www.test.ad.jp",
98
+ "connection"=>"close"
99
+ }
100
+ }
101
+
102
+ assert_equal result_hash, res_data
103
+ end
104
+
105
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-http-status
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - hiro-su
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fluentd
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: polling
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: fluentd
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: polling
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Fluentd input plugin for to get the http status
79
+ email:
80
+ - h.sugipon@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - LICENSE.txt
88
+ - README.md
89
+ - Rakefile
90
+ - fluent-plugin-http-status.gemspec
91
+ - http.conf.sample
92
+ - lib/fluent/plugin/in_http_status.rb
93
+ - test/helper.rb
94
+ - test/plugin/test_in_http_status.rb
95
+ homepage: ''
96
+ licenses: []
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 1.8.24
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Fluentd input plugin for to get the http status
119
+ test_files:
120
+ - test/helper.rb
121
+ - test/plugin/test_in_http_status.rb