Class: Sensu::Client::HTTPSocket
- Inherits:
-
EM::HttpServer::Server
- Object
- EM::HttpServer::Server
- Sensu::Client::HTTPSocket
- Includes:
- API::Utilities::TransportInfo, CheckUtils, Utilities
- Defined in:
- lib/sensu/client/http_socket.rb
Overview
EventMachine connection handler for the Sensu HTTP client’s socket.
The Sensu client listens on localhost, port 3031 (by default), for TCP HTTP connections. This allows software running on the host to push check results (that may contain metrics) into Sensu, without needing to know anything about Sensu’s internal implementation.
All requests and responses expect a json-encoded body (if a body is expected at all).
This socket requires receiving a proper HTTP request to any of the following endpoints:
GET /info
This endpoint returns 200 OK with some basic Sensu info
POST /results
This endpoint expects application/json body with a check result
GET /settings
This endpoint responds with 200 OK and the Sensu configuration
GET /brew
This endpoint gets you some fresh coffee
Constant Summary
Constants included from Utilities
Instance Attribute Summary collapse
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#settings ⇒ Object
Returns the value of attribute settings.
-
#transport ⇒ Object
Returns the value of attribute transport.
Instance Method Summary collapse
- #authorized? ⇒ Boolean
- #http_request_errback(error) ⇒ Object
-
#initialize ⇒ HTTPSocket
constructor
A new instance of HTTPSocket.
-
#process_http_request ⇒ Object
This method is called to process HTTP requests.
- #process_request_info ⇒ Object
- #process_request_results ⇒ Object
- #process_request_settings ⇒ Object
- #send_response(status, status_string, content) ⇒ Object
Methods included from CheckUtils
#process_check_result, #publish_check_result, #validate_check_result
Methods included from Utilities
#attributes_match?, #check_subdued?, #deep_merge, #determine_check_cron_time, #eval_attribute_value, #find_attribute_value, #in_time_window?, #in_time_windows?, #object_substitute_tokens, #process_cpu_times, #process_eval_string, #random_uuid, #redact_sensitive, #retry_until_true, #substitute_tokens, #system_address, #system_hostname, #testing?
Methods included from API::Utilities::TransportInfo
Constructor Details
#initialize ⇒ HTTPSocket
Returns a new instance of HTTPSocket.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/sensu/client/http_socket.rb', line 41 def initialize super @endpoints = { "/info" => { "methods" => { "GET" => method(:process_request_info) }, "help" => "Sensu client information" }, "/results" => { "methods" => { "POST" => method(:process_request_results) }, "help" => "Send check JSON results here" }, "/settings" => { "methods" => { "GET" => method(:process_request_settings) }, "help" => "Get redacted Sensu settings (requires basic auth). Use ?redacted=false if you want the setting unredacted." }, "/brew" => { "methods" => { "GET" => Proc.new { |response| send_response(418, "I'm a teapot", { :response => "I'm a teapot!" }) } }, "help" => "Ask Sensu to brew a cup of joe (try it!)" } } @response = nil end |
Instance Attribute Details
#logger ⇒ Object
Returns the value of attribute logger.
39 40 41 |
# File 'lib/sensu/client/http_socket.rb', line 39 def logger @logger end |
#settings ⇒ Object
Returns the value of attribute settings.
39 40 41 |
# File 'lib/sensu/client/http_socket.rb', line 39 def settings @settings end |
#transport ⇒ Object
Returns the value of attribute transport.
39 40 41 |
# File 'lib/sensu/client/http_socket.rb', line 39 def transport @transport end |
Instance Method Details
#authorized? ⇒ Boolean
76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/sensu/client/http_socket.rb', line 76 def = @settings[:client][:http_socket] || Hash.new if [:user] and [:password] if @http[:authorization] scheme, base64 = @http[:authorization].split("\s") if scheme == "Basic" user, password = Base64.decode64(base64).split(":") return (user == [:user] && password == [:password]) end end end false end |
#http_request_errback(error) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/sensu/client/http_socket.rb', line 144 def http_request_errback(error) @logger.error("http socket error while processing request", { :error => error.to_s, :backtrace => error.backtrace }) @response = EM::DelegatedHttpResponse.new(self) @response.content_type "application/json" send_response(500, "Internal Server Error", { "response" => "Internal Server Error: Check your Sensu logs for error details" }) end |
#process_http_request ⇒ Object
This method is called to process HTTP requests
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/sensu/client/http_socket.rb', line 157 def process_http_request @logger.debug("http socket processing", { :http_request_method => @http_request_method, :http_request_uri => @http_request_uri }) @response = EM::DelegatedHttpResponse.new(self) @response.content_type "application/json" endpoint = @endpoints[@http_request_uri] if endpoint @logger.debug("http socket endpoint found", { :http_request_uri => @http_request_uri, :accepted_methods => endpoint["methods"].keys }) method_name = @http_request_method.upcase method_handler = endpoint["methods"][method_name] if method_handler @logger.debug("http socket executing handler", { :method_name => method_name, :http_request_uri => @http_request_uri }) method_handler.call else @logger.debug("http socket method is not allowed for endpoint", { :method_name => method_name, :http_request_uri => @http_request_uri }) send_response(405, "Method Not Allowed", { :response => "Valid methods for this endpoint: #{reqdef['methods'].keys}" }) end else @logger.warn("http socket unknown endpoint requested", :http_request_uri => @http_request_uri) help_response = { :endpoints => {} } @endpoints.each do |key, value| help_response[:endpoints][key] ||= Hash.new help_response[:endpoints][key]["help"] = value["help"] help_response[:endpoints][key]["methods"] = value["methods"].keys end send_response(404, "Not Found", help_response) end end |
#process_request_info ⇒ Object
102 103 104 105 106 107 108 109 110 111 |
# File 'lib/sensu/client/http_socket.rb', line 102 def process_request_info transport_info do |info| send_response(200, "OK", { :sensu => { :version => VERSION }, :transport => info }) end end |
#process_request_results ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/sensu/client/http_socket.rb', line 113 def process_request_results if @http[:content_type] and @http[:content_type] == "application/json" and @http_content begin check = Sensu::JSON::load(@http_content) process_check_result(check) send_response(202, "OK", {:response => "ok"}) rescue Sensu::JSON::ParseError, ArgumentError send_response(400, "Failed to parse JSON body", {:response => "Failed to parse JSON body"}) end else send_response(415, "Only application/json content type accepted", {:response => "Invalid content type"}) end end |
#process_request_settings ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/sensu/client/http_socket.rb', line 127 def process_request_settings if @logger.info("http socket responding to request for configuration settings") if @http_query_string and @http_query_string.downcase.include?("redacted=false") send_response(200, "OK", @settings.to_hash) else send_response(200, "OK", redact_sensitive(@settings.to_hash)) end else @logger.warn("http socket refusing to serve unauthorized settings request") @response.headers["WWW-Authenticate"] = 'Basic realm="Sensu Client Restricted Area"' send_response(401, "Unauthorized", { :response => "You must be authenticated using your http_options user and password settings" }) end end |
#send_response(status, status_string, content) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/sensu/client/http_socket.rb', line 90 def send_response(status, status_string, content) @logger.debug("http socket sending response", { :status => status, :status_string => status_string, :content => content }) @response.status = status @response.status_string = status_string @response.content = Sensu::JSON::dump(content) @response.send_response end |