marty 1.0.23 → 1.0.24

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: d0f81a144144beb77d9fafc82b8d638be6fbb501
4
- data.tar.gz: 49a509cc8458a156deaf186c4401acbc10411436
3
+ metadata.gz: 86b79d602a84a7fea3fbca2b3704a8f9ccf6b00b
4
+ data.tar.gz: 0720c7fe854939427a378e0cca9cfc8ebf96302f
5
5
  SHA512:
6
- metadata.gz: eb8843be6891a672779cca79c29ca08b8879d58ef1f7c99a6353ecbd1cc5c28ced1f42913e891f7cb4311a0c5f59d50d906899488ea0978c87a2a75c7543a602
7
- data.tar.gz: fd0588d9011f7734e478eca8a51e7f3092bd2fbb4a4734f399c2ee91dacad499b27d6ed70d062c877356c90d9be7235b191151618f7f0e8514b724a963bc3989
6
+ metadata.gz: b4d7f133d884839c72815a068934c54b26f7c366850fda2c313cd600a277eb93d2f438d5ad932fa5b66a9f0b9b25d7177465e209bdd1e8127d0309e4bc37fed7
7
+ data.tar.gz: 429013d616affaa52db3d1eaffe52bc6402fd5e70245fb61f7de855debe7cbc68cd6214cb3e2c29dee96e535f80cc0da5e996c7a8ecc37c37df90e4dda5a873d
data/.gitignore CHANGED
@@ -3,6 +3,7 @@ log/*.log
3
3
  pkg/
4
4
  spec/dummy/db/*.sqlite3
5
5
  spec/dummy/log/*.log
6
+ spec/dummy/log/*.sql
6
7
  spec/dummy/tmp/
7
8
  spec/dummy/.sass-cache
8
9
 
data/Gemfile CHANGED
@@ -10,6 +10,7 @@ gem 'daemons', '~> 1.1.9'
10
10
  gem 'mime-types', '< 3.0', platforms: :ruby_19
11
11
  gem 'rails', '~> 4.2.1'
12
12
  gem 'pg', '~> 0.18.4'
13
+ gem 'sqlite3'
13
14
 
14
15
  group :development, :test do
15
16
  gem 'pry-rails'
@@ -32,13 +32,14 @@ class Marty::Grid < ::Netzke::Grid::Base
32
32
  super
33
33
 
34
34
  c.permissions = {
35
- create: class_can?(:create),
36
- read: class_can?(:read),
37
- update: class_can?(:update),
38
- delete: class_can?(:delete)
35
+ create: class_can?(:create),
36
+ read: class_can?(:read),
37
+ update: class_can?(:update),
38
+ delete: class_can?(:delete)
39
39
  }
40
- c.editing = :both
41
- c.store_config = {page_size: 30}
40
+
41
+ c.editing = :both
42
+ c.store_config = {page_size: 30}
42
43
  end
43
44
 
44
45
  def has_search_action?
@@ -0,0 +1,76 @@
1
+ class Marty::LogView < Marty::Grid
2
+ include Marty::Extras::Layout
3
+ has_marty_permissions read: [:admin],
4
+ update: [:admin]
5
+
6
+ def configure(c)
7
+ super
8
+
9
+ c.title ||= I18n.t('log_viewer', default: "Log Viewer")
10
+ c.model = "Marty::Log"
11
+ c.paging = :buffered
12
+ c.editing = :in_form
13
+ c.attributes = [
14
+ :timestamp,
15
+ :message_type,
16
+ :message,
17
+ :details
18
+ ]
19
+
20
+ c.store_config.merge!(sorters: [{property: :timestamp, direction: 'DESC'}])
21
+ end
22
+
23
+ def default_context_menu
24
+ []
25
+ end
26
+
27
+ def default_form_items
28
+ [
29
+ :timestamp,
30
+ :message_type,
31
+ :message,
32
+ textarea_field(:details).merge!({height: 400})
33
+ ]
34
+ end
35
+
36
+ component :edit_window do |c|
37
+ super(c)
38
+ c.width = 1200
39
+ end
40
+
41
+ attribute :message_type do |c|
42
+ c.text = I18n.t("log_grid.message_type")
43
+ c.width = 100
44
+ c.read_only = true
45
+ end
46
+
47
+ attribute :message do |c|
48
+ c.text = I18n.t("log_grid.message")
49
+ c.width = 400
50
+ c.read_only = true
51
+ end
52
+
53
+ attribute :timestamp do |c|
54
+ c.text = I18n.t("log_grid.timestamp")
55
+ c.width = 200
56
+ c.read_only = true
57
+ c.xtype = :datecolumn
58
+ c.format = 'Y-m-d h:i:s.u'
59
+ c.field_config = {
60
+ xtype: :displayfield,
61
+ }
62
+ c.getter = lambda { |r| Time.at(r.timestamp) }
63
+ end
64
+
65
+ column :details do |c|
66
+ c.getter = lambda { |r| CGI.escapeHTML(r.details) }
67
+ end
68
+
69
+ attribute :details do |c|
70
+ c.text = I18n.t("log_grid.details")
71
+ c.width = 900
72
+ c.read_only = true
73
+ end
74
+ end
75
+
76
+ LogView = Marty::LogView
@@ -47,6 +47,20 @@ class Marty::MainAuthApp < Marty::AuthApp
47
47
  }
48
48
  end
49
49
 
50
+ def log_menu
51
+ [
52
+ {
53
+ text: 'Log Maintenance',
54
+ icon: icon_hack(:wrench),
55
+ disabled: !self.class.has_admin_perm?,
56
+ menu: [
57
+ :log_view,
58
+ :log_cleanup,
59
+ ]
60
+ }
61
+ ]
62
+ end
63
+
50
64
  def system_menu
51
65
  {
52
66
  text: I18n.t("system"),
@@ -60,7 +74,7 @@ class Marty::MainAuthApp < Marty::AuthApp
60
74
  :event_view,
61
75
  :reload_scripts,
62
76
  :load_seed,
63
- ] + background_jobs_menu
77
+ ] + background_jobs_menu + log_menu
64
78
  }
65
79
  end
66
80
 
@@ -235,6 +249,21 @@ class Marty::MainAuthApp < Marty::AuthApp
235
249
  a.disabled = !self.class.has_admin_perm?
236
250
  end
237
251
 
252
+ action :log_view do |a|
253
+ a.text = 'View Log'
254
+ a.tooltip = 'View Log'
255
+ a.handler = :netzke_load_component_by_action
256
+ a.icon = :cog
257
+ a.disabled = !self.class.has_admin_perm?
258
+ end
259
+
260
+ action :log_cleanup do |a|
261
+ a.text = 'Cleanup Log Table'
262
+ a.tooltip = 'Delete old log records'
263
+ a.icon = :cog
264
+ a.disabled = !self.class.has_admin_perm?
265
+ end
266
+
238
267
  ######################################################################
239
268
 
240
269
  def bg_command(param)
@@ -268,6 +297,15 @@ class Marty::MainAuthApp < Marty::AuthApp
268
297
  client.show_detail res.html_safe.gsub("\n","<br/>"), 'Delayed Job Restart'
269
298
  end
270
299
 
300
+ endpoint :log_cleanup do |params|
301
+ begin
302
+ Marty::Log.cleanup(params)
303
+ rescue => e
304
+ res = e.message
305
+ client.show_detail res.html_safe.gsub("\n","<br/>"), 'Log Cleanup'
306
+ end
307
+ end
308
+
271
309
  ######################################################################
272
310
  # Postings
273
311
 
@@ -401,6 +439,23 @@ class Marty::MainAuthApp < Marty::AuthApp
401
439
  this.server.bgStatus({});
402
440
  }
403
441
  JS
442
+
443
+ c.netzke_on_log_cleanup = l(<<-JS)
444
+ function(params) {
445
+ var me = this;
446
+ Ext.Msg.show({
447
+ title: 'Log Cleanup',
448
+ msg: 'Enter number of days to keep',
449
+ width: 375,
450
+ buttons: Ext.Msg.OKCANCEL,
451
+ prompt: true,
452
+ fn: function (btn, value) {
453
+ btn == "ok" && me.server.logCleanup(value);
454
+ }
455
+ });
456
+ }
457
+ JS
458
+
404
459
  end
405
460
 
406
461
  action :select_posting do |a|
@@ -444,6 +499,10 @@ class Marty::MainAuthApp < Marty::AuthApp
444
499
  c.disabled = Marty::Util.warped?
445
500
  end
446
501
 
502
+ component :log_view do |c|
503
+ c.klass = Marty::LogView
504
+ end
505
+
447
506
  endpoint :reload_scripts do |params|
448
507
  Marty::Script.load_scripts
449
508
  client.netzke_notify 'Scripts have been reloaded'
@@ -0,0 +1,56 @@
1
+ class Marty::Log < Marty::Base
2
+
3
+ def self.logfile
4
+ @logfile ||= Rails.root.join('log', Rails.env + '.sql').to_s
5
+ end
6
+
7
+ establish_connection({
8
+ adapter: "sqlite3",
9
+ database: logfile
10
+ })
11
+ self.table_name = "log"
12
+ self.primary_key = "id"
13
+
14
+ def self.db_init
15
+ db = SQLite3::Database.new(Marty::Log.logfile)
16
+ db.execute <<-SQL
17
+ CREATE TABLE IF NOT EXISTS log (
18
+ id INTEGER PRIMARY KEY,
19
+ message_type TEXT,
20
+ message TEXT,
21
+ timestamp REAL,
22
+ details BLOB )
23
+ SQL
24
+ db
25
+ end
26
+
27
+ def self.write_log(type, message, details)
28
+ begin
29
+ @db ||= db_init
30
+ stmt = @db.prepare <<-SQL
31
+ INSERT INTO log (message_type, message, timestamp, details)
32
+ values (?, ?, ?, ?)
33
+ SQL
34
+ stmt.bind_param(1, type.to_s)
35
+ stmt.bind_param(2, message)
36
+ stmt.bind_param(3, Time.zone.now.to_f)
37
+ stmt.bind_param(4, details.pretty_inspect)
38
+
39
+ stmt.execute
40
+ rescue => e
41
+ Marty::Util.logger.error("Marty::Logger failure: #{e.message}")
42
+ ensure
43
+ stmt.close if stmt rescue nil
44
+ end
45
+ end
46
+
47
+ def self.cleanup(days_to_keep)
48
+ raise "Must give numeric value. (Got '#{days_to_keep}')" unless
49
+ (Float(days_to_keep) rescue false)
50
+ @db ||= db_init
51
+ cutoff = Time.zone.now.to_i - days_to_keep.to_i*60*60*24
52
+ @db.execute <<-SQL
53
+ delete from log where timestamp <= #{cutoff}
54
+ SQL
55
+ end
56
+ end
@@ -48,6 +48,12 @@ en:
48
48
  created_dt: Create Date/Time
49
49
  delete: Delete Script
50
50
 
51
+ log_grid:
52
+ message_type: Type
53
+ message: Message
54
+ timestamp: Timestamp
55
+ details: Details
56
+
51
57
  user_grid:
52
58
  title: Users
53
59
  new: New User
@@ -0,0 +1,26 @@
1
+ require 'sqlite3'
2
+
3
+ class Marty::Logger
4
+
5
+ def self.method_missing(m, *args, &block)
6
+ return super unless
7
+ [:debug, :info, :warn, :error, :fatal, :unknown].include?(m)
8
+ Marty::Util.logger.send(m, args[0]) if Marty::Util.logger.respond_to?(m)
9
+ log(m, *args)
10
+ end
11
+
12
+ def self.log(type, message, details=nil)
13
+ Marty::Log.write_log(type, message, details)
14
+ end
15
+
16
+ def self.with_logging(error_message, error_data)
17
+ begin
18
+ yield
19
+ rescue => e
20
+ error(error_message, { message: e.message,
21
+ data: error_data })
22
+ raise "#{error_message}: #{e.message}"
23
+ end
24
+ end
25
+
26
+ end
@@ -1,3 +1,3 @@
1
1
  module Marty
2
- VERSION = "1.0.23"
2
+ VERSION = "1.0.24"
3
3
  end
@@ -40,4 +40,5 @@ Gem::Specification.new do |s|
40
40
  s.add_dependency 'coderay'
41
41
  s.add_dependency 'net-ldap', '~> 0.12.0'
42
42
  s.add_dependency 'rubyzip'
43
+ s.add_dependency 'sqlite3'
43
44
  end
@@ -32,6 +32,8 @@ module Dummy
32
32
  # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
33
33
  # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
34
34
  # config.time_zone = 'Central Time (US & Canada)'
35
+ config.active_record.default_timezone = :local
36
+ config.time_zone = 'Pacific Time (US & Canada)'
35
37
 
36
38
  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
37
39
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
@@ -0,0 +1,90 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'logger view', js: true, capybara: true do
4
+
5
+ def manual_insert(type, message, ts, detail)
6
+ stmt = @db.prepare <<-SQL
7
+ INSERT INTO log (message_type, message, timestamp, details)
8
+ VALUES (?, ?, ?, ?)
9
+ SQL
10
+ stmt.bind_param(1, type)
11
+ stmt.bind_param(2, message)
12
+ stmt.bind_param(3, ts)
13
+ stmt.bind_param(4, detail)
14
+ stmt.execute
15
+ stmt.close
16
+ end
17
+
18
+ before(:all) do
19
+ self.use_transactional_fixtures = false
20
+ @db = SQLite3::Database.new(Marty::Log.logfile)
21
+
22
+ info_s = { info: 'message' }
23
+ error_s = [1, 2, 3, { error: 'message' }]
24
+ fatal_s = ["string", 123, { fatal: "message", another_key: 'value' }]
25
+ Marty::Logger.info('info message', nil)
26
+ Marty::Logger.error('error message', error_s)
27
+ Marty::Logger.fatal('fatal message', fatal_s)
28
+ manual_insert("debug", "hi mom", (Time.zone.now - 5.days).to_i,
29
+ ["one", "two", 3, 4.0].pretty_inspect)
30
+ manual_insert("warn", "all your base", (Time.zone.now - 10.days).to_i,
31
+ [5].pretty_inspect)
32
+ @ts = (@db.execute "select timestamp from log order by timestamp desc").map do
33
+ |(ts)|
34
+ Time.zone.at(ts).strftime('%Y-%m-%dT%H:%M:%S.%L%:z')
35
+ end
36
+
37
+ @clean_file = "/tmp/clean_#{Process.pid}.psql"
38
+ save_clean_db(@clean_file)
39
+ populate_test_users
40
+ end
41
+
42
+ after(:all) do
43
+ restore_clean_db(@clean_file)
44
+ @db.execute "delete from log"
45
+ @db.close
46
+ self.use_transactional_fixtures = true
47
+ end
48
+
49
+ let(:logview) { netzke_find('log_view') }
50
+ it "updates views correctly" do
51
+ log_in_as('marty')
52
+ press('System')
53
+ show_submenu('Log Maintenance')
54
+ press('View Log')
55
+ wait_for_ready
56
+ exp_types = ["fatal", "error", "info", "debug", "warn"]
57
+ exp_messages = ["fatal message", "error message",
58
+ "info message", "hi mom", "all your base"]
59
+ exp_details = [ "[\"string\", 123, {:fatal=>\"message\", "\
60
+ ":another_key=>\"value\"}]\n",
61
+ "[1, 2, 3, {:error=>\"message\"}]\n",
62
+ "nil\n",
63
+ "[\"one\", \"two\", 3, 4.0]\n",
64
+ "[5]\n"]
65
+ [[nil, 5], [7, 4], [3, 3], [0, 0]].each do |days, exp_count|
66
+ if days
67
+ press('System')
68
+ show_submenu('Log Maintenance')
69
+ press('Cleanup Log Table')
70
+ wait_for_ajax
71
+ find(:xpath, "//input[contains(@id, 'textfield')]", wait: 5).set(days)
72
+ press('OK')
73
+ wait_for_ready
74
+ find(:refresh).click
75
+ wait_for_ready
76
+ end
77
+ cnt = logview.row_count()
78
+ expect(cnt).to eq(exp_count)
79
+ types = logview.col_values('message_type', cnt, 0)
80
+ messages = logview.col_values('message', cnt, 0)
81
+ details = logview.col_values('details', cnt, 0).
82
+ map { |d| CGI.unescapeHTML(d) }
83
+ ts = logview.col_values('timestamp', cnt, 0)
84
+ expect(ts).to eq(@ts.slice(0,exp_count))
85
+ expect(types).to eq(exp_types.slice(0,exp_count))
86
+ expect(messages).to eq(exp_messages.slice(0,exp_count))
87
+ expect(details).to eq(exp_details.slice(0,exp_count))
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ module Marty
4
+ describe Logger do
5
+ before(:all) do
6
+ self.use_transactional_fixtures = false
7
+ end
8
+ before(:each) do
9
+ @db = SQLite3::Database.new(Marty::Log.logfile)
10
+ end
11
+ after(:each) do
12
+ @db.execute "delete from log"
13
+ @db.close
14
+ end
15
+ after(:all) do
16
+ self.use_transactional_fixtures = true
17
+ end
18
+
19
+ it "logs" do
20
+ File.open(Rails.root.join("log/test.log")) do |f|
21
+ f.seek(0, IO::SEEK_END)
22
+ info_s = { info: 'message' }
23
+ error_s = [1, 2, 3, { error: 'message' }]
24
+ fatal_s = ["string", 123, { fatal: "message", another_key: 'value' }]
25
+ Marty::Logger.info('info message', info_s)
26
+ Marty::Logger.error('error message', error_s)
27
+ Marty::Logger.fatal('fatal message', fatal_s)
28
+ rails_log = f.readlines
29
+ log = @db.execute "select * from log"
30
+ log_detail = []
31
+ log_ts = []
32
+ log.each do |l|
33
+ id, type, msg, ts, detail_str = l
34
+ log_detail[id] = [type, msg, detail_str]
35
+ log_ts[id] = ts
36
+ end
37
+ expect(rails_log).to eq(["info message\n",
38
+ "error message\n",
39
+ "fatal message\n"])
40
+ expect(log_detail[1]).to eq(["info", "info message",
41
+ info_s.pretty_inspect])
42
+ expect(log_detail[2]).to eq(["error", "error message",
43
+ error_s.pretty_inspect])
44
+ expect(log_detail[3]).to eq(["fatal", "fatal message",
45
+ fatal_s.pretty_inspect])
46
+ (1..3).each do |idx|
47
+ expect(log_ts[idx]).to be_within(5).of(Time.zone.now.to_i)
48
+ end
49
+ end
50
+ end
51
+ it "with_logging" do
52
+ bd = 'block description'
53
+ the_error = 'error during my block'
54
+ data = [1, 2, 3, Marty::User.first]
55
+ begin
56
+ Marty::Logger.with_logging(bd, data) do
57
+ raise the_error
58
+ end
59
+ rescue => e
60
+ raised = e.message
61
+ end
62
+ expect(raised).to eq("#{bd}: #{the_error}")
63
+ log = Marty::Log.first
64
+ expect(log.message_type).to eq('error')
65
+ expect(log.message).to eq(bd)
66
+ expect(log.details).to eq({ message: the_error,
67
+ data: data }.pretty_inspect)
68
+ end
69
+ end
70
+ describe "Logger errors" do
71
+ it "fails gracefully" do
72
+ allow(Marty::Log).to receive(:db_init).
73
+ and_raise("Error initializing DB")
74
+ Marty::Log.instance_variable_set(:@db, nil)
75
+ File.open(Rails.root.join("log/test.log")) do |f|
76
+ f.seek(0, IO::SEEK_END)
77
+ expect{Marty::Logger.info('info message', [1,2,3])}.not_to raise_error
78
+ rails_log = f.readlines
79
+ expect(rails_log).to eq(["info message\n",
80
+ "Marty::Logger failure: Error initializing DB\n"])
81
+ end
82
+ end
83
+ it "fails gracefully in ensure" do
84
+ Marty::Logger.info('init db', [])
85
+ close_err = 'Error closing statement'
86
+ allow_any_instance_of(SQLite3::Statement).to receive(:close).
87
+ and_raise(close_err)
88
+ File.open(Rails.root.join("log/test.log")) do |f|
89
+ f.seek(0, IO::SEEK_END)
90
+ expect{Marty::Logger.info('ensure message', [1,2,3])}.not_to raise_error
91
+ rails_log = f.readlines
92
+ expect(rails_log).to eq(["ensure message\n"])
93
+ allow_any_instance_of(SQLite3::Statement).to receive(:close).
94
+ and_call_original
95
+ sleep 1
96
+ Marty::Log.cleanup(0)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -11,9 +11,12 @@ ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__
11
11
 
12
12
  Dir[Rails.root.join("../support/**/*.rb")].each { |f| require f }
13
13
 
14
+ CLASSES_TO_EXCLUDE_FROM_SHARED = ["Marty::Log"]
14
15
  class ActiveRecord::Base
15
16
  mattr_accessor :shared_connection
16
-
17
+ class << self
18
+ alias_method :orig_connection, :connection
19
+ end
17
20
  def self.clear_connection
18
21
  @@shared_connection = nil
19
22
  end
@@ -21,7 +24,8 @@ class ActiveRecord::Base
21
24
  clear_connection
22
25
 
23
26
  def self.connection
24
- @@shared_connection || retrieve_connection
27
+ CLASSES_TO_EXCLUDE_FROM_SHARED.include?(model_name) ? orig_connection :
28
+ @@shared_connection || retrieve_connection
25
29
  end
26
30
 
27
31
  def self.reset_shared_connection
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marty
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.23
4
+ version: 1.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arman Bostani
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2017-03-01 00:00:00.000000000 Z
17
+ date: 2017-03-21 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: pg
@@ -156,6 +156,20 @@ dependencies:
156
156
  - - ">="
157
157
  - !ruby/object:Gem::Version
158
158
  version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: sqlite3
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
159
173
  description: Marty is a framework for viewing and reporting on versioned data.
160
174
  email:
161
175
  - arman.bostani@pnmac.com
@@ -187,6 +201,7 @@ files:
187
201
  - app/components/marty/grid_append_only.rb
188
202
  - app/components/marty/import_type_view.rb
189
203
  - app/components/marty/live_search_grid_panel.rb
204
+ - app/components/marty/log_view.rb
190
205
  - app/components/marty/main_auth_app.rb
191
206
  - app/components/marty/mcfly_grid_panel.rb
192
207
  - app/components/marty/new_posting_form.rb
@@ -392,6 +407,7 @@ files:
392
407
  - app/models/marty/grid_index_numrange.rb
393
408
  - app/models/marty/grid_index_string.rb
394
409
  - app/models/marty/import_type.rb
410
+ - app/models/marty/log.rb
395
411
  - app/models/marty/name_validator.rb
396
412
  - app/models/marty/pg_enum.rb
397
413
  - app/models/marty/posting.rb
@@ -450,6 +466,7 @@ files:
450
466
  - lib/marty/data_importer.rb
451
467
  - lib/marty/engine.rb
452
468
  - lib/marty/lazy_column_loader.rb
469
+ - lib/marty/logger.rb
453
470
  - lib/marty/mcfly_query.rb
454
471
  - lib/marty/migrations.rb
455
472
  - lib/marty/monkey.rb
@@ -1556,6 +1573,7 @@ files:
1556
1573
  - spec/features/javascripts/job_dashboard_live_search.js.coffee
1557
1574
  - spec/features/javascripts/login.js.coffee
1558
1575
  - spec/features/jobs_dashboard_spec.rb
1576
+ - spec/features/log_view_spec.rb
1559
1577
  - spec/features/reporting_spec.rb
1560
1578
  - spec/features/scripting_spec.rb
1561
1579
  - spec/features/scripting_test_spec.rb
@@ -1565,6 +1583,7 @@ files:
1565
1583
  - spec/job_helper.rb
1566
1584
  - spec/lib/data_exporter_spec.rb
1567
1585
  - spec/lib/data_importer_spec.rb
1586
+ - spec/lib/logger_spec.rb
1568
1587
  - spec/lib/migrations/vw_marty_postings.sql.expected
1569
1588
  - spec/lib/migrations_spec.rb
1570
1589
  - spec/lib/xl_spec.rb