Skip to content

Commit

Permalink
v0.2.3
Browse files Browse the repository at this point in the history
Added a Combo Line Chart to the Servers Dashboard which combines the memory and cpu
usage into a single chart. This feature can be disabled to have two charts side by side
with setting the URL Parameter `?combo=false`.
  • Loading branch information
kobaltz committed Feb 10, 2024
1 parent 773157e commit 665804f
Show file tree
Hide file tree
Showing 15 changed files with 185 additions and 67 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
mission_control-servers (0.2.2)
mission_control-servers (0.2.3)
importmap-rails
rails (>= 7.1.3)
stimulus-rails
Expand Down
2 changes: 1 addition & 1 deletion app/assets/builds/mission_control_servers_application.css

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@
}

.line-chart {
height: 300px;
height: 400px;
width: 100%;
@apply text-sm font-semibold leading-6 text-gray-600;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module MissionControl::Servers
class Dashboards::ComboHistoriesController < ApplicationController
def show
@project = MissionControl::Servers::Project.find_by(token: params[:project_id])
@hostname = params[:hostname]
services = @project.services.where(hostname: @hostname).ordered
@combo_history_data = MissionControl::Servers::Service.combo_history(services)
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
static values = {
label: "Chart",
labelArray: Array,
dataArray: Array,
color: "rgb(54, 162, 235)"
}
connect() {
new Chart(this.element, {
type: 'line',
data: {
labels: this.labelArrayValue,
datasets: this.dataArrayValue
},
options: {
animation: false,
maintainAspectRatio: false
}
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export default class extends Controller {
}]
},
options: {
animation: false
animation: false,
maintainAspectRatio: false
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default class extends Controller {
if (activeTab && activeContent) {
activeTab.classList.add("text-xl", "text-gray-100", 'bg-indigo-500', 'dark:bg-indigo-900', 'transition', 'duration-300', 'ease-in-out');

activeContent.classList.remove('absolute', 'top-0', 'left-full', 'w-0', 'h-0');
activeContent.classList.remove('absolute', 'top-0', 'w-0', 'h-0');
activeContent.classList.add('relative');
}
}
Expand All @@ -45,7 +45,7 @@ export default class extends Controller {
link.classList.remove("text-xl", "text-gray-100", 'bg-indigo-500', "dark:bg-indigo-900");
});
this.contentTargets.forEach(content => {
content.classList.add('absolute', 'top-0', 'left-full', 'w-0', 'h-0');
content.classList.add('absolute', 'top-0', 'w-0', 'h-0');
content.classList.remove('relative');
});
}
Expand Down
45 changes: 45 additions & 0 deletions app/models/mission_control/servers/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,51 @@ class Service < ApplicationRecord

scope :ordered, -> { order(created_at: :desc) }

def self.combo_history(services, start_time: 1.hour.ago, end_time: Time.now.utc)
timestamps = (start_time.to_i..end_time.to_i).step(60).map { |t| Time.at(t).utc.change(sec: 0).to_i }
grouped_services = services.group_by { |service| service.created_at.utc.change(sec: 0).to_i }

cpu_usages = []
memory_usages = []
created_at_times = []

timestamps.each do |timestamp|
relevant_services = grouped_services[timestamp] || []
max_cpu_service = relevant_services.max_by(&:cpu)
max_memory_service = relevant_services.max_by do |service|
return 0 if service.mem_used.to_f + service.mem_free.to_f == 0.0
service.mem_used.to_f / (service.mem_used.to_f + service.mem_free.to_f)
end
cpu_usages << (max_cpu_service&.cpu || 0).to_f
if max_memory_service
total_memory = max_memory_service.mem_used.to_f + max_memory_service.mem_free.to_f
percentage_memory_used = (max_memory_service.mem_used.to_f / total_memory) * 100
memory_usages << percentage_memory_used.to_i
else
memory_usages << 0.0
end
created_at_times << Time.at(timestamp).utc.strftime('%H:%M%p')
end

data = [
{
label: 'CPU Usage',
data: cpu_usages,
fill: true,
borderColor: "rgb(54, 162, 235)",
tension: 0.25
},
{
label: 'Memory Usage',
data: memory_usages,
fill: true,
borderColor: "rgb(235, 127, 54)",
tension: 0.25
}
]
{ created_at_times: created_at_times, data: data }
end

def self.cpu_usage_history(services, start_time: 1.hour.ago, end_time: Time.now.utc)
timestamps = (start_time.to_i..end_time.to_i).step(60).map { |t| Time.at(t).utc.change(sec: 0).to_i }
grouped_services = services.group_by { |service| service.created_at.utc.change(sec: 0).to_i }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<%= turbo_frame_tag dom_id(@project, [@hostname, :combo_history].join('-')) do %>
<div class="progress-bar" style="height: 5px; width: 100%;">
<div class="progress" data-refresh-target="progressBar" style="height: 100%; width: 100%;"></div>
</div>
<div class="flex flex-col bg-gray-400/5 p-2">
<dt class="line-chart">
<canvas class="chart"
data-controller="combo-chart"
data-combo-chart-label-value="CPU & Memory History"
data-combo-chart-label-array-value="<%= @combo_history_data[:created_at_times] %>"
data-combo-chart-data-array-value="<%= @combo_history_data[:data].to_json %>"
data-combo-chart-color-value="rgb(54, 162, 235)"></canvas>
</dt>
<dd class="card-heading">CPU & Memory History</dd>
</div>
<% end %>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
data-line-chart-label-value="Memory Used History"
data-line-chart-label-array-value="<%= @memory_history_data[:created_at_times] %>"
data-line-chart-data-array-value="<%= @memory_history_data[:memory_usages] %>"
data-line-chart-color-value="rgb(54, 162, 235)"></canvas>
data-line-chart-color-value="rgb(235, 127, 54)"></canvas>
</dt>
<dd class="card-heading">Memory Used History</dd>
</div>
Expand Down
53 changes: 53 additions & 0 deletions app/views/mission_control/servers/projects/_panels.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<%= tag.div id: [hostname, "tab-content"].join("-"), class: "py-4 sm:py-8 tab-content", "data-target": hostname, "data-tabs-target": "content" do %>
<div class="mx-auto max-w-7xl px-6 lg:px-8">
<div class="mx-auto max-w-2xl lg:max-w-none">
<dl class="grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-2 lg:grid-cols-4">
<%= turbo_frame_tag dom_id(project, [hostname, :cpu_usage].join('-')),
src: project_dashboards_cpu_usage_path(project_id: project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_cpu_usage_path(project_id: project.token, hostname: hostname),
"data-refresh-interval-value": 30000 %>

<%= turbo_frame_tag dom_id(project, [hostname, :memory_usage].join('-')),
src: project_dashboards_memory_usage_path(project_id: project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_memory_usage_path(project_id: project.token, hostname: hostname),
"data-refresh-interval-value": 30000 %>

<%= turbo_frame_tag dom_id(project, [hostname, :disk_free].join('-')),
src: project_dashboards_disk_free_path(project_id: project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_disk_free_path(project_id: project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>

<%= turbo_frame_tag dom_id(project, [hostname, :last_seen].join('-')),
src: project_dashboards_last_seen_path(project_id: project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_last_seen_path(project_id: project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>
</dl>
<% if params[:combo] == "false" %>
<dl class="mt-8 grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-1 lg:grid-cols-2">
<%= turbo_frame_tag dom_id(project, [hostname, :cpu_history].join('-')),
src: project_dashboards_cpu_history_path(project_id: project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_cpu_history_path(project_id: project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>
<%= turbo_frame_tag dom_id(project, [hostname, :memory_history].join('-')),
src: project_dashboards_memory_history_path(project_id: project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_memory_history_path(project_id: project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>
</dl>
<% else %>
<dl class="mt-8 grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-1 lg:grid-cols-1">
<%= turbo_frame_tag dom_id(project, [hostname, :combo_history].join('-')),
src: project_dashboards_combo_history_path(project_id: project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_combo_history_path(project_id: project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>
</dl>
<% end %>
</div>
</div>
<% end %>
74 changes: 15 additions & 59 deletions app/views/mission_control/servers/projects/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -44,67 +44,23 @@
<% interval = params[:interval].present? ? params[:interval].to_i * 1000 : 10_000 %>
<%= tag.div data: { controller: "tabs", "tabs-refresh-interval-value": interval } do %>
<div class="mt-3">
<div class="">
<!-- Current: "text-gray-900", Default: "text-gray-500 hover:text-gray-700" -->
<nav class="isolate flex divide-x divide-gray-200 dark:divide-gray-500 rounded-lg shadow" aria-label="Tabs">
<% @services.each_with_index do |(hostname, services), index| %>
<% first_tab_class = index.zero? ? "rounded-l-lg" : "" %>
<% last_tab_class = index == @services.length - 1 ? "rounded-r-lg" : "" %>
<%= tag.a "#",
"data-action": "click->tabs#changeTab",
"data-target": hostname,
"data-tabs-target": "link",
class: "tab-link flex items-center justify-center #{first_tab_class} #{last_tab_class}" do %>
<%= hostname %>
<% end %>
<!-- Current: "text-gray-900", Default: "text-gray-500 hover:text-gray-700" -->
<nav class="isolate flex divide-x divide-gray-200 dark:divide-gray-500 rounded-lg shadow" aria-label="Tabs">
<% @services.each_with_index do |(hostname, services), index| %>
<% first_tab_class = index.zero? ? "rounded-l-lg" : "" %>
<% last_tab_class = index == @services.length - 1 ? "rounded-r-lg" : "" %>
<%= tag.a "#",
"data-action": "click->tabs#changeTab",
"data-target": hostname,
"data-tabs-target": "link",
class: "tab-link flex items-center justify-center #{first_tab_class} #{last_tab_class}" do %>
<%= hostname %>
<% end %>
</nav>
</div>
<% end %>
</nav>
</div>

<% @services.each do |hostname, services| %>
<%= tag.div id: [hostname, "tab-content"].join("-"), class: "py-4 sm:py-8 tab-content", "data-target": hostname, "data-tabs-target": "content" do %>
<div class="mx-auto max-w-7xl px-6 lg:px-8">
<div class="mx-auto max-w-2xl lg:max-w-none">
<dl class="grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-2 lg:grid-cols-4">
<%= turbo_frame_tag dom_id(@project, [hostname, :cpu_usage].join('-')),
src: project_dashboards_cpu_usage_path(project_id: @project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_cpu_usage_path(project_id: @project.token, hostname: hostname),
"data-refresh-interval-value": 30000 %>

<%= turbo_frame_tag dom_id(@project, [hostname, :memory_usage].join('-')),
src: project_dashboards_memory_usage_path(project_id: @project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_memory_usage_path(project_id: @project.token, hostname: hostname),
"data-refresh-interval-value": 30000 %>

<%= turbo_frame_tag dom_id(@project, [hostname, :disk_free].join('-')),
src: project_dashboards_disk_free_path(project_id: @project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_disk_free_path(project_id: @project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>

<%= turbo_frame_tag dom_id(@project, [hostname, :last_seen].join('-')),
src: project_dashboards_last_seen_path(project_id: @project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_last_seen_path(project_id: @project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>
</dl>
<dl class="mt-8 grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-1 lg:grid-cols-2">
<%= turbo_frame_tag dom_id(@project, [hostname, :cpu_history].join('-')),
src: project_dashboards_cpu_history_path(project_id: @project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_cpu_history_path(project_id: @project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>
<%= turbo_frame_tag dom_id(@project, [hostname, :memory_history].join('-')),
src: project_dashboards_memory_history_path(project_id: @project.token, hostname: hostname),
"data-controller": "refresh",
"data-refresh-src-value": project_dashboards_memory_history_path(project_id: @project.token, hostname: hostname),
"data-refresh-interval-value": 60000 %>
</dl>
</div>
</div>
<% end %>
<% @services.each do |hostname, _services| %>
<%= render partial: "mission_control/servers/projects/panels", locals: { project: @project, hostname: hostname }%>
<% end %>
<% end %>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
resource :last_seen, only: :show
resource :cpu_history, only: :show
resource :memory_history, only: :show
resource :combo_history, only: :show
end
end
root to: "projects#index"
Expand Down
2 changes: 1 addition & 1 deletion lib/mission_control/servers/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module MissionControl
module Servers
VERSION = "0.2.2"
VERSION = "0.2.3"
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require "test_helper"

module MissionControl::Servers
class Dashboards::ComboHistoriesControllerTest < ActionDispatch::IntegrationTest
include Engine.routes.url_helpers

# test "the truth" do
# assert true
# end
end
end

0 comments on commit 665804f

Please sign in to comment.