Bump base image (#538)
[discourse_docker.git] / image / monitor / src / monitor.rb
... / ...
CommitLineData
1require 'statsd-ruby'
2require 'docker'
3
4$statsd = Statsd.new '10.0.0.1', 8125
5
6module Docker
7 class CloseConnectionError < StandardError; end
8 class Container
9 def name
10 info["Names"].first[1..-1]
11 end
12
13 def stats
14 path = path_for(:stats)
15
16 result = nil
17
18 streamer = lambda do |chunk, remaining, total|
19 result ||= chunk
20 raise CloseConnectionError if result
21 end
22 options = { response_block: streamer }.merge(connection.options)
23
24 Excon.get(connection.url + path[1..-1], options) rescue CloseConnectionError
25
26 Docker::Util.parse_json(result)
27 end
28 end
29end
30
31def median(array)
32 sorted = array.sort
33 len = sorted.length
34 return ((sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0).to_i
35end
36
37
38def analyze_container(container)
39
40 data = container.exec(["ps", "-eo", "rss,args"])[0].join("\n").split("\n")
41 unicorns = data.grep(/unicorn/).map(&:to_i)
42 sidekiqs = data.grep(/sidekiq/).map(&:to_i)
43
44 result = {}
45
46 if unicorns.length > 0
47 result["unicorn.max_rss"] = unicorns.max
48 result["unicorn.median_rss"] = median(unicorns)
49 end
50
51 if sidekiqs.length > 0
52 result["sidekiq.max_rss"] = sidekiqs.max
53 result["sidekiq.median_rss"] = median(sidekiqs)
54 end
55 result["total_mem_usage"] = container.stats["memory_stats"]["usage"]
56
57 @prev_stats ||= {}
58 prev_stats = @prev_stats[container.name]
59 @prev_stats[container.name] = stats = container.stats
60
61 if prev_stats
62 cpu_delta = stats["cpu_stats"]["system_cpu_usage"] - prev_stats["cpu_stats"]["system_cpu_usage"]
63 app_cpu_delta = stats["cpu_stats"]["cpu_usage"]["total_usage"] - prev_stats["cpu_stats"]["cpu_usage"]["total_usage"]
64
65 result["cpu_usage"] = (app_cpu_delta.to_f / cpu_delta.to_f) * stats["cpu_stats"]["cpu_usage"]["percpu_usage"].length * 100.0
66 end
67
68 result
69
70end
71
72def containers
73 Docker::Container.all
74end
75
76hostname = Docker.info["Name"]
77
78STDERR.puts "#{Time.now} Starting Monitor"
79
80while true
81
82 begin
83 containers.each do |c|
84
85 analyze_container(c).each do |k, v|
86 if v && v > 0
87 $statsd.gauge "#{hostname}.#{c.name}.#{k}", v
88 end
89 end
90 end
91 rescue => e
92 STDERR.puts e
93 STDERR.puts e.backtrace
94 end
95
96 sleep 60
97end
98