Add basic server status page at /status.
Lists versions of various dependencies plus some Postgres and Redis metrics.
This commit is contained in:
8
app/controllers/status_controller.rb
Normal file
8
app/controllers/status_controller.rb
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
class StatusController < ApplicationController
|
||||||
|
respond_to :html, :json, :xml
|
||||||
|
|
||||||
|
def show
|
||||||
|
@status = ServerStatus.new
|
||||||
|
respond_with(@status)
|
||||||
|
end
|
||||||
|
end
|
||||||
109
app/logical/server_status.rb
Normal file
109
app/logical/server_status.rb
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
class ServerStatus
|
||||||
|
extend Memoist
|
||||||
|
include ActiveModel::Serializers::JSON
|
||||||
|
include ActiveModel::Serializers::Xml
|
||||||
|
|
||||||
|
def serializable_hash(*options)
|
||||||
|
{
|
||||||
|
status: {
|
||||||
|
hostname: hostname,
|
||||||
|
uptime: uptime,
|
||||||
|
loadavg: loadavg,
|
||||||
|
ruby_version: RUBY_VERSION,
|
||||||
|
distro_version: distro_version,
|
||||||
|
kernel_version: kernel_version,
|
||||||
|
libvips_version: libvips_version,
|
||||||
|
ffmpeg_version: ffmpeg_version,
|
||||||
|
mkvmerge_version: mkvmerge_version,
|
||||||
|
redis_version: redis_version,
|
||||||
|
postgres_version: postgres_version,
|
||||||
|
},
|
||||||
|
postgres: {
|
||||||
|
connection_stats: postgres_connection_stats,
|
||||||
|
},
|
||||||
|
redis: {
|
||||||
|
info: redis_info,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
concerning :InfoMethods do
|
||||||
|
def hostname
|
||||||
|
Socket.gethostname
|
||||||
|
end
|
||||||
|
|
||||||
|
def uptime
|
||||||
|
seconds = File.read("/proc/uptime").split[0].to_f
|
||||||
|
"#{seconds.seconds.in_days.round} days"
|
||||||
|
end
|
||||||
|
|
||||||
|
def loadavg
|
||||||
|
File.read("/proc/loadavg").chomp
|
||||||
|
end
|
||||||
|
|
||||||
|
def kernel_version
|
||||||
|
File.read("/proc/version").chomp
|
||||||
|
end
|
||||||
|
|
||||||
|
def distro_version
|
||||||
|
`source /etc/os-release; echo "$NAME $VERSION"`.chomp
|
||||||
|
end
|
||||||
|
|
||||||
|
def libvips_version
|
||||||
|
Vips::LIBRARY_VERSION
|
||||||
|
end
|
||||||
|
|
||||||
|
def ffmpeg_version
|
||||||
|
version = `ffmpeg -version`
|
||||||
|
version[/ffmpeg version ([0-9.]+)/, 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
def mkvmerge_version
|
||||||
|
`mkvmerge --version`.chomp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
concerning :RedisMethods do
|
||||||
|
def redis_info
|
||||||
|
return {} if Rails.cache.try(:redis).nil?
|
||||||
|
Rails.cache.redis.info
|
||||||
|
end
|
||||||
|
|
||||||
|
def redis_used_memory
|
||||||
|
redis_info["used_memory_rss_human"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def redis_version
|
||||||
|
redis_info["redis_version"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
concerning :PostgresMethods do
|
||||||
|
def postgres_version
|
||||||
|
ApplicationRecord.connection.select_value("SELECT version()")
|
||||||
|
end
|
||||||
|
|
||||||
|
def postgres_active_connections
|
||||||
|
ApplicationRecord.connection.select_value("SELECT COUNT(*) FROM pg_stat_activity WHERE state = 'active'")
|
||||||
|
end
|
||||||
|
|
||||||
|
def postgres_connection_stats
|
||||||
|
run_query("SELECT pid, state, query_start, state_change, xact_start, backend_start, backend_type FROM pg_stat_activity ORDER BY state, query_start DESC, backend_type")
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_query(query)
|
||||||
|
result = ApplicationRecord.connection.select_all(query)
|
||||||
|
serialize_result(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialize_result(result)
|
||||||
|
result.rows.map do |row|
|
||||||
|
row.each_with_index.map do |col, i|
|
||||||
|
[result.columns[i], col]
|
||||||
|
end.to_h
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
memoize :redis_info
|
||||||
|
end
|
||||||
32
app/views/status/show.html.erb
Normal file
32
app/views/status/show.html.erb
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<div id="c-status">
|
||||||
|
<div id="a-show" class="fixed-width-container">
|
||||||
|
<h1>Status</h1>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
Server: <%= @status.hostname %>
|
||||||
|
</summary>
|
||||||
|
<%= render "list", hash: @status.serializable_hash[:status] %>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<h1>Postgres</h1>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
<%= pluralize @status.postgres_active_connections, "active connection" %>.
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
<%= render "table", rows: @status.serializable_hash[:postgres][:connection_stats] %>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<h1>Redis</h1>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
<%= @status.redis_used_memory %> memory used.
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
<%= render "list", hash: @status.serializable_hash[:redis][:info] %>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -227,6 +227,7 @@ Rails.application.routes.draw do
|
|||||||
get :sign_out, on: :collection
|
get :sign_out, on: :collection
|
||||||
end
|
end
|
||||||
resource :source, :only => [:show]
|
resource :source, :only => [:show]
|
||||||
|
resource :status, only: [:show], controller: "status"
|
||||||
resources :tags do
|
resources :tags do
|
||||||
collection do
|
collection do
|
||||||
get :autocomplete
|
get :autocomplete
|
||||||
|
|||||||
20
test/functional/status_controller_test.rb
Normal file
20
test/functional/status_controller_test.rb
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class StatusControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
context "The status controller" do
|
||||||
|
should "work for a html response" do
|
||||||
|
get status_path
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
should "work for a json response" do
|
||||||
|
get status_path(format: :json)
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
should "work for an xml response" do
|
||||||
|
get status_path(format: :json)
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user