mongodb_logger 0.3.3 → 0.4.0

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 (61) hide show
  1. data/.rvmrc +1 -1
  2. data/.travis.yml +13 -7
  3. data/Gemfile +1 -7
  4. data/README.md +128 -117
  5. data/Rakefile +11 -40
  6. data/SUPPORTED_RAILS_VERSIONS +3 -1
  7. data/app/assets/javascripts/analytics.js.coffee +66 -0
  8. data/app/assets/javascripts/logs.js.coffee +107 -164
  9. data/app/assets/javascripts/mongodb_logger.js +11 -2
  10. data/app/assets/javascripts/vendors/jquery-1.8.3.min.js +2 -0
  11. data/app/assets/javascripts/vendors/jquery-ui-1.9.2.min.js +6 -0
  12. data/app/assets/javascripts/vendors/jquery.pjax.min.js +13 -6
  13. data/app/assets/javascripts/vendors/rickshaw/d3.layout.min.js +1 -0
  14. data/app/assets/javascripts/vendors/rickshaw/d3.min.js +2 -0
  15. data/app/assets/javascripts/vendors/rickshaw/rickshaw.js +2637 -0
  16. data/app/assets/stylesheets/humanity/{jquery-ui-1.8.16.custom.css → jquery-ui-1.9.2.custom.css} +0 -0
  17. data/app/assets/stylesheets/layout.css +1 -1
  18. data/app/assets/stylesheets/library.css.erb +2 -2
  19. data/app/assets/stylesheets/mongodb_logger.css +2 -1
  20. data/app/assets/stylesheets/rickshaw/rickshaw.css +307 -0
  21. data/bin/mongodb_logger_web +1 -2
  22. data/config.ru +8 -1
  23. data/examples/server_config.yml +1 -2
  24. data/features/mongodb_logger_web.feature +1 -1
  25. data/features/step_definitions/mongodb_logger_web_steps.rb +18 -12
  26. data/lib/mongodb_logger.rb +6 -2
  27. data/lib/mongodb_logger/adapters.rb +3 -0
  28. data/lib/mongodb_logger/adapters/base.rb +45 -0
  29. data/lib/mongodb_logger/adapters/mongo.rb +91 -0
  30. data/lib/mongodb_logger/adapters/moped.rb +95 -0
  31. data/lib/mongodb_logger/logger.rb +39 -71
  32. data/lib/mongodb_logger/replica_set_helper.rb +11 -2
  33. data/lib/mongodb_logger/server.rb +15 -36
  34. data/lib/mongodb_logger/server/model/analytic.rb +54 -37
  35. data/lib/mongodb_logger/server/view_helpers.rb +5 -1
  36. data/lib/mongodb_logger/server/views/analytics.erb +8 -7
  37. data/lib/mongodb_logger/server/views/layout.erb +4 -11
  38. data/lib/mongodb_logger/server/views/overview.erb +6 -6
  39. data/lib/mongodb_logger/server/views/shared/_collection_stats.erb +4 -4
  40. data/lib/mongodb_logger/server/views/shared/_dynamic_filter.erb +1 -1
  41. data/lib/mongodb_logger/server/views/shared/_log_info.erb +1 -1
  42. data/lib/mongodb_logger/server/views/shared/_tabs.erb +2 -2
  43. data/lib/mongodb_logger/server/views/shared/_tail_panel.erb +4 -4
  44. data/lib/mongodb_logger/server/views/shared/_top_panel.erb +1 -1
  45. data/lib/mongodb_logger/server/views/show_log.erb +11 -1
  46. data/lib/mongodb_logger/server_config.rb +17 -66
  47. data/lib/mongodb_logger/version.rb +1 -1
  48. data/mongodb_logger.gemspec +19 -20
  49. data/spec/javascripts/MongodbLoggerMainSpec.js +2 -2
  50. data/spec/javascripts/support/jasmine.yml +5 -5
  51. data/test/Gemfile_tests +2 -1
  52. data/test/config/samples/database.yml +3 -1
  53. data/test/config/samples/database_no_file_logging.yml +3 -1
  54. data/test/shoulda_macros/log_macros.rb +1 -1
  55. data/test/test.sh +5 -5
  56. data/test/test_helper.rb +26 -18
  57. data/test/unit/mongodb_logger_test.rb +21 -20
  58. metadata +70 -88
  59. data/app/assets/javascripts/vendors/jquery-1.7.1.min.js +0 -4
  60. data/app/assets/javascripts/vendors/jquery-ui-1.8.16.min.js +0 -791
  61. data/mongodb_logger.java.gemspec +0 -43
@@ -2,18 +2,27 @@ module MongodbLogger
2
2
  module ReplicaSetHelper
3
3
  # Use retry alg from mongodb to gobble up connection failures during replica set master vote
4
4
  # Defaults to a 10 second wait
5
- def rescue_connection_failure(max_retries=40)
5
+ def rescue_connection_failure(max_retries = 40)
6
6
  success = false
7
7
  retries = 0
8
8
  while !success
9
9
  begin
10
10
  yield
11
11
  success = true
12
- rescue Mongo::ConnectionFailure => e
12
+ rescue mongo_error_type => e
13
13
  raise e if (retries += 1) >= max_retries
14
14
  sleep 0.25
15
15
  end
16
16
  end
17
17
  end
18
+
19
+ private
20
+
21
+ def mongo_error_type
22
+ return @mongo_error if @mongo_error
23
+ @mongo_error = Mongo::ConnectionFailure if defined?(Mongo) && defined?(Mongo::ConnectionFailure)
24
+ @mongo_error = Moped::SocketError if defined?(Moped) && defined?(Moped::SocketError)
25
+ @mongo_error
26
+ end
18
27
  end
19
28
  end
@@ -57,14 +57,8 @@ module MongodbLogger
57
57
 
58
58
  before do
59
59
  begin
60
- if ServerConfig.db && ServerConfig.collection
61
- @db = ServerConfig.db
62
- @collection = ServerConfig.collection
63
- else
64
- @db = Rails.logger.mongo_connection
65
- @collection = @db[Rails.logger.mongo_collection_name]
66
- end
67
- @collection_stats = @collection.stats
60
+ @mongo_adapter = (ServerConfig.mongo_adapter ? ServerConfig.mongo_adapter : Rails.logger.mongo_adapter)
61
+ @collection_stats = @mongo_adapter.collection_stats
68
62
  rescue => e
69
63
  erb :error, {:layout => false}, :error => "Can't connect to MongoDB!"
70
64
  return false
@@ -89,33 +83,19 @@ module MongodbLogger
89
83
  %w( overview ).each do |page|
90
84
  get "/#{page}/?" do
91
85
  @filter = ServerModel::Filter.new(params[:filter])
92
- @logs = @collection.find(@filter.get_mongo_conditions).sort('$natural', -1).limit(@filter.get_mongo_limit)
86
+ @logs = @mongo_adapter.filter_by_conditions(@filter)
93
87
  show page, !request.xhr?
94
88
  end
95
89
  end
96
90
 
97
91
  get "/tail_logs/?:log_last_id?" do
98
- buffer = []
99
- last_id = nil
100
- if params[:log_last_id] && !params[:log_last_id].blank?
101
- log_last_id = params[:log_last_id]
102
- tail = Mongo::Cursor.new(@collection, :tailable => true, :order => [['$natural', 1]],
103
- :selector => {'_id' => { '$gt' => BSON::ObjectId(log_last_id) }})
104
- while log = tail.next
105
- buffer << partial(:"shared/log", :object => log)
106
- log_last_id = log["_id"].to_s
107
- end
108
- buffer.reverse!
109
- else
110
- @log = @collection.find_one({}, {:sort => ['$natural', -1]})
111
- log_last_id = @log["_id"].to_s unless @log.blank?
112
- end
113
-
114
- content_type :json
115
- { :log_last_id => log_last_id,
116
- :time => Time.now.strftime("%F %T"),
117
- :content => buffer.join("\n"),
118
- :collection_stats => partial(:"shared/collection_stats", :object => @collection_stats) }.to_json
92
+ @info = @mongo_adapter.tail_log_from_params(params)
93
+ @info.merge!(
94
+ :content => @info[:logs].map{|log| partial(:"shared/log", :object => log) }.join("\n"),
95
+ :collection_stats => partial(:"shared/collection_stats", :object => @collection_stats)
96
+ )
97
+ content_type :json
98
+ @info.to_json
119
99
  end
120
100
 
121
101
  get "/changed_filter/:type" do
@@ -133,13 +113,13 @@ module MongodbLogger
133
113
 
134
114
  # log info
135
115
  get "/log/:id" do
136
- @log = @collection.find_one(BSON::ObjectId(params[:id]))
116
+ @log = @mongo_adapter.find_by_id(params[:id])
137
117
  show :show_log, !request.xhr?
138
118
  end
139
119
 
140
120
  # log info right
141
121
  get "/log_info/:id" do
142
- @log = @collection.find_one(BSON::ObjectId(params[:id]))
122
+ @log = @mongo_adapter.find_by_id(params[:id])
143
123
  partial(:"shared/log_info", :object => @log)
144
124
  end
145
125
 
@@ -152,14 +132,13 @@ module MongodbLogger
152
132
  # analytics
153
133
  %w( analytics ).each do |page|
154
134
  get "/#{page}/?" do
155
- @analytic = ServerModel::Analytic.new(@collection, params[:analytic])
135
+ @analytic = ServerModel::Analytic.new(@mongo_adapter, params[:analytic])
156
136
  show page, !request.xhr?
157
137
  end
158
138
  post "/#{page}/?" do
159
- @analytic = ServerModel::Analytic.new(@collection, params[:analytic])
160
- @analytic_data = @analytic.get_data
139
+ @analytic = ServerModel::Analytic.new(@mongo_adapter, params[:analytic])
161
140
  content_type :json
162
- @analytic_data.to_json
141
+ @analytic.get_data.to_json
163
142
  end
164
143
  end
165
144
 
@@ -2,32 +2,22 @@ module MongodbLogger
2
2
  module ServerModel
3
3
  class Analytic
4
4
 
5
- FIXED_PARAMS_ON_FORM = ['type', 'start_date', 'end_date']
5
+ FIXED_PARAMS_ON_FORM = ['type', 'unit', 'start_date', 'end_date']
6
6
  ANALYTIC_TYPES = [[0, "Count of requests"], [1, "Count of errors"]]
7
- ANALYTIC_HEADERS = [
8
- {
9
- :key => ["year", "month", "day"],
10
- :value => ["count"]
11
- },
12
- {
13
- :key => ["year", "month", "day"],
14
- :value => ["count"]
15
- }
16
- ]
17
- attr_reader :params, :collection
7
+ ANALYTIC_UNITS = [[0, "Month"], [1, "Day"], [2, "Hour"]]
8
+
9
+ attr_reader :params, :mongo_adapter
18
10
  FORM_NAME = "analytic"
19
11
 
20
-
21
- def initialize(collection, params)
12
+ def initialize(mongo_adapter, params)
22
13
  FIXED_PARAMS_ON_FORM.each do |key|
23
14
  create_variable(key, nil)
24
15
  end
25
- @collection = collection
16
+ @mongo_adapter = mongo_adapter
26
17
  @params = params
27
18
  @params.each do |k,v|
28
19
  self.send("#{k}=", v) if self.respond_to?(k) && v && !v.blank?
29
20
  end unless @params.blank?
30
-
31
21
  # def values
32
22
  self.start_date ||= Time.now.strftime('%Y-%m-%d')
33
23
  self.end_date ||= Time.now.strftime('%Y-%m-%d')
@@ -43,38 +33,65 @@ module MongodbLogger
43
33
  FORM_NAME
44
34
  end
45
35
 
46
- def count_of_requests(conditions, is_errors = false)
47
- collection_name = "mongodb_logger_count_of_requests"
48
- map = "function() { var key = {year: this.request_time.getFullYear(), month: this.request_time.getMonth() + 1, day: this.request_time.getDate()}; emit(key, {count: 1});}"
49
- reduce_count = "function(key, values) { var sum = 0; values.forEach(function(f) { sum += f.count; }); return {count: sum};}"
50
- if is_errors
51
- collection_name = "mongodb_logger_count_of_errors"
52
- conditions.merge!({:is_exception => true})
36
+ def calculate_default_map_reduce(params = {})
37
+ addinional_params = case self.unit.to_i
38
+ when 1
39
+ "day: this.request_time.getDate()"
40
+ when 2
41
+ "day: this.request_time.getDate(), hour: this.request_time.getHours() + 1"
42
+ else
43
+ ""
53
44
  end
54
- @collection.map_reduce(map, reduce_count, {:out => collection_name, :query => conditions, :sort => ['$natural', -1]})
45
+ map = <<EOF
46
+ function() {
47
+ var key = {
48
+ year: this.request_time.getFullYear(),
49
+ month: this.request_time.getMonth() + 1,
50
+ #{addinional_params}
51
+ };
52
+ emit(key, {count: 1});
53
+ }
54
+ EOF
55
+ reduce = <<EOF
56
+ function(key, values) {
57
+ var sum = 0;
58
+ values.forEach(function(f) {
59
+ sum += f.count;
60
+ });
61
+ return {count: sum};
62
+ }
63
+ EOF
64
+ case self.type.to_i
65
+ when 1
66
+ params[:conditions].merge!({:is_exception => true})
67
+ else
68
+ # nothing
69
+ end
70
+
71
+ @mongo_adapter.calculate_mapreduce(map, reduce, {:conditions => params[:conditions]})
55
72
  end
56
73
 
57
74
  def get_data
58
- m_start= Date.parse(self.start_date) rescue nil
59
- m_start = Date.today if m_start.nil?
60
- m_end = Date.parse(self.end_date) rescue nil
61
- m_end = Date.today if m_end.nil?
75
+ m_start= Date.parse(self.start_date) rescue Date.today
76
+ m_end = Date.parse(self.end_date) rescue Date.today
62
77
 
63
78
  conditions = { :request_time => {
64
79
  '$gte' => Time.utc(m_start.year, m_start.month, m_start.day, 0, 0, 0),
65
80
  '$lte' => Time.utc(m_end.year, m_end.month, m_end.day, 23, 59, 59)
66
81
  }}
67
82
 
68
- mapreduce_collection = case self.type.to_i
69
- when 0
70
- count_of_requests(conditions)
71
- when 1
72
- count_of_requests(conditions, true)
73
- else
74
- count_of_requests(conditions)
75
- end
83
+ all_data = calculate_default_map_reduce(
84
+ :conditions => conditions
85
+ )
76
86
 
77
- {:data => mapreduce_collection.find(), :headers => ANALYTIC_HEADERS[self.type.to_i]}
87
+ {
88
+ :data => (all_data ? all_data.first.last : []),
89
+ :headers => {
90
+ :key => ["year", "month", "day", "hour"],
91
+ :value => ["count"]
92
+ },
93
+ unit: self.unit
94
+ }
78
95
  end
79
96
 
80
97
  end
@@ -11,6 +11,10 @@ module Sinatra::ViewHelpers
11
11
  end
12
12
  end
13
13
 
14
+ def percent_of_userd_memory(collection_stats)
15
+ ((collection_stats[:size] / collection_stats[:storageSize]) * 100).round
16
+ end
17
+
14
18
  def string_from_log_message(message)
15
19
  message.is_a?(Array) ? message.join("\n") : message.to_s
16
20
  end
@@ -19,7 +23,7 @@ module Sinatra::ViewHelpers
19
23
  meta_data = Hash.new
20
24
  log.each do |key, val|
21
25
  # predefined fields
22
- next if [:_id, :messages, :request_time, :ip, :runtime, :application_name, :is_exception, :params, :method, :controller, :action, :path, :url].include?(key.to_sym)
26
+ next if [:_id, :messages, :request_time, :ip, :runtime, :application_name, :is_exception, :params, :method, :controller, :action, :session, :path, :url].include?(key.to_sym)
23
27
  meta_data[key] = val
24
28
  end
25
29
  meta_data
@@ -13,7 +13,7 @@
13
13
  </div>
14
14
  <div class="unit size1of2">
15
15
  <div class="prm">
16
- <%#= text_field_tag @filter, :action, :placeholder => "Action" %>
16
+ <%= select_tag @analytic, :unit, MongodbLogger::ServerModel::Analytic::ANALYTIC_UNITS %>
17
17
  </div>
18
18
  </div>
19
19
  </div>
@@ -38,11 +38,12 @@
38
38
  </form>
39
39
  </div> <!-- filter -->
40
40
 
41
- <div class="filter-toggle"><span class="arrow-down">Analyze</span></div>
42
-
43
- <div id="analyticData">
44
- <div class="pal txtC">
45
- Select what to analyze
41
+ <div class="filter_toggle filter-toggle"><span class="arrow-down">Analyze</span></div>
42
+ <div style="margin: 10px">
43
+ <div id="analyticData">
44
+ <div class="pal txtC">
45
+ Select what to analyze
46
+ </div>
46
47
  </div>
47
48
  </div>
48
49
 
@@ -51,7 +52,7 @@
51
52
  <div class="unit size1of4">
52
53
  <div class="details">
53
54
 
54
- <div id="log_info">
55
+ <div id="logInfo">
55
56
  <div class="pale h2 pal txtC">
56
57
  Comming soon...
57
58
  </div> <!-- pale h2 -->
@@ -10,19 +10,19 @@
10
10
  <div class="wrapper">
11
11
  <div class="unit-right stats">
12
12
  <div class="unit size2of3">
13
- <div class="ptxs pls"><strong>DB:</strong> <%=h @db.name %></div>
14
- <div class="pls"><strong>Collection:</strong> <%=h @collection.name %></div>
13
+ <div class="ptxs pls"><strong>DB:</strong> <%=h @collection_stats[:db_name] %></div>
14
+ <div class="pls"><strong>Collection:</strong> <%=h @collection_stats[:collection] %></div>
15
15
  </div> <!-- unit -->
16
16
  <div id="collection_stats">
17
17
  <%= partial(:"shared/collection_stats", :object => @collection_stats) %>
18
18
  </div>
19
19
  </div>
20
- <a href="<%=h url_path("overview") %>" class="logo" data-pjax='#main_pjax'><img src="<%= asset_path 'logo.png' %>" alt="MongoDB Logger"></a>
20
+ <a href="<%=h url_path("overview") %>" class="logo" data-pjax='#mainPjax'><img src="<%= asset_path 'logo.png' %>" alt="MongoDB Logger"></a>
21
21
  </div> <!-- wrapper -->
22
22
  </div> <!-- header -->
23
23
  <div class="content">
24
24
  <div class="wrapper">
25
- <div id="main_pjax" class="mainbox">
25
+ <div id="mainPjax" class="mainbox">
26
26
  <%= yield %>
27
27
  </div> <!-- mainbox -->
28
28
  </div> <!-- wrapper -->
@@ -32,12 +32,5 @@
32
32
  <!-- scripts -->
33
33
  <script src="<%= asset_path('mongodb_logger.js') %>" type="text/javascript"></script>
34
34
 
35
- <!-- charts -->
36
- <script type="text/javascript" src="https://www.google.com/jsapi"></script>
37
- <script type="text/javascript">
38
- google.load('visualization', '1', {'packages':['corechart']});
39
- google.setOnLoadCallback(MongodbLoggerMain.init_analytic_charts);
40
- </script>
41
-
42
35
  </body>
43
36
  </html>
@@ -1,4 +1,4 @@
1
- <% if @collection_stats["capped"] && (1 == @collection_stats["capped"] || true == @collection_stats["capped"]) %>
1
+ <% if @collection_stats[:is_capped] %>
2
2
  <% content_for :right_top_panel do %>
3
3
  <%= partial(:"shared/tail_panel") %>
4
4
  <% end %>
@@ -49,7 +49,7 @@
49
49
  </div> <!-- outer -->
50
50
 
51
51
  <div class="outer">
52
- <ul id="more_filter_list">
52
+ <ul id="moreFilterList">
53
53
  <% @filter.more_filters.each_with_index do |f_filter, index| %>
54
54
  <li>
55
55
  <%= partial(:"shared/dynamic_filter", :object => f_filter) %>
@@ -57,7 +57,7 @@
57
57
  <% end %>
58
58
  </ul>
59
59
  <div class="mbs">
60
- <a id="add_more_filter" href="<%=h url_path("add_filter") %>" class="add">+ Add Filter</a>
60
+ <a id="addMoreFilter" href="<%=h url_path("add_filter") %>" class="add">+ Add Filter</a>
61
61
  </div>
62
62
 
63
63
  </div> <!-- outer -->
@@ -84,10 +84,10 @@
84
84
  </form>
85
85
  </div> <!-- filter -->
86
86
 
87
- <div class="filter-toggle"><span class="arrow-down <%= 'rotate' unless @filter.get_mongo_conditions.blank? %>">Filter</span></div>
87
+ <div class="filter_toggle filter-toggle"><span class="arrow-down <%= 'rotate' unless @filter.get_mongo_conditions.blank? %>">Filter</span></div>
88
88
 
89
89
  <% if @logs.count > 0 %>
90
- <table id="logs_list">
90
+ <table id="logsList">
91
91
  <tr>
92
92
  <th>Received</th>
93
93
  <th>Controller</th>
@@ -109,7 +109,7 @@
109
109
  <div class="unit size1of4">
110
110
  <div class="details">
111
111
 
112
- <div id="log_info">
112
+ <div id="logInfo">
113
113
  <div class="pale h2 pal txtC">
114
114
  Please choose log to see details
115
115
  </div> <!-- pale h2 -->
@@ -1,11 +1,11 @@
1
1
  <div class="unit size1of3">
2
2
  <div class="pts prs txtR">
3
- <span class="log-num" title="count of logs"><%=h collection_stats["count"] %></span></div>
3
+ <span class="log-num" title="count of logs"><%=h collection_stats[:count] %></span></div>
4
4
  </div> <!-- unit -->
5
- <% if collection_stats["capped"] && (1 == collection_stats["capped"] || true == collection_stats["capped"]) %>
5
+ <% if collection_stats[:is_capped] %>
6
6
  <div class="progress">
7
- <span class="size"><%=h number_to_human_size(collection_stats["size"]) %> of <%=h number_to_human_size(collection_stats["storageSize"]) %></span>
8
- <div class="used" style="width: <%=((collection_stats["size"].to_f / collection_stats["storageSize"].to_f) * 100).round%>%"></div>
7
+ <span class="size"><%=h number_to_human_size(collection_stats[:size]) %> of <%=h number_to_human_size(collection_stats[:storageSize]) %></span>
8
+ <div class="used" style="width: <%= percent_of_userd_memory(collection_stats) %>%"></div>
9
9
  </div> <!-- progress -->
10
10
  <% else %>
11
11
  <div class="warning"><p>You do not use capped collection for logs.
@@ -2,7 +2,7 @@
2
2
  <div class="unit size1of3">
3
3
  <div class="unit size1of2">
4
4
  <div class="prm">
5
- <%= select_tag dynamic_filter, :type, MongodbLogger::ServerModel::AdditionalFilter::VAR_TYPES, :class => "filter_type", :rel => url_path("changed_filter") %>
5
+ <%= select_tag dynamic_filter, :type, MongodbLogger::ServerModel::AdditionalFilter::VAR_TYPES, :class => "filter_type", "data-url" => url_path("changed_filter") %>
6
6
  </div> <!-- prm -->
7
7
  </div> <!-- unit -->
8
8
  <div class="unit size1of2">
@@ -1,6 +1,6 @@
1
1
  <div class="pas">
2
2
  <div class="unit-right">
3
- <a href="<%=h url_path("log/#{log_info['_id']}") %>" data-pjax='#main_pjax' class="button small grey">More Info</a>
3
+ <a href="<%=h url_path("log/#{log_info['_id']}") %>" data-pjax='#mainPjax' class="button small grey">More Info</a>
4
4
  </div> <!-- unit-right -->
5
5
  <h2 class="phs mvs"><span class="<%= log_info['is_exception'] ? 'failure' : 'success' %>">Message</span></h2>
6
6
  <div class="phs wrap_text">
@@ -1,4 +1,4 @@
1
1
  <ul class="unit">
2
- <li <%= class_if_current(url_path("overview")) %>><a href="<%=h url_path("overview") %>" data-pjax='#main_pjax'>Logs</a></li>
3
- <li <%= class_if_current(url_path("analytics")) %>><a href="<%=h url_path("analytics") %>" data-pjax='#main_pjax'>Analytics</a></li>
2
+ <li <%= class_if_current(url_path("overview")) %>><a href="<%=h url_path("overview") %>" data-pjax='#mainPjax'>Logs</a></li>
3
+ <li <%= class_if_current(url_path("analytics")) %>><a href="<%=h url_path("analytics") %>" data-pjax='#mainPjax'>Analytics</a></li>
4
4
  </ul>
@@ -1,12 +1,12 @@
1
- <div id="tail_logs_block">
1
+ <div id="tailLogsBlock">
2
2
  <div class="initial">
3
- <a id="tail_logs_link" href="#" data-url="<%=h url_path("tail_logs") %>" class="button mts mrs">
3
+ <a id="tailLogsLink" href="#" data-url="<%=h url_path("tail_logs") %>" class="button mts mrs">
4
4
  <span class="start" data-url="<%=h url_path("tail_logs") %>">Tail</span>
5
5
  </a>
6
6
  </div>
7
7
  <div class="info">
8
- <span id="tail_logs_time" class="logs-time mrs"></span>
9
- <a id="tail_logs_stop_link" href="#" class="button negative mts mrs">
8
+ <span id="tailLogsTime" class="logs-time mrs"></span>
9
+ <a id="tailLogsStopLink" href="#" class="button negative mts mrs">
10
10
  <span class="stop">Stop</span>
11
11
  </a>
12
12
  </div>