rearview 1.0.2.rc.4-jruby → 1.0.3.rc.1-jruby

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: 8eb51ada322145d9946b67fc0dc4947f5680e5c6
4
- data.tar.gz: 70fd11318489a6bcc5b0085ec482958c09a74614
3
+ metadata.gz: ce33a4e10c1dd4c3fe6d940f610673d590578607
4
+ data.tar.gz: 117613590526a62d88620c8568e89d77f48ad863
5
5
  SHA512:
6
- metadata.gz: cc24d0a8d00e2cd1f1984d8fd8fa75607737bd45fe9594f858bbb590a8f2304bc8d3a64ceeef589d1a08620115782b0f6b0feb6976719378a88706fe9ec9936e
7
- data.tar.gz: 2679624c0822f2067accca9facb99cee5891369d354833df63ea6503bb42686690fd7afdd7c442e490fb6271b294d3e3259c5454a679c45534f72d99b8a33ecb
6
+ metadata.gz: 756c8909ec2fe1f5f7b03b3afcaad0ae91bec46717645c2b8022e228df7448f744cc7c8ed14094c317470e9fb9498314d9ff3a9bdaa5ec35b3674c58ee40e241
7
+ data.tar.gz: 352a54c8c209c6ee12fac82e3fb56f3502c75f5ca0547ff5c6b276387185607ecefed623e281d952b8bfff2880a8189bd23c7539a6c53a196ca962cdd04ba17b
@@ -40,10 +40,20 @@ Rearview.configure do |config|
40
40
  config.default_from = "rearview@localhost"
41
41
 
42
42
  # The url options for rearview application host. Required to generate
43
- # proper monitor alerts.
43
+ # monitor alerts with correct URL references.
44
44
  # ex:
45
- # config.default_url_options = {:host=>'rearview.mycomopany.com', :protocol=>'https'}
46
- config.default_url_options = {:host=>'localhost', :port=>'3000'}
45
+ # config.default_url_options = { host: 'rearview.mycomopany.com', protocol: 'https'}
46
+ config.default_url_options = { host: 'localhost', port: '3000'}
47
+
48
+ # Enable collection of stats for rearview itself. This will send JVM and monitor related
49
+ # stats to graphite using statsd.
50
+ #
51
+ config.enable_stats=false
52
+
53
+ # The connection information for the stats service. Only necessary if enable_stats is true.
54
+ # ex:
55
+ # config.statsd_connection = { host: 'statsd.mycompany.com', port: 8125 , namespace: 'rearview' }
56
+ #
47
57
 
48
58
  case Rails.env
49
59
  when "test"
@@ -56,6 +66,7 @@ Rearview.configure do |config|
56
66
 
57
67
  if File.basename($0) == "rake"
58
68
  config.enable_monitor = false
69
+ config.enable_stats = false
59
70
  end
60
71
 
61
72
  # Options passed via environment will override anything else set to this point...
data/lib/rearview.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "rearview/engine"
2
2
  require "rearview/concerns"
3
3
  require "rearview/ext/state_machine"
4
+ require "rearview/ext/numeric"
4
5
  require "rearview/constants_module_maker"
5
6
  require 'rearview/logger'
6
7
  require 'rearview/cron_helper'
@@ -15,13 +16,17 @@ require 'rearview/distribute'
15
16
  require 'rearview/monitor_supervisor'
16
17
  require 'rearview/monitor_service'
17
18
  require 'rearview/configuration'
19
+ require 'rearview/vm'
20
+ require 'rearview/statsd'
21
+ require 'rearview/stats_task'
22
+ require 'rearview/stats_service'
18
23
  require 'rearview/version'
19
24
 
20
25
  module Rearview
21
26
  include Rearview::Logger
22
27
 
23
28
  class << self
24
- attr_accessor :monitor_service,:alert_clients
29
+ attr_accessor :monitor_service,:stats_service,:alert_clients
25
30
  end
26
31
 
27
32
  module_function
@@ -64,6 +69,12 @@ module Rearview
64
69
  else
65
70
  logger.warn "[#{self}] monitor disabled"
66
71
  end
72
+ if config.stats_enabled?
73
+ logger.info "[#{self}] starting up stats service"
74
+ @stats_service = Rearview::StatsService.supervise
75
+ @stats_service.actors.first.startup
76
+ end
77
+
67
78
  @alert_clients = Rearview::Alerts.registry.values
68
79
  @booted = true
69
80
  end
@@ -46,7 +46,7 @@ module Rearview
46
46
  ATTRIBUTES = [:default_from, :graphite_url, :pagerduty_url, :sandbox_exec,
47
47
  :sandbox_timeout, :sandbox_dir, :enable_alerts, :preload_jobs,
48
48
  :logger, :enable_monitor, :verify, :default_url_options,
49
- :authentication]
49
+ :authentication, :enable_stats, :statsd_connection]
50
50
 
51
51
  attr_accessor *ATTRIBUTES
52
52
 
@@ -58,6 +58,7 @@ module Rearview
58
58
  validates :sandbox_exec, presence: true
59
59
  validates :sandbox_timeout, presence: true, numericality: { greater_than: 4 }
60
60
  validates :authentication, presence: true
61
+ validates :statsd_connection, presence: true, if: -> { self.stats_enabled? }
61
62
 
62
63
  validate :validate_sandbox_execution
63
64
 
@@ -69,6 +70,8 @@ module Rearview
69
70
  @verify = false
70
71
  @enable_monitor = true
71
72
  @authentication = { strategy: :database }
73
+ @enable_stats = false
74
+ @default_url_options = {:host=>"localhost",:port=>"3000"}
72
75
  @pagerduty_url = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
73
76
  super
74
77
  end
@@ -85,6 +88,10 @@ module Rearview
85
88
  preload_jobs
86
89
  end
87
90
 
91
+ def stats_enabled?
92
+ enable_stats
93
+ end
94
+
88
95
  def verify?
89
96
  verify
90
97
  end
@@ -7,6 +7,7 @@ require 'protected_attributes'
7
7
  require 'httparty'
8
8
  require 'celluloid'
9
9
  require 'jbuilder'
10
+ require 'statsd'
10
11
 
11
12
  jar_dir = File.expand_path('../../jar', __FILE__)
12
13
  for jar in Dir["#{jar_dir}/*.jar"]
@@ -31,6 +32,8 @@ module Rearview
31
32
  initializer 'devise.use_rearview_helpers' do |app|
32
33
  Devise::SessionsController.class_eval { helper Rearview::ApplicationHelper }
33
34
  end
34
- Jbuilder.key_format :camelize => :lower
35
+ initializer 'jbuilder.key_format' do |app|
36
+ Jbuilder.key_format :camelize => :lower
37
+ end
35
38
  end
36
39
  end
@@ -0,0 +1,8 @@
1
+ class Numeric
2
+ def bytes_to_kilobytes
3
+ self / KILOBYTE
4
+ end
5
+ def bytes_to_megabytes
6
+ self / KILOBYTE ** 2
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ module Rearview
2
+ class StatsService
3
+ class StatsServiceError < StandardError; end;
4
+ include Celluloid
5
+ include Rearview::Logger
6
+ def statsd
7
+ @statsd ||= Rearview::Statsd.new
8
+ end
9
+ def started?
10
+ @started
11
+ end
12
+ def startup
13
+ raise StatsServiceError.new("service already started") if started?
14
+ @started = true
15
+ @stats_task = Rearview::StatsTask.supervise
16
+ end
17
+ def shutdown
18
+ raise StatsServiceError.new("service not started") unless started?
19
+ @stats_task.actors.first.terminate
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,51 @@
1
+ require 'json'
2
+
3
+ module Rearview
4
+ class StatsTask
5
+ class StatsTaskError < StandardError; end;
6
+ include Celluloid
7
+ include Celluloid::Logger
8
+ attr_reader :delay, :statsd
9
+ def initialize(delay=120,start=true)
10
+ @delay = delay
11
+ @statsd = Rearview::Statsd.new
12
+ # This number is not documented well. The batch size is actually the max
13
+ # number of batch calls allowed, before the UDP message is sent. Anything
14
+ # after this value is quietly dropped. However, keep in mind that the
15
+ # safest max UDP message size is 512.
16
+ #
17
+ # So make sure that batch_size * 8bytes/per int < 512
18
+ @statsd.batch_size = 11
19
+ schedule if start
20
+ end
21
+
22
+ def schedule
23
+ debug "#{self} schedule"
24
+ @timer = after(@delay) { self.run }
25
+ end
26
+
27
+ def run
28
+ debug "#{self} run"
29
+ vm = Rearview::Vm.new
30
+ @statsd.batch do |batch|
31
+ batch.gauge('vm.total_memory',vm.total_memory.bytes_to_kilobytes)
32
+ batch.gauge('vm.free_memory',vm.free_memory.bytes_to_kilobytes)
33
+ batch.gauge('vm.max_memory',vm.max_memory.bytes_to_kilobytes)
34
+ batch.gauge('vm.heap.committed',vm.heap.committed.bytes_to_kilobytes)
35
+ batch.gauge('vm.heap.init',vm.heap.init.bytes_to_kilobytes)
36
+ batch.gauge('vm.heap.max',vm.heap.max.bytes_to_kilobytes)
37
+ batch.gauge('vm.heap.used',vm.heap.used.bytes_to_kilobytes)
38
+ batch.gauge('vm.non_heap.committed',vm.non_heap.committed.bytes_to_kilobytes)
39
+ batch.gauge('vm.non_heap.init',vm.non_heap.init.bytes_to_kilobytes)
40
+ batch.gauge('vm.non_heap.max',vm.non_heap.max.bytes_to_kilobytes)
41
+ batch.gauge('vm.non_heap.used',vm.non_heap.used.bytes_to_kilobytes)
42
+ end
43
+ rescue
44
+ error "#{self} run failed: #{$!}\n#{$@.join("\n")}"
45
+ ensure
46
+ schedule
47
+ end
48
+
49
+ end
50
+ end
51
+
@@ -0,0 +1,11 @@
1
+ module Rearview
2
+ class Statsd < ::Statsd
3
+
4
+ def initialize
5
+ super(Rearview.config.statsd_connection[:host],Rearview.config.statsd_connection[:port])
6
+ self.namespace = Rearview.config.statsd_connection[:namespace]
7
+ end
8
+
9
+ end
10
+ end
11
+
@@ -59,9 +59,9 @@ module MonitorUtilities
59
59
  # checks for a deployment and if found returns data before and after the deploy along with the delta
60
60
  def deploy_check(num_points, deploy, metric)
61
61
  if metric == deploy
62
- raise "You've passed the deploy metric to be analyzed against itself, which is not a valid analysis."
62
+ raise "Error: You've passed the deploy metric to be analyzed against itself, which is not a valid analysis."
63
63
  elsif metric.values.size < (num_points * 2) + 1
64
- raise "Not enough data to evaluate. There must be #{num_points} data points before and after a deploy."
64
+ raise "Error: Not enough data to evaluate. There must be #{num_points} data points before and after a deploy."
65
65
  else
66
66
  results = []
67
67
  last_deploy = deploy.values.rindex { |v| !v.nil? }
@@ -83,18 +83,21 @@ module MonitorUtilities
83
83
  end
84
84
  end
85
85
 
86
- def form_error(metric, tolerance, actual)
87
- "#{metric.label} experienced a standard deviation shift of #{actual.round(2)}, which is greater than the threshold of #{tolerance}."
88
- end
89
-
86
+ # determines delta in standard deviation between 2 data sets
90
87
  def collect_comparisons(metric)
91
- five_minute_sv = metric.values.each_slice(5).to_a.map { |pair| pair.stdev }
92
- five_minute_sv.each_slice(2).to_a.map { |pair| pair.sort }.map { |pair| pair[1] - pair[0] }
88
+ five_minute_sv = metric.values.each_slice(metric.values.length / 2).to_a.map { |pair| pair.stdev }
89
+ five_minute_sv.each_slice(2).to_a.map { |pair| pair.sort }.map { |pair| pair[1].to_f - pair[0].to_f }
93
90
  end
94
91
 
92
+ # checks standard deviation delta for metric(s) and returns metric label delta if > deviation
95
93
  def collect_aberrations(*metrics, deviation)
96
- metrics.map do |m|
97
- collect_comparisons(m).inject([]) { |accum, shift| shift >= deviation ? form_error(m, deviation, shift) : "" }
94
+ if metrics.first.values.length % 2 == 1
95
+ raise "ERROR: collect_aberrations expects an even number of data points and you passed in #{metrics.first.values.length}"
96
+ end
97
+ aberrations = {}
98
+ metrics.each do |m|
99
+ collect_comparisons(m).inject(aberrations) { |hash, delta| hash[m.label] = delta if delta >= deviation; hash }
98
100
  end
101
+ aberrations
99
102
  end
100
103
  end # Class end
@@ -1,3 +1,3 @@
1
1
  module Rearview
2
- VERSION = "1.0.2.rc.4"
2
+ VERSION = "1.0.3.rc.1"
3
3
  end
@@ -0,0 +1,69 @@
1
+ require 'forwardable'
2
+ java_import "java.lang.Runtime"
3
+ java_import "java.lang.management.ManagementFactory"
4
+
5
+ module Rearview
6
+ class Vm
7
+ extend Forwardable
8
+
9
+ # init:
10
+ # The initial amount of memory (bytes) that the Java virtual machine
11
+ # requests from the operating system for memory management during startup.
12
+ #
13
+ # used:
14
+ # The amount of memory currently used (bytes)
15
+ #
16
+ # committed:
17
+ # represents the amount of memory (bytes) that is guaranteed to be
18
+ # available for use by the Java virtual machine.
19
+ #
20
+ # max:
21
+ # represents the maximum amount of memory (bytes) that can be used for memory
22
+ # management
23
+ class Memory
24
+ extend Forwardable
25
+ attr_accessor :memory_bean
26
+ def_delegators :@memory_bean,:committed,:init,:max,:used
27
+ end
28
+
29
+ # The JVM has a heap that is the runtime memory from which all class instances
30
+ # and arrays are allocated.
31
+ class Heap < Memory
32
+ def initialize
33
+ @memory_bean = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()
34
+ end
35
+ end
36
+
37
+ # The JVM manages additional memory that is not part of the heap. This memory
38
+ # is used for things like per-class structures such as a runtime constant pool,
39
+ # field and method data, and the code for methods and constructors.
40
+ class NonHeap < Memory
41
+ def initialize
42
+ @memory_bean = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()
43
+ end
44
+ end
45
+
46
+ def initialize
47
+ @runtime = Runtime.getRuntime()
48
+ end
49
+
50
+ # total_memory:
51
+ # The total amount of memory currently available for current and future objects (bytes)
52
+ #
53
+ # max_memory:
54
+ # The maximum amount of memory that the virtual machine will attempt to use (bytes)
55
+ #
56
+ # free_meory:
57
+ # An approximation to the total amount of memory currently available for future allocated objects (bytes)
58
+ def_delegators :@runtime, :total_memory, :free_memory, :max_memory
59
+
60
+ def heap
61
+ @heap ||= Heap.new
62
+ end
63
+
64
+ def non_heap
65
+ @non_heap ||= NonHeap.new
66
+ end
67
+
68
+ end
69
+ end
@@ -43,13 +43,13 @@
43
43
  37
44
44
  39
45
45
  30
46
- 30
46
+ 0
47
47
  34
48
48
  36
49
49
  43
50
50
  40
51
51
  45
52
- 34
52
+ nil
53
53
  40
54
54
  41
55
55
  43
@@ -1,20 +1,20 @@
1
1
  development:
2
2
  adapter: mysql
3
- database: rearview_dummy_development
3
+ database: rearview_ruby_development
4
4
  username: root
5
5
  password:
6
6
  host: localhost
7
7
 
8
8
  test:
9
9
  adapter: mysql
10
- database: rearview_dummy_test
10
+ database: rearview_ruby_test
11
11
  username: root
12
12
  password:
13
13
  host: localhost
14
14
 
15
15
  production:
16
16
  adapter: mysql
17
- database: rearview_dummy_production
17
+ database: rearview_ruby_production
18
18
  username: root
19
19
  password:
20
20
  host: localhost
@@ -149,3 +149,75 @@
149
149
   (12.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
150
150
   (2.0ms) SELECT version FROM `schema_migrations`
151
151
   (2.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
152
+  (85.0ms) DROP DATABASE IF EXISTS `rearview_dummy_test`
153
+  (13.0ms) CREATE DATABASE `rearview_dummy_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
154
+  (29.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
155
+  (16.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
156
+  (10.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
157
+  (11.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
158
+  (8.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
159
+  (10.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
160
+  (13.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
161
+  (11.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
162
+  (11.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
163
+  (17.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
164
+  (15.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
165
+  (8.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
166
+  (8.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
167
+  (13.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
168
+  (1.0ms) SELECT version FROM `schema_migrations`
169
+  (1.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
170
+  (7.0ms) DROP DATABASE IF EXISTS `rearview_dummy_test`
171
+  (2.0ms) CREATE DATABASE `rearview_dummy_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
172
+  (54.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
173
+  (9.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
174
+  (19.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
175
+  (14.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
176
+  (9.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
177
+  (12.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
178
+  (10.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
179
+  (13.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
180
+  (10.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
181
+  (9.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
182
+  (9.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
183
+  (8.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
184
+  (17.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
185
+  (11.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
186
+  (2.0ms) SELECT version FROM `schema_migrations`
187
+  (1.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
188
+  (108.0ms) DROP DATABASE IF EXISTS `rearview_ruby_test`
189
+  (8.0ms) CREATE DATABASE `rearview_ruby_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
190
+  (39.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
191
+  (9.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
192
+  (19.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
193
+  (17.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
194
+  (9.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
195
+  (10.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
196
+  (8.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
197
+  (11.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
198
+  (10.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
199
+  (8.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
200
+  (14.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
201
+  (12.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
202
+  (9.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
203
+  (15.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
204
+  (1.0ms) SELECT version FROM `schema_migrations`
205
+  (1.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')
206
+  (12.0ms) DROP DATABASE IF EXISTS `rearview_ruby_test`
207
+  (1.0ms) CREATE DATABASE `rearview_ruby_test` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`
208
+  (10.0ms) CREATE TABLE `applications` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `user_id` int(11), `name` varchar(255) NOT NULL, `created_at` datetime, `updated_at` datetime, `deleted_at` datetime, `ancestry` varchar(255), `description` varchar(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8
209
+  (10.0ms) CREATE INDEX `index_applications_on_ancestry` ON `applications` (`ancestry`)
210
+  (9.0ms) CREATE INDEX `user_id` ON `applications` (`user_id`)
211
+  (15.0ms) CREATE TABLE `job_data` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11) DEFAULT 0 NOT NULL, `created_at` datetime, `updated_at` datetime, `data` longtext NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
212
+  (7.0ms) CREATE TABLE `job_errors` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `job_id` int(11), `created_at` datetime, `message` longtext, `status` varchar(255), `last_alerted_at` datetime, `updated_at` datetime) ENGINE=InnoDB DEFAULT CHARSET=utf8
213
+  (8.0ms) CREATE INDEX `job_id` ON `job_errors` (`job_id`)
214
+  (14.0ms) CREATE TABLE `jobs` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `name` varchar(255) NOT NULL, `active` tinyint(1) DEFAULT 1 NOT NULL, `last_run` datetime, `cron_expr` varchar(1024) NOT NULL, `status` varchar(255), `user_id` int(11), `alert_keys` text, `deleted_at` datetime, `error_timeout` int(11) DEFAULT 60 NOT NULL, `next_run` datetime, `description` text, `app_id` int(11) NOT NULL, `metrics` text NOT NULL, `monitor_expr` text, `minutes` int(11), `to_date` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
215
+  (10.0ms) CREATE INDEX `app_id` ON `jobs` (`app_id`)
216
+  (9.0ms) CREATE UNIQUE INDEX `id_name_version_key` ON `jobs` (`id`, `name`)
217
+  (9.0ms) CREATE INDEX `jobs_ibfk_1` ON `jobs` (`user_id`)
218
+  (16.0ms) CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `created_at` datetime, `updated_at` datetime, `encrypted_password` varchar(255) DEFAULT '' NOT NULL, `email` varchar(255) NOT NULL, `first_name` varchar(255), `last_name` varchar(255), `last_login` datetime, `preferences` text) ENGINE=InnoDB DEFAULT CHARSET=utf8
219
+  (9.0ms) CREATE UNIQUE INDEX `email` ON `users` (`email`)
220
+  (13.0ms) CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8
221
+  (11.0ms) CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
222
+  (1.0ms) SELECT version FROM `schema_migrations`
223
+  (1.0ms) INSERT INTO `schema_migrations` (version) VALUES ('20131106162900')