fluent-plugin-docker-metrics 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 +7 -0
- data/Gemfile +3 -0
- data/README.md +37 -0
- data/fluent-plugin-docker-metrics.gemspec +22 -0
- data/lib/fluent/plugin/in_docker_metrics.rb +136 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fe3c77f3d0e10766bb18060d471de817455fd9cb
|
4
|
+
data.tar.gz: f56a4465bb6a566240a4c27276bca97d07081222
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bcbcfd347ac2a1a7cb1e06bc0cdce38fce40968a3405c75577b50a0782cb5ea341c41cdad4a56b42139a4a450278347dba0777001799d8c85e4fb941454e05d5
|
7
|
+
data.tar.gz: 6d4ad921e6da4e8be9c4da6581a79253fe17cbbe692ab6e88d18e24778173da75e4c503b1fc0ee2d5bf953270dd376f367f9c6d52434a2a4063a15675048d1aa
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# Fluentd Docker Metrics Input Plugin
|
2
|
+
|
3
|
+
This is a [Fluentd](http://www.fluentd.org) plugin to collect Docker metrics periodically.
|
4
|
+
|
5
|
+
## How it works
|
6
|
+
|
7
|
+
It's assumed to run on the host server. It periodically runs `docker ps --no-trunc -q`
|
8
|
+
to get a list of running Docker container IDs, and it looks at `/sys/fs/cgroups/<metric_type>/docker/<container_id>/`
|
9
|
+
for relevant stats. You can say this is an implementation of the metric collection strategy outlined in [this blog post](http://blog.docker.com/2013/10/gathering-lxc-docker-containers-metrics/).
|
10
|
+
|
11
|
+
## Installing
|
12
|
+
|
13
|
+
to be uploaded on Rubygems
|
14
|
+
|
15
|
+
## Example config
|
16
|
+
|
17
|
+
```
|
18
|
+
<source>
|
19
|
+
type docker_metrics
|
20
|
+
stats_interval 1m
|
21
|
+
</source>
|
22
|
+
```
|
23
|
+
|
24
|
+
## Parameters
|
25
|
+
|
26
|
+
* **stats_interval**: how often to poll Docker containers for stats. The default is every minute.
|
27
|
+
* **cgroup_path**: The path to cgroups pseudofiles. The default is `sys/fs/cgroup`.
|
28
|
+
* **tag_prefix**: The tag prefix. The default value is "docker"
|
29
|
+
|
30
|
+
## Example output
|
31
|
+
|
32
|
+
```
|
33
|
+
2014-06-26 18:16:43 +0000 docker.memory.stat: {"key":"memory_stat_total_active_anon","value":26025984,"source":"docker:precise64:b7f17c393775476bc0999cb6dcb4c6416e94b0473317375b9a245985dc6e91c5"}
|
34
|
+
2014-06-26 18:16:43 +0000 docker.memory.stat: {"key":"memory_stat_total_inactive_file","value":131072,"source":"docker:precise64:b7f17c393775476bc0999cb6dcb4c6416e94b0473317375b9a245985dc6e91c5"}
|
35
|
+
```
|
36
|
+
|
37
|
+
In particular, each event is a key-value pair of individual metrics. Also, it has a field whose value is "\<tag_prefix\>:\<hostname\>:\<container_id\>"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: 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 |spec|
|
6
|
+
spec.name = "fluent-plugin-docker-metrics"
|
7
|
+
spec.version = "0.0.1"
|
8
|
+
spec.authors = ["kiyoto"]
|
9
|
+
spec.email = ["kiyoto@treasure-data.com"]
|
10
|
+
spec.summary = %q{Fluentd plugin to collect Docker container metrics}
|
11
|
+
spec.homepage = "https://github.com/kiyoto/fluent-plugin-docker-metrics"
|
12
|
+
spec.license = "Apache License, Version 2.0"
|
13
|
+
|
14
|
+
spec.files = `git ls-files`.split($/)
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler"
|
20
|
+
spec.add_development_dependency "rake"
|
21
|
+
spec.add_runtime_dependency "fluentd"
|
22
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module Fluent
|
2
|
+
class DockerMetricsInput < Input
|
3
|
+
Plugin.register_input('docker_metrics', self)
|
4
|
+
|
5
|
+
config_param :cgroup_path, :string, :default => '/sys/fs/cgroup'
|
6
|
+
config_param :stats_interval, :time, :default => 60 # every minute
|
7
|
+
config_param :tag_prefix, :string, :default => "docker"
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
require 'socket'
|
12
|
+
@hostname = Socket.gethostname
|
13
|
+
end
|
14
|
+
|
15
|
+
def configure(conf)
|
16
|
+
super
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def start
|
21
|
+
@loop = Coolio::Loop.new
|
22
|
+
tw = TimerWatcher.new(@stats_interval, true, @log, &method(:get_metrics))
|
23
|
+
tw.attach(@loop)
|
24
|
+
@thread = Thread.new(&method(:run))
|
25
|
+
end
|
26
|
+
def run
|
27
|
+
@loop.run
|
28
|
+
rescue
|
29
|
+
log.error "unexpected error", :error=>$!.to_s
|
30
|
+
log.error_backtrace
|
31
|
+
end
|
32
|
+
|
33
|
+
# Metrics collection methods
|
34
|
+
def get_metrics
|
35
|
+
list_container_ids.each do |id|
|
36
|
+
emit_container_metric(id, 'memory', 'memory.stat')
|
37
|
+
emit_container_metric(id, 'cpuacct', 'cpuacct.stat')
|
38
|
+
emit_container_metric(id, 'blkio', 'blkio.io_serviced')
|
39
|
+
emit_container_metric(id, 'blkio', 'blkio.io_service_bytes')
|
40
|
+
emit_container_metric(id, 'blkio', 'blkio.io_service_queued')
|
41
|
+
emit_container_metric(id, 'blkio', 'blkio.sectors')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def list_container_ids
|
46
|
+
`docker ps --no-trunc -q`.split /\s+/
|
47
|
+
end
|
48
|
+
|
49
|
+
def emit_container_metric(id, metric_type, metric_filename, opts = {})
|
50
|
+
path = "#{@cgroup_path}/#{metric_type}/docker/#{id}/#{metric_filename}"
|
51
|
+
if File.exists?(path)
|
52
|
+
parser = if metric_type != 'blkio'
|
53
|
+
KeyValueStatsParser.new(path, metric_filename.gsub('.', '_'))
|
54
|
+
else
|
55
|
+
BlkioStatsParser.new(path, metric_filename.gsub('.', '_'))
|
56
|
+
end
|
57
|
+
time = Engine.now
|
58
|
+
tag = "#{@tag_prefix}.#{metric_filename}"
|
59
|
+
mes = MultiEventStream.new
|
60
|
+
parser.parse_each_line do |data|
|
61
|
+
next if not data
|
62
|
+
# TODO: address this more elegantly
|
63
|
+
if data[:key] =~ /^(?:cpuacct|blkio|memory_stat_pg)/
|
64
|
+
data[:type] = 'counter'
|
65
|
+
end
|
66
|
+
data["source"] = "#{@tag_prefix}:#{@hostname}:#{id}"
|
67
|
+
mes.add(time, data)
|
68
|
+
end
|
69
|
+
Engine.emit_stream(tag, mes)
|
70
|
+
else
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def shutdown
|
76
|
+
@loop.stop
|
77
|
+
@thread.join
|
78
|
+
end
|
79
|
+
|
80
|
+
class TimerWatcher < Coolio::TimerWatcher
|
81
|
+
|
82
|
+
def initialize(interval, repeat, log, &callback)
|
83
|
+
@callback = callback
|
84
|
+
@log = log
|
85
|
+
super(interval, repeat)
|
86
|
+
end
|
87
|
+
def on_timer
|
88
|
+
@callback.call
|
89
|
+
rescue
|
90
|
+
@log.error $!.to_s
|
91
|
+
@log.error_backtrace
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class CGroupStatsParser
|
96
|
+
def initialize(path, metric_type)
|
97
|
+
raise ConfigError if not File.exists?(path)
|
98
|
+
@path = path
|
99
|
+
@metric_type = metric_type
|
100
|
+
end
|
101
|
+
|
102
|
+
def parse_line(line)
|
103
|
+
end
|
104
|
+
|
105
|
+
def parse_each_line(&block)
|
106
|
+
File.new(@path).each_line do |line|
|
107
|
+
block.call(parse_line(line))
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class KeyValueStatsParser < CGroupStatsParser
|
113
|
+
def parse_line(line)
|
114
|
+
k, v = line.split(/\s+/, 2)
|
115
|
+
if k and v
|
116
|
+
{ key: @metric_type + "_" + k, value: v.to_i }
|
117
|
+
else
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class BlkioStatsParser < CGroupStatsParser
|
124
|
+
BlkioLineRegexp = /^(?<major>\d+):(?<minor>\d+) (?<key>[^ ]+) (?<value>\d+)/
|
125
|
+
|
126
|
+
def parse_line(line)
|
127
|
+
m = BlkioLineRegexp.match(line)
|
128
|
+
if m
|
129
|
+
{ key: @metric_type + "_" + m["key"].downcase, value: m["value"] }
|
130
|
+
else
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-docker-metrics
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- kiyoto
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: fluentd
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- kiyoto@treasure-data.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- Gemfile
|
63
|
+
- README.md
|
64
|
+
- fluent-plugin-docker-metrics.gemspec
|
65
|
+
- lib/fluent/plugin/in_docker_metrics.rb
|
66
|
+
homepage: https://github.com/kiyoto/fluent-plugin-docker-metrics
|
67
|
+
licenses:
|
68
|
+
- Apache License, Version 2.0
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.2.2
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Fluentd plugin to collect Docker container metrics
|
90
|
+
test_files: []
|