mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-30 18:47:51 +00:00 
			
		
		
		
	feat: add chatwoot instance status in superadmin (#6045)
* feat: add chatwoot instance status in superadmin * feat: add redis metrics to instance health page * chore: fix rubocop * chore: rescue redis no connection * chore: add rspec * chore: refactor * feat: add instance health to /api * chore: rescue postgres * chore: fix spec
This commit is contained in:
		| @@ -2,6 +2,24 @@ class ApiController < ApplicationController | ||||
|   skip_before_action :set_current_user, only: [:index] | ||||
|  | ||||
|   def index | ||||
|     render json: { version: Chatwoot.config[:version], timestamp: Time.now.utc.to_formatted_s(:db) } | ||||
|     render json: { version: Chatwoot.config[:version], | ||||
|                    timestamp: Time.now.utc.to_formatted_s(:db), | ||||
|                    queue_services: redis_status, | ||||
|                    data_services: postgres_status } | ||||
|   end | ||||
|  | ||||
|   private | ||||
|  | ||||
|   def redis_status | ||||
|     r = Redis.new(Redis::Config.app) | ||||
|     return 'ok' if r.ping | ||||
|   rescue Redis::CannotConnectError | ||||
|     'failing' | ||||
|   end | ||||
|  | ||||
|   def postgres_status | ||||
|     ActiveRecord::Base.connection.active? ? 'ok' : 'failing' | ||||
|   rescue ActiveRecord::ConnectionNotEstablished | ||||
|     'failing' | ||||
|   end | ||||
| end | ||||
|   | ||||
							
								
								
									
										44
									
								
								app/controllers/super_admin/instance_statuses_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/controllers/super_admin/instance_statuses_controller.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| class SuperAdmin::InstanceStatusesController < SuperAdmin::ApplicationController | ||||
|   def show | ||||
|     @metrics = {} | ||||
|     chatwoot_version | ||||
|     sha | ||||
|     postgres_status | ||||
|     redis_metrics | ||||
|   end | ||||
|  | ||||
|   def chatwoot_version | ||||
|     @metrics['Chatwoot version'] = Chatwoot.config[:version] | ||||
|   end | ||||
|  | ||||
|   def sha | ||||
|     sha = `git rev-parse HEAD` | ||||
|     @metrics['Git SHA'] = sha.presence || 'n/a' | ||||
|   end | ||||
|  | ||||
|   def postgres_status | ||||
|     @metrics['Postgres alive'] = if ActiveRecord::Base.connection.active? | ||||
|                                    'true' | ||||
|                                  else | ||||
|                                    'false' | ||||
|                                  end | ||||
|   end | ||||
|  | ||||
|   def redis_metrics | ||||
|     r = Redis.new(Redis::Config.app) | ||||
|     if r.ping == 'PONG' | ||||
|       redis_server = r.info | ||||
|       @metrics['Redis alive'] = 'false' | ||||
|       @metrics['Redis version'] = redis_server['redis_version'] | ||||
|       @metrics['Redis number of connected clients'] = redis_server['connected_clients'] | ||||
|       @metrics["Redis 'maxclients' setting"] = redis_server['maxclients'] | ||||
|       @metrics['Redis memory used'] = redis_server['used_memory_human'] | ||||
|       @metrics['Redis memory peak'] = redis_server['used_memory_peak_human'] | ||||
|       @metrics['Redis total memory available'] = redis_server['total_system_memory_human'] | ||||
|       @metrics["Redis 'maxmemory' setting"] = redis_server['maxmemory'] | ||||
|       @metrics["Redis 'maxmemory_policy' setting"] = redis_server['maxmemory_policy'] | ||||
|     end | ||||
|   rescue Redis::CannotConnectError | ||||
|     @metrics['Redis alive'] = false | ||||
|   end | ||||
| end | ||||
| @@ -40,7 +40,7 @@ as defined by the routes in the `admin/` namespace | ||||
|     </li> | ||||
|  | ||||
|     <% Administrate::Namespace.new(namespace).resources.each do |resource| %> | ||||
|       <% next if ["account_users", "dashboard", "devise/sessions", "app_configs" ].include?  resource.resource %> | ||||
|       <% next if ["account_users", "dashboard", "devise/sessions", "app_configs", "instance_statuses" ].include?  resource.resource %> | ||||
|       <li class="navigation__link navigation__link--<%= nav_link_state(resource) %>"> | ||||
|         <i class="<%= sidebar_icons[resource.resource.to_sym] %>"></i> | ||||
|         <%= link_to( | ||||
| @@ -50,6 +50,11 @@ as defined by the routes in the `admin/` namespace | ||||
|       </li> | ||||
|     <% end %> | ||||
|  | ||||
|   <li class="navigation__link"> | ||||
|       <i class="ion ion-medkit"></i> | ||||
|       <%= link_to "Instance Health", super_admin_instance_status_url %> | ||||
|     </li> | ||||
|  | ||||
|     <li class="navigation__link"> | ||||
|       <i class="ion ion ion-network"></i> | ||||
|       <%= link_to "Sidekiq", sidekiq_web_url, { target: "_blank" } %> | ||||
|   | ||||
							
								
								
									
										23
									
								
								app/views/super_admin/instance_statuses/show.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/views/super_admin/instance_statuses/show.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| <% content_for(:title) do %> | ||||
|   Instance Health | ||||
| <% end %> | ||||
| <header class="main-content__header" role="banner"> | ||||
|   <h1 class="main-content__page-title" id="page-title"> | ||||
|     <%= content_for(:title) %> | ||||
|   </h1> | ||||
| </header> | ||||
| <section class="main-content__body"> | ||||
|   <table> | ||||
|   <tr> | ||||
|     <th>Metric</th> | ||||
|     <th>Value</th> | ||||
|   </tr> | ||||
|   <% @metrics.each do |key,value| %> | ||||
|    <tr> | ||||
|    <td> <%= key %> </td> | ||||
|    <td> <%= value %> </td> | ||||
|   </tr> | ||||
|   <% end %> | ||||
| </table> | ||||
|  | ||||
| </section> | ||||
| @@ -374,6 +374,7 @@ Rails.application.routes.draw do | ||||
|       resources :installation_configs, only: [:index, :new, :create, :show, :edit, :update] | ||||
|       resources :agent_bots, only: [:index, :new, :create, :show, :edit, :update] | ||||
|       resources :platform_apps, only: [:index, :new, :create, :show, :edit, :update] | ||||
|       resource :instance_status, only: [:show] | ||||
|  | ||||
|       # resources that doesn't appear in primary navigation in super admin | ||||
|       resources :account_users, only: [:new, :create, :destroy] | ||||
|   | ||||
| @@ -6,6 +6,8 @@ RSpec.describe 'API Base', type: :request do | ||||
|       get '/api/' | ||||
|       expect(response).to have_http_status(:success) | ||||
|       expect(response.body).to include(Chatwoot.config[:version]) | ||||
|       expect(response.body).to include('queue_services') | ||||
|       expect(response.body).to include('data_services') | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -0,0 +1,25 @@ | ||||
| require 'rails_helper' | ||||
|  | ||||
| RSpec.describe 'Super Admin Instance health', type: :request do | ||||
|   let(:super_admin) { create(:super_admin) } | ||||
|  | ||||
|   describe 'GET /super_admin/instance_status' do | ||||
|     context 'when it is an unauthenticated super admin' do | ||||
|       it 'returns unauthorized' do | ||||
|         get '/super_admin/instance_status' | ||||
|         expect(response).to have_http_status(:redirect) | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     context 'when it is an authenticated super admin' do | ||||
|       it 'shows the instance_status page' do | ||||
|         sign_in(super_admin, scope: :super_admin) | ||||
|         get '/super_admin/instance_status' | ||||
|         expect(response).to have_http_status(:success) | ||||
|         expect(response.body).to include('Chatwoot version') | ||||
|         sha = `git rev-parse HEAD` | ||||
|         expect(response.body).to include(sha) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
		Reference in New Issue
	
	Block a user
	 Vishnu Narayanan
					Vishnu Narayanan