1# -*- coding: utf-8 -*- 2# © Copyright EnterpriseDB UK Limited 2011-2021 3# 4# This file is part of Barman. 5# 6# Barman is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 3 of the License, or 9# (at your option) any later version. 10# 11# Barman is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with Barman. If not, see <http://www.gnu.org/licenses/>. 18 19""" 20This module represents the barman diagnostic tool. 21""" 22 23import datetime 24import json 25import logging 26 27import barman 28from barman import fs, output 29from barman.backup import BackupInfo 30from barman.exceptions import CommandFailedException, FsOperationFailed 31from barman.utils import BarmanEncoder 32 33_logger = logging.getLogger(__name__) 34 35 36def exec_diagnose(servers, errors_list): 37 """ 38 Diagnostic command: gathers information from backup server 39 and from all the configured servers. 40 41 Gathered information should be used for support and problems detection 42 43 :param dict(str,barman.server.Server) servers: list of configured servers 44 :param list errors_list: list of global errors 45 """ 46 # global section. info about barman server 47 diagnosis = {"global": {}, "servers": {}} 48 # barman global config 49 diagnosis["global"]["config"] = dict(barman.__config__._global_config) 50 diagnosis["global"]["config"]["errors_list"] = errors_list 51 try: 52 command = fs.UnixLocalCommand() 53 # basic system info 54 diagnosis["global"]["system_info"] = command.get_system_info() 55 except CommandFailedException as e: 56 diagnosis["global"]["system_info"] = {"error": repr(e)} 57 diagnosis["global"]["system_info"]["barman_ver"] = barman.__version__ 58 diagnosis["global"]["system_info"]["timestamp"] = datetime.datetime.now() 59 # per server section 60 for name in sorted(servers): 61 server = servers[name] 62 if server is None: 63 output.error("Unknown server '%s'" % name) 64 continue 65 # server configuration 66 diagnosis["servers"][name] = {} 67 diagnosis["servers"][name]["config"] = vars(server.config) 68 if "config" in diagnosis["servers"][name]["config"]: 69 del diagnosis["servers"][name]["config"]["config"] 70 # server system info 71 if server.config.ssh_command: 72 try: 73 command = fs.UnixRemoteCommand( 74 ssh_command=server.config.ssh_command, path=server.path 75 ) 76 diagnosis["servers"][name]["system_info"] = command.get_system_info() 77 except FsOperationFailed: 78 pass 79 # barman status information for the server 80 diagnosis["servers"][name]["status"] = server.get_remote_status() 81 # backup list 82 backups = server.get_available_backups(BackupInfo.STATUS_ALL) 83 diagnosis["servers"][name]["backups"] = backups 84 # wal status 85 diagnosis["servers"][name]["wals"] = { 86 "last_archived_wal_per_timeline": server.backup_manager.get_latest_archived_wals_info(), 87 } 88 # Release any PostgreSQL resource 89 server.close() 90 output.info( 91 json.dumps(diagnosis, cls=BarmanEncoder, indent=4, sort_keys=True), log=False 92 ) 93