panoptimon 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # 0.3.0
2
+
3
+ * plugins/graphite/ - added
4
+ * collectors/iostat/ - allow missing headers
5
+ * `monitor.http.hostport()` logged on init
6
+ * `panoptimon --plugin-test` with .rb file
7
+
1
8
  # 0.2.0
2
9
 
3
10
  Removed the mysql_status collector from core to reduce gem dependencies.
data/bin/panoptimon CHANGED
@@ -61,8 +61,13 @@ end
61
61
 
62
62
  if opts.plugin_test
63
63
 
64
+ # allow either json (as-installed) or rb name + json on command-line
64
65
  opts.plugin_test.each do |p|
65
- monitor._init_plugin(monitor._load_plugin_config(Pathname.new(p)))
66
+ p = Pathname.new(p)
67
+ c = p.to_s =~ /\.rb$/ ? JSON.parse(ARGV.shift).
68
+ merge({name: p.basename.to_s, base: p.dirname, rb: p})
69
+ : monitor._load_plugin_config(p)
70
+ monitor._init_plugin(c)
66
71
  end
67
72
 
68
73
  module MetricReader
@@ -16,7 +16,7 @@ p = IO.popen(cmd, 'r')
16
16
 
17
17
  puts '{}' # beep
18
18
 
19
- def prep l
19
+ def parse_header l
20
20
  want = {
21
21
  'kb_read/s' => 'rkB/s',
22
22
  'kb_write/s' => 'wkB/s',
@@ -33,8 +33,10 @@ def prep l
33
33
  }
34
34
  head = l.chomp.split(/\s+/)
35
35
  head = Hash[*head.zip(0..(head.length-1)).flatten]
36
- raise "oops" unless head.values_at(*want.values).length == want.values.length
37
- o = {}; want.each {|k,v| o[k] = head[v]}
36
+ want.values.find_all{|x| not(head[x])}.tap {|missed|
37
+ warn "missing headers: "+ missed.join(', ') if missed.length > 0
38
+ }
39
+ o = {}; want.each {|k,v| o[k] = head[v] if head[v]}
38
40
  return o
39
41
  end
40
42
 
@@ -43,7 +45,7 @@ group = {}
43
45
 
44
46
  until p.eof?
45
47
  l = p.readline("\n\n").split(/\n/)
46
- omap ||= prep(l[0])
48
+ omap ||= parse_header(l[0])
47
49
  puts JSON::generate(Hash[*l.drop(1).map {|x|
48
50
  r = x.split(/\s+/)
49
51
  [r[0], # device name
@@ -18,6 +18,10 @@ class HTTP
18
18
  @http.backend.start
19
19
  end
20
20
 
21
+ def hostport
22
+ "#{@http.host}:#{@http.port}"
23
+ end
24
+
21
25
  def call (env)
22
26
  path = env['PATH_INFO']
23
27
  return favicon(env) if path == '/favicon.ico'
@@ -100,6 +100,8 @@ class Monitor
100
100
  # TODO rescue LoadError => nicer error message
101
101
  require 'panoptimon/http'
102
102
  @http = HTTP.new
103
+ logger.warn "Serving http on #{@http.hostport}"
104
+ @http
103
105
  end
104
106
 
105
107
  def empty_binding; binding; end
@@ -1,5 +1,5 @@
1
1
  # Copyright (C) 2012 Sourcefire, Inc.
2
2
 
3
3
  module Panoptimon
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -0,0 +1,56 @@
1
+ # Graphite Plugin
2
+
3
+ This plugin emits metrics to Graphite.
4
+
5
+ # Supported Platforms
6
+
7
+ * Linux
8
+ * *others untested*
9
+
10
+ # Metric Names
11
+
12
+ The panoptimon field separator is '|', but graphite uses '.' or '/'.
13
+ The metric names emitted by this plugin will be rewritten to use '.'
14
+ as a field separator, and any existing '.' or '/' characters are
15
+ replaced with '_'. This *could* cause a conflict with some metrics,
16
+ but is rather unlikely.
17
+
18
+ example: disk|/dev/sda3|space_used
19
+ becomes: disk._dev_sda3.space_used
20
+
21
+ # Configuration
22
+
23
+ ### graphite.json example
24
+
25
+ ````
26
+ {
27
+ "host": "graphite.example.com",
28
+ "port": 2003,
29
+ "prefix": "env.location.foo"
30
+ }
31
+ ````
32
+
33
+ ## `host`
34
+
35
+ The name or IP of your Graphite server
36
+
37
+ Default: `localhost`
38
+
39
+ ## `port`
40
+
41
+ The port carbon is listening on.
42
+
43
+ Default: `2003`
44
+
45
+ ## `prefix`
46
+
47
+ The prefix to the path streamed to Graphite. For instance, if you set
48
+ `prefix` to `qa.san-jose.app1`, the full CPU idle path Graphite receives
49
+ will be `qa.san-jose.app1.cpu.idle`. This allows you to customize how
50
+ metrics are organized in Graphite.
51
+
52
+ Default: `<%= host %>`
53
+
54
+ The erb-like strings `<%= host %>` and `<%= domain %>` will be replaced
55
+ (respectively) with the first and remaining dot-separated parts of your
56
+ host name.
@@ -0,0 +1,3 @@
1
+ {
2
+ "host": "localhost",
3
+ "port": 2003 }
@@ -0,0 +1,36 @@
1
+ require 'socket'
2
+
3
+ hostname = ->(;h){->(i){
4
+ unless h
5
+ a, b = Socket.gethostname.split(/\./, 2)
6
+ h = {host: a, domain: b}
7
+ end
8
+ h[i.to_sym]
9
+ }}[]
10
+
11
+ host = config[:host] || 'localhost'
12
+ port = config[:port] || '2003'
13
+ prefix = config[:prefix] || '<%= host %>'
14
+
15
+ prefix.gsub!(/<%= *(host|domain) *%>/) { hostname[$1] }
16
+
17
+ socket = TCPSocket.open(host, port)
18
+
19
+ ->(metrics) {
20
+ t = Time.now.to_i
21
+ metrics.keys.each { |k|
22
+
23
+ metric = k.dup
24
+
25
+ # Graphite will use "/" and "." as a delim. Replace with "_".
26
+ # Not great, but... sanitize the output a bit.
27
+ metric.gsub!(/\//, '_')
28
+ metric.gsub!(/\./, '_')
29
+
30
+ # Replace pan's default "|" delim with "." so Graphite groups properly.
31
+ metric.gsub!(/\|/, '.')
32
+
33
+ stat = "#{prefix}.#{metric} #{metrics[k]} #{t}"
34
+ socket.write("#{stat}\n")
35
+ }
36
+ }
metadata CHANGED
@@ -1,99 +1,82 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panoptimon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Eric Wilhelm
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-04-30 00:00:00.000000000 Z
12
+ date: 2013-05-17 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: eventmachine
15
- requirement: !ruby/object:Gem::Requirement
16
+ requirement: &11208660 !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ~>
18
20
  - !ruby/object:Gem::Version
19
21
  version: 1.0.0
20
22
  type: :runtime
21
23
  prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: 1.0.0
24
+ version_requirements: *11208660
27
25
  - !ruby/object:Gem::Dependency
28
26
  name: daemons
29
- requirement: !ruby/object:Gem::Requirement
27
+ requirement: &11208180 !ruby/object:Gem::Requirement
28
+ none: false
30
29
  requirements:
31
- - - '>='
30
+ - - ! '>='
32
31
  - !ruby/object:Gem::Version
33
32
  version: '0'
34
33
  type: :runtime
35
34
  prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
35
+ version_requirements: *11208180
41
36
  - !ruby/object:Gem::Dependency
42
37
  name: json
43
- requirement: !ruby/object:Gem::Requirement
38
+ requirement: &11207580 !ruby/object:Gem::Requirement
39
+ none: false
44
40
  requirements:
45
- - - '>='
41
+ - - ! '>='
46
42
  - !ruby/object:Gem::Version
47
43
  version: '0'
48
44
  type: :runtime
49
45
  prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
46
+ version_requirements: *11207580
55
47
  - !ruby/object:Gem::Dependency
56
48
  name: thin
57
- requirement: !ruby/object:Gem::Requirement
49
+ requirement: &11206900 !ruby/object:Gem::Requirement
50
+ none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
61
54
  version: 1.5.0
62
55
  type: :runtime
63
56
  prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ~>
67
- - !ruby/object:Gem::Version
68
- version: 1.5.0
57
+ version_requirements: *11206900
69
58
  - !ruby/object:Gem::Dependency
70
59
  name: riemann-client
71
- requirement: !ruby/object:Gem::Requirement
60
+ requirement: &11206020 !ruby/object:Gem::Requirement
61
+ none: false
72
62
  requirements:
73
- - - '>='
63
+ - - ! '>='
74
64
  - !ruby/object:Gem::Version
75
65
  version: '0'
76
66
  type: :runtime
77
67
  prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - '>='
81
- - !ruby/object:Gem::Version
82
- version: '0'
68
+ version_requirements: *11206020
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: sys-filesystem
85
- requirement: !ruby/object:Gem::Requirement
71
+ requirement: &11205560 !ruby/object:Gem::Requirement
72
+ none: false
86
73
  requirements:
87
- - - '>='
74
+ - - ! '>='
88
75
  - !ruby/object:Gem::Version
89
76
  version: '0'
90
77
  type: :runtime
91
78
  prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - '>='
95
- - !ruby/object:Gem::Version
96
- version: '0'
79
+ version_requirements: *11205560
97
80
  description: The All-Seeing System Monitor Daemon
98
81
  email: sysops@sourcefire.com
99
82
  executables:
@@ -217,6 +200,9 @@ files:
217
200
  - plugins/email/README.md
218
201
  - plugins/email/email.json
219
202
  - plugins/email/email.rb
203
+ - plugins/graphite/README.md
204
+ - plugins/graphite/graphite.json
205
+ - plugins/graphite/graphite.rb
220
206
  - plugins/log_to_file/log_to_file.json
221
207
  - plugins/log_to_file/log_to_file.rb
222
208
  - plugins/log_to_logger/log_to_logger.json
@@ -276,26 +262,27 @@ files:
276
262
  homepage: https://github.com/synthesist/panoptimon
277
263
  licenses:
278
264
  - bsd
279
- metadata: {}
280
265
  post_install_message:
281
266
  rdoc_options: []
282
267
  require_paths:
283
268
  - lib
284
269
  required_ruby_version: !ruby/object:Gem::Requirement
270
+ none: false
285
271
  requirements:
286
- - - '>='
272
+ - - ! '>='
287
273
  - !ruby/object:Gem::Version
288
274
  version: '1.9'
289
275
  required_rubygems_version: !ruby/object:Gem::Requirement
276
+ none: false
290
277
  requirements:
291
- - - '>='
278
+ - - ! '>='
292
279
  - !ruby/object:Gem::Version
293
280
  version: '0'
294
281
  requirements: []
295
282
  rubyforge_project:
296
- rubygems_version: 2.0.3
283
+ rubygems_version: 1.8.11
297
284
  signing_key:
298
- specification_version: 4
285
+ specification_version: 3
299
286
  summary: Panoptimon collects and routes system metrics.
300
287
  test_files:
301
288
  - spec/collector/config_spec.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 52529feb511cde3ec602078341a19d2d09060562
4
- data.tar.gz: a672846b2ddea694e1f1b23fc9aa632629dfc131
5
- SHA512:
6
- metadata.gz: 3cb1390a85c8037597ff699d5c1df7b38ff750b0356ad7c1a097f2ef86395dd1ba21470d83e63b139bcbcd202fb3fb87dedb6ed36019632fe101ab58b5b3ff1d
7
- data.tar.gz: fee7c6f5b141321e96f58cf96087e69dc65d084a899a330c93afe82292b409556b788b034fefd51b4f40f772379f2100d2f16ccf36c7afbd2d1271044e30a879