fluent-plugin-dstat 0.2.3 → 0.2.4
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 +7 -0
- data/README.md +8 -4
- data/VERSION +1 -1
- data/fluent-plugin-dstat.gemspec +6 -5
- data/lib/fluent/plugin/in_dstat.rb +151 -144
- metadata +18 -33
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fc4761593955b9c9bd4cb5bd1488446829ee8e23
|
4
|
+
data.tar.gz: 6082e8de5344ea01c541dd452466c670452625f5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1b83eefbe45c89710d3da6cdb8d96eacc247b784f61d620d0b769d8bf365501c6b9e3c295e7dd2c58f52f96035e29ca2a695f708282b9f4e6dc628440ebd258c
|
7
|
+
data.tar.gz: 83be387534ec99e441d59994d10f5bec21d894205f46d3bbd67119a3ab1368c56950be540f85d5c2a3ab83d80c0917d9bfa26527706d7dc32f908861a55adca6
|
data/README.md
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
Dstat plugin for
|
2
|
-
|
3
|
-
Description goes here.
|
1
|
+
Dstat plugin for [Fluentd](http://fluentd.org)
|
4
2
|
|
5
3
|
## What's Dstat?
|
6
4
|
|
@@ -19,7 +17,13 @@ This plugin use Dstat, so you need to install Dstat before using this plugin.
|
|
19
17
|
</source>
|
20
18
|
```
|
21
19
|
|
22
|
-
|
20
|
+
#### Parameters
|
21
|
+
|
22
|
+
* option
|
23
|
+
* option for dstat command (default: -fcdnm)
|
24
|
+
|
25
|
+
* tag
|
26
|
+
* supported ${hostname} placeholder powered by [Fluent::Mixin::RewriteTagName](https://github.com/y-ken/fluent-mixin-rewrite-tag-name)
|
23
27
|
|
24
28
|
## Output Format
|
25
29
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.4
|
data/fluent-plugin-dstat.gemspec
CHANGED
@@ -2,14 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: fluent-plugin-dstat 0.2.4 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "fluent-plugin-dstat"
|
8
|
-
s.version = "0.2.
|
9
|
+
s.version = "0.2.4"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Shunsuke Mikami"]
|
12
|
-
s.date = "
|
14
|
+
s.date = "2014-02-09"
|
13
15
|
s.email = "shun0102@gmail.com"
|
14
16
|
s.extra_rdoc_files = [
|
15
17
|
"LICENSE.txt",
|
@@ -29,12 +31,11 @@ Gem::Specification.new do |s|
|
|
29
31
|
"test/plugin/test_in_dstat.rb"
|
30
32
|
]
|
31
33
|
s.homepage = "http://github.com/shun0102/fluent-plugin-dstat"
|
32
|
-
s.
|
33
|
-
s.rubygems_version = "1.8.23"
|
34
|
+
s.rubygems_version = "2.2.0"
|
34
35
|
s.summary = "Dstat Input plugin for Fluent event collector"
|
35
36
|
|
36
37
|
if s.respond_to? :specification_version then
|
37
|
-
s.specification_version =
|
38
|
+
s.specification_version = 4
|
38
39
|
|
39
40
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
40
41
|
s.add_runtime_dependency(%q<fluentd>, ["~> 0.10.7"])
|
@@ -1,176 +1,183 @@
|
|
1
|
+
require 'fluent/mixin/rewrite_tag_name'
|
2
|
+
|
1
3
|
module Fluent
|
4
|
+
class DstatInput < Input
|
2
5
|
|
3
|
-
|
6
|
+
Plugin.register_input('dstat', self)
|
4
7
|
|
5
|
-
|
8
|
+
def initialize
|
9
|
+
super
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@last_time = Time.now
|
16
|
-
end
|
11
|
+
require 'csv'
|
12
|
+
@line_number = 0
|
13
|
+
@first_keys = []
|
14
|
+
@second_keys = []
|
15
|
+
@data_array = []
|
16
|
+
@max_lines = 100
|
17
|
+
@last_time = Time.now
|
18
|
+
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
config_param :tag, :string
|
21
|
+
config_param :dstat_path, :string, :default => "dstat"
|
22
|
+
config_param :option, :string, :default => "-fcdnm"
|
23
|
+
config_param :delay, :integer, :default => 1
|
24
|
+
config_param :tmp_file, :string, :default => "/tmp/dstat.csv"
|
25
|
+
config_param :hostname_command, :string, :default => "hostname"
|
23
26
|
|
24
|
-
|
25
|
-
super
|
26
|
-
@command = "dstat #{@option} --output #{@tmp_file} #{@delay}"
|
27
|
-
@hostname = `#{@hostname_command}`.chomp!
|
28
|
-
end
|
27
|
+
include Fluent::Mixin::RewriteTagName
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
end
|
29
|
+
def configure(conf)
|
30
|
+
super
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
@pid = @io.pid
|
38
|
-
|
39
|
-
@loop = Coolio::Loop.new
|
40
|
-
@dw = DstatCSVWatcher.new(@tmp_file, &method(:receive_lines))
|
41
|
-
@dw.attach(@loop)
|
42
|
-
@tw = TimerWatcher.new(1, true, &method(:check_dstat))
|
43
|
-
@tw.attach(@loop)
|
44
|
-
@thread = Thread.new(&method(:run))
|
45
|
-
end
|
32
|
+
@command = "#{@dstat_path} #{@option} --output #{@tmp_file} #{@delay}"
|
33
|
+
@hostname = `#{@hostname_command}`.chomp!
|
34
|
+
end
|
46
35
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@tw.detach
|
51
|
-
@loop.stop
|
52
|
-
@thread.join
|
53
|
-
File.delete(@tmp_file)
|
54
|
-
end
|
36
|
+
def check_dstat
|
37
|
+
restart if (Time.now - @last_time) > @delay*3
|
38
|
+
end
|
55
39
|
|
56
|
-
|
57
|
-
|
58
|
-
@
|
59
|
-
|
60
|
-
|
61
|
-
|
40
|
+
def start
|
41
|
+
touch_or_truncate(@tmp_file)
|
42
|
+
@io = IO.popen(@command, "r")
|
43
|
+
@pid = @io.pid
|
44
|
+
|
45
|
+
@loop = Coolio::Loop.new
|
46
|
+
@dw = DstatCSVWatcher.new(@tmp_file, &method(:receive_lines))
|
47
|
+
@dw.attach(@loop)
|
48
|
+
@tw = TimerWatcher.new(1, true, &method(:check_dstat))
|
49
|
+
@tw.attach(@loop)
|
50
|
+
@thread = Thread.new(&method(:run))
|
62
51
|
end
|
63
|
-
end
|
64
52
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
@io = IO.popen(@command, "r")
|
74
|
-
@pid = @io.pid
|
75
|
-
@dw = DstatCSVWatcher.new(@tmp_file, &method(:receive_lines))
|
76
|
-
@dw.attach(@loop)
|
77
|
-
@tw = TimerWatcher.new(1, true, &method(:check_dstat))
|
78
|
-
@tw.attach(@loop)
|
79
|
-
end
|
53
|
+
def shutdown
|
54
|
+
Process.kill(:TERM, @pid)
|
55
|
+
@dw.detach
|
56
|
+
@tw.detach
|
57
|
+
@loop.stop
|
58
|
+
@thread.join
|
59
|
+
File.delete(@tmp_file)
|
60
|
+
end
|
80
61
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
62
|
+
def run
|
63
|
+
begin
|
64
|
+
@loop.run
|
65
|
+
rescue
|
66
|
+
$log.error "unexpected error", :error=>$!.to_s
|
67
|
+
$log.error_backtrace
|
68
|
+
end
|
86
69
|
end
|
87
|
-
end
|
88
70
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
71
|
+
def restart
|
72
|
+
Process.detach(@pid)
|
73
|
+
Process.kill(:TERM, @pid)
|
74
|
+
@dw.detach
|
75
|
+
@tw.detach
|
76
|
+
@line_number = 0
|
77
|
+
touch_or_truncate(@tmp_file)
|
78
|
+
|
79
|
+
@io = IO.popen(@command, "r")
|
80
|
+
@pid = @io.pid
|
81
|
+
@dw = DstatCSVWatcher.new(@tmp_file, &method(:receive_lines))
|
82
|
+
@dw.attach(@loop)
|
83
|
+
@tw = TimerWatcher.new(1, true, &method(:check_dstat))
|
84
|
+
@tw.attach(@loop)
|
85
|
+
end
|
86
|
+
|
87
|
+
def touch_or_truncate(file)
|
88
|
+
if File.exist?(file)
|
89
|
+
File.truncate(file, 0)
|
90
|
+
else
|
91
|
+
`touch #{file}`
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def receive_lines(lines)
|
96
|
+
lines.each do |line|
|
97
|
+
next if line == ""
|
98
|
+
case @line_number
|
99
|
+
when 0..1
|
100
|
+
when 2
|
101
|
+
line.delete!("\"")
|
102
|
+
@first_keys = CSV.parse_line(line)
|
103
|
+
pre_key = ""
|
104
|
+
@first_keys.each_with_index do |key, index|
|
105
|
+
if key.nil? || key == ""
|
106
|
+
@first_keys[index] = pre_key
|
107
|
+
end
|
108
|
+
pre_key = @first_keys[index]
|
101
109
|
end
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
110
|
+
when 3
|
111
|
+
line.delete!("\"")
|
112
|
+
@second_keys = line.split(',')
|
113
|
+
@first_keys.each_with_index do |key, index|
|
114
|
+
@data_array[index] = {}
|
115
|
+
@data_array[index][:first] = key
|
116
|
+
@data_array[index][:second] = @second_keys[index]
|
117
|
+
end
|
118
|
+
else
|
119
|
+
values = line.split(',')
|
120
|
+
data = Hash.new { |hash,key| hash[key] = Hash.new {} }
|
121
|
+
values.each_with_index do |v, index|
|
122
|
+
data[@first_keys[index]][@second_keys[index]] = v
|
123
|
+
end
|
124
|
+
record = {
|
125
|
+
'hostname' => @hostname,
|
126
|
+
'dstat' => data
|
127
|
+
}
|
128
|
+
emit_tag = @tag.dup
|
129
|
+
filter_record(emit_tag, Engine.now, record)
|
130
|
+
Engine.emit(emit_tag, Engine.now, record)
|
111
131
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
132
|
+
|
133
|
+
if (@line_number % @max_lines) == (@max_lines - 1)
|
134
|
+
@dw.detach
|
135
|
+
File.truncate(@tmp_file, 0)
|
136
|
+
@dw = DstatCSVWatcher.new(@tmp_file, &method(:receive_lines))
|
137
|
+
@dw.attach(@loop)
|
117
138
|
end
|
118
|
-
record = {
|
119
|
-
'hostname' => @hostname,
|
120
|
-
'dstat' => data
|
121
|
-
}
|
122
|
-
Engine.emit(@tag, Engine.now, record)
|
123
|
-
end
|
124
139
|
|
125
|
-
|
126
|
-
@
|
127
|
-
File.truncate(@tmp_file, 0)
|
128
|
-
@dw = DstatCSVWatcher.new(@tmp_file, &method(:receive_lines))
|
129
|
-
@dw.attach(@loop)
|
140
|
+
@line_number += 1
|
141
|
+
@last_time = Time.now
|
130
142
|
end
|
131
143
|
|
132
|
-
@line_number += 1
|
133
|
-
@last_time = Time.now
|
134
144
|
end
|
135
145
|
|
136
|
-
|
146
|
+
class DstatCSVWatcher < Cool.io::StatWatcher
|
147
|
+
INTERVAL = 0.500
|
148
|
+
attr_accessor :previous, :cur
|
137
149
|
|
138
|
-
|
139
|
-
|
140
|
-
|
150
|
+
def initialize(path, &receive_lines)
|
151
|
+
super path, INTERVAL
|
152
|
+
@path = path
|
153
|
+
@io = File.open(path)
|
154
|
+
@pos = 0
|
155
|
+
@receive_lines = receive_lines
|
156
|
+
end
|
141
157
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
158
|
+
def on_change(prev, cur)
|
159
|
+
buffer = @io.read(cur.size - @pos)
|
160
|
+
@pos = cur.size
|
161
|
+
lines = []
|
162
|
+
while line = buffer.slice!(/.*?\n/m)
|
163
|
+
lines << line.chomp
|
164
|
+
end
|
165
|
+
@receive_lines.call(lines)
|
166
|
+
end
|
148
167
|
end
|
149
168
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
while line = buffer.slice!(/.*?\n/m)
|
155
|
-
lines << line.chomp
|
169
|
+
class TimerWatcher < Coolio::TimerWatcher
|
170
|
+
def initialize(interval, repeat, &check_dstat)
|
171
|
+
@check_dstat = check_dstat
|
172
|
+
super(interval, repeat)
|
156
173
|
end
|
157
|
-
@receive_lines.call(lines)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
class TimerWatcher < Coolio::TimerWatcher
|
161
|
-
def initialize(interval, repeat, &check_dstat)
|
162
|
-
@check_dstat = check_dstat
|
163
|
-
super(interval, repeat)
|
164
|
-
end
|
165
174
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
175
|
+
def on_timer
|
176
|
+
@check_dstat.call
|
177
|
+
rescue
|
178
|
+
$log.error $!.to_s
|
179
|
+
$log.error_backtrace
|
180
|
+
end
|
171
181
|
end
|
172
182
|
end
|
173
183
|
end
|
174
|
-
|
175
|
-
|
176
|
-
end
|
metadata
CHANGED
@@ -1,94 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-dstat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Shunsuke Mikami
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-02-09 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: fluentd
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 0.10.7
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 0.10.7
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rdoc
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: shoulda
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - ">="
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: bundler
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- - ~>
|
59
|
+
- - "~>"
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '1.0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- - ~>
|
66
|
+
- - "~>"
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '1.0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: jeweler
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- - ~>
|
73
|
+
- - "~>"
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: 1.6.4
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- - ~>
|
80
|
+
- - "~>"
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: 1.6.4
|
94
83
|
description:
|
@@ -99,7 +88,7 @@ extra_rdoc_files:
|
|
99
88
|
- LICENSE.txt
|
100
89
|
- README.md
|
101
90
|
files:
|
102
|
-
- .document
|
91
|
+
- ".document"
|
103
92
|
- AUTHORS
|
104
93
|
- Gemfile
|
105
94
|
- LICENSE.txt
|
@@ -112,29 +101,25 @@ files:
|
|
112
101
|
- test/plugin/test_in_dstat.rb
|
113
102
|
homepage: http://github.com/shun0102/fluent-plugin-dstat
|
114
103
|
licenses: []
|
104
|
+
metadata: {}
|
115
105
|
post_install_message:
|
116
106
|
rdoc_options: []
|
117
107
|
require_paths:
|
118
108
|
- lib
|
119
109
|
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
-
none: false
|
121
110
|
requirements:
|
122
|
-
- -
|
111
|
+
- - ">="
|
123
112
|
- !ruby/object:Gem::Version
|
124
113
|
version: '0'
|
125
|
-
segments:
|
126
|
-
- 0
|
127
|
-
hash: 2096726281248138972
|
128
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
115
|
requirements:
|
131
|
-
- -
|
116
|
+
- - ">="
|
132
117
|
- !ruby/object:Gem::Version
|
133
118
|
version: '0'
|
134
119
|
requirements: []
|
135
120
|
rubyforge_project:
|
136
|
-
rubygems_version:
|
121
|
+
rubygems_version: 2.2.0
|
137
122
|
signing_key:
|
138
|
-
specification_version:
|
123
|
+
specification_version: 4
|
139
124
|
summary: Dstat Input plugin for Fluent event collector
|
140
125
|
test_files: []
|