bosh-monitor 1.2980.0 → 1.2981.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5b153d8361a68b7be9246dca36ea5c91e791ba2
4
- data.tar.gz: 55ed9a88a052175affce4963dc78f49fb13fce07
3
+ metadata.gz: de5c0802c02e2abd67ade2f77f300ef6e8438e9a
4
+ data.tar.gz: 4f2e36dc946ccab2afa26fb66f517fedf03bd97b
5
5
  SHA512:
6
- metadata.gz: 3f9e46d1751ae95e516005560eb809282e6e683e1ada1bc0ec9a4974cbad63753fbf7d139a5f88481a1cd3972975e833ffa704a35a707522b44976a5d4f32f16
7
- data.tar.gz: b6178d2945aca5d646ca4505288c2f15b06b269053c3c4b69d973c5c4acd50f82193ea94cfdefe6e1a20cf9f7152cee36d7b9297d10caf25240edae0f56fe7d2
6
+ metadata.gz: 1e883ab6db000252c6b5735f32724e1076a127ca847986cbf55d8035a3f325ee4155b43aaa8c2fb6c64f48c80a76cb0f3e38a64833a9a911c58ba730e78396e7
7
+ data.tar.gz: 2c1160cbf398c4b57e8b338b7d5547f1617f298aa7f5412156f3c45f6835ea2b01d036c33579252f32564eb4b6c63dfd9474dcb3ec70e6032d9d3df13b145de3
data/README.md CHANGED
@@ -45,7 +45,8 @@ Among the included plugins are:
45
45
  - DataDog - Sends various events to DataDog.com using their API
46
46
  - AWS CloudWatch - Sends various events to Amazon's CloudWatch using their API
47
47
  - Emailer - Sends configurable Emails on events reciept
48
-
48
+ Consul Event Forwarder - Sends heartbeats as events and TTL checks to a consul cluster
49
+
49
50
  Plugins should conform to the following interface:
50
51
 
51
52
  | *Method* | *Arguments* | *Description* |
data/lib/bosh/monitor.rb CHANGED
@@ -74,3 +74,4 @@ require 'bosh/monitor/plugins/pagerduty'
74
74
  require 'bosh/monitor/plugins/resurrector'
75
75
  require 'bosh/monitor/plugins/tsdb'
76
76
  require 'bosh/monitor/plugins/varz'
77
+ require 'bosh/monitor/plugins/consul_event_forwarder'
@@ -0,0 +1,57 @@
1
+ #Using Bosh Monitor Plugins
2
+
3
+ ##AWS CloudWatch
4
+ Sends various events to Amazon's CloudWatch using their
5
+
6
+ ##DataDog
7
+ Sends various events to DataDog.com using their API
8
+
9
+ | option | description |
10
+ |------------------|------------------------|
11
+ | api_key | Your api Key |
12
+ | application_key | Your Application Key |
13
+
14
+ ##Consul Event Forwarder Plugin
15
+ The Consul plugin works by forwarding nats heartbeat events and alerts to a consul server or agent. The nats messages can be forwarded as ttl checks and events. Heartbeat messages will be forwarded as TTL checks, each time a heartbeat occurs it will update the ttl check with it's status. When an alert occurs it will be forwareded to Consul as an Event. The current best use case seems to be to forward to a consul agent (possibly on your inception server)
16
+
17
+ | option | description |
18
+ |-----------------------|-------------------------------------|
19
+ | host | The address of the cluster or agent |
20
+ | namespace | A namespace to separate multiple instances of the same release
21
+ | events_api | The events api endpoint defaults to /v1/event/fire/
22
+ | ttl_api | The Check update and registration endpoint defaults to /v1/agent/check/
23
+ | port | Defaults to 8500
24
+ | protocal | Defaults to HTTP
25
+ | params | Can be used to pass access token "token=MYACCESSTOKEN"
26
+ | ttl | TTL Checks will be used if a ttl period is set here. Example "120s"
27
+ | events | If set to true heartbeats will be forwarded as events
28
+ | ttl_note | A note that will be passed back to consul with a ttl check
29
+ | heartbeats_as_alerts | * If set to true all heartbeats will also be forwarded as event, this gives you 'real time' vitals data to correlate with
30
+
31
+ ####* When heartbeats are sent as alerts the format has been made more concise to come in under the event payload bytesize limits that consul enforces
32
+ ```ruby
33
+ {
34
+ :agent => agent_id,
35
+ :name => "job_name / index",
36
+ :state => job_state,
37
+ :data => {
38
+ :cpu => [sys, user, wait]
39
+ :dsk => {
40
+ :eph => [inode_percent, percent],
41
+ :sys =>[inode_percent, percent]
42
+ }
43
+ :ld => load,
44
+ :mem => [kb, percent],
45
+ :swp => [kb, percent]
46
+ }
47
+ }
48
+ ```
49
+
50
+ ## Event Logger
51
+ Logs all events
52
+
53
+ ## PagerDuty
54
+ Sends various events to PagerDuty.com using their API
55
+
56
+ ## Resurrector
57
+ Restarts VMs that have stopped heartbeating
@@ -0,0 +1,170 @@
1
+ # Consul Bosh Monitor Plugin
2
+ # Forwards alert and heartbeat messages as events to a consul agent
3
+ module Bosh::Monitor
4
+ module Plugins
5
+ class ConsulEventForwarder < Base
6
+ include Bosh::Monitor::Plugins::HttpRequestHelper
7
+
8
+ CONSUL_REQUEST_HEADER = { 'Content-Type' => 'application/javascript' }
9
+ TTL_STATUS_MAP = { 'running' => :pass, 'failing' => :fail, 'unknown' => :fail, 'default' => :warn }
10
+ REQUIRED_OPTIONS = ["host", "port", "protocol" ]
11
+ CONSUL_MAX_EVENT_BYTESIZE = 512
12
+
13
+ CONSUL_ENDPOINTS = {
14
+ event: "/v1/event/fire/", #fire an event
15
+ register: "/v1/agent/check/register", #register a check
16
+ deregister: "/v1/agent/check/deregister/", #deregister a check
17
+ pass: "/v1/agent/check/pass/", #mark a check as passing
18
+ warn: "/v1/agent/check/warn/", #mark a check as warning
19
+ fail: "/v1/agent/check/fail/" #mark a check as failing
20
+ }
21
+
22
+ def run
23
+ @checklist = []
24
+ @host = options['host']
25
+ @namespace = options['namespace']
26
+ @port = options['port']
27
+ @protocol = options['protocol']
28
+ @params = options['params']
29
+ @ttl = options['ttl']
30
+ @use_events = options['events']
31
+ @ttl_note = options['ttl_note']
32
+
33
+ @heartbeats_as_alerts = options['heartbeats_as_alerts']
34
+ @use_ttl = !@ttl.nil?
35
+
36
+ @status_map = Hash.new(:warn)
37
+ @status_map.merge!(TTL_STATUS_MAP)
38
+
39
+ logger.info("Consul Event Forwarder plugin is running...")
40
+ end
41
+
42
+ def validate_options
43
+ valid_array = REQUIRED_OPTIONS.map{ |o| options[o].to_s.empty? }
44
+ !valid_array.include?(true)
45
+ end
46
+
47
+ def process(event)
48
+ validate_options && forward_event(event)
49
+ end
50
+
51
+ private
52
+
53
+ def consul_uri(event, note_type)
54
+ path = get_path_for_note_type(event, note_type)
55
+ URI.parse("#{@protocol}://#{@host}:#{@port}#{path}?#{@params}")
56
+ end
57
+
58
+ #heartbeats get forwarded as ttl checks and alerts get forwarded as events
59
+ #if heartbeat_as_alert is true than a heartbeat gets forwarded as events as well
60
+ def forward_event(event)
61
+
62
+ if forward_this_event?(event)
63
+ notify_consul(event, :event)
64
+ end
65
+
66
+ if forward_this_ttl?(event)
67
+ event_unregistered?(event) ? notify_consul(event, :register, registration_payload(event)) : notify_consul(event, :ttl)
68
+ end
69
+
70
+ end
71
+
72
+ #should an individual alert or heartbeat be forwarded as a consul event
73
+ def forward_this_event?(event)
74
+ @use_events && ( event.is_a?(Bosh::Monitor::Events::Alert) || ( event.is_a?(Bosh::Monitor::Events::Heartbeat) && @heartbeats_as_alerts) )
75
+ end
76
+
77
+ def forward_this_ttl?(event)
78
+ @use_ttl && event.is_a?(Bosh::Monitor::Events::Heartbeat)
79
+ end
80
+
81
+ def get_path_for_note_type(event, note_type)
82
+ case note_type
83
+ when :event
84
+ CONSUL_ENDPOINTS[:event] + label_for_event(event)
85
+ when :ttl
86
+ job_state = event.attributes['job_state']
87
+ status_id = @status_map[job_state]
88
+ CONSUL_ENDPOINTS[status_id] + label_for_ttl(event)
89
+ when :register
90
+ CONSUL_ENDPOINTS[:register]
91
+ end
92
+ end
93
+
94
+ def label_for_event(event)
95
+ case event
96
+ when Bosh::Monitor::Events::Heartbeat
97
+ "#{@namespace}#{event.job}"
98
+ when Bosh::Monitor::Events::Alert
99
+ event_label = event.title.downcase.gsub(" ","_")
100
+ "#{@namespace}#{event_label}"
101
+ else
102
+ #Something we haven't encountered yet
103
+ "#{@namespace}event"
104
+ end
105
+ end
106
+
107
+ def label_for_ttl(event)
108
+ "#{@namespace}#{event.job}"
109
+ end
110
+
111
+ # Notify consul of an event
112
+ # note_type: the type of notice we are sending (:event, :ttl, :register)
113
+ # message: an optional body for the message, event.json is used by default
114
+ def notify_consul(event, note_type, message=nil)
115
+ body = message.nil? ? right_sized_body_for_consul(event).to_json : message.to_json
116
+ uri = consul_uri(event, note_type)
117
+
118
+ request = { :body => body }
119
+
120
+ send_http_put_request(uri , request)
121
+
122
+ #if a registration request returns without error we log it
123
+ #we don't want to send extra registrations
124
+ @checklist << event.job if note_type == :register
125
+ rescue => e
126
+ logger.error("Could not forward event to Consul Cluster @#{@host}: #{e.inspect}")
127
+ end
128
+
129
+ #consul limits event payload to < 512 bytes, unfortunately we have to do some pruning so this limit is not as likely to be reached
130
+ #this is suboptimal but otherwise the event post will fail, and how do we decide what data isn't important?
131
+ def right_sized_body_for_consul(event)
132
+ body = event.to_hash
133
+ if event.is_a?(Bosh::Monitor::Events::Heartbeat)
134
+ vitals = body[:vitals]
135
+ #currently assuming the event hash details are always put together in the same order
136
+ #this should yield consistent results from the values method
137
+ {
138
+ :agent => body[:agent_id],
139
+ :name => "#{body[:job]}/#{body[:index]}",
140
+ :state => "#{body[:job_state]}",
141
+ :data => {
142
+ :cpu => vitals['cpu'].values,
143
+ :dsk => {
144
+ :eph => vitals['disk']['ephemeral'].values,
145
+ :sys => vitals['disk']['system'].values,
146
+ },
147
+ :ld => vitals['load'],
148
+ :mem => vitals['mem'].values,
149
+ :swp => vitals['swap'].values
150
+ }
151
+ }
152
+ else
153
+ body
154
+ end
155
+ end
156
+
157
+ #Has this process not encountered a specific ttl check yet?
158
+ #We keep track so we aren't sending superfluous registrations
159
+ #Only register ttl for events that have a job assigned
160
+ def event_unregistered?(event)
161
+ @use_ttl && event.respond_to?(:job) && !@checklist.include?(event.job)
162
+ end
163
+
164
+ def registration_payload(event)
165
+ { "name" => label_for_ttl(event), "notes" => @ttl_note, "ttl" => @ttl }
166
+ end
167
+
168
+ end
169
+ end
170
+ end
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Monitor
3
- VERSION = '1.2980.0'
3
+ VERSION = '1.2981.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2980.0
4
+ version: 1.2981.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VMware
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-02 00:00:00.000000000 Z
11
+ date: 2015-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eventmachine
@@ -180,7 +180,7 @@ dependencies:
180
180
  version: '0'
181
181
  description: |-
182
182
  BOSH Health Monitor
183
- cb6c5e
183
+ 4246cc
184
184
  email: support@cloudfoundry.com
185
185
  executables:
186
186
  - bosh-monitor-console
@@ -207,8 +207,10 @@ files:
207
207
  - lib/bosh/monitor/events/base.rb
208
208
  - lib/bosh/monitor/events/heartbeat.rb
209
209
  - lib/bosh/monitor/metric.rb
210
+ - lib/bosh/monitor/plugins/README.md
210
211
  - lib/bosh/monitor/plugins/base.rb
211
212
  - lib/bosh/monitor/plugins/cloud_watch.rb
213
+ - lib/bosh/monitor/plugins/consul_event_forwarder.rb
212
214
  - lib/bosh/monitor/plugins/datadog.rb
213
215
  - lib/bosh/monitor/plugins/dummy.rb
214
216
  - lib/bosh/monitor/plugins/email.rb