http_status_agent.rb 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. module Agents
  2. class HttpStatusAgent < Agent
  3. include WebRequestConcern
  4. include FormConfigurable
  5. can_dry_run!
  6. can_order_created_events!
  7. default_schedule "every_12h"
  8. form_configurable :url
  9. form_configurable :disable_redirect_follow, type: :array, values: ['true', 'false']
  10. form_configurable :headers_to_save
  11. description <<-MD
  12. The HttpStatusAgent will check a url and emit the resulting HTTP status code with the time that it waited for a reply. Additionally, it will optionally emit the value of one or more specified headers.
  13. Specify a `Url` and the Http Status Agent will produce an event with the HTTP status code. If you specify one or more `Headers to save` (comma-delimited) as well, that header or headers' value(s) will be included in the event.
  14. The `disable redirect follow` option causes the Agent to not follow HTTP redirects. For example, setting this to `true` will cause an agent that receives a 301 redirect to `http://yahoo.com` to return a status of 301 instead of following the redirect and returning 200.
  15. MD
  16. event_description <<-MD
  17. Events will have the following fields:
  18. {
  19. "url": "...",
  20. "status": "...",
  21. "elapsed_time": "...",
  22. "headers": {
  23. "...": "..."
  24. }
  25. }
  26. MD
  27. def working?
  28. memory['last_status'].to_i > 0
  29. end
  30. def default_options
  31. {
  32. 'url' => "http://google.com",
  33. 'disable_redirect_follow' => "true",
  34. }
  35. end
  36. def validate_options
  37. errors.add(:base, "a url must be specified") unless options['url'].present?
  38. end
  39. def header_array(str)
  40. (str || '').split(',').map(&:strip)
  41. end
  42. def check
  43. check_this_url interpolated[:url], header_array(interpolated[:headers_to_save])
  44. end
  45. def receive(incoming_events)
  46. incoming_events.each do |event|
  47. interpolate_with(event) do
  48. check_this_url interpolated[:url], header_array(interpolated[:headers_to_save])
  49. end
  50. end
  51. end
  52. private
  53. def check_this_url(url, local_headers)
  54. # Track time
  55. measured_result = TimeTracker.track { ping(url) }
  56. payload = { 'url' => url, 'response_received' => false, 'elapsed_time' => measured_result.elapsed_time }
  57. # Deal with failures
  58. if measured_result.result
  59. payload.merge!({ 'response_received' => true, 'status' => measured_result.status.to_s })
  60. # Deal with headers
  61. if local_headers.present?
  62. header_results = measured_result.result.headers.select {|header, value| local_headers.include?(header)}
  63. # Fill in headers that we wanted, but weren't returned
  64. local_headers.each { |header| header_results[header] = nil unless header_results.has_key?(header) }
  65. payload.merge!({ 'headers' => header_results })
  66. end
  67. create_event payload: payload
  68. memory['last_status'] = measured_result.status.to_s
  69. else
  70. create_event payload: payload
  71. memory['last_status'] = nil
  72. end
  73. end
  74. def ping(url)
  75. result = faraday.get url
  76. result.status > 0 ? result : nil
  77. rescue
  78. nil
  79. end
  80. end
  81. end