panoptimon 0.2.0 → 0.3.0

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