rearview 1.1.2-jruby → 1.2.0-jruby

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -3
  3. data/app/controllers/rearview/application_controller.rb +11 -0
  4. data/app/controllers/rearview/dashboard_children_controller.rb +1 -1
  5. data/app/controllers/rearview/dashboards_controller.rb +1 -1
  6. data/app/controllers/rearview/home_controller.rb +1 -1
  7. data/app/controllers/rearview/jobs_controller.rb +33 -29
  8. data/app/controllers/rearview/monitor_controller.rb +16 -2
  9. data/app/controllers/rearview/user_controller.rb +2 -2
  10. data/app/helpers/rearview/application_helper.rb +3 -3
  11. data/app/mailers/rearview/alert_mailer.rb +0 -2
  12. data/app/mailers/rearview/metrics_validation_mailer.rb +12 -0
  13. data/app/models/rearview/job.rb +17 -13
  14. data/app/views/rearview/home/show.html.erb +2 -0
  15. data/app/views/rearview/jobs/_job.json.jbuilder +1 -0
  16. data/app/views/rearview/metrics_validation_mailer/validation_failed_email.text.erb +13 -0
  17. data/app/views/rearview/monitor/create.json.jbuilder +1 -0
  18. data/db/migrate/20131106162900_base_schema.rb +2 -2
  19. data/lib/generators/templates/rearview.rb +24 -7
  20. data/lib/graphite.rb +13 -0
  21. data/lib/graphite/cacerts.pem +2184 -0
  22. data/lib/graphite/client.rb +44 -0
  23. data/lib/graphite/graph.rb +35 -0
  24. data/lib/{rearview/graphite_parser.rb → graphite/raw_parser.rb} +2 -3
  25. data/lib/graphite/target.rb +9 -0
  26. data/lib/graphite/target_grammer.rb +114 -0
  27. data/lib/graphite/target_grammer.treetop +53 -0
  28. data/lib/graphite/target_parser.rb +50 -0
  29. data/lib/graphite/treetop_ext.rb +14 -0
  30. data/lib/rearview.rb +11 -3
  31. data/lib/rearview/alerts_handler.rb +2 -6
  32. data/lib/rearview/configuration.rb +44 -19
  33. data/lib/rearview/cron_expression_validator.rb +11 -0
  34. data/lib/rearview/metrics_validator.rb +52 -0
  35. data/lib/rearview/metrics_validator_service.rb +24 -0
  36. data/lib/rearview/metrics_validator_task.rb +56 -0
  37. data/lib/rearview/monitor_runner.rb +9 -7
  38. data/lib/rearview/monitor_service.rb +2 -0
  39. data/lib/rearview/stats_service.rb +4 -2
  40. data/lib/rearview/version.rb +1 -1
  41. data/lib/tasks/rearview_tasks.rake +7 -1
  42. data/public/{help → rearview-src/help}/alert.html +0 -0
  43. data/public/{help → rearview-src/help}/quick.html +0 -0
  44. data/public/rearview-src/js/app.js +9 -0
  45. data/public/rearview-src/js/model/user.js +6 -2
  46. data/public/rearview-src/js/view/addmonitor.js +13 -8
  47. data/public/rearview-src/js/view/alert.js +11 -4
  48. data/public/rearview-src/js/view/dashboard.js +4 -2
  49. data/public/rearview-src/js/view/expandedmonitor.js +22 -9
  50. data/public/rearview-src/js/view/settings.js +84 -0
  51. data/public/rearview-src/less/login.less +4 -4
  52. data/public/rearview-src/less/rearview.less +17 -10
  53. data/public/{monitors → rearview-src/monitors}/index.json +1 -1
  54. data/public/{monitors → rearview-src/monitors}/outage.rb +0 -0
  55. data/public/rearview-src/templates/alert.hbs +10 -2
  56. data/public/rearview-src/templates/primarynav.hbs +6 -6
  57. data/public/rearview-src/templates/schedulemonitor.hbs +2 -1
  58. data/public/rearview-src/templates/settings.hbs +23 -0
  59. data/public/rearview/build.txt +1 -0
  60. data/public/rearview/help/alert.html +20 -0
  61. data/public/rearview/help/quick.html +34 -0
  62. data/public/rearview/js/app.js +1 -1
  63. data/public/rearview/js/main.js +21 -21
  64. data/public/rearview/js/model/user.js +1 -1
  65. data/public/rearview/js/view/addmonitor.js +1 -1
  66. data/public/rearview/js/view/alert.js +1 -1
  67. data/public/rearview/js/view/dashboard.js +1 -1
  68. data/public/rearview/js/view/expandedmonitor.js +1 -1
  69. data/public/rearview/js/view/settings.js +1 -0
  70. data/public/rearview/less/login.less +4 -4
  71. data/public/rearview/less/rearview.less +17 -10
  72. data/public/rearview/monitors/index.json +3 -0
  73. data/public/rearview/monitors/outage.rb +2 -0
  74. data/public/rearview/templates/alert.hbs +10 -2
  75. data/public/rearview/templates/primarynav.hbs +6 -6
  76. data/public/rearview/templates/schedulemonitor.hbs +2 -1
  77. data/public/rearview/templates/settings.hbs +23 -0
  78. data/spec/controllers/jobs_controller_spec.rb +1 -0
  79. data/spec/controllers/monitor_controller_spec.rb +3 -0
  80. data/spec/controllers/user_controller_spec.rb +5 -2
  81. data/spec/data/metrics.yml +598 -0
  82. data/spec/dummy/log/development.log +1044 -0
  83. data/spec/dummy/log/test.log +171716 -0
  84. data/spec/helpers/application_helper_spec.rb +33 -0
  85. data/spec/lib/graphite/client_spec.rb +126 -0
  86. data/spec/lib/graphite/graph_spec.rb +17 -0
  87. data/spec/lib/graphite/graphite_spec.rb +4 -0
  88. data/spec/lib/{rearview/graphite_parser_spec.rb → graphite/raw_parser.rb} +6 -5
  89. data/spec/lib/graphite/target_grammer_spec.rb +106 -0
  90. data/spec/lib/graphite/target_parser_spec.rb +124 -0
  91. data/spec/lib/graphite/target_spec.rb +5 -0
  92. data/spec/lib/rearview/configuration_spec.rb +69 -48
  93. data/spec/lib/rearview/metrics_validator_service_spec.rb +43 -0
  94. data/spec/lib/rearview/metrics_validator_spec.rb +84 -0
  95. data/spec/lib/rearview/metrics_validator_task_spec.rb +62 -0
  96. data/spec/lib/rearview/monitor_runner_spec.rb +3 -3
  97. data/spec/lib/rearview/stats_task_spec.rb +21 -0
  98. data/spec/mailers/metrics_validation_mailer_spec.rb +46 -0
  99. data/spec/models/job_spec.rb +82 -9
  100. data/spec/spec_helper.rb +15 -4
  101. data/spec/support/json_factory.rb +1 -1
  102. data/spec/views/dashboards/show.json.jbuilder_spec.rb +3 -1
  103. data/spec/views/jobs/show.json.jbuilder_spec.rb +2 -1
  104. metadata +98 -11
  105. data/public/rearview-src/templates/test.txt +0 -1
  106. data/public/rearview/templates/test.txt +0 -1
@@ -0,0 +1,44 @@
1
+ module Graphite
2
+ class Client
3
+ extend Forwardable
4
+ attr_reader :connection
5
+ def_delegators :@connection, :get, :post
6
+ def initialize(options={})
7
+ default_options = {}
8
+ default_options[:ssl] = {
9
+ verify: true,
10
+ ca_file: File.expand_path('../cacerts.pem', __FILE__)
11
+ }
12
+ basic_auth = options.delete(:basic_auth)
13
+ @connection = Faraday.new(default_options.merge(options))
14
+ if basic_auth.present?
15
+ @connection.basic_auth(basic_auth[:user],basic_auth[:password])
16
+ end
17
+ end
18
+ def render(params={})
19
+ connection.get('/render',params)
20
+ end
21
+ def find_metric(metric)
22
+ connection.get('/metrics/find',{ query: metric })
23
+ end
24
+ def metric_exists?(metric)
25
+ exists = false
26
+ response = find_metric(metric)
27
+ # Does this need to handle redirects?
28
+ if response.status == 200 && response.headers['content-type']=='application/json'
29
+ json = JSON.parse(response.body)
30
+ exists = true unless json.empty?
31
+ end
32
+ exists
33
+ end
34
+ def reachable?
35
+ reachable = false
36
+ begin
37
+ response = connection.get('/render')
38
+ reachable = response.status==200 && response.headers['content-type']=='image/png' && response.headers['content-length'].to_i > 0
39
+ rescue Exception => e
40
+ end
41
+ reachable
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,35 @@
1
+ module Graphite
2
+ class Graph
3
+ attr_accessor :targets,:params
4
+ def initialize
5
+ @targets = []
6
+ @params = {}
7
+ end
8
+ def method_missing(sym)
9
+ if @params.has_key?(sym.to_s)
10
+ @params[sym.to_s]
11
+ else
12
+ super
13
+ end
14
+ end
15
+ def self.from_url(url)
16
+ graph = self.new
17
+ uri = URI(url)
18
+ url_params = CGI.parse(uri.query)
19
+ target_parser = Graphite::TargetParser.new
20
+ url_params.delete("target").each do |t|
21
+ target_parser.parse!(t)
22
+ graph.targets << target_parser.tree.to_model
23
+ end
24
+ url_params.keys.inject(graph.params) { |acc,key|
25
+ acc[key] = if url_params[key].present? && url_params[key].size==1
26
+ url_params[key].first
27
+ else
28
+ url_params[key]
29
+ end
30
+ acc
31
+ }
32
+ graph
33
+ end
34
+ end
35
+ end
@@ -1,11 +1,10 @@
1
- module Rearview
2
- class GraphiteParser
1
+ module Graphite
2
+ class RawParser
3
3
  ## returns an array of arrays of pairs with 2 elements timestamp and value (may be nil)
4
4
  def self.parse(lines)
5
5
  lines.strip.split("\n").map do |line|
6
6
  metric, startTime, endTime, interval, dataStr = /(.*),(\d+),(\d+),(\d+)\|(.*)/.match(line)[1..-1]
7
7
  data = dataStr.split(",")
8
-
9
8
  0.upto(data.length - 1).map do |i|
10
9
  value = data[i]
11
10
  {
@@ -0,0 +1,9 @@
1
+ module Graphite
2
+ class Target
3
+ attr_accessor :color,:alias,:metric,:functions
4
+ def initialize
5
+ yield self if block_given?
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,114 @@
1
+ module Graphite
2
+ module TargetGrammer
3
+
4
+ class SyntaxNode < Treetop::Runtime::SyntaxNode
5
+ def text
6
+ self.text_value
7
+ end
8
+ end
9
+
10
+ class Target < SyntaxNode
11
+ def path?
12
+ elements[0].kind_of?(Graphite::TargetGrammer::Path)
13
+ end
14
+ def expression?
15
+ elements[0].kind_of?(Graphite::TargetGrammer::Expression)
16
+ end
17
+ def comment?
18
+ elements[0].kind_of?(Graphite::TargetGrammer::Comment)
19
+ end
20
+ def unknown?
21
+ !path? && !expression?
22
+ end
23
+ def color
24
+ unless @color
25
+ e = self.expressions.detect {|e| e.identifier.try(:text) == "color" }
26
+ if e && e.args && e.args.elements
27
+ color_val = e.args.elements.last.detect { |e| e.kind_of?(Graphite::TargetGrammer::StringLiteral) }
28
+ unless color_val.nil?
29
+ @color = color_val.text
30
+ end
31
+ end
32
+ end
33
+ @color
34
+ end
35
+ def alias
36
+ unless @alias
37
+ e = self.expressions.detect {|e| e.identifier.try(:text) == "alias" }
38
+ if e && e.args && e.args.elements
39
+ alias_val = e.args.elements.last.detect { |e| e.kind_of?(Graphite::TargetGrammer::StringLiteral) }
40
+ unless alias_val.nil?
41
+ @alias = alias_val.text
42
+ end
43
+ end
44
+ end
45
+ @alias
46
+ end
47
+ def metric
48
+ unless @metric
49
+ @metric = if path?
50
+ self.elements[0].text
51
+ else
52
+ path = self.detect { |e| e.kind_of?(Graphite::TargetGrammer::Path) }
53
+ unless path.nil?
54
+ path.text
55
+ end
56
+ end
57
+ end
58
+ @metric
59
+ end
60
+ def functions
61
+ unless @functions
62
+ @functions = self.expressions.map { |e| e.identifier.text }
63
+ end
64
+ @functions
65
+ end
66
+ def expressions
67
+ unless @expressions
68
+ @expressions = self.find_all { |e| e.kind_of?(Graphite::TargetGrammer::Expression) }
69
+ end
70
+ @expressions
71
+ end
72
+ def to_model
73
+ Graphite::Target.new do |model|
74
+ model.alias = self.alias
75
+ model.color = self.color
76
+ model.metric = self.metric
77
+ model.functions = self.functions
78
+ end
79
+ end
80
+ end
81
+
82
+ class IntegerLiteral < SyntaxNode
83
+ end
84
+
85
+ class StringLiteral < SyntaxNode
86
+ def text
87
+ eval self.text_value
88
+ end
89
+ end
90
+
91
+ class FloatLiteral < SyntaxNode
92
+ end
93
+
94
+ class Identifier < SyntaxNode
95
+ end
96
+
97
+ class Expression < SyntaxNode
98
+ end
99
+
100
+ class PathSegment < SyntaxNode
101
+ end
102
+
103
+ class Path < SyntaxNode
104
+ end
105
+
106
+ class Arg < SyntaxNode
107
+ end
108
+
109
+ class Comment < SyntaxNode
110
+ end
111
+
112
+ end
113
+ end
114
+
@@ -0,0 +1,53 @@
1
+ grammar TargetGrammer
2
+
3
+ rule target
4
+ ( comment / expression / path )* <Graphite::TargetGrammer::Target>
5
+ end
6
+
7
+ rule expression
8
+ identifier '(' args ')' <Graphite::TargetGrammer::Expression>
9
+ end
10
+
11
+ rule args
12
+ arg ( space* ',' space* arg )*
13
+ end
14
+
15
+ rule arg
16
+ ( expression / path / string / integer / float / space )?
17
+ end
18
+
19
+ rule path
20
+ path_segment ( '.' path_segment )* <Graphite::TargetGrammer::Path>
21
+ end
22
+
23
+ rule path_segment
24
+ [a-zA-Z0-9_\*\-]+ <Graphite::TargetGrammer::PathSegment>
25
+ end
26
+
27
+ rule comment
28
+ '#' ( . )* <Graphite::TargetGrammer::Comment>
29
+ end
30
+
31
+ rule integer
32
+ ('+' / '-')? [0-9]+ <Graphite::TargetGrammer::IntegerLiteral>
33
+ end
34
+
35
+ rule float
36
+ ('+' / '-')? [0-9]+ (('.' [0-9]+) / ('e' [0-9]+)) <Graphite::TargetGrammer::FloatLiteral>
37
+ end
38
+
39
+ rule string
40
+ '"' ('\"' / !'"' .)* '"' <Graphite::TargetGrammer::StringLiteral>
41
+ /
42
+ "'" ('\"' / !"'" .)* "'" <Graphite::TargetGrammer::StringLiteral>
43
+ end
44
+
45
+ rule identifier
46
+ [a-zA-Z0-9_]* <Graphite::TargetGrammer::Identifier>
47
+ end
48
+
49
+ rule space
50
+ [\s]+
51
+ end
52
+
53
+ end
@@ -0,0 +1,50 @@
1
+
2
+ module Graphite
3
+ class TargetParser
4
+ class TargetParserError < StandardError
5
+ attr_accessor :parser_details
6
+ def initialize(parser_details)
7
+ @parser_details = parser_details
8
+ end
9
+ def to_s
10
+ "parse failure %{message}" % parser_details
11
+ end
12
+ end
13
+ attr_reader :parser,:tree
14
+ attr_accessor :data
15
+ def initialize(data=nil)
16
+ @data = data
17
+ @parser = TargetGrammerParser.new
18
+ end
19
+ def parse(data=nil)
20
+ if data.present?
21
+ @data = data
22
+ end
23
+ @tree = @parser.parse(@data)
24
+ end
25
+ def parse!(data=nil)
26
+ self.parse(data)
27
+ if error?
28
+ raise TargetParserError.new(error)
29
+ end
30
+ @tree
31
+ end
32
+ def self.parse(data)
33
+ inst = self.new(data)
34
+ inst.parse
35
+ inst
36
+ end
37
+ def error?
38
+ @tree.nil?
39
+ end
40
+ def error
41
+ { message: @parser.failure_reason, line: @parser.failure_line, column: @parser.failure_column }
42
+ end
43
+ def self.grammer
44
+ File.expand_path("../target_grammer.treetop",__FILE__)
45
+ end
46
+ end
47
+ end
48
+
49
+ Treetop.load(Graphite::TargetParser.grammer)
50
+
@@ -0,0 +1,14 @@
1
+
2
+ class Treetop::Runtime::SyntaxNode
3
+ include Enumerable
4
+ def each(&block)
5
+ self.elements.each { |e| each_recursive(e,&block) }
6
+ end
7
+ def each_recursive(node,&block)
8
+ yield node
9
+ unless node.terminal?
10
+ node.elements.each { |e| each_recursive(e,&block) }
11
+ end
12
+ end
13
+ end
14
+
@@ -1,3 +1,5 @@
1
+ require 'graphite'
2
+
1
3
  require 'rearview/engine'
2
4
  require 'rearview/concerns'
3
5
  require 'rearview/ext/state_machine'
@@ -6,7 +8,6 @@ require 'rearview/constants_module_maker'
6
8
  require 'rearview/logger'
7
9
  require 'rearview/log_formatter'
8
10
  require 'rearview/cron_helper'
9
- require 'rearview/graphite_parser'
10
11
  require 'rearview/results_handler'
11
12
  require 'rearview/alerts_handler'
12
13
  require 'rearview/url_helper'
@@ -16,6 +17,10 @@ require 'rearview/monitor_task'
16
17
  require 'rearview/distribute'
17
18
  require 'rearview/monitor_supervisor'
18
19
  require 'rearview/monitor_service'
20
+ require 'rearview/metrics_validator'
21
+ require 'rearview/metrics_validator_task'
22
+ require 'rearview/metrics_validator_service'
23
+ require 'rearview/cron_expression_validator'
19
24
  require 'rearview/configuration'
20
25
  require 'rearview/vm'
21
26
  require 'rearview/statsd'
@@ -27,7 +32,7 @@ module Rearview
27
32
  include Rearview::Logger
28
33
 
29
34
  class << self
30
- attr_accessor :monitor_service,:stats_service,:alert_clients
35
+ attr_accessor :monitor_service,:stats_service,:validator_service,:alert_clients
31
36
  end
32
37
 
33
38
  module_function
@@ -70,10 +75,13 @@ module Rearview
70
75
  logger.warn "monitor disabled!"
71
76
  end
72
77
  if config.stats_enabled?
73
- logger.info "starting up stats service"
74
78
  @stats_service = Rearview::StatsService.supervise
75
79
  @stats_service.actors.first.startup
76
80
  end
81
+ if config.metrics_validator_enabled?
82
+ @validator_service = Rearview::MetricsValidatorService.supervise
83
+ @validator_service.actors.first.startup
84
+ end
77
85
  @alert_clients = Rearview::Alerts.registry.values
78
86
  @booted = true
79
87
  end
@@ -8,21 +8,17 @@ module Rearview
8
8
  @monitor_results = monitor_results
9
9
  end
10
10
  def run
11
- logger.info "#{self} run"
12
11
  if Rearview.config.alerts_enabled?
13
12
  Rearview.alert_clients.each do |client|
14
- alert_agent = client.new
15
13
  begin
14
+ alert_agent = client.new
16
15
  alert_agent.alert(@job,@monitor_results)
17
16
  rescue
18
- logger.error "#{self} #{alert_agent} failed: #{$!}\n#{$@.join("\n")}"
17
+ logger.error "#{self} #{client} failed: #{$!}\n#{$@.join("\n")}"
19
18
  end
20
19
  end
21
20
  end
22
21
  self
23
- rescue
24
- logger.error "#{self} failed: #{$!}\n#{$@.join("\n")}"
25
- self
26
22
  end
27
23
  end
28
24
  end
@@ -8,49 +8,39 @@ module Rearview
8
8
 
9
9
  class UrlValidator < ActiveModel::EachValidator
10
10
  def validate_each(record, attribute, value)
11
+ passed = true
11
12
  if value.present?
12
13
  uri = URI.parse(value) rescue nil
13
14
  unless uri.present? && uri.scheme.present? && (uri.scheme.downcase=="http" || uri.scheme.downcase=="https")
14
15
  record.errors.add attribute, (options[:message] || "is not a valid URL")
15
- else
16
- if options[:reachable]
17
- reachable = ReachableValidator.new(options.dup.merge(attributes: @attributes))
18
- reachable.validate_each(record,attribute,value)
19
- end
20
- end
21
- end
22
- end
23
- end
24
-
25
- class ReachableValidator < ActiveModel::EachValidator
26
- def validate_each(record, attribute, value)
27
- if value.present?
28
- response = HTTParty.get(value) rescue nil
29
- unless response.present? && response.code == 200
30
- record.errors.add attribute, (options[:message] || "is not a reachable URL")
16
+ passed = false
31
17
  end
32
18
  end
19
+ passed
33
20
  end
34
21
  end
35
22
 
36
23
  class DirectoryValidator < ActiveModel::EachValidator
37
24
  def validate_each(record, attribute, value)
25
+ passed = true
38
26
  if value.present?
39
27
  unless File.directory?(value)
40
28
  record.errors.add attribute, (options[:message] || "is not a directory")
29
+ passed = false
41
30
  end
42
31
  end
43
32
  end
44
33
  end
45
34
 
46
- ATTRIBUTES = [:default_from, :graphite_url, :pagerduty_url, :sandbox_exec,
35
+ ATTRIBUTES = [:default_from, :graphite_connection, :pagerduty_url, :sandbox_exec,
47
36
  :sandbox_timeout, :sandbox_dir, :enable_alerts, :preload_jobs,
48
37
  :logger, :enable_monitor, :verify, :default_url_options,
49
- :authentication, :enable_stats, :statsd_connection]
38
+ :authentication, :enable_stats, :statsd_connection,
39
+ :enable_metrics_validator, :metrics_validator_schedule]
50
40
 
51
41
  attr_accessor *ATTRIBUTES
52
42
 
53
- validates :graphite_url, presence: true, url: { reachable: true }
43
+ validates :graphite_connection, presence: true
54
44
  validates :pagerduty_url, presence: true, url: true
55
45
  validates :default_from, presence: true
56
46
  validates :default_url_options, presence: true
@@ -59,8 +49,10 @@ module Rearview
59
49
  validates :sandbox_timeout, presence: true, numericality: { greater_than: 4 }
60
50
  validates :authentication, presence: true
61
51
  validates :statsd_connection, presence: true, if: -> { self.stats_enabled? }
52
+ validates :metrics_validator_schedule, presence: true, :'rearview/cron_expression' => true, if: -> { self.metrics_validator_enabled? }
62
53
 
63
54
  validate :validate_sandbox_execution
55
+ validate :validate_graphite_connection
64
56
 
65
57
  def initialize(attributes={})
66
58
  @default_from = "rearview@localhost"
@@ -73,6 +65,9 @@ module Rearview
73
65
  @enable_stats = false
74
66
  @default_url_options = {:host=>"localhost",:port=>"3000"}
75
67
  @pagerduty_url = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
68
+ @graphite_connection = {}
69
+ @enable_metrics_validator = false
70
+ @metrics_validator_schedule = nil
76
71
  super
77
72
  end
78
73
 
@@ -84,6 +79,10 @@ module Rearview
84
79
  enable_monitor
85
80
  end
86
81
 
82
+ def metrics_validator_enabled?
83
+ enable_metrics_validator
84
+ end
85
+
87
86
  def preload_jobs?
88
87
  preload_jobs
89
88
  end
@@ -102,6 +101,16 @@ module Rearview
102
101
  opts.on("--[no-]alerts", "Enable/disable alerts") { |v| self.enable_alerts = v }
103
102
  opts.on("--[no-]monitor", "Enable/disable monitor") { |v| self.enable_monitor = v }
104
103
  opts.on("--[no-]verify", "Enable/disable verification") { |v| self.verify = v }
104
+ opts.on("--[no-]stats-service", "Enable/disable stats service") { |v| self.enable_stats = v }
105
+ opts.on("--[no-]validation-service", "Enable/disable validation service") { |v| self.enable_metrics_validator = v }
106
+ opts.on("--[no-]soft-boot", "Enable/disable soft boot") { |v|
107
+ if v
108
+ self.preload_jobs = false
109
+ self.enable_stats = false
110
+ self.enable_metrics_validator = false
111
+ self.enable_alerts = false
112
+ end
113
+ }
105
114
  end.parse!(argv)
106
115
  end
107
116
 
@@ -118,6 +127,22 @@ module Rearview
118
127
  exit_code == 0
119
128
  end
120
129
 
130
+ def validate_graphite_connection
131
+ if graphite_connection.present?
132
+ if !graphite_connection[:url].present?
133
+ self.errors.add(:graphite_connection, "graphite URL can't be blank")
134
+ else
135
+ url_validator = UrlValidator.new({ attributes: [:graphite_connection], message: "does not contain a valid URL" })
136
+ if url_validator.validate_each(self,:graphite_connection,graphite_connection[:url])
137
+ client = Graphite::Client.new(graphite_connection)
138
+ unless(client.reachable?)
139
+ self.errors.add(:graphite_connection, "graphite cannot be reached")
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+
121
146
  def dump
122
147
  ATTRIBUTES.sort.map { |attrib| "#{attrib.to_s}=#{(self.send(attrib).nil? ? "nil" : self.send(attrib))}" }.join("\n")
123
148
  end