rails-server-monitor 0.1.4

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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +7 -0
  5. data/app/components/rails_server_monitor/leftbar_component.html.erb +20 -0
  6. data/app/components/rails_server_monitor/leftbar_component.rb +18 -0
  7. data/app/components/rails_server_monitor/server_table_row.html.erb +6 -0
  8. data/app/components/rails_server_monitor/server_table_row.rb +11 -0
  9. data/app/components/rails_server_monitor/warnings/high_cpu_usage_component.html.erb +18 -0
  10. data/app/components/rails_server_monitor/warnings/high_cpu_usage_component.rb +24 -0
  11. data/app/components/rails_server_monitor/warnings/low_disk_space_component.html.erb +17 -0
  12. data/app/components/rails_server_monitor/warnings/low_disk_space_component.rb +28 -0
  13. data/app/components/rails_server_monitor/warnings/low_memory_component.html.erb +17 -0
  14. data/app/components/rails_server_monitor/warnings/low_memory_component.rb +28 -0
  15. data/app/components/rails_server_monitor/warnings/warning_component.html.erb +13 -0
  16. data/app/components/rails_server_monitor/warnings/warning_component.rb +14 -0
  17. data/app/controllers/rails_server_monitor/application_controller.rb +6 -0
  18. data/app/controllers/rails_server_monitor/home_controller.rb +9 -0
  19. data/app/controllers/rails_server_monitor/servers_controller.rb +22 -0
  20. data/app/controllers/rails_server_monitor/snapshots_controller.rb +21 -0
  21. data/app/helpers/rails_server_monitor/application_helper.rb +29 -0
  22. data/app/javascript/controllers/index.js +9 -0
  23. data/app/javascript/packs/rails-server-application.js +17 -0
  24. data/app/javascript/stylesheets/main.scss +1 -0
  25. data/app/javascript/stylesheets/tailwind.scss +3 -0
  26. data/app/middlewares/rails_server_monitor/rack_middleware.rb +44 -0
  27. data/app/middlewares/rails_server_monitor/sidekiq_middleware.rb +29 -0
  28. data/app/models/rails_server_monitor/application_record.rb +7 -0
  29. data/app/models/rails_server_monitor/server.rb +27 -0
  30. data/app/models/rails_server_monitor/server_group.rb +10 -0
  31. data/app/models/rails_server_monitor/server_snapshot.rb +12 -0
  32. data/app/services/rails_server_monitor/chart_for_server.rb +51 -0
  33. data/app/services/rails_server_monitor/cleanup.rb +14 -0
  34. data/app/services/rails_server_monitor/server_setup.rb +90 -0
  35. data/app/services/rails_server_monitor/take_snapshot.rb +85 -0
  36. data/app/views/layouts/rails_server_monitor/application.html.erb +25 -0
  37. data/app/views/layouts/rails_server_monitor/application_record.rb +7 -0
  38. data/app/views/rails_server_monitor/home/index.html.erb +18 -0
  39. data/app/views/rails_server_monitor/servers/show.html.erb +133 -0
  40. data/app/views/rails_server_monitor/snapshots/show.html.erb +18 -0
  41. data/config/routes.rb +8 -0
  42. data/config/webpack/base.js +3 -0
  43. data/config/webpack/development.js +23 -0
  44. data/config/webpack/production.js +5 -0
  45. data/config/webpack/test.js +5 -0
  46. data/config/webpacker.yml +92 -0
  47. data/lib/generators/rails_server_monitor/install_generator.rb +20 -0
  48. data/lib/generators/rails_server_monitor/templates/install.rb.tt +29 -0
  49. data/lib/rails/server/monitor/engine.rb +3 -0
  50. data/lib/rails_server_monitor.rb +35 -0
  51. data/lib/rails_server_monitor/configuration.rb +41 -0
  52. data/lib/rails_server_monitor/engine.rb +12 -0
  53. data/lib/rails_server_monitor/version.rb +5 -0
  54. data/lib/tasks/rails_server_monitor_tasks.rake +24 -0
  55. metadata +292 -0
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class SidekiqMiddleware
5
+ def call(worker, *opts)
6
+ return if ignore_worker?(worker)
7
+
8
+ server = RailsServerMonitor::ServerSetup.new.call
9
+ snapshot = RailsServerMonitor::TakeSnapshot.new(server)
10
+
11
+ if snapshot.can_take_snapshot?
12
+ snapshot.call
13
+
14
+ RailsServerMonitor::Cleanup.new.call
15
+ end
16
+ end
17
+
18
+ def ignore_worker?(worker)
19
+ return false if config.ignore_workers.blank?
20
+ klass_name = worker.class.name
21
+
22
+ config.ignore_workers.include?(klass_name)
23
+ end
24
+
25
+ def config
26
+ RailsServerMonitor.config
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class ApplicationRecord < ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class Server < ApplicationRecord
5
+ self.table_name = "rails_server_monitor_servers"
6
+ store :system_information, accessors: %i(
7
+ system_os
8
+ system_os_language
9
+ system_os_timezone
10
+ system_kernel_version
11
+ system_cpu_name
12
+ system_cpu_cores
13
+ system_cpu_frequency
14
+ system_ram_available_in_mb
15
+ system_hdd_available_in_gb
16
+ ), coder: JSON
17
+
18
+ belongs_to :group, class_name: "RailsServerMonitor::ServerGroup", counter_cache: true, optional: true
19
+ has_many :server_snapshots, class_name: "RailsServerMonitor::ServerSnapshot",
20
+ foreign_key: :rails_server_monitor_server_id,
21
+ dependent: :delete_all
22
+
23
+ def display_name
24
+ @display_name ||= custom_name.present? ? custom_name : hostname
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class ServerGroup < ApplicationRecord
5
+ self.table_name = "rails_server_monitor_server_groups"
6
+
7
+ has_many :servers, class_name: "RailsServerMonitor::Server", dependent: :nullify
8
+ validates :name, presence: true, uniqueness: true
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class ServerSnapshot < ApplicationRecord
5
+ self.table_name = "rails_server_monitor_server_snapshots"
6
+
7
+ belongs_to :rails_server_monitor_server, class_name: "RailsServerMonitor::Server"
8
+
9
+ serialize :ram_stats, JSON
10
+ serialize :hdd_stats, JSON
11
+ end
12
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class ChartForServer
5
+ attr_reader :server, :timeline
6
+ def initialize(server, timeline: :today)
7
+ @server = server
8
+ @timeline = timeline
9
+ end
10
+
11
+ def render_chart
12
+ [
13
+ {
14
+ name: "% CPU usage", data: fill_hash_for_attribute(:cpu_usage_percentage),
15
+ },
16
+ {
17
+ name: "% RAM usage", data: fill_hash_for_attribute(:ram_usage_percentage)
18
+ },
19
+ {
20
+ name: "% HDD usage", data: fill_hash_for_attribute(:hdd_usage_percentage)
21
+ }
22
+ ]
23
+ end
24
+
25
+ def today?
26
+ timeline == :today
27
+ end
28
+
29
+
30
+ def last_record
31
+ @last_record = scope.last
32
+ end
33
+
34
+ def scope
35
+ return @scope if defined? @scope
36
+ query = server.server_snapshots.order(id: :asc)
37
+ if today?
38
+ query = query.where("created_at > ?", 1.day.ago)
39
+ end
40
+ @scope = query.to_a
41
+ end
42
+
43
+ def fill_hash_for_attribute(attr)
44
+ {}.tap do |h|
45
+ scope.each do |snapshot|
46
+ h[snapshot.created_at] = snapshot.send(attr)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class Cleanup
5
+ def call
6
+ RailsServerMonitor::ServerSnapshot.where("created_at < ?", Time.zone.now - config.cleanup_snapshots_after)
7
+ .delete_all
8
+ end
9
+
10
+ def config
11
+ RailsServerMonitor.config
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class ServerSetup
5
+ attr_reader :server
6
+
7
+ def initialize
8
+ @server = RailsServerMonitor::Server.find_or_initialize_by(hostname: hostname)
9
+ end
10
+
11
+ def call
12
+ server.tap do
13
+ next update_server if server.updated_at.blank?
14
+
15
+ needs_update = (Time.zone.now - server.updated_at) >= config.update_server_interval
16
+ update_server if needs_update
17
+ end
18
+ end
19
+
20
+ private
21
+ def hostname
22
+ @hostname ||= `hostname`.squish
23
+ end
24
+
25
+ def update_server
26
+ server.assign_attributes({
27
+ last_seen_at: Time.zone.now,
28
+ system_os: system_os,
29
+ system_os_language: system_os_language,
30
+ system_os_timezone: system_os_timezone,
31
+ system_kernel_version: system_kernel_version,
32
+ system_cpu_name: system_cpu_name,
33
+ system_cpu_cores: system_cpu_cores,
34
+ system_cpu_frequency: system_cpu_frequency,
35
+ system_ram_available_in_mb: system_ram_available_in_mb,
36
+ system_hdd_available_in_gb: system_hdd_available_in_gb
37
+ })
38
+
39
+ server.save!
40
+ end
41
+
42
+ def system_os
43
+ File.read("/etc/lsb-release") if File.exist?("/etc/lsb-release")
44
+ end
45
+
46
+ def system_os_language
47
+ ENV["LANG"]
48
+ end
49
+
50
+ def system_os_timezone
51
+ File.read("/etc/timezone")
52
+ end
53
+
54
+ def system_kernel_version
55
+ `uname -r`.squish
56
+ end
57
+
58
+ def system_cpu_name
59
+ Sys::CPU.model
60
+ end
61
+
62
+ def system_cpu_cores
63
+ Sys::CPU.num_cpu
64
+ end
65
+
66
+ def system_cpu_frequency
67
+ Sys::CPU.freq
68
+ end
69
+
70
+ def system_ram_available_in_mb
71
+ ram_helper[:total]
72
+ end
73
+
74
+ def system_hdd_available_in_gb
75
+ storage_helper[:total]
76
+ end
77
+
78
+ def config
79
+ RailsServerMonitor.config
80
+ end
81
+
82
+ def storage_helper
83
+ @store ||= Vidibus::Sysinfo.storage.to_h
84
+ end
85
+
86
+ def ram_helper
87
+ @ram_helper ||= Vidibus::Sysinfo.memory.to_h
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class TakeSnapshot
5
+ attr_reader :server
6
+
7
+ def initialize(server)
8
+ @server = server
9
+ end
10
+
11
+ def call
12
+ return unless can_take_snapshot?
13
+ create_snapshot!
14
+ end
15
+
16
+ def can_take_snapshot?
17
+ return @can_take_snapshot if defined? @can_take_snapshot
18
+ latest_snapshot = server.server_snapshots.order(id: :desc).first
19
+ if latest_snapshot.blank?
20
+ return @can_take_snapshot = true
21
+ end
22
+ if (Time.zone.now - latest_snapshot.created_at) >= config.snapshot_server_interval
23
+ return @can_take_snapshot = true
24
+ end
25
+
26
+ @can_take_snapshot = false
27
+ end
28
+
29
+ private
30
+ def create_snapshot!
31
+ RailsServerMonitor::ServerSnapshot.create!(
32
+ cpu_usage_percentage: cpu_usage_percentage,
33
+ ram_usage_percentage: ram_usage_percentage,
34
+ hdd_usage_percentage: hdd_usage_percentage,
35
+ ram_stats: ram_stats,
36
+ hdd_stats: hdd_stats,
37
+ network_stats: network_stats,
38
+ rails_server_monitor_server: server
39
+ )
40
+ end
41
+
42
+ def cpu_usage_percentage
43
+ psm_helper.uw_cpuused.round
44
+ end
45
+
46
+ def ram_usage_percentage
47
+ percentage_off(ram_helper[:total], ram_helper[:used])
48
+ end
49
+
50
+ def hdd_usage_percentage
51
+ percentage_off(storage_helper[:total], storage_helper[:used])
52
+ end
53
+
54
+ def ram_stats
55
+ ram_helper.slice(:used, :free)
56
+ end
57
+
58
+ def hdd_stats
59
+ storage_helper.slice(:used, :free)
60
+ end
61
+
62
+ def network_stats
63
+ end
64
+
65
+ def psm_helper
66
+ RubyStatsPsm
67
+ end
68
+
69
+ def config
70
+ RailsServerMonitor.config
71
+ end
72
+
73
+ def storage_helper
74
+ @store ||= Vidibus::Sysinfo.storage.to_h
75
+ end
76
+
77
+ def ram_helper
78
+ @ram_helper ||= Vidibus::Sysinfo.memory.to_h
79
+ end
80
+
81
+ def percentage_off(total, current)
82
+ ((current / total.to_f) * 100).round
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= @title ? "#{@title} - " : "" %>Rails Server Monitor Engine</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= safe_render_js "rails-server-application", 'data-turbolinks-track': "reload" %>
9
+ <%= safe_render_css "rails-server-application", 'data-turbolinks-track': "reload" %>
10
+ </head>
11
+ <body>
12
+
13
+ <div class="flex">
14
+ <div class="overflow-y-auto fixed top-0 left-0 bottom-0 bg-white w-1/5">
15
+ <%= render RailsServerMonitor::LeftbarComponent.new(ctx: self) %>
16
+ </div>
17
+ <div class="w-1/5 mr-4"></div>
18
+
19
+ <div class="flex-1">
20
+ <%= yield %>
21
+ </div>
22
+ </div>
23
+
24
+ </body>
25
+ </html>
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsServerMonitor
4
+ class ApplicationRecord < ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ <div class="p-2">
2
+ <div class="bg-red-300 text-3xl p-2 text-gray-800">
3
+ Warnings
4
+ </div>
5
+
6
+ <div>
7
+ <%= render RailsServerMonitor::Warnings::HighCpuUsageComponent.new(ctx: self) %>
8
+ </div>
9
+
10
+ <div>
11
+ <%= render RailsServerMonitor::Warnings::LowMemoryComponent.new(ctx: self) %>
12
+ </div>
13
+
14
+
15
+ <div>
16
+ <%= render RailsServerMonitor::Warnings::LowDiskSpaceComponent.new(ctx: self) %>
17
+ </div>
18
+ </div>
@@ -0,0 +1,133 @@
1
+ <div class="p-2">
2
+ <div class="text-center text-2xl font-bold">
3
+ <%= @server.display_name %>
4
+ </div>
5
+
6
+
7
+ <div class="flex mt-4">
8
+ <%= content_tag :div, class: "#{@chart.today? ? "w-1/2" : "w-full"}" do %>
9
+ <%= line_chart @chart.render_chart %>
10
+ <% end %>
11
+
12
+ <% if @chart.today? && @chart.last_record.present? %>
13
+ <div class="w-1/2 p-2">
14
+ <div class="mb-2 text-xl">
15
+ Current server stats information:
16
+ </div>
17
+
18
+ <div class="flex">
19
+ <div class="grid grid-cols-2 gap-4 w-1/2">
20
+ <%= render(RailsServerMonitor::ServerTableRow.new(
21
+ title: "CPU Usage",
22
+ value: "#{@chart.last_record.cpu_usage_percentage} %"
23
+ )) %>
24
+
25
+
26
+ <%= render(RailsServerMonitor::ServerTableRow.new(
27
+ title: "Ram Used",
28
+ value: "#{@chart.last_record.ram_stats["used"]} MB"
29
+ )) %>
30
+
31
+ <%= render(RailsServerMonitor::ServerTableRow.new(
32
+ title: "Ram Free",
33
+ value: "#{@chart.last_record.ram_stats["free"]} MB"
34
+ )) %>
35
+ </div>
36
+ <div class="grid grid-cols-2 gap-4 w-1/2">
37
+ <%= render(RailsServerMonitor::ServerTableRow.new(
38
+ title: "HDD Used",
39
+ value: "#{@chart.last_record.hdd_stats["used"]} GB"
40
+ )) %>
41
+
42
+ <%= render(RailsServerMonitor::ServerTableRow.new(
43
+ title: "HDD Free",
44
+ value: "#{@chart.last_record.hdd_stats["free"]} GB"
45
+ )) %>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ <% end %>
50
+ </div>
51
+
52
+ <div class="mt-20">
53
+ <div class="mb-2 text-xl">
54
+ Sever information:
55
+ </div>
56
+
57
+ <div class="grid grid-cols-2 gap-4 w-1/2">
58
+ <%= render(RailsServerMonitor::ServerTableRow.new(
59
+ title: "Hostname",
60
+ value: @server.hostname
61
+ )) %>
62
+
63
+ <div class="bg-blue-300 text-gray-800 p-1">
64
+ Custom name:
65
+ </div>
66
+ <div class="p-1">
67
+ <%= @server.custom_name %>
68
+ </div>
69
+ <div class="bg-blue-300 text-gray-800 p-1">
70
+ Custom description:
71
+ </div>
72
+ <div class="p-1">
73
+ <%= @server.custom_description %>
74
+ </div>
75
+ <div class="mb-2 text-xl">
76
+ OS information
77
+ </div>
78
+ <div></div>
79
+
80
+ <div class="bg-blue-300 text-gray-800 p-1">
81
+ Operating system:
82
+ </div>
83
+ <div class="p-1">
84
+ <%= simple_format @server.system_os %>
85
+ </div>
86
+
87
+ <%= render(RailsServerMonitor::ServerTableRow.new(
88
+ title: "Kernel version",
89
+ value: @server.system_kernel_version
90
+ )) %>
91
+
92
+ <%= render(RailsServerMonitor::ServerTableRow.new(
93
+ title: "OS language",
94
+ value: @server.system_os_language
95
+ )) %>
96
+
97
+ <%= render(RailsServerMonitor::ServerTableRow.new(
98
+ title: "OS Time zone",
99
+ value: @server.system_os_timezone
100
+ )) %>
101
+
102
+ <div class="mb-2 text-xl">
103
+ CPU information
104
+ </div>
105
+ <div></div>
106
+
107
+ <%= render(RailsServerMonitor::ServerTableRow.new(
108
+ title: "CPU Model",
109
+ value: @server.system_cpu_name
110
+ )) %>
111
+
112
+ <%= render(RailsServerMonitor::ServerTableRow.new(
113
+ title: "CPU Codes",
114
+ value: @server.system_cpu_cores
115
+ )) %>
116
+
117
+ <%= render(RailsServerMonitor::ServerTableRow.new(
118
+ title: "CPU Frequency",
119
+ value: "#{@server.system_cpu_frequency} Mhz"
120
+ )) %>
121
+
122
+ <%= render(RailsServerMonitor::ServerTableRow.new(
123
+ title: "RAM",
124
+ value: "#{@server.system_ram_available_in_mb} MB"
125
+ )) %>
126
+
127
+ <%= render(RailsServerMonitor::ServerTableRow.new(
128
+ title: "Storage",
129
+ value: "#{@server.system_hdd_available_in_gb} GB"
130
+ )) %>
131
+ </div>
132
+ </div>
133
+ </div>