[PATCH 3/3] RM3393 added graphs to logs page

Tzu-Mainn Chen tzumainn at redhat.com
Mon Jun 18 16:17:40 UTC 2012


---
 src/app/controllers/logs_controller.rb    |  191 +++++++++++++++++++++++------
 src/app/views/logs/_filter_view.html.haml |   44 +++++++
 src/app/views/logs/_pretty_view.html.haml |   40 ++++++
 src/app/views/logs/index.html.haml        |   56 ++-------
 src/config/locales/en.yml                 |    2 +
 5 files changed, 250 insertions(+), 83 deletions(-)
 create mode 100644 src/app/views/logs/_filter_view.html.haml
 create mode 100644 src/app/views/logs/_pretty_view.html.haml

diff --git a/src/app/controllers/logs_controller.rb b/src/app/controllers/logs_controller.rb
index a814867..d5370eb 100644
--- a/src/app/controllers/logs_controller.rb
+++ b/src/app/controllers/logs_controller.rb
@@ -21,11 +21,17 @@ class LogsController < ApplicationController
     clear_breadcrumbs
     save_breadcrumb(logs_path)
 
-    load_headers
+    params[:view] = "filter" if params[:view].nil?
+    @view = params[:view]
+
     load_options
-    load_logs
+    load_events
+    load_headers unless @view == "pretty"
+    generate_graph if @view == "pretty"
+
     respond_to do |format|
-      format.html
+      format.html { @partial = filter_view? ? 'filter_view' : 'pretty_view' }
+      format.js { render :partial => filter_view? ? 'filter_view' : 'pretty_view' }
     end
   end
 
@@ -37,11 +43,13 @@ class LogsController < ApplicationController
                            "state" => params[:state],
                            "from_date" => params[:from_date],
                            "to_date" => params[:to_date],
-                           "order" => params[:order] })
+                           "order" => params[:order],
+                           "group" => params[:group],
+                           "view" => params[:view] })
   end
 
   def export_logs
-    load_logs
+    load_events
     load_headers
 
     csvm = Object.const_defined?(:FasterCSV) ? FasterCSV : CSV
@@ -70,7 +78,7 @@ class LogsController < ApplicationController
 
   protected
 
-  def load_logs
+  def load_events
     @source_type = params[:source_type].nil? ? "" : params[:source_type]
     @pool_select = params[:pool_select].nil? ? "" : params[:pool_select]
     @provider_select =
@@ -87,6 +95,16 @@ class LogsController < ApplicationController
                  params[:to_date][:month].to_i,
                  params[:to_date][:day].to_i)
 
+    # modify parameters for pretty view
+    if @view == "pretty"
+      @state = ""
+      @pool_select = ""
+      @provider_select = ""
+      @owner_id = ""
+      @order = t('logs.options.time_order')
+      @source_type = "Deployment" if @source_type == ""
+    end
+
     if @source_type.present?
       conditions = ["event_time between ? and ? and source_type = ?",
                     @from_date.to_datetime.beginning_of_day, @to_date.to_datetime.end_of_day, @source_type]
@@ -169,36 +187,45 @@ class LogsController < ApplicationController
   end
 
   def load_options
-    @source_type_options = [[t('logs.options.default_event_types'), ""],
-                            t('logs.options.deployment_event_type'),
-                            t('logs.options.instance_event_type')]
-    @state_options = ([[t('logs.options.default_states'), ""]] +
-                      Deployment::STATES + Instance::STATES).uniq
-    @pool_options = [[t('logs.options.default_pools'), ""]]
-    PoolFamily.list_for_user(current_session, current_user, Privilege::VIEW).
-      find(:all, :include => :pools, :order => "name",
-           :select => ["id", "name"]).each do |pool_family|
-      @pool_options << [pool_family.name, "pool_family:" + pool_family.id.to_s]
-      @pool_options += pool_family.pools.
-        map{|x| [" -- " + x.name, "pool:" + x.id.to_s]}
-    end
-    @provider_options = [[t('logs.options.default_providers'), ""]]
-    Provider.list_for_user(current_session, current_user, Privilege::VIEW).
-      find(:all, :include => :provider_accounts, :order => "name",
-           :select => ["id", "name"]).each do |provider|
-      @provider_options << [provider.name, "provider:" + provider.id.to_s]
-      @provider_options += provider.provider_accounts.
-        map{|x| [" -- " + x.name, "provider_account:" + x.id.to_s]}
+    if @view == "pretty"
+      @source_type_options = [t('logs.options.deployment_event_type'),
+                              t('logs.options.instance_event_type')]
+      @group_options = [[t('logs.options.default_group_by'), ""],
+                        t('logs.index.pool'),
+                        t('logs.index.provider'),
+                        t('logs.index.owner')]
+    else
+      @source_type_options = [[t('logs.options.default_event_types'), ""],
+                              t('logs.options.deployment_event_type'),
+                              t('logs.options.instance_event_type')]
+      @pool_options = [[t('logs.options.default_pools'), ""]]
+      PoolFamily.list_for_user(current_session, current_user, Privilege::VIEW).
+        find(:all, :include => :pools, :order => "name",
+             :select => ["id", "name"]).each do |pool_family|
+        @pool_options << [pool_family.name, "pool_family:" + pool_family.id.to_s]
+        @pool_options += pool_family.pools.
+          map{|x| [" -- " + x.name, "pool:" + x.id.to_s]}
+      end
+      @provider_options = [[t('logs.options.default_providers'), ""]]
+      Provider.list_for_user(current_session, current_user, Privilege::VIEW).
+        find(:all, :include => :provider_accounts, :order => "name",
+             :select => ["id", "name"]).each do |provider|
+        @provider_options << [provider.name, "provider:" + provider.id.to_s]
+        @provider_options += provider.provider_accounts.
+          map{|x| [" -- " + x.name, "provider_account:" + x.id.to_s]}
+      end
+      @owner_options = [[t('logs.options.default_users'), ""]] +
+        User.find(:all, :order => "login",
+                  :select => ["id", "login"]).map{|x| [x.login, x.id]}
+      @order_options = [t('logs.options.time_order'),
+                        t('logs.options.deployment_instance_order'),
+                        t('logs.options.state_order'),
+                        t('logs.options.pool_order'),
+                        t('logs.options.provider_order'),
+                        t('logs.options.owner_order')]
+      @state_options = ([[t('logs.options.default_states'), ""]] +
+                        Deployment::STATES + Instance::STATES).uniq
     end
-    @owner_options = [[t('logs.options.default_users'), ""]] +
-      User.find(:all, :order => "login",
-                :select => ["id", "login"]).map{|x| [x.login, x.id]}
-    @order_options = [t('logs.options.time_order'),
-                      t('logs.options.deployment_instance_order'),
-                      t('logs.options.state_order'),
-                      t('logs.options.pool_order'),
-                      t('logs.options.provider_order'),
-                      t('logs.options.owner_order')]
   end
 
   def load_headers
@@ -214,4 +241,98 @@ class LogsController < ApplicationController
     ]
   end
 
+  def generate_graph
+    @group = params[:group].nil? ? "" : params[:group]
+
+    start_code = (@source_type == 'Deployment' ? 'first_running' : 'running')
+    end_code = (@source_type == 'Deployment' ? 'all_stopped' : 'stopped')
+
+    initial_conditions = ["exists (select 1 from events
+                                   where source_type = '" + @source_type + "'
+                                   and source_id = " + @source_type + "s.id
+                                   and status_code = '" + start_code + "'
+                                   and event_time <= ?) 
+                           and not exists (select 1 from events
+                                           where source_type = '" + @source_type + "'
+                                           and source_id = " + @source_type + "s.id
+                                           and status_code = '" + end_code + "'
+                                           and event_time <= ?)",
+                          @from_date.to_datetime.beginning_of_day,
+                          @from_date.to_datetime.beginning_of_day]
+
+    if @source_type == "Deployment"
+      @initial_sources = Deployment.unscoped.
+        list_for_user(current_session, current_user, Privilege::VIEW).
+        find(:all, :conditions => initial_conditions)
+    else 
+      @initial_sources = Instance.unscoped.
+        list_for_user(current_session, current_user, Privilege::VIEW).
+        find(:all, :conditions => initial_conditions)
+    end
+
+    @datasets = Hash.new
+    counts = Hash.new
+
+    counts["All"] = @initial_sources.count
+
+    if @group_options.include?(@group) 
+      @initial_sources.each do |source|
+        label = get_source_label(source, @group)
+
+        if counts.has_key?(label)
+          counts[label] = counts[label] + 1
+        else
+          counts[label] = 1
+        end
+      end
+    end
+
+    counts.each.map{ |label,count|
+      @datasets[label] = [ [@from_date.to_datetime.beginning_of_day.to_i * 1000, count] ]
+    }
+
+    @events.each do |event|
+      event_timestamp = event.event_time.to_i * 1000
+
+      if event.status_code == start_code || event.status_code == end_code
+        increment = (event.status_code == end_code) ? -1 : 1
+
+        add_dataset_point("All", event_timestamp, increment, counts)
+
+        if @group_options.include?(@group) 
+          label = get_source_label(event.source, @group)
+          add_dataset_point(label, event_timestamp, increment, counts)
+        end
+      end
+    end
+    
+    counts.each.map{ |label,count|
+      @datasets[label] << [@to_date.to_datetime.end_of_day.to_i * 1000, count]
+    }
+  end
+
+  def get_source_label(source, label_type)
+    label = "Unknown"
+    case @group
+    when t('logs.index.pool')
+      label = source.pool.name unless source.pool.nil?
+    when t('logs.index.provider')
+      label = source.provider_account.name unless source.provider_account.nil?
+    when t('logs.index.owner')
+      label = source.owner.name unless source.owner.nil?
+    end
+
+    label
+  end
+
+  def add_dataset_point(label, timestamp, increment, counts)
+    if !@datasets.has_key?(label)
+      counts[label] = 0
+      @datasets[label] = [ [timestamp - 1, 0] ]
+    end
+
+    @datasets[label] << [timestamp - 1, counts[label]]
+    counts[label] = counts[label] + increment
+    @datasets[label] << [timestamp, counts[label]]
+  end
 end
diff --git a/src/app/views/logs/_filter_view.html.haml b/src/app/views/logs/_filter_view.html.haml
new file mode 100644
index 0000000..b58b2eb
--- /dev/null
+++ b/src/app/views/logs/_filter_view.html.haml
@@ -0,0 +1,44 @@
+- content_for :filter_controls do
+  %li
+    = label_tag "source_type", t('filter_table.viewing')
+    = hidden_field_tag :current_path, request.fullpath
+    = select_tag "source_type", options_for_select(@source_type_options, @source_type)
+    = select_tag "state", options_for_select(@state_options, @state)
+    = select_tag "pool_select", options_for_select(@pool_options, @pool_select)
+    = select_tag "provider_select", options_for_select(@provider_options, @provider_select)
+    = select_tag "owner_id", options_for_select(@owner_options, @owner_id)
+    = restful_submit_tag t("filter_table.apply_filters"), "index", filter_logs_path, 'POST', :class => 'button', :id => 'apply_logs_filter'
+    %span.label.badge.dark= @events.count
+  %br
+    = t('filter_table.from')
+    = select_date @from_date, :prefix => :from_date
+    = t('filter_table.to')
+    = select_date @to_date, :prefix => :to_date
+    = t('filter_table.order_by')
+    = select_tag "order", options_for_select(@order_options, @order)
+    %li.more_actions
+      %span
+        = image_tag "more_actions_drop.png"
+      %ul
+        %li= link_to "#{t'logs.index.export_logs'}", export_logs_logs_path(:source_type => @source_type, :state => @state, :pool_select => @pool_select, :provider_select => @provider_select, :owner_id => @owner_id, :from_date => {:day => @from_date.day, :month => @from_date.month, :year => @from_date.year}, :to_date => {:day => @to_date.day, :month => @to_date.month, :year => @to_date.year}, :order => @order)
+
+= filter_table(@header, @paginated_events) do |event|
+  - source = event.source
+  - provider_account = source.nil? ? nil : source.provider_account
+  %tr{:class => cycle('nostripe','stripe')}
+    %td= event.event_time.strftime("%d-%b-%Y %H:%M:%S")
+    %td= source.nil? ? t('logs.index.not_available') : source.name
+    %td= source.nil? ? t('logs.index.not_available') : source.state
+    %td= source.nil? ? t('logs.index.not_available') : source.pool_family.name + "/" + source.pool.name
+    %td= provider_account.nil? ? t('logs.index.not_available') : provider_account.provider.name + "/" + provider_account.name
+    %td= source.nil? ? t('logs.index.not_available') : source.owner.login
+    %td= event.summary
+    %td
+      - if !source.nil?
+        %a.hoverpopup
+          = image_tag "icon_view.png"
+          %span
+            - if source.class.name == "Deployment"
+              = render :partial => 'deployment_popup', :locals => {:deployment => source}
+            - elsif source.class.name == "Instance"
+              = render :partial => 'instance_popup', :locals => {:instance => source}
diff --git a/src/app/views/logs/_pretty_view.html.haml b/src/app/views/logs/_pretty_view.html.haml
new file mode 100644
index 0000000..d559a4f
--- /dev/null
+++ b/src/app/views/logs/_pretty_view.html.haml
@@ -0,0 +1,40 @@
+= form_tag logs_path, :method => :get, :class => 'filterable-data' do
+  %div.controls
+    %ul.filter-controls
+      %li
+        = label_tag "source_type", t('filter_table.viewing')
+        = hidden_field_tag :view, @view
+        = select_tag "source_type", options_for_select(@source_type_options, @source_type)
+        = t('logs.index.grouped_by')
+        = select_tag "group", options_for_select(@group_options, @group)
+        = t('filter_table.from')
+        = select_date @from_date, :prefix => :from_date
+        = t('filter_table.to')
+        = select_date @to_date, :prefix => :to_date
+        = restful_submit_tag t("filter_table.apply_filters"), "index", filter_logs_path, 'POST', :class => 'button', :id => 'apply_logs_filter'
+%br
+
+%div{:id => 'placeholder', :style => 'width:925px;height:600px;'}
+
+:javascript
+  $(function () {
+    var datasets = [
+      {
+        label: "All",
+        data: [#{ @datasets["All"].each.map{ |p| "[#{p[0]}, #{p[1]}]"}.join(", ") }]
+      },
+      #{ @datasets.reject{|label,data| label == "All"}.each.map{ |label,data| "{
+        label: \"" + label + "\",
+        data: [#{ data.each.map{ |p| "[#{p[0]}, #{p[1]}]"}.join(", ") }]
+      }" }.join(",
+      ") }
+    ];
+
+    $.plot($("#placeholder"), datasets, {
+      xaxis: {
+        mode: "time",
+        min: #{@from_date.to_datetime.beginning_of_day.to_i * 1000},
+        max: #{@to_date.to_datetime.end_of_day.to_i * 1000}
+      }
+    });
+  });
diff --git a/src/app/views/logs/index.html.haml b/src/app/views/logs/index.html.haml
index 376c035..d8101ac 100644
--- a/src/app/views/logs/index.html.haml
+++ b/src/app/views/logs/index.html.haml
@@ -1,51 +1,11 @@
 = render :partial => 'layouts/nav_history'
 
-%section.content-section
-  %header
-    %h2= t('logs.index.title')
+%header.page-header
+  .obj_actions
+    .button-group
+      = pretty_filter_toggle(logs_path(:view => 'pretty'),
+                             logs_path(:view => 'filter'))
+  %h1.section-index= t('logs.index.title')
 
-  .content
-    - content_for :filter_controls do
-      %li
-        = label_tag "source_type", t('filter_table.viewing')
-        = hidden_field_tag :current_path, request.fullpath
-        = select_tag "source_type", options_for_select(@source_type_options, @source_type)
-        = select_tag "state", options_for_select(@state_options, @state)
-        = select_tag "pool_select", options_for_select(@pool_options, @pool_select)
-        = select_tag "provider_select", options_for_select(@provider_options, @provider_select)
-        = select_tag "owner_id", options_for_select(@owner_options, @owner_id)
-        = restful_submit_tag t("filter_table.apply_filters"), "index", filter_logs_path, 'POST', :class => 'button', :id => 'apply_logs_filter'
-        %span.label.badge.dark= @events.count
-      %br
-        = t('filter_table.from')
-        = select_date @from_date, :prefix => :from_date
-        = t('filter_table.to')
-        = select_date @to_date, :prefix => :to_date
-        = t('filter_table.order_by')
-        = select_tag "order", options_for_select(@order_options, @order)
-        %li.more_actions
-          %span
-            = image_tag "more_actions_drop.png"
-          %ul
-            %li= link_to "#{t'logs.index.export_logs'}", export_logs_logs_path(:source_type => @source_type, :state => @state, :pool_select => @pool_select, :provider_select => @provider_select, :owner_id => @owner_id, :from_date => {:day => @from_date.day, :month => @from_date.month, :year => @from_date.year}, :to_date => {:day => @to_date.day, :month => @to_date.month, :year => @to_date.year}, :order => @order)
-
-    = filter_table(@header, @paginated_events) do |event|
-      - source = event.source
-      - provider_account = source.nil? ? nil : source.provider_account
-      %tr{:class => cycle('nostripe','stripe')}
-        %td= event.event_time.strftime("%d-%b-%Y %H:%M:%S")
-        %td= source.nil? ? t('logs.index.not_available') : source.name
-        %td= source.nil? ? t('logs.index.not_available') : source.state
-        %td= source.nil? ? t('logs.index.not_available') : source.pool_family.name + "/" + source.pool.name
-        %td= provider_account.nil? ? t('logs.index.not_available') : provider_account.provider.name + "/" + provider_account.name
-        %td= source.nil? ? t('logs.index.not_available') : source.owner.login
-        %td= event.summary
-        %td
-          - if !source.nil?
-            %a.hoverpopup
-              = image_tag "icon_view.png"
-              %span
-                - if source.class.name == "Deployment"
-                  = render :partial => 'deployment_popup', :locals => {:deployment => source}
-                - elsif source.class.name == "Instance"
-                  = render :partial => 'instance_popup', :locals => {:instance => source}
+%section.content-section.toggle-view.logs
+  = render :partial => @partial
diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml
index 01a472e..f836fbf 100644
--- a/src/config/locales/en.yml
+++ b/src/config/locales/en.yml
@@ -19,6 +19,7 @@ en:
       instance_event_type: Instance
       default_pools: All Pools
       default_providers: All Providers
+      default_group_by: All
       time_order: Time
       deployment_instance_order: Deployment/Instance
       state_order: State
@@ -29,6 +30,7 @@ en:
       title: Logs
       not_available: N/A
       event_time: Time
+      grouped_by: Grouped By
       deployment: Deployment/Instance
       state: State
       pool: Pool
-- 
1.7.6.5




More information about the aeolus-devel mailing list