Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exception handling, database nil, body name key #21

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 14 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,35 @@
# Usage
The configuration options are pretty straight forward.

Metrics are inserted into the database with a table per check name. So if you're using the `rabbitmq_overview_metrics` plugin, you'd have a table in the defined database called `rabbitmq_overview_metrics` with the following columns:
Metrics are inserted into the database with a table per check name. So if you're using the `metrics-memory.rb` plugin, you'd have a series in the defined database called `full_hostname .metric.type` with the following columns:

- host
- metric.name1
- metric.name2

Eg with the [load-metrics.rb](https://github.com/sensu/sensu-community-plugins/blob/master/plugins/system/load-metrics.rb) the following series would be generated:
Ex:
select * from full_hostname.memory.free

The following series would be generated:
```
┌────────────┬─────────────────┬────────────────────────────────────────┬──────────────┬───────────────┬──────────────────┐
│ time │ sequence_number │ host │ load_avg.one │ load_avg.five │ load_avg.fifteen │
├────────────┼─────────────────┼────────────────────────────────────────┼──────────────┼───────────────┼──────────────────┤
│ 1414548271 │ 209090001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.89 │ 0.53 │
│ 1414548261 │ 209080001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.89 │ 0.52 │
│ 1414548251 │ 209070001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.88 │ 0.52 │
│ 1414548241 │ 209060001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.88 │ 0.51 │
│ 1414548231 │ 209050001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.87 │ 0.51 │
│ 1414548221 │ 209040001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.87 │ 0.50 │
│ 1414548211 │ 209030001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.87 │ 0.50 │
│ 1414548201 │ 209020001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.86 │ 0.49 │
│ 1414548191 │ 209010001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.86 │ 0.49 │
│ 1414548181 │ 209000001 │ default-ubuntu-1404-i386.vagrantup.com │ 1.00 │ 0.85 │ 0.48 │
└────────────┴─────────────────┴────────────────────────────────────────┴──────────────┴───────────────┴──────────────────┘
time sequence_number value
1437403355000 6523755600001 4788113408
```

Additionally a `duration` column would be present based on the time it took the check to run (this is gleaned from the sensu event data).

The value for `metric` is determined based on the value of `strip_metric` described below. You can query it like so:

![an image](http://s3itch.lusis.org/InfluxDB_Administration_20140203_153132.png)

## Extension not a handler
Note that the first push of this was a handler that could be called via `pipe`. This is now an actual extension that's more performant since it's actually in the sensu-server runtime. Additionally it's now using batch submission to InfluxDB by writing all the points for a given series at once.

Just drop the file in `/etc/sensu/extensions` and add it to your `metrics` configuration (`/etc/sensu/conf.d/handlers/metrics.json`:

```json
{
"handlers": {
"metrics": {
"type": "set",
"handlers": [ "debug", "influxdb"]
}
"checks": {
"metric_memory": {
"type": "metric",
"command": "/opt/sensu/embedded/bin/ruby /etc/sensu/plugins/metrics/metrics-memory.rb",
"handlers": ["influxdb"],
"subscribers": ["all"],
"interval": 60
}
}
}

```
In the check config, an optional `influxdb` section can be added, containing a `database` option. If specified, this overrides the default `database` option in the handler config. This allows events to be written to different influxdb databases on a check-by-check basis.

Expand All @@ -68,7 +51,6 @@ In the check config, an optional `influxdb` section can be added, containing a `
}
}
```

## Handler config (`/etc/sensu/conf.d/influxdb.json`)

```json
Expand All @@ -84,17 +66,3 @@ In the check config, an optional `influxdb` section can be added, containing a `
}
}
```

Host, port, user, password and database are pretty straight forward. If `ssl_enable` is set to true, the connection to the influxdb server will be made using https instead of http. `strip_metric` however might not be. This is used to "clean up" the data sent to influxdb. Normally everything sent to handlers is akin to the `graphite`/`stats` style:

something.host.metrictype.foo.bar

or

host.stats.something.foo.bar

Really the pattern is irrelevant. People have different tastes. Adding much of that data to the column name in InfluxDB is rather silly so `strip_metric` provides you with a chance to add a value that strips off everything up to (and including that value). This allows you to continue sending to graphite or statsd or whatever and still use this handler.

Using the examples above, if you set the `strip_metric` to `host`, then the column in InfluxDB would be called `metrictype.foo.bar` or `stats.something.foo.bar`. If you set the value to `foo` then the column would simply be called `foo`

Note that `strip_metric` isn't required.
51 changes: 26 additions & 25 deletions influxdb.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require "rubygems" if RUBY_VERSION < '1.9.0'
require "em-http"
require "em-http-request"
require "eventmachine"
require "json"

Expand All @@ -26,10 +26,6 @@ def post_init()

def run(event_data)
data = parse_event(event_data)
values = Array.new()
metrics = Array.new()

values.push(data["timestamp"].to_i, data["host"])
data["output"].split(/\n/).each do |line|
key, value, time = line.split(/\s+/)

Expand All @@ -39,42 +35,47 @@ def run(event_data)
key.gsub!(/^.*#{@settings['influxdb']['strip_metric']}\.(.*$)/, '\1')
end

metrics.push(key)
# TODO: Try and sanitise the time
values.push(value)
end
# Multiplied by 1000 to match influxdb timescale
time = (time.to_i)*1000

body = [{
"name" => data["series"],
"columns" => ["time", "host"].concat(metrics),
"points" => [values]
}]
body = [{
"name" => key,
"columns" => ["time", "value"],
"points" => [[time, value.to_f]]
}]

settings = parse_settings()
database = data["influxdb"]["database"] || settings["database"]
settings = parse_settings()
database = data["database"]

protocol = "http"
if settings["ssl_enable"]
protocol = "https"
end
protocol = "http"
if settings["ssl_enable"]
protocol = "https"
end

EventMachine::HttpRequest.new("#{ protocol }://#{ settings["host"] }:#{ settings["port"] }/db/#{ database }/series?u=#{ settings["user"] }&p=#{ settings["password"] }"i, em_options).post :head => { "content-type" => "application/x-www-form-urlencoded" }, :body => body.to_json
influx_url = "#{ protocol }://#{ settings['host'] }:#{ settings['port'] }/db/#{ database }/series?u=#{ settings['user'] }&p=#{ settings['password'] }"

begin
conn = EventMachine::HttpRequest.new(influx_url).post :head => { "content-type" => "application/x-www-form-urlencoded" }, :body => body.to_json
rescue => e
puts "Error on connection #{e}"
end
end
end

private
def parse_event(event_data)
begin
event = JSON.parse(event_data)
data = {
"database" => event["check"]["influxdb"]["database"],
"database" => (event["database"].nil? ? @settings['influxdb']['database'] : event["database"]),
"duration" => event["check"]["duration"],
"host" => event["client"]["name"],
"output" => event["check"]["output"],
"series" => event["check"]["name"],
"timestamp" => event["check"]["issued"]
}
rescue => e
puts "Failed to parse event data"
puts " Failed to parse event data: #{e} "
end
return data
end
Expand All @@ -86,13 +87,13 @@ def parse_settings()
"host" => @settings["influxdb"]["host"],
"password" => @settings["influxdb"]["password"],
"port" => @settings["influxdb"]["port"],
"ssl_enable" => @settings["influxdb"]["ssl_enable"],
"ssl_enable" => @settings["influxdb"]["ssl_enable"],
"strip_metric" => @settings["influxdb"]["strip_metric"],
"timeout" => @settings["influxdb"]["timeout"],
"user" => @settings["influxdb"]["user"]
}
rescue => e
puts "Failed to parse InfluxDB settings"
puts "Failed to parse InfluxDB settings #{e} "
end
return settings
end
Expand Down