mission_control-servers 0.0.1 → 0.0.2

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 (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>