metrix 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -8,17 +8,30 @@ Add this line to your application's Gemfile:
8
8
 
9
9
  gem 'metrix'
10
10
 
11
- And then execute:
11
+ ## Configuration
12
12
 
13
- $ bundle
13
+ #/etc/metrix.tml
14
+ elasticsearch: http://127.0.0.1:9200/_status
15
+ mongodb: http://127.0.0.1:28017/serverStatus
16
+ fpm: http://127.0.0.1:9001/fpm-status
17
+ nginx: http://127.0.0.1:8000/
18
+ opentsdb: tcp://127.0.0.1:4242/
19
+ graphite: tcp://127.0.0.1:2003/
20
+ load: true
21
+ system: true
22
+ processes: true
14
23
 
15
- Or install it yourself as:
24
+ ## Start
16
25
 
17
- $ gem install metrix
26
+ $ metrix start
18
27
 
19
- ## Usage
28
+ ## Stop
20
29
 
21
- TODO: Write usage instructions here
30
+ $ metrix stop
31
+
32
+ ## Status
33
+
34
+ $ metrix status
22
35
 
23
36
  ## Contributing
24
37
 
data/lib/metrix/cli.rb CHANGED
@@ -5,12 +5,14 @@ require "metrix/nginx"
5
5
  require "metrix/system"
6
6
  require "metrix/load"
7
7
  require "metrix/fpm"
8
+ require "metrix/process"
9
+ require "metrix/load"
8
10
  require "logger"
9
11
  require "fileutils"
10
12
 
11
13
  module Metrix
12
14
  class CLI
13
- attr_reader :reporter, :elastic_search_host, :mongodb_host, :interval
15
+ attr_reader :interval
14
16
 
15
17
  def initialize(args)
16
18
  @args = args
@@ -20,20 +22,32 @@ module Metrix
20
22
  Metrix.logger = Syslog::Logger.new("metrix")
21
23
  end
22
24
 
25
+ def parse!
26
+ @action = opts.parse(@args).first
27
+ end
28
+
29
+ def action
30
+ @action ||= parse!
31
+ end
32
+
23
33
  def run
24
- Metrix.logger.level = log_level
25
- action = opts.parse(@args).first
26
- case action
34
+ parse!
35
+ load_configs_from_file!
36
+ case @action
27
37
  when "start"
28
38
  if running?
29
39
  logger.warn "refuse to run. seems that #{pid_path} exists!"
30
40
  abort "not allowed to run" if running?
31
41
  end
32
- pid = Process.fork do
42
+ if daemonize?
43
+ pid = Process.fork do
44
+ start
45
+ end
46
+ sleep 1
47
+ Process.detach(pid)
48
+ else
33
49
  start
34
50
  end
35
- sleep 1
36
- Process.detach(pid)
37
51
  when "status"
38
52
  if File.exists?(pid_path)
39
53
  logger.debug "#{pid_path} exists"
@@ -50,6 +64,8 @@ module Metrix
50
64
  logger.info "killing pid #{pid}"
51
65
  system "kill #{pid}"
52
66
  puts "killed #{pid}"
67
+ when "configtest"
68
+ puts "running configtest #{attributes.inspect}"
53
69
  else
54
70
  logger.warn "action #{action} unknown!"
55
71
  abort "action #{action} unknown!"
@@ -78,46 +94,19 @@ module Metrix
78
94
  begin
79
95
  cnt += 1
80
96
  now = Time.now.utc
81
- if elastic_search?
82
- fetch_metrix :elastic_search do
83
- reporter << Metrix::ElasticSearch.new(elastic_search_status)
84
- end
85
- end
86
-
87
- if mongodb?
88
- fetch_metrix :mongodb do
89
- reporter << Metrix::Mongodb.new(mongodb_status)
97
+ fetch_metrix(:elasticsearch) { reporter << Metrix::ElasticSearch.new(fetch_resource(:elasticsearch)) }
98
+ fetch_metrix(:mongodb) { reporter << Metrix::Mongodb.new(fetch_resource(:mongodb)) }
99
+ fetch_metrix(:nginx) { reporter << Metrix::Nginx.new(fetch_resource(:nginx)) }
100
+ fetch_metrix(:fpm) { reporter << Metrix::FPM.new(fetch_resource(:fpm)) }
101
+ fetch_metrix(:system) { reporter << Metrix::System.new(File.read("/proc/stat")) }
102
+ fetch_metrix(:load) { reporter << Metrix::Load.new(File.read("/proc/loadavg")) }
103
+
104
+ fetch_metrix :processes do
105
+ Metrix::ProcessMetric.all.each do |m|
106
+ reporter << m
90
107
  end
91
108
  end
92
109
 
93
- if nginx?
94
- fetch_metrix :nginx do
95
- reporter << Metrix::Nginx.new(nginx_status)
96
- end
97
- end
98
-
99
- if fpm?
100
- fetch_metrix :fpm do
101
- reporter << Metrix::FPM.new(fpm_status)
102
- end
103
- end
104
-
105
- if system?
106
- fetch_metrix :system do
107
- reporter << Metrix::System.new(File.read("/proc/stat"))
108
- end
109
- fetch_metrix :load do
110
- reporter << Metrix::Load.new(File.read("/proc/loadavg"))
111
- end
112
- end
113
-
114
- if processes?
115
- fetch_metrix :processes do
116
- Metrix::ProcessMetric.all.each do |m|
117
- reporter << m
118
- end
119
- end
120
- end
121
110
  reporter.flush
122
111
  rescue SystemExit
123
112
  $running = false
@@ -125,18 +114,37 @@ module Metrix
125
114
  Metrix.logger.error "#{err.message}"
126
115
  Metrix.logger.error "#{err.backtrace.inspect}"
127
116
  ensure
128
- sleep_for = @interval - (Time.now - started - cnt * interval)
129
- if sleep_for > 0
130
- Metrix.logger.info "finished run in %.06f, sleeping for %.06f" % [Time.now - now, sleep_for]
131
- sleep sleep_for
132
- else
133
- Metrix.logger.info "not sleeping because %.06f is negative" % [sleep_for]
117
+ begin
118
+ sleep_for = @interval - (Time.now - started - cnt * interval)
119
+ if sleep_for > 0
120
+ Metrix.logger.info "finished run in %.06f, sleeping for %.06f" % [Time.now - now, sleep_for]
121
+ sleep sleep_for
122
+ else
123
+ Metrix.logger.info "not sleeping because %.06f is negative" % [sleep_for]
124
+ end
125
+ rescue SystemExit, Interrupt
126
+ $running = false
134
127
  end
135
128
  end
136
129
  end
137
130
  delete_pidfile!
138
131
  end
139
132
 
133
+ def reporter
134
+ if attributes[:opentsdb]
135
+ require "metrix/opentsdb"
136
+ uri = URI.parse(attributes[:opentsdb])
137
+ Metrix::OpenTSDB.new(uri.host, uri.port)
138
+ elsif attributes[:graphite]
139
+ require "metrix/graphite"
140
+ uri = URI.parse(attributes[:graphite])
141
+ Metrix::Graphite.new(uri.host, uri.port)
142
+ elsif @foreground == true
143
+ require "metrix/reporter/stdout"
144
+ Metrix::Reporter::Stdout.new
145
+ end
146
+ end
147
+
140
148
  def write_pidfile!(pid)
141
149
  logger.info "writing #{pid} to #{pid_path}"
142
150
  File.open(pid_path, "w") { |f| f.print(pid) }
@@ -154,44 +162,20 @@ module Metrix
154
162
  File.exists?(pid_path)
155
163
  end
156
164
 
157
- def log_level
158
- @log_level || Logger::INFO
165
+ def enabled?(key)
166
+ !!attributes[key]
159
167
  end
160
168
 
161
- def processes?
162
- !!@processes
169
+ def elasticsearch_status
170
+ get_url url_for(:elasticsearch)
163
171
  end
164
172
 
165
- def elastic_search?
166
- !!@elastic_search
173
+ def fetch_resource(key)
174
+ get_url(url_for(key))
167
175
  end
168
176
 
169
- def mongodb?
170
- !!@mongodb
171
- end
172
-
173
- def fpm?
174
- !!@fpm
175
- end
176
-
177
- def nginx?
178
- !!@nginx
179
- end
180
-
181
- def elastic_search_status
182
- get_url "http://127.0.0.1:9200/_status"
183
- end
184
-
185
- def mongodb_status
186
- get_url "http://127.0.0.1:28017/serverStatus"
187
- end
188
-
189
- def fpm_status
190
- get_url "http://127.0.0.1:9001/fpm-status"
191
- end
192
-
193
- def nginx_status
194
- get_url "http://127.0.0.1:8000/"
177
+ def url_for(key)
178
+ attributes[key]
195
179
  end
196
180
 
197
181
  def get_url(url)
@@ -203,6 +187,7 @@ module Metrix
203
187
  end
204
188
 
205
189
  def fetch_metrix(type)
190
+ return false if !enabled?(type)
206
191
  started = Time.now
207
192
  logger.info "fetching metrix for #{type}"
208
193
  yield
@@ -215,15 +200,37 @@ module Metrix
215
200
  Metrix.logger
216
201
  end
217
202
 
218
- def system?
219
- !!@system
220
- end
221
-
222
203
  def log_to_stdout
223
204
  Metrix.logger = Logger.new(STDOUT)
224
205
  Metrix.logger.level = Logger::INFO
225
206
  end
226
207
 
208
+ def daemonize?
209
+ @foreground != true
210
+ end
211
+
212
+ def attributes
213
+ @attributes ||= {}
214
+ end
215
+
216
+ def load_configs_from_file!
217
+ require "erb"
218
+ require "yaml"
219
+ hash = YAML.load(ERB.new(File.read(config_path)).result)
220
+ @attributes = hash.inject({}) do |hash, (k, v)|
221
+ hash[k.to_sym] = v
222
+ hash
223
+ end
224
+ end
225
+
226
+ def config_path
227
+ @config_path || default_config_path
228
+ end
229
+
230
+ def default_config_path
231
+ File.expand_path("/etc/metrix.yml")
232
+ end
233
+
227
234
  def opts
228
235
  require "optparse"
229
236
  @opts ||= OptionParser.new do |o|
@@ -232,53 +239,14 @@ module Metrix
232
239
  exit
233
240
  end
234
241
 
235
- o.on("--fpm") do
236
- @fpm = true
237
- end
238
-
239
- o.on("--nginx") do
240
- @nginx = true
241
- end
242
-
243
- o.on("--mongodb") do
244
- @mongodb = true
245
- end
246
-
247
- o.on("--elasticsearch") do
248
- @elastic_search = true
249
- end
250
-
251
- o.on("--graphite-host HOST") do |value|
252
- require "metrix/graphite"
253
- @reporter = Metrix::Graphite.new(value, 2003)
254
- end
255
-
256
- o.on("--opentsdb-host HOST") do |value|
257
- require "metrix/opentsdb"
258
- @reporter = Metrix::OpenTSDB.new(value, 4242)
242
+ o.on("-c PATH") do |value|
243
+ @config_path = value
259
244
  end
260
245
 
261
- o.on("--stdout") do
262
- require "metrix/reporter/stdout"
263
- @reporter = Metrix::Reporter::Stdout.new
264
- end
265
-
266
- o.on("--debug") do
267
- @log_level = Logger::DEBUG
268
- end
269
-
270
- o.on("--no-syslog") do
246
+ o.on("-d", "--debug") do |value|
247
+ @foreground = true
271
248
  log_to_stdout
272
- end
273
-
274
- o.on("--processes") do
275
- require "metrix/process"
276
- @processes = true
277
- end
278
-
279
- o.on("--system") do
280
- require "metrix/system"
281
- @system = true
249
+ Metrix.logger.level = Logger::DEBUG
282
250
  end
283
251
  end
284
252
  end
@@ -2,6 +2,8 @@ require "socket"
2
2
 
3
3
  module Metrix
4
4
  class OpenTSDB
5
+ attr_reader :host, :port
6
+
5
7
  def initialize(host, port = 4242)
6
8
  @host = host
7
9
  @port = port
data/lib/metrix/system.rb CHANGED
@@ -49,14 +49,6 @@ module Metrix
49
49
  }
50
50
  end
51
51
 
52
- def load1
53
- loadavg.split(" ").first.to_f
54
- end
55
-
56
- def loadavg
57
- @loadavg ||= File.read("/proc/loadavg")
58
- end
59
-
60
52
  def prefix
61
53
  "system"
62
54
  end
@@ -1,3 +1,3 @@
1
1
  module Metrix
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -0,0 +1,6 @@
1
+ system: true
2
+ processes: true
3
+ load: true
4
+ opentsdb: tcp://<%= "some.host" %>:1234
5
+ log_level: debug
6
+ fpm: http://localhost:9001
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
  require "metrix/cli"
3
3
 
4
- describe "Metrix::CLI", :wip do
4
+ describe "Metrix::CLI" do
5
5
  subject(:cli) { Metrix::CLI.new([]) }
6
6
  it { should_not be_nil }
7
7
 
@@ -28,4 +28,60 @@ describe "Metrix::CLI", :wip do
28
28
 
29
29
  it { should_not be_allowed_to_run }
30
30
  end
31
+
32
+ describe "with graphite reporter" do
33
+ subject(:reporter) do
34
+ cli.attributes[:graphite] = "tcp://123.3.4.5:1212"
35
+ cli.reporter
36
+ end
37
+
38
+ it { should_not be_nil }
39
+ it { subject.host.should eq("123.3.4.5") }
40
+ it { subject.port.should eq(1212) }
41
+ end
42
+
43
+ describe "initializing from config file" do
44
+ let(:path) { FIXTURES_PATH.join("metrix.yml").to_s }
45
+ subject(:cli) { Metrix::CLI.new(["-c", path, "configtest"]) }
46
+
47
+ before do
48
+ cli.stub(:puts)
49
+ cli.run
50
+ end
51
+
52
+ it { cli.config_path.should eq(path) }
53
+ it { should_not be_nil }
54
+ it { should be_enabled(:system) }
55
+ it { should be_enabled(:load) }
56
+ it { should be_enabled(:processes) }
57
+ it { subject.reporter.should be_kind_of(Metrix::OpenTSDB) }
58
+ it { subject.attributes[:opentsdb].should include("some.host") }
59
+ it { subject.should_not be_enabled(:elasticsearch) }
60
+ it { subject.url_for(:fpm).should_not be_nil }
61
+ it { subject.should be_enabled(:fpm) }
62
+ it { subject.should_not be_enabled(:mongodb) }
63
+ it { subject.should be_daemonize }
64
+
65
+ describe "#reporter" do
66
+ subject(:reporter) { cli.reporter }
67
+ it { should_not be_nil }
68
+ it { subject.host.should eq("some.host") }
69
+ end
70
+ end
71
+
72
+ describe "with no parameters called" do
73
+ subject(:cli) { Metrix::CLI.new([]) }
74
+ it { should_not be_nil }
75
+ it { cli.config_path.should eq("/etc/metrix.yml") }
76
+ end
77
+
78
+ describe "running in forground" do
79
+ subject(:cli) { Metrix::CLI.new(["--debug"]) }
80
+ before do
81
+ cli.parse!
82
+ end
83
+ it { should_not be_nil }
84
+ it { subject.reporter.should_not be_nil }
85
+ it { cli.config_path.should eq("/etc/metrix.yml") }
86
+ end
31
87
  end
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
  require "metrix/fpm"
3
3
 
4
- describe "Metrix::FPM", :wip do
4
+ describe "Metrix::FPM" do
5
5
  let(:data) { FIXTURES_PATH.join("php.fpm.status.txt").read }
6
6
  subject(:fpm) { Metrix::FPM.new(data) }
7
7
  it { should_not be_nil }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metrix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -109,6 +109,7 @@ files:
109
109
  - spec/fixtures/ec2metadata.txt
110
110
  - spec/fixtures/es_status.json
111
111
  - spec/fixtures/loadavg.txt
112
+ - spec/fixtures/metrix.yml
112
113
  - spec/fixtures/mongo_server_status.json
113
114
  - spec/fixtures/nginx.status.txt
114
115
  - spec/fixtures/php.fpm.status.txt
@@ -154,6 +155,7 @@ test_files:
154
155
  - spec/fixtures/ec2metadata.txt
155
156
  - spec/fixtures/es_status.json
156
157
  - spec/fixtures/loadavg.txt
158
+ - spec/fixtures/metrix.yml
157
159
  - spec/fixtures/mongo_server_status.json
158
160
  - spec/fixtures/nginx.status.txt
159
161
  - spec/fixtures/php.fpm.status.txt