metrix 0.0.6 → 0.0.7

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.
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