mission_control-servers 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +68 -10
  3. data/app/controllers/mission_control/servers/dashboards/cpu_histories_controller.rb +10 -0
  4. data/app/controllers/mission_control/servers/dashboards/cpu_usages_controller.rb +9 -0
  5. data/app/controllers/mission_control/servers/dashboards/disk_frees_controller.rb +9 -0
  6. data/app/controllers/mission_control/servers/dashboards/memory_histories_controller.rb +10 -0
  7. data/app/controllers/mission_control/servers/dashboards/memory_usages_controller.rb +9 -0
  8. data/app/controllers/mission_control/servers/dashboards/project_tables_controller.rb +7 -0
  9. data/app/controllers/mission_control/servers/ingresses_controller.rb +3 -2
  10. data/app/controllers/mission_control/servers/projects_controller.rb +12 -0
  11. data/app/controllers/mission_control/servers/scripts_controller.rb +52 -0
  12. data/app/helpers/mission_control/servers/application_helper.rb +4 -0
  13. data/app/helpers/mission_control/servers/dashboards/cpu_histories_helper.rb +4 -0
  14. data/app/helpers/mission_control/servers/dashboards/cpu_usages_helper.rb +4 -0
  15. data/app/helpers/mission_control/servers/dashboards/disk_frees_helper.rb +4 -0
  16. data/app/helpers/mission_control/servers/dashboards/memory_histories_helper.rb +4 -0
  17. data/app/helpers/mission_control/servers/dashboards/memory_usages_helper.rb +4 -0
  18. data/app/helpers/mission_control/servers/dashboards/project_tables_helper.rb +4 -0
  19. data/app/javascript/mission_control/servers/controllers/copy_controller.js +14 -0
  20. data/app/javascript/mission_control/servers/controllers/dialog_controller.js +13 -0
  21. data/app/javascript/mission_control/servers/controllers/line_chart_controller.js +29 -0
  22. data/app/javascript/mission_control/servers/controllers/pie_chart_controller.js +32 -0
  23. data/app/javascript/mission_control/servers/controllers/refresh_controller.js +66 -0
  24. data/app/models/mission_control/servers/service.rb +47 -0
  25. data/app/views/mission_control/servers/dashboards/cpu_histories/show.html.erb +15 -0
  26. data/app/views/mission_control/servers/dashboards/cpu_usages/show.html.erb +18 -0
  27. data/app/views/mission_control/servers/dashboards/disk_frees/show.html.erb +11 -0
  28. data/app/views/mission_control/servers/dashboards/memory_histories/show.html.erb +15 -0
  29. data/app/views/mission_control/servers/dashboards/memory_usages/show.html.erb +18 -0
  30. data/app/views/mission_control/servers/dashboards/project_tables/show.html.erb +39 -0
  31. data/app/views/mission_control/servers/projects/_form.html.erb +12 -13
  32. data/app/views/mission_control/servers/projects/index.html.erb +39 -13
  33. data/app/views/mission_control/servers/projects/new.html.erb +6 -6
  34. data/app/views/mission_control/servers/projects/show.html.erb +70 -109
  35. data/config/routes.rb +9 -0
  36. data/db/migrate/20240205020304_create_mission_control_servers_projects.rb +1 -1
  37. data/db/migrate/20240205031009_create_mission_control_servers_services.rb +2 -2
  38. data/lib/mission_control/servers/configuration.rb +13 -0
  39. data/lib/mission_control/servers/version.rb +1 -1
  40. data/lib/mission_control/servers.rb +12 -1
  41. metadata +27 -3
  42. data/app/views/mission_control/servers/projects/_project.html.erb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cfb3369ca36a1c1d3eff6ce91d7564b158e2c29bfecd78e04db95ad14fa5fb33
4
- data.tar.gz: ecf03b0b116e3c94181d0b0bd54b98365f5769d0eda3b92303d9945bb5f47edd
3
+ metadata.gz: e7f4ae5c47c0164182ee1d8ecf4e3745dbb360abeb2d6edf9aaf18a82600c004
4
+ data.tar.gz: 4762f538171344931546cb95a284fe7bd5bb9f6c804f3b0a42d63b2f2d1df302
5
5
  SHA512:
6
- metadata.gz: 5b9c7ffe3741a4d38940e389b89dab8f63bd362a7b460ef23cd21f656454b2e0ebceb3af648e3c91ee8bef295fb2fd2a6c803789afc09afde7e09d7a1465aac1
7
- data.tar.gz: b0d4c0d6affacf42d11c9c23047a90af99d189b6579945e165dd6fa3bc98a810da13b44a626704ed17251626c05c3a0132ac20d743475db8018934fd59b1440c
6
+ metadata.gz: 97e1618b50e48d513fd32d1fe98c33a84fbf9f9b1b7a3976ee2961b3eb34ffdc95391aee835da1f59cb13925f2938cfdb51d2b42c8ff8b6e26dda375c2727224
7
+ data.tar.gz: f0479dc129ab3266c591d13d040b0a8d8a6427d88eff466f72c14ddaf1ef9000c94190c8379d972ffca7b96eeb5d9f4f679e82123744b5eba5251893528364a4
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # MissionControl::Servers
2
- Don't use this yet. It will be a gem to monitor servers and send the data to Mission Control.
2
+ The goal of MissionControl::Servers is to provide a simple monitoring of the resources
3
+ on your Ruby on Rails application. You can either use this directly on the projects or create a separate Ruby on
4
+ Rails application to mount this in.
3
5
 
4
6
  ## Installation
5
7
  Add this line to your application's Gemfile:
@@ -9,26 +11,82 @@ bundle add "mission_control-servers"
9
11
  bin/rails mission_control_servers:install:migrations
10
12
  ```
11
13
 
14
+ Add a mount to your `config/routes.rb`
12
15
 
13
- # Usage
16
+ ```ruby
17
+ mount MissionControl::Servers::Engine => "/mission_control-servers"
18
+ ```
19
+
20
+ ## Configuration
14
21
 
15
- Use within your own Rails application or have a separate application to monitor your servers.
22
+ Within your application, you can make some configuration changes in how the gem operates. Below are the default
23
+ configuration options. You can override these options by creating an initializer file.
16
24
 
17
- You'll make a POST request to the endpoint with the following parameters:
25
+ For example, if you're wanting to use MissionControl::Servers in a single project, then there is no need to have
26
+ the ability to create multiple projects. You can set the `single_project_mode` to true which will hide the ability
27
+ to create new projects.
18
28
 
29
+ ```ruby
30
+ # config/initializers/mission_control_servers.rb
31
+ MissionControl::Servers.configure do |config|
32
+ config.single_project_mode = true
33
+ end
19
34
  ```
20
- endpoint="https://YOUR_APPLICATION/mission_control-servers/projects/YOUR_TOKEN/ingress"; cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1""}'); mem_free=$(free -m | awk '/^Mem:/ {print $2}'); mem_used=$(free -m | awk '/^Mem:/ {print $7}'); disk_free=$(df -h | awk '$NF=="/"{print $4}'); curl -X POST $endpoint -d "service[cpu]=$cpu_usage&service[mem_used]=$mem_free&service[mem_free]=$mem_used&service[disk_free]=$disk_free&service[hostname]=${hostname}"
35
+
36
+ ## Usage
37
+
38
+ Create a project. Once you create a project, you can easily copy the script specific to that project.
39
+
40
+ Install a script which captures:
41
+
42
+ - Hostname
43
+ - CPU Usage
44
+ - Memory Usage
45
+ - Free Memory
46
+ - Free Disk Space
47
+
48
+ The data will be retained for 7 days automatically. After 7 days, the data will start truncating itself
49
+ so that it doesn't take up much disk space within the database.
50
+
51
+ ## Protecting the Dashboard
52
+
53
+ You can protect the dashboard by using a constraint. This will allow you to only allow certain users to access
54
+ the dashboard. However, the ingress still needs to be accessible by the servers which are being monitored.
55
+
56
+ ```ruby
57
+ Rails.application.routes.draw do
58
+ constraints AdminConstraint do
59
+ mount MissionControl::Servers::Engine => "/mission_control-servers"
60
+ end
61
+ post '/mission_control-servers/projects/:project_id/ingress', to: 'mission_control/servers/ingresses#create'
62
+ end
21
63
  ```
22
64
 
23
- This script should be added to a cron job to run every minute (or however often you want to monitor your servers).
65
+ In this example, we have directly given a path to the ingress, but locked down everything else to the AdminConstraint.
66
+ The AdminConstraint takes in the request and calls the `matches?` method. If the method returns true,
67
+ then the routes will be defined for that request.
68
+
69
+ ```ruby
70
+ class AdminConstraint
71
+ def self.matches?(request)
72
+ true
73
+ end
74
+ end
75
+ ```
76
+
77
+ ## Screenshots
78
+
79
+ Simple Installation
80
+
81
+ ![ScreenShot-2024-02-06-08-50-39](https://github.com/kobaltz/mission_control-servers/assets/635114/78f96ff6-ac14-4798-96a5-59a59eff574c)
24
82
 
25
- Change `YOUR_APPLICATION` to your application's endpoint and `YOUR_TOKEN` to your project's token.
83
+ View all of your projects
26
84
 
27
- # Screenshots
85
+ ![ScreenShot-2024-02-06-21-34-07](https://github.com/kobaltz/mission_control-servers/assets/635114/6f524e6e-1d4d-4587-9949-f1f3c57724c8)
28
86
 
29
- These are going to change rapidly as the project is in development.
87
+ Detailed Dashboard updates automatically
30
88
 
31
- ![image](https://github.com/kobaltz/mission_control-servers/assets/635114/65a87ccf-8ce8-4164-b315-a08d065d8f8f)
89
+ ![ScreenShot-2024-02-06-22-21-15](https://github.com/kobaltz/mission_control-servers/assets/635114/320c57ad-64bf-4582-a680-c79c91e62b60)
32
90
 
33
91
  ## License
34
92
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,10 @@
1
+ module MissionControl::Servers
2
+ class Dashboards::CpuHistoriesController < ApplicationController
3
+ def show
4
+ @project = MissionControl::Servers::Project.find_by(token: params[:project_id])
5
+ @hostname = params[:hostname]
6
+ services = @project.services.where(hostname: @hostname).ordered
7
+ @cpu_history_data = MissionControl::Servers::Service.cpu_usage_history(services)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module MissionControl::Servers
2
+ class Dashboards::CpuUsagesController < ApplicationController
3
+ def show
4
+ @project = MissionControl::Servers::Project.find_by(token: params[:project_id])
5
+ @hostname = params[:hostname]
6
+ @service = @project.services.where(hostname: @hostname).last
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module MissionControl::Servers
2
+ class Dashboards::DiskFreesController < ApplicationController
3
+ def show
4
+ @project = MissionControl::Servers::Project.find_by(token: params[:project_id])
5
+ @hostname = params[:hostname]
6
+ @service = @project.services.where(hostname: @hostname).last
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module MissionControl::Servers
2
+ class Dashboards::MemoryHistoriesController < ApplicationController
3
+ def show
4
+ @project = MissionControl::Servers::Project.find_by(token: params[:project_id])
5
+ @hostname = params[:hostname]
6
+ services = @project.services.where(hostname: @hostname).ordered
7
+ @memory_history_data = MissionControl::Servers::Service.memory_usage_history(services)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module MissionControl::Servers
2
+ class Dashboards::MemoryUsagesController < ApplicationController
3
+ def show
4
+ @project = MissionControl::Servers::Project.find_by(token: params[:project_id])
5
+ @hostname = params[:hostname]
6
+ @service = @project.services.where(hostname: @hostname).last
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module MissionControl::Servers
2
+ class Dashboards::ProjectTablesController < ApplicationController
3
+ def show
4
+ @project = Project.includes(:services).find_by(token: params[:project_id])
5
+ end
6
+ end
7
+ end
@@ -4,9 +4,10 @@ module MissionControl::Servers
4
4
  before_action :set_project
5
5
 
6
6
  def create
7
- @ingress = @project.services.new(ingress_params)
7
+ head :unprocessable_entity and return unless @project
8
+ ingress = @project.services.new(ingress_params)
8
9
 
9
- if @ingress.save!
10
+ if ingress.save!
10
11
  head :ok
11
12
  else
12
13
  head :unprocessable_entity
@@ -1,6 +1,7 @@
1
1
  module MissionControl::Servers
2
2
  class ProjectsController < ApplicationController
3
3
  before_action :set_project, only: %i[ show edit update destroy ]
4
+ before_action :verify_single_project_mode, only: %i[ new create ]
4
5
 
5
6
  # GET /projects
6
7
  def index
@@ -9,6 +10,11 @@ module MissionControl::Servers
9
10
 
10
11
  # GET /projects/1
11
12
  def show
13
+ @services = if params[:hostname]
14
+ @project.services.where(hostname: params[:hostname]).group_by(&:hostname)
15
+ else
16
+ @project.services.group_by(&:hostname)
17
+ end
12
18
  end
13
19
 
14
20
  # GET /projects/new
@@ -47,6 +53,12 @@ module MissionControl::Servers
47
53
  end
48
54
 
49
55
  private
56
+ def verify_single_project_mode
57
+ if MissionControl::Servers.configuration.single_project_mode && Project.any?
58
+ redirect_to projects_url, notice: "Single project mode is enabled. You can only have one project at a time."
59
+ end
60
+ end
61
+
50
62
  # Use callbacks to share common setup or constraints between actions.
51
63
  def set_project
52
64
  @project = Project.find(params[:id])
@@ -0,0 +1,52 @@
1
+ module MissionControl::Servers
2
+ class ScriptsController < ApplicationController
3
+ before_action :set_project
4
+
5
+ def show
6
+ head :not_found and return unless @project
7
+ response.content_type = 'text/plain'
8
+
9
+ # Render the script directly or from a file
10
+ render plain: script_content
11
+ end
12
+
13
+ private
14
+ # Use callbacks to share common setup or constraints between actions.
15
+ def set_project
16
+ @project = Project.find_by(token: params[:project_id])
17
+ end
18
+
19
+ def script_content
20
+ <<~SCRIPT
21
+ cat <<'EOF' > metrics.sh
22
+ #!/bin/bash
23
+
24
+ endpoint="#{project_ingress_url(@project.token)}"
25
+ cpu_usage=$(
26
+ top -bn1 | \
27
+ grep "Cpu(s)" | \
28
+ sed "s/.*, *\\([0-9.]*\\)%* id.*/\\1/" | \
29
+ awk '{print 100 - $1}'
30
+ )
31
+ mem_used=$(free -m | awk '/^Mem:/ {print $3}')
32
+ mem_free=$(free -m | awk '/^Mem:/ {print $7}')
33
+ disk_free=$(df -h | awk '\$NF=="/"{print $4}')
34
+ hostname=$(hostname)
35
+
36
+ data="service[cpu]=$cpu_usage"
37
+ data+="&service[mem_used]=$mem_used"
38
+ data+="&service[mem_free]=$mem_free"
39
+ data+="&service[disk_free]=$disk_free"
40
+ data+="&service[hostname]=$hostname"
41
+
42
+ curl -X POST $endpoint -d $data
43
+ EOF
44
+
45
+ chmod +x metrics.sh
46
+
47
+ cron_job="* * * * * $(pwd)/metrics.sh"
48
+ (crontab -l 2>/dev/null | grep -v -F "$cron_job"; echo "$cron_job") | crontab -
49
+ SCRIPT
50
+ end
51
+ end
52
+ end
@@ -1,6 +1,10 @@
1
1
  module MissionControl
2
2
  module Servers
3
3
  module ApplicationHelper
4
+ def allowed_to_create_project?
5
+ !MissionControl::Servers.configuration.single_project_mode ||
6
+ (MissionControl::Servers.configuration.single_project_mode && !@projects.present?)
7
+ end
4
8
  end
5
9
  end
6
10
  end
@@ -0,0 +1,4 @@
1
+ module MissionControl::Servers
2
+ module Dashboards::CpuHistoriesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MissionControl::Servers
2
+ module Dashboards::CpuUsagesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MissionControl::Servers
2
+ module Dashboards::DiskFreesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MissionControl::Servers
2
+ module Dashboards::MemoryHistoriesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MissionControl::Servers
2
+ module Dashboards::MemoryUsagesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MissionControl::Servers
2
+ module Dashboards::ProjectTablesHelper
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+
3
+ export default class extends Controller {
4
+ static targets = ["source"];
5
+
6
+ copy(event) {
7
+ const text = this.sourceTarget.textContent;
8
+ navigator.clipboard.writeText(text).then(() => {
9
+ event.target.textContent = "Copied!";
10
+ }).catch(err => {
11
+ console.error('Failed to copy text: ', err);
12
+ });
13
+ }
14
+ }
@@ -0,0 +1,13 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+
3
+ export default class extends Controller {
4
+ static targets = ["modal"]
5
+
6
+ show() {
7
+ this.modalTarget.classList.remove("hidden");
8
+ }
9
+
10
+ hide() {
11
+ this.modalTarget.classList.add("hidden");
12
+ }
13
+ }
@@ -0,0 +1,29 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static values = {
5
+ label: "Chart",
6
+ labelArray: Array,
7
+ dataArray: Array,
8
+ color: "rgb(54, 162, 235)"
9
+ }
10
+ connect() {
11
+ new Chart(this.element, {
12
+ type: 'line',
13
+ data: {
14
+ labels: this.labelArrayValue,
15
+ datasets: [{
16
+ label: this.labelValue,
17
+ data: this.dataArrayValue,
18
+ fill: true,
19
+ borderColor: this.colorValue,
20
+ tension: 0.25
21
+ }]
22
+ },
23
+ options: {
24
+ animation: false
25
+ }
26
+ });
27
+ }
28
+
29
+ }
@@ -0,0 +1,32 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static values = {
5
+ label: "Chart",
6
+ idle: Number,
7
+ used: Number,
8
+ idleLabel: String,
9
+ usedLabel: String,
10
+ idleColor: "rgb(235, 235, 235)",
11
+ usedColor: "rgb(54, 162, 235)"
12
+ }
13
+ connect() {
14
+ const ctx = this.element
15
+ new Chart(ctx, {
16
+ type: 'doughnut',
17
+ data: {
18
+ labels: [this.usedLabelValue, this.idleLabelValue],
19
+ datasets: [
20
+ {
21
+ label: this.labelValue,
22
+ data: [this.usedValue, this.idleValue],
23
+ backgroundColor: [this.usedColorValue,this.idleColorValue],
24
+ hoverOffset: 4
25
+ }
26
+ ]
27
+ },
28
+ options: { animation: false }
29
+ });
30
+ }
31
+
32
+ }
@@ -0,0 +1,66 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static values = {
5
+ src: String,
6
+ interval: 60000
7
+ }
8
+
9
+ static targets = ["progressBar"]
10
+
11
+ connect() {
12
+ this.startRefreshProcess()
13
+ if (this.hasProgressBarTarget) {
14
+ this.resetProgressBar()
15
+ } else {
16
+ setTimeout(() => {
17
+ this.resetProgressBar()
18
+ }, 500)
19
+ }
20
+ }
21
+
22
+ disconnect() {
23
+ this.stopRefreshProcess()
24
+ }
25
+
26
+ startRefreshProcess() {
27
+ this.intervalId = setInterval(() => {
28
+ this.refreshContent()
29
+ }, this.intervalValue)
30
+ }
31
+
32
+ stopRefreshProcess() {
33
+ clearInterval(this.intervalId)
34
+ clearInterval(this.countdownId)
35
+ }
36
+
37
+ refreshContent() {
38
+ if (this.element.src) {
39
+ this.element.reload()
40
+ } else {
41
+ this.element.setAttribute('src', this.srcValue)
42
+ }
43
+ this.resetProgressBar()
44
+ }
45
+
46
+ startProgressBar() {
47
+ let percentage = 100
48
+ this.progressBarTarget.style.width = `${percentage}%`
49
+
50
+ const countdown = () => {
51
+ percentage -= 100 / (this.intervalValue / 500)
52
+ this.progressBarTarget.style.width = `${percentage}%`
53
+
54
+ if (percentage <= 0) {
55
+ clearInterval(this.countdownId)
56
+ }
57
+ }
58
+
59
+ this.countdownId = setInterval(countdown, 500)
60
+ }
61
+
62
+ resetProgressBar() {
63
+ clearInterval(this.countdownId)
64
+ this.startProgressBar()
65
+ }
66
+ }
@@ -1,5 +1,52 @@
1
1
  module MissionControl::Servers
2
2
  class Service < ApplicationRecord
3
3
  belongs_to :project
4
+ after_create :trim_old_records
5
+
6
+ scope :ordered, -> { order(created_at: :desc) }
7
+
8
+ def self.cpu_usage_history(services, start_time: 1.hour.ago, end_time: Time.now.utc)
9
+ timestamps = (start_time.to_i..end_time.to_i).step(60).map { |t| Time.at(t).utc.change(sec: 0).to_i }
10
+ grouped_services = services.group_by { |service| service.created_at.utc.change(sec: 0).to_i }
11
+
12
+ cpu_usages = []
13
+ created_at_times = []
14
+
15
+ timestamps.each do |timestamp|
16
+ relevant_services = grouped_services[timestamp] || []
17
+ max_cpu_service = relevant_services.max_by(&:cpu)
18
+ cpu_usages << (max_cpu_service&.cpu || 0).to_f
19
+ created_at_times << Time.at(timestamp).utc.strftime('%H:%M%p')
20
+ end
21
+
22
+ { cpu_usages: cpu_usages, created_at_times: created_at_times }
23
+ end
24
+
25
+ def self.memory_usage_history(services, start_time: 1.hour.ago, end_time: Time.now.utc)
26
+ timestamps = (start_time.to_i..end_time.to_i).step(60).map { |t| Time.at(t).utc.change(sec: 0).to_i }
27
+ grouped_services = services.group_by { |service| service.created_at.utc.change(sec: 0).to_i }
28
+
29
+ memory_usages = []
30
+ created_at_times = []
31
+
32
+ timestamps.each do |timestamp|
33
+ relevant_services = grouped_services[timestamp] || []
34
+ max_memory_service = relevant_services.max_by(&:mem_used)
35
+ memory_usages << (max_memory_service&.mem_used || 0).to_f
36
+ created_at_times << Time.at(timestamp).utc.strftime('%H:%M%p')
37
+ end
38
+
39
+ { memory_usages: memory_usages, created_at_times: created_at_times }
40
+ end
41
+
42
+ def mem_percent
43
+ (mem_used.to_f / (mem_used.to_f + mem_free.to_f) * 100).to_i
44
+ end
45
+
46
+ private
47
+
48
+ def trim_old_records
49
+ project.services.where(hostname: hostname).where(created_at: ..1.week.ago).delete_all
50
+ end
4
51
  end
5
52
  end
@@ -0,0 +1,15 @@
1
+ <%= turbo_frame_tag dom_id(@project, [@hostname, :cpu_history].join('-')) do %>
2
+ <div class="progress-bar bg-gray-300" style="height: 5px; width: 100%;">
3
+ <div class="progress bg-blue-500" data-refresh-target="progressBar" style="height: 100%; width: 100%;"></div>
4
+ </div>
5
+ <div class="flex flex-col bg-gray-400/5 p-8">
6
+ <dt class="text-sm font-semibold leading-6 text-gray-600">
7
+ <canvas data-controller="line-chart"
8
+ data-line-chart-label-value="CPU History"
9
+ data-line-chart-label-array-value="<%= @cpu_history_data[:created_at_times] %>"
10
+ data-line-chart-data-array-value="<%= @cpu_history_data[:cpu_usages] %>"
11
+ data-line-chart-color-value="rgb(54, 162, 235)"></canvas>
12
+ </dt>
13
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">CPU History</dd>
14
+ </div>
15
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <%= turbo_frame_tag dom_id(@project, [@hostname, :cpu_usage].join('-')) do %>
2
+ <div class="progress-bar bg-gray-300" style="height: 5px; width: 100%;">
3
+ <div class="progress bg-blue-500" data-refresh-target="progressBar" style="height: 100%; width: 100%;"></div>
4
+ </div>
5
+ <div class="flex flex-col bg-gray-400/5 p-8">
6
+ <dt class="text-sm font-semibold leading-6 text-gray-600">
7
+ <canvas data-controller="pie-chart"
8
+ data-pie-chart-label-value="CPU Usage"
9
+ data-pie-chart-idle-value="<%= 100.0 - @service.cpu %>"
10
+ data-pie-chart-idle-label-value="Idle"
11
+ data-pie-chart-idle-color-value="rgb(235, 235, 235)"
12
+ data-pie-chart-used-value="<%= @service.cpu %>"
13
+ data-pie-chart-used-label-value="Active"
14
+ data-pie-chart-used-color-value="rgb(54, 162, 235)"></canvas>
15
+ </dt>
16
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">CPU Usage</dd>
17
+ </div>
18
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <%= turbo_frame_tag dom_id(@project, [@hostname, :disk_free].join('-')) do %>
2
+ <div class="progress-bar bg-gray-300" style="height: 5px; width: 100%;">
3
+ <div class="progress bg-blue-500" data-refresh-target="progressBar" style="height: 100%; width: 100%;"></div>
4
+ </div>
5
+ <div class="flex flex-col bg-gray-400/5 p-8">
6
+ <dt class="text-6xl font-semibold leading-6 mt-5 text-gray-600">
7
+ <%= @service.disk_free %>
8
+ </dt>
9
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">Disk Free</dd>
10
+ </div>
11
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <%= turbo_frame_tag dom_id(@project, [@hostname, :memory_history].join('-')) do %>
2
+ <div class="progress-bar bg-gray-300" style="height: 5px; width: 100%;">
3
+ <div class="progress bg-blue-500" data-refresh-target="progressBar" style="height: 100%; width: 100%;"></div>
4
+ </div>
5
+ <div class="flex flex-col bg-gray-400/5 p-8">
6
+ <dt class="text-sm font-semibold leading-6 text-gray-600">
7
+ <canvas data-controller="line-chart"
8
+ data-line-chart-label-value="Memory Used History"
9
+ data-line-chart-label-array-value="<%= @memory_history_data[:created_at_times] %>"
10
+ data-line-chart-data-array-value="<%= @memory_history_data[:memory_usages] %>"
11
+ data-line-chart-color-value="rgb(54, 162, 235)"></canvas>
12
+ </dt>
13
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">Memory Used History</dd>
14
+ </div>
15
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <%= turbo_frame_tag dom_id(@project, [@hostname, :memory_usage].join('-')) do %>
2
+ <div class="progress-bar bg-gray-300" style="height: 5px; width: 100%;">
3
+ <div class="progress bg-blue-500" data-refresh-target="progressBar" style="height: 100%; width: 100%;"></div>
4
+ </div>
5
+ <div class="flex flex-col bg-gray-400/5 p-8">
6
+ <dt class="text-sm font-semibold leading-6 text-gray-600">
7
+ <canvas data-controller="pie-chart"
8
+ data-pie-chart-label-value="Memory Usage"
9
+ data-pie-chart-idle-value="<%= @service.mem_free %>"
10
+ data-pie-chart-idle-label-value="Idle"
11
+ data-pie-chart-idle-color-value="rgb(235, 235, 235)"
12
+ data-pie-chart-used-value="<%= @service.mem_used %>"
13
+ data-pie-chart-used-label-value="Active"
14
+ data-pie-chart-used-color-value="rgb(54, 162, 235)"></canvas>
15
+ </dt>
16
+ <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">Memory Usage</dd>
17
+ </div>
18
+ <% end %>
@@ -0,0 +1,39 @@
1
+ <%= turbo_frame_tag dom_id(@project, "table") do %>
2
+ <div class="mx-4 my-4 ring-1 ring-gray-300 sm:mx-0 sm:rounded-lg">
3
+ <div class="progress-bar ring-1 ring-gray-300 sm:mx-0 sm:rounded-lg bg-gray-300" style="height: 5px; width: 100%;">
4
+ <div class="progress bg-blue-500 ring-1 ring-gray-300 sm:mx-0 sm:rounded-lg" data-refresh-target="progressBar" style="height: 100%; width: 100%;"></div>
5
+ </div>
6
+ <table class="min-w-full divide-y divide-gray-300">
7
+ <thead>
8
+ <tr>
9
+ <th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Hostname</th>
10
+ <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">CPU Usage</th>
11
+ <th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Memory Used</th>
12
+ <th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Memory Used %</th>
13
+ <th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Memory Free</th>
14
+ <th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Disk Free</th>
15
+ <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
16
+ <span class="sr-only">Select</span>
17
+ </th>
18
+ </tr>
19
+ </thead>
20
+ <tbody>
21
+ <% @project.services.group_by(&:hostname).each do |hostname, services| %>
22
+ <tr>
23
+ <td class="relative py-4 pl-4 pr-3 text-sm sm:pl-6">
24
+ <div class="font-medium text-gray-900"><%= hostname%></div>
25
+ </td>
26
+ <td class="px-3 py-3.5 text-sm text-gray-500 lg:table-cell"><%= services.last.cpu %>%</td>
27
+ <td class="hidden px-3 py-3.5 text-sm text-gray-500 lg:table-cell"><%= number_to_human_size(services.last.mem_used * 1.megabyte) %></td>
28
+ <td class="hidden px-3 py-3.5 text-sm text-gray-500 lg:table-cell"><%= services.last.mem_percent %>%</td>
29
+ <td class="hidden px-3 py-3.5 text-sm text-gray-500 lg:table-cell"><%= number_to_human_size(services.last.mem_free * 1.megabyte) %></td>
30
+ <td class="hidden px-3 py-3.5 text-sm text-gray-500 lg:table-cell"><%= services.last.disk_free %></td>
31
+ <td class="relative py-3.5 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
32
+ <%= link_to "Dashboard", project_path(@project, hostname: hostname), class: "inline-flex items-center rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-30 disabled:hover:bg-white" %>
33
+ </td>
34
+ </tr>
35
+ <% end %>
36
+ </tbody>
37
+ </table>
38
+ </div>
39
+ <% end %>
@@ -1,9 +1,9 @@
1
- <%= form_with(model: project) do |form| %>
1
+ <%= form_with(model: project, class: "max-w-lg mx-auto my-10") do |form| %>
2
2
  <% if project.errors.any? %>
3
- <div style="color: red">
4
- <h2><%= pluralize(project.errors.count, "error") %> prohibited this project from being saved:</h2>
5
-
6
- <ul>
3
+ <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
4
+ <strong class="font-bold">Oops!</strong>
5
+ <span class="block sm:inline"><%= pluralize(project.errors.count, "error") %> prohibited this project from being saved:</span>
6
+ <ul class="list-disc list-inside mt-2">
7
7
  <% project.errors.each do |error| %>
8
8
  <li><%= error.full_message %></li>
9
9
  <% end %>
@@ -11,17 +11,16 @@
11
11
  </div>
12
12
  <% end %>
13
13
 
14
- <div>
15
- <%= form.label :title, style: "display: block" %>
16
- <%= form.text_field :title %>
14
+ <div class="mb-4">
15
+ <%= form.label :title, class: "block text-gray-700 text-sm font-bold mb-2" %>
16
+ <%= form.text_field :title, class: "shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" %>
17
17
  </div>
18
18
 
19
- <div>
20
- <%= form.label :token, style: "display: block" %>
21
- <%= form.text_field :token %>
19
+ <div class="mb-6">
20
+ <%= form.hidden_field :token %>
22
21
  </div>
23
22
 
24
- <div>
25
- <%= form.submit %>
23
+ <div class="flex items-center justify-between">
24
+ <%= form.submit class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" %>
26
25
  </div>
27
26
  <% end %>
@@ -1,14 +1,40 @@
1
- <p style="color: green"><%= notice %></p>
2
-
3
- <h1>Projects</h1>
4
-
5
- <div id="projects">
6
- <% @projects.each do |project| %>
7
- <%= render project %>
8
- <p>
9
- <%= link_to "Show this project", project %>
10
- </p>
11
- <% end %>
1
+ <div class="px-4 sm:px-6 lg:px-8">
2
+ <div class="sm:flex sm:items-center">
3
+ <div class="sm:flex-auto">
4
+ <h1 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">Projects</h1>
5
+ <p class="mt-2 text-sm text-gray-700">Resource monitor for your Ruby on Rails applications.</p>
6
+ </div>
7
+ <div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
8
+ <% if allowed_to_create_project? %>
9
+ <%= link_to "New project", new_project_path, class: "block rounded-md bg-indigo-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" %>
10
+ <% end %>
11
+ </div>
12
+ </div>
13
+ <div class="mt-8 flow-root">
14
+ <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
15
+ <div class="inline-block min-w-full py-2 align-middle">
16
+ <table class="min-w-full divide-y divide-gray-300">
17
+ <tbody class="divide-y divide-gray-200 bg-white">
18
+ <% @projects.each do |project| %>
19
+ <tr>
20
+ <td class="whitespace-nowrap text-2xl font-bold tracking-tight text-gray-900 sm:text-3xl"><%= project.title %></td>
21
+ <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
22
+ <%= link_to "Dashboards", project, class: "rounded-md bg-indigo-50 px-2.5 py-1.5 text-sm font-semibold text-indigo-600 shadow-sm hover:bg-indigo-100" %>
23
+ </td>
24
+ </tr>
25
+ <tr>
26
+ <td colspan=2>
27
+ <%= turbo_frame_tag dom_id(project, "table"),
28
+ src: project_dashboards_project_table_path(project.token),
29
+ "data-controller": "refresh",
30
+ "data-refresh-src-value": project_dashboards_project_table_path(project.token),
31
+ "data-refresh-interval-value": 60000 %>
32
+ </td>
33
+ </tr>
34
+ <% end %>
35
+ </tbody>
36
+ </table>
37
+ </div>
38
+ </div>
39
+ </div>
12
40
  </div>
13
-
14
- <%= link_to "New project", new_project_path %>
@@ -1,9 +1,9 @@
1
- <h1>New project</h1>
1
+ <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 my-10">
2
+ <h1 class="text-2xl text-center font-semibold text-gray-900 mb-8">New Project</h1>
2
3
 
3
- <%= render "form", project: @project %>
4
+ <%= render "form", project: @project %>
4
5
 
5
- <br>
6
-
7
- <div>
8
- <%= link_to "Back to projects", projects_path %>
6
+ <div class="text-center mt-6">
7
+ <%= link_to "Back to projects", projects_path, class: "text-blue-600 hover:text-blue-800 transition duration-150 ease-in-out" %>
8
+ </div>
9
9
  </div>
@@ -1,128 +1,89 @@
1
1
  <div class="lg:flex lg:items-center lg:justify-between">
2
2
  <div class="min-w-0 flex-1">
3
3
  <h2 class="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight"><%= @project.title %></h2>
4
- <div class="mt-1 flex flex-col sm:mt-0 sm:flex-row sm:flex-wrap sm:space-x-6">
5
- <div class="mt-2 flex items-center text-sm text-gray-500">
6
- <svg class="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
7
- <path fill-rule="evenodd" d="M9.69 18.933l.003.001C9.89 19.02 10 19 10 19s.11.02.308-.066l.002-.001.006-.003.018-.008a5.741 5.741 0 00.281-.14c.186-.096.446-.24.757-.433.62-.384 1.445-.966 2.274-1.765C15.302 14.988 17 12.493 17 9A7 7 0 103 9c0 3.492 1.698 5.988 3.355 7.584a13.731 13.731 0 002.273 1.765 11.842 11.842 0 00.976.544l.062.029.018.008.006.003zM10 11.25a2.25 2.25 0 100-4.5 2.25 2.25 0 000 4.5z" clip-rule="evenodd" />
8
- </svg>
9
- <%= link_to project_ingress_url(@project), project_ingress_url(@project) %>
10
- </div>
11
- </div>
12
4
  </div>
13
5
 
14
6
  <div class="mt-5 flex lg:ml-4 lg:mt-0">
15
7
  <span class="hidden sm:block">
16
8
  <%= link_to edit_project_path(@project), class: "inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" do %>
17
- <svg class="-ml-0.5 mr-1.5 h-5 w-5 text-gray-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
18
- <path d="M2.695 14.763l-1.262 3.154a.5.5 0 00.65.65l3.155-1.262a4 4 0 001.343-.885L17.5 5.5a2.121 2.121 0 00-3-3L3.58 13.42a4 4 0 00-.885 1.343z" />
19
- </svg>
20
9
  Edit
21
10
  <% end %>
11
+ <%= link_to projects_path, class: "inline-flex items-center rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" do %>
12
+ Projects
13
+ <% end %>
14
+
15
+ <span data-controller="dialog copy">
16
+ <button data-action="click->dialog#show" class="rounded-md bg-indigo-50 px-2.5 py-1.5 text-sm font-semibold text-indigo-600 shadow-sm hover:bg-indigo-100">
17
+ Deploy
18
+ </button>
19
+ <div data-dialog-target="modal" class="hidden fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
20
+ <div data-action="click->dialog#hide" class="fixed inset-0 bg-gray-500 bg-opacity-75"></div>
21
+ <div class="flex items-end justify-center min-h-full p-4 text-center sm:items-center">
22
+ <div class="relative bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 md:max-w-3xl sm:w-full">
23
+ <div class="px-4 pt-5 pb-4 sm:p-6">
24
+ <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">Installation Instructions</h3>
25
+ <div class="mt-2">
26
+ <p class="text-sm text-gray-500">
27
+ You'll make a cURL request from each server that you want to monitor.
28
+ Copy and paste the script below to each server to start sending metrics to your dashboard.
29
+ </p>
30
+ <button data-action="click->copy#copy" class="rounded-md bg-blue-500 mt-4 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-600">
31
+ Copy
32
+ </button>
33
+ <pre data-copy-target="source" class="bg-gray-700 text-white p-4 mt-4 text-sm overflow-x-auto">curl -sSL <%= project_script_url(@project.token) %> | sh</pre>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </span>
40
+
22
41
  </span>
23
42
  </div>
24
43
  </div>
25
44
 
45
+ <% @services.each do |hostname, services| %>
46
+ <div class="bg-white py-4 sm:py-8">
47
+ <div class="mx-auto max-w-7xl px-6 lg:px-8">
48
+ <div class="mx-auto max-w-2xl lg:max-w-none">
49
+ <div class="text-center">
50
+ <h2 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl"><%= hostname %></h2>
51
+ </div>
52
+ <dl class="mt-8 grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-2 lg:grid-cols-3">
53
+ <%= turbo_frame_tag dom_id(@project, [hostname, :cpu_usage].join('-')),
54
+ src: project_dashboards_cpu_usage_path(project_id: @project.token, hostname: hostname),
55
+ "data-controller": "refresh",
56
+ "data-refresh-src-value": project_dashboards_cpu_usage_path(project_id: @project.token, hostname: hostname),
57
+ "data-refresh-interval-value": 30000 %>
58
+
59
+ <%= turbo_frame_tag dom_id(@project, [hostname, :memory_usage].join('-')),
60
+ src: project_dashboards_memory_usage_path(project_id: @project.token, hostname: hostname),
61
+ "data-controller": "refresh",
62
+ "data-refresh-src-value": project_dashboards_memory_usage_path(project_id: @project.token, hostname: hostname),
63
+ "data-refresh-interval-value": 30000 %>
26
64
 
27
- <div class="bg-white py-24 sm:py-32">
28
- <div class="mx-auto max-w-7xl px-6 lg:px-8">
29
- <div class="mx-auto max-w-2xl lg:max-w-none">
30
- <div class="text-center">
31
- <h2 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">web server 1</h2>
65
+ <%= turbo_frame_tag dom_id(@project, [hostname, :disk_free].join('-')),
66
+ src: project_dashboards_disk_free_path(project_id: @project.token, hostname: hostname),
67
+ "data-controller": "refresh",
68
+ "data-refresh-src-value": project_dashboards_disk_free_path(project_id: @project.token, hostname: hostname),
69
+ "data-refresh-interval-value": 60000 %>
70
+ </dl>
71
+ <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">
72
+ <%= turbo_frame_tag dom_id(@project, [hostname, :cpu_history].join('-')),
73
+ src: project_dashboards_cpu_history_path(project_id: @project.token, hostname: hostname),
74
+ "data-controller": "refresh",
75
+ "data-refresh-src-value": project_dashboards_cpu_history_path(project_id: @project.token, hostname: hostname),
76
+ "data-refresh-interval-value": 60000 %>
77
+ </dl>
78
+ <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">
79
+ <%= turbo_frame_tag dom_id(@project, [hostname, :memory_history].join('-')),
80
+ src: project_dashboards_memory_history_path(project_id: @project.token, hostname: hostname),
81
+ "data-controller": "refresh",
82
+ "data-refresh-src-value": project_dashboards_memory_history_path(project_id: @project.token, hostname: hostname),
83
+ "data-refresh-interval-value": 60000 %>
84
+ </dl>
32
85
  </div>
33
- <dl class="mt-8 grid grid-cols-1 gap-0.5 overflow-hidden rounded-2xl text-center sm:grid-cols-2 lg:grid-cols-3">
34
- <div class="flex flex-col bg-gray-400/5 p-8">
35
- <dt class="text-sm font-semibold leading-6 text-gray-600">
36
- <canvas id="cpuUsage"></canvas>
37
- </dt>
38
- <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">CPU Usage</dd>
39
- </div>
40
- <div class="flex flex-col bg-gray-400/5 p-8">
41
- <dt class="text-sm font-semibold leading-6 text-gray-600">
42
- <canvas id="freeMemory"></canvas>
43
- </dt>
44
- <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">Memory Usage</dd>
45
- </div>
46
- <div class="flex flex-col bg-gray-400/5 p-8">
47
- <dt class="text-6xl font-semibold leading-6 mt-5 text-gray-600">
48
- 918Gi
49
- </dt>
50
- <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">Disk Free</dd>
51
- </div>
52
- </dl>
53
- <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">
54
- <div class="flex flex-col bg-gray-400/5 p-8">
55
- <dt class="text-sm font-semibold leading-6 text-gray-600">
56
- <canvas id="cpuHistory"></canvas>
57
- </dt>
58
- <dd class="order-first text-3xl font-semibold tracking-tight text-gray-900">CPU History</dd>
59
- </div>
60
- </dl>
61
86
  </div>
62
87
  </div>
63
- </div>
64
-
65
-
66
- <script>
67
- var ctx = document.getElementById('cpuHistory');
68
-
69
- new Chart(ctx, {
70
- type: 'line',
71
- data: {
72
- labels: ['9:01pm', '9:02pm', '9:03pm', '9:04pm', '9:05pm', '9:06pm', '9:07pm'],
73
- datasets: [{
74
- label: 'CPU Usage',
75
- data: [65, 59, 80, 81, 56, 55, 40],
76
- fill: true,
77
- borderColor: 'rgb(75, 192, 192)',
78
- tension: 0.1
79
- }]
80
- }
81
- });
82
- </script>
83
-
84
- <script>
85
- var ctx = document.getElementById('freeMemory');
86
-
87
- new Chart(ctx, {
88
- type: 'doughnut',
89
- data: {
90
- labels: [
91
- 'Used',
92
- 'Free'
93
- ],
94
- datasets: [{
95
- label: 'Memory',
96
- data: [300, 100],
97
- backgroundColor: [
98
- 'rgb(255, 99, 132)',
99
- 'rgb(54, 162, 235)'
100
- ],
101
- hoverOffset: 4
102
- }]
103
- }
104
- });
105
- </script>
106
-
107
- <script>
108
- var ctx = document.getElementById('cpuUsage');
88
+ <% end %>
109
89
 
110
- new Chart(ctx, {
111
- type: 'doughnut',
112
- data: {
113
- labels: [
114
- 'Active',
115
- 'Idle'
116
- ],
117
- datasets: [{
118
- label: 'CPU Usage',
119
- data: [300, 100],
120
- backgroundColor: [
121
- 'rgb(54, 162, 235)',
122
- 'rgb(235, 235, 235)'
123
- ],
124
- hoverOffset: 4
125
- }]
126
- }
127
- });
128
- </script>
data/config/routes.rb CHANGED
@@ -1,6 +1,15 @@
1
1
  MissionControl::Servers::Engine.routes.draw do
2
2
  resources :projects do
3
3
  resource :ingress, only: :create
4
+ resource :script, only: :show
5
+ namespace :dashboards do
6
+ resource :project_table, only: :show
7
+ resource :cpu_usage, only: :show
8
+ resource :memory_usage, only: :show
9
+ resource :disk_free, only: :show
10
+ resource :cpu_history, only: :show
11
+ resource :memory_history, only: :show
12
+ end
4
13
  end
5
14
  root to: "projects#index"
6
15
  end
@@ -2,7 +2,7 @@ class CreateMissionControlServersProjects < ActiveRecord::Migration[7.1]
2
2
  def change
3
3
  create_table :mission_control_servers_projects do |t|
4
4
  t.string :title
5
- t.string :token
5
+ t.string :token, index: { unique: true }
6
6
 
7
7
  t.timestamps
8
8
  end
@@ -2,11 +2,11 @@ class CreateMissionControlServersServices < ActiveRecord::Migration[7.1]
2
2
  def change
3
3
  create_table :mission_control_servers_services do |t|
4
4
  t.belongs_to :project, null: false, foreign_key: { to_table: :mission_control_servers_projects }
5
- t.string :hostname
5
+ t.string :hostname, index: true, null: false
6
6
  t.decimal :cpu, precision: 8, scale: 2
7
7
  t.decimal :mem_used, precision: 8, scale: 2
8
8
  t.decimal :mem_free, precision: 8, scale: 2
9
- t.decimal :disk_free, precision: 8, scale: 2
9
+ t.string :disk_free
10
10
 
11
11
  t.timestamps
12
12
  end
@@ -0,0 +1,13 @@
1
+ module MissionControl
2
+ module Servers
3
+ class Configuration
4
+
5
+ attr_accessor :single_project_mode
6
+
7
+ def initialize
8
+ @single_project_mode = true
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,5 @@
1
1
  module MissionControl
2
2
  module Servers
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -1,5 +1,6 @@
1
1
  require "mission_control/servers/version"
2
2
  require "mission_control/servers/engine"
3
+ require "mission_control/servers/configuration"
3
4
 
4
5
  require "zeitwerk"
5
6
 
@@ -10,6 +11,16 @@ loader.setup
10
11
 
11
12
  module MissionControl
12
13
  module Servers
13
- # Your code goes here...
14
+ class << self
15
+ attr_writer :configuration
16
+
17
+ def configuration
18
+ @configuration ||= Configuration.new
19
+ end
20
+
21
+ def configure
22
+ yield(configuration) if block_given?
23
+ end
24
+ end
14
25
  end
15
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mission_control-servers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Kimura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-05 00:00:00.000000000 Z
11
+ date: 2024-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -79,21 +79,44 @@ files:
79
79
  - app/assets/config/mission_control_servers_manifest.js
80
80
  - app/assets/stylesheets/mission_control/servers/application.css
81
81
  - app/controllers/mission_control/servers/application_controller.rb
82
+ - app/controllers/mission_control/servers/dashboards/cpu_histories_controller.rb
83
+ - app/controllers/mission_control/servers/dashboards/cpu_usages_controller.rb
84
+ - app/controllers/mission_control/servers/dashboards/disk_frees_controller.rb
85
+ - app/controllers/mission_control/servers/dashboards/memory_histories_controller.rb
86
+ - app/controllers/mission_control/servers/dashboards/memory_usages_controller.rb
87
+ - app/controllers/mission_control/servers/dashboards/project_tables_controller.rb
82
88
  - app/controllers/mission_control/servers/ingresses_controller.rb
83
89
  - app/controllers/mission_control/servers/projects_controller.rb
90
+ - app/controllers/mission_control/servers/scripts_controller.rb
84
91
  - app/helpers/mission_control/servers/application_helper.rb
92
+ - app/helpers/mission_control/servers/dashboards/cpu_histories_helper.rb
93
+ - app/helpers/mission_control/servers/dashboards/cpu_usages_helper.rb
94
+ - app/helpers/mission_control/servers/dashboards/disk_frees_helper.rb
95
+ - app/helpers/mission_control/servers/dashboards/memory_histories_helper.rb
96
+ - app/helpers/mission_control/servers/dashboards/memory_usages_helper.rb
97
+ - app/helpers/mission_control/servers/dashboards/project_tables_helper.rb
85
98
  - app/helpers/mission_control/servers/projects_helper.rb
86
99
  - app/javascript/mission_control/servers/application.js
87
100
  - app/javascript/mission_control/servers/controllers/application.js
101
+ - app/javascript/mission_control/servers/controllers/copy_controller.js
102
+ - app/javascript/mission_control/servers/controllers/dialog_controller.js
88
103
  - app/javascript/mission_control/servers/controllers/index.js
104
+ - app/javascript/mission_control/servers/controllers/line_chart_controller.js
105
+ - app/javascript/mission_control/servers/controllers/pie_chart_controller.js
106
+ - app/javascript/mission_control/servers/controllers/refresh_controller.js
89
107
  - app/jobs/mission_control/servers/application_job.rb
90
108
  - app/mailers/mission_control/servers/application_mailer.rb
91
109
  - app/models/mission_control/servers/application_record.rb
92
110
  - app/models/mission_control/servers/project.rb
93
111
  - app/models/mission_control/servers/service.rb
94
112
  - app/views/layouts/mission_control/servers/application.html.erb
113
+ - app/views/mission_control/servers/dashboards/cpu_histories/show.html.erb
114
+ - app/views/mission_control/servers/dashboards/cpu_usages/show.html.erb
115
+ - app/views/mission_control/servers/dashboards/disk_frees/show.html.erb
116
+ - app/views/mission_control/servers/dashboards/memory_histories/show.html.erb
117
+ - app/views/mission_control/servers/dashboards/memory_usages/show.html.erb
118
+ - app/views/mission_control/servers/dashboards/project_tables/show.html.erb
95
119
  - app/views/mission_control/servers/projects/_form.html.erb
96
- - app/views/mission_control/servers/projects/_project.html.erb
97
120
  - app/views/mission_control/servers/projects/edit.html.erb
98
121
  - app/views/mission_control/servers/projects/index.html.erb
99
122
  - app/views/mission_control/servers/projects/new.html.erb
@@ -103,6 +126,7 @@ files:
103
126
  - db/migrate/20240205020304_create_mission_control_servers_projects.rb
104
127
  - db/migrate/20240205031009_create_mission_control_servers_services.rb
105
128
  - lib/mission_control/servers.rb
129
+ - lib/mission_control/servers/configuration.rb
106
130
  - lib/mission_control/servers/engine.rb
107
131
  - lib/mission_control/servers/version.rb
108
132
  - lib/tasks/mission_control/servers_tasks.rake
@@ -1,12 +0,0 @@
1
- <div id="<%= dom_id project %>">
2
- <p>
3
- <strong>Title:</strong>
4
- <%= project.title %>
5
- </p>
6
-
7
- <p>
8
- <strong>Token:</strong>
9
- <%= project.token %>
10
- </p>
11
-
12
- </div>