rearview 1.1.2-jruby → 1.2.0-jruby

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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