From b489689a76f9f6208befe7a2b597defb12537336 Mon Sep 17 00:00:00 2001 From: Usman Nasir Date: Thu, 21 May 2020 23:21:36 +0500 Subject: [PATCH] add detailed schedule backup logging --- backup/backupManager.py | 95 ++++++++++++++- backup/static/backup/backup.js | 66 ++++++++++- backup/templates/backup/backupLogs.html | 125 ++++++++++++++++++++ backup/templates/backup/backupSchedule.html | 9 +- backup/urls.py | 4 +- backup/views.py | 17 +++ plogical/backupSchedule.py | 21 +++- plogical/backupScheduleLocal.py | 24 +++- serverStatus/views.py | 7 -- static/backup/backup.js | 66 ++++++++++- 10 files changed, 413 insertions(+), 21 deletions(-) create mode 100755 backup/templates/backup/backupLogs.html diff --git a/backup/backupManager.py b/backup/backupManager.py index 6e298d26b..eb9f4fe73 100755 --- a/backup/backupManager.py +++ b/backup/backupManager.py @@ -9,7 +9,7 @@ django.setup() import json from plogical.acl import ACLManager import plogical.CyberCPLogFileWriter as logging -from websiteFunctions.models import Websites, Backups, dest, backupSchedules +from websiteFunctions.models import Websites, Backups, dest, backupSchedules, BackupJob, BackupJobLogs from plogical.virtualHostUtilities import virtualHostUtilities import subprocess import shlex @@ -1186,3 +1186,96 @@ class BackupManager: data = {'cancelStatus': 0, 'error_message': str(msg)} json_data = json.dumps(data) return HttpResponse(json_data) + + def backupLogs(self, request = None, userID = None, data = None): + try: + currentACL = ACLManager.loadedACL(userID) + + if currentACL['admin'] == 1: + pass + else: + return ACLManager.loadError() + + all_files = [] + + logFiles = BackupJob.objects.all().order_by('-id') + + for logFile in logFiles: + all_files.append(logFile.logFile) + + return render(request, 'backup/backupLogs.html', {'backups': all_files}) + + except BaseException as msg: + return HttpResponse(str(msg)) + + def fetchLogs(self, userID = None, data = None): + try: + currentACL = ACLManager.loadedACL(userID) + + if currentACL['admin'] == 1: + pass + else: + return ACLManager.loadError() + + page = int(str(data['page']).rstrip('\n')) + recordsToShow = int(data['recordsToShow']) + logFile = data['logFile'] + + logJob = BackupJob.objects.get(logFile=logFile) + + logs = logJob.backupjoblogs_set.all() + + from s3Backups.s3Backups import S3Backups + from plogical.backupSchedule import backupSchedule + + pagination = S3Backups.getPagination(len(logs), recordsToShow) + endPageNumber, finalPageNumber = S3Backups.recordsPointer(page, recordsToShow) + finalLogs = logs[finalPageNumber:endPageNumber] + + json_data = "[" + checker = 0 + counter = 0 + + for log in finalLogs: + + if log.status == backupSchedule.INFO: + status = 'INFO' + else: + status = 'ERROR' + + dic = { + 'LEVEL': status, "Message": log.message + } + if checker == 0: + json_data = json_data + json.dumps(dic) + checker = 1 + else: + json_data = json_data + ',' + json.dumps(dic) + counter = counter + 1 + + json_data = json_data + ']' + + if logJob.location == backupSchedule.LOCAL: + location = 'local' + else: + location = 'remote' + + + data = { + 'status': 1, + 'error_message': 'None', + 'logs': json_data, + 'pagination': pagination, + 'jobSuccessSites': logJob.jobSuccessSites, + 'jobFailedSites': logJob.jobFailedSites, + 'location': location + } + + + json_data = json.dumps(data) + return HttpResponse(json_data) + + except BaseException as msg: + data = {'remoteRestoreStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data) + return HttpResponse(json_data) diff --git a/backup/static/backup/backup.js b/backup/static/backup/backup.js index cbe74d8ef..59c654f87 100755 --- a/backup/static/backup/backup.js +++ b/backup/static/backup/backup.js @@ -1541,4 +1541,68 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { }); -///** Backup site ends **/// \ No newline at end of file +///** Backup site ends **/// + + +//*** Remote Backup site ****// +app.controller('backupLogsScheduled', function ($scope, $http, $timeout) { + + $scope.cyberpanelLoading = true; + $scope.logDetails = true; + + $scope.currentPage = 1; + $scope.recordsToShow = 10; + + $scope.fetchLogs = function () { + + $scope.cyberpanelLoading = false; + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + var data = { + logFile: $scope.logFile, + recordsToShow: $scope.recordsToShow, + page: $scope.currentPage + }; + + dataurl = "/backup/fetchLogs"; + + $http.post(dataurl, data, config).then(ListInitialData, cantLoadInitialData); + + function ListInitialData(response) { + $scope.cyberpanelLoading = true; + if (response.data.status === 1) { + $scope.logDetails = false; + $scope.logs = JSON.parse(response.data.logs); + $scope.pagination = response.data.pagination; + $scope.jobSuccessSites = response.data.jobSuccessSites; + $scope.jobFailedSites = response.data.jobFailedSites; + $scope.location = response.data.location; + } else { + new PNotify({ + title: 'Error!', + text: response.data.error_message, + type: 'error' + }); + } + } + function cantLoadInitialData(response) { + $scope.cyberpanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type: 'error' + }); + } + + + }; + + +}); + +///** Backup site ends **/// diff --git a/backup/templates/backup/backupLogs.html b/backup/templates/backup/backupLogs.html new file mode 100755 index 000000000..0c7dadf49 --- /dev/null +++ b/backup/templates/backup/backupLogs.html @@ -0,0 +1,125 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "Backup Logs - CyberPanel" %}{% endblock %} +{% block content %} + + {% load static %} + + {% get_current_language as LANGUAGE_CODE %} + + + +
+
+

{% trans "Backup Logs" %}

+

{% trans "On this page you can view detailed logs of your local and remote scheduled backups." %}

+
+ +
+
+

+ {% trans "Restore Website" %} +

+
+ +
+ + +
+ +
+ +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + +
{% trans "Successful Sites" %}{% trans "Failed Sites" %}{% trans "Location" %}
{$ jobSuccessSites $}{$ jobFailedSites $}{$ location $}
+
+
+ +
+ +
+
+
+ +
+
+
+
+ + + + + + + + + + + + + + +
{% trans "LEVEL" %}{% trans "Message" %}
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ + +
+ + +{% endblock %} \ No newline at end of file diff --git a/backup/templates/backup/backupSchedule.html b/backup/templates/backup/backupSchedule.html index 69de37618..6fb11b5b5 100755 --- a/backup/templates/backup/backupSchedule.html +++ b/backup/templates/backup/backupSchedule.html @@ -11,7 +11,7 @@

{% trans "Schedule Back up" %} - {% trans "Remote Backups" %}

{% trans "On this page you can schedule Back ups to localhost or remote server (If you have added one)." %}

@@ -20,8 +20,11 @@

- {% trans "Schedule Back up" %} + {% trans "Schedule Back up" %} - {% trans "Backup Logs" %}

diff --git a/backup/urls.py b/backup/urls.py index 0a7164ba2..9d09770a5 100755 --- a/backup/urls.py +++ b/backup/urls.py @@ -48,7 +48,7 @@ urlpatterns = [ url(r'^localInitiate$', views.localInitiate, name='localInitiate'), - - + url(r'^backupLogs$', views.backupLogs, name='backupLogs'), + url(r'^fetchLogs$', views.fetchLogs, name='fetchLogs'), ] \ No newline at end of file diff --git a/backup/views.py b/backup/views.py index ef8842283..bf6512c25 100755 --- a/backup/views.py +++ b/backup/views.py @@ -327,6 +327,23 @@ def cancelRemoteBackup(request): except KeyError: return redirect(loadLoginPage) +def backupLogs(request): + try: + userID = request.session['userID'] + bm = BackupManager() + return bm.backupLogs(request, userID) + except KeyError: + return redirect(loadLoginPage) + +def fetchLogs(request): + try: + userID = request.session['userID'] + + wm = BackupManager() + return wm.fetchLogs(userID, json.loads(request.body)) + + except KeyError: + return redirect(loadLoginPage) @csrf_exempt def localInitiate(request): diff --git a/plogical/backupSchedule.py b/plogical/backupSchedule.py index eba989f92..a6a420e8e 100755 --- a/plogical/backupSchedule.py +++ b/plogical/backupSchedule.py @@ -12,7 +12,7 @@ import os import time from plogical.backupUtilities import backupUtilities from re import match,I,M -from websiteFunctions.models import Backups +from websiteFunctions.models import Backups, BackupJob, BackupJobLogs from plogical.processUtilities import ProcessUtilities from random import randint import json, requests @@ -22,14 +22,22 @@ import signal class backupSchedule: now = datetime.now() + LOCAL = 0 + REMOTE = 1 + INFO = 0 + ERROR = 1 + backupLog = '' @staticmethod - def remoteBackupLogging(fileName, message): + def remoteBackupLogging(fileName, message, status = 0): try: file = open(fileName,'a') file.writelines("[" + time.strftime("%m.%d.%Y_%H-%M-%S") + "] "+ message + "\n") print(("[" + time.strftime("%m.%d.%Y_%H-%M-%S") + "] "+ message + "\n")) file.close() + + BackupJobLogs(owner=backupSchedule.backupLog, status=status, message="[" + time.strftime("%m.%d.%Y_%H-%M-%S") + "] "+ message).save() + except IOError as msg: return "Can not write to error file." @@ -120,18 +128,25 @@ class backupSchedule: except: pass - backupSchedule.remoteBackupLogging(backupLogPath, "An error occurred, Error message: " + status) + backupSchedule.remoteBackupLogging(backupLogPath, "Local backup creating failed for %s, Error message: %s" % (virtualHost, status), backupSchedule.ERROR) + try: os.remove(pathToFile) except: pass return 0, tempStoragePath + elif os.path.exists(schedulerPath): + backupSchedule.remoteBackupLogging(backupLogPath, 'Backup process killed without reporting any error.', + backupSchedule.ERROR) os.remove(schedulerPath) return 0, 'Backup process killed without reporting any error.' except BaseException as msg: logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [119:startBackup]") + backupSchedule.remoteBackupLogging(backupLogPath, + "Local backup creating failed for %s, Error message: %s" % ( + virtualHost, str(msg)), backupSchedule.ERROR) return 0, str(msg) @staticmethod diff --git a/plogical/backupScheduleLocal.py b/plogical/backupScheduleLocal.py index 313594ffd..1fcee1aea 100755 --- a/plogical/backupScheduleLocal.py +++ b/plogical/backupScheduleLocal.py @@ -29,6 +29,12 @@ class backupScheduleLocal: backupRunTime = time.strftime("%m.%d.%Y_%H-%M-%S") backupLogPath = "/usr/local/lscp/logs/local_backup_log." + backupRunTime + jobSuccessSites = 0 + jobFailedSites = 0 + + backupSchedule.backupLog = BackupJob(logFile=backupLogPath, location=backupSchedule.LOCAL, jobSuccessSites=jobSuccessSites, jobFailedSites=jobFailedSites) + backupSchedule.backupLog.save() + writeToFile = open(backupLogPath, "a") backupSchedule.remoteBackupLogging(backupLogPath, "#################################################") @@ -43,6 +49,9 @@ class backupScheduleLocal: try: retValues = backupSchedule.createLocalBackup(virtualHost, backupLogPath) + if retValues[0] == 0: + continue + if os.path.exists(backupScheduleLocal.localBackupPath): backupPath = retValues[1] + ".tar.gz" localBackupPath = '%s/%s' % (open(backupScheduleLocal.localBackupPath, 'r').read().rstrip('/'), backupRunTime) @@ -52,10 +61,14 @@ class backupScheduleLocal: command = 'mv %s %s' % (backupPath, localBackupPath) ProcessUtilities.normalExecutioner(command) - except BaseException as msg: - backupSchedule.remoteBackupLogging(backupLogPath, - '[ERROR] Backup failed for %s, error: %s moving on..' % (virtualHost, str(msg))) + jobSuccessSites = jobSuccessSites + 1 + except BaseException as msg: + + jobFailedSites = jobFailedSites + 1 + + backupSchedule.remoteBackupLogging(backupLogPath, + '[ERROR] Backup failed for %s, error: %s moving on..' % (virtualHost, str(msg)), backupSchedule.ERROR) @@ -71,6 +84,11 @@ class backupScheduleLocal: writeToFile.close() + job = BackupJob.objects.get(logFile=backupLogPath) + job.jobFailedSites = jobFailedSites + job.jobSuccessSites = jobSuccessSites + job.save() + except BaseException as msg: logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [214:startBackup]") diff --git a/serverStatus/views.py b/serverStatus/views.py index 33efa23f6..60e7bc850 100755 --- a/serverStatus/views.py +++ b/serverStatus/views.py @@ -93,7 +93,6 @@ def litespeedStatus(request): logging.CyberCPLogFileWriter.writeToFile(str(msg) + "[litespeedStatus]") return redirect(loadLoginPage) - def stopOrRestartLitespeed(request): try: userID = request.session['userID'] @@ -127,7 +126,6 @@ def stopOrRestartLitespeed(request): logging.CyberCPLogFileWriter.writeToFile(str(msg) + "[stopOrRestartLitespeed]") return HttpResponse("Not Logged in as admin") - def cyberCPMainLogFile(request): try: userID = request.session['userID'] @@ -145,7 +143,6 @@ def cyberCPMainLogFile(request): logging.CyberCPLogFileWriter.writeToFile(str(msg) + "[cyberCPMainLogFile]") return redirect(loadLoginPage) - def getFurtherDataFromLogFile(request): try: userID = request.session['userID'] @@ -196,7 +193,6 @@ def services(request): except KeyError: return redirect(loadLoginPage) - def servicesStatus(request): try: userID = request.session['userID'] @@ -291,7 +287,6 @@ def servicesStatus(request): except KeyError: return redirect(loadLoginPage) - def servicesAction(request): try: userID = request.session['userID'] @@ -344,7 +339,6 @@ def servicesAction(request): final_json = json.dumps(final_dic) return HttpResponse(final_json) - def switchTOLSWS(request): try: userID = request.session['userID'] @@ -378,7 +372,6 @@ def switchTOLSWS(request): json_data = json.dumps(data_ret) return HttpResponse(json_data) - def switchTOLSWSStatus(request): try: diff --git a/static/backup/backup.js b/static/backup/backup.js index cbe74d8ef..59c654f87 100644 --- a/static/backup/backup.js +++ b/static/backup/backup.js @@ -1541,4 +1541,68 @@ app.controller('remoteBackupControl', function ($scope, $http, $timeout) { }); -///** Backup site ends **/// \ No newline at end of file +///** Backup site ends **/// + + +//*** Remote Backup site ****// +app.controller('backupLogsScheduled', function ($scope, $http, $timeout) { + + $scope.cyberpanelLoading = true; + $scope.logDetails = true; + + $scope.currentPage = 1; + $scope.recordsToShow = 10; + + $scope.fetchLogs = function () { + + $scope.cyberpanelLoading = false; + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + var data = { + logFile: $scope.logFile, + recordsToShow: $scope.recordsToShow, + page: $scope.currentPage + }; + + dataurl = "/backup/fetchLogs"; + + $http.post(dataurl, data, config).then(ListInitialData, cantLoadInitialData); + + function ListInitialData(response) { + $scope.cyberpanelLoading = true; + if (response.data.status === 1) { + $scope.logDetails = false; + $scope.logs = JSON.parse(response.data.logs); + $scope.pagination = response.data.pagination; + $scope.jobSuccessSites = response.data.jobSuccessSites; + $scope.jobFailedSites = response.data.jobFailedSites; + $scope.location = response.data.location; + } else { + new PNotify({ + title: 'Error!', + text: response.data.error_message, + type: 'error' + }); + } + } + function cantLoadInitialData(response) { + $scope.cyberpanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type: 'error' + }); + } + + + }; + + +}); + +///** Backup site ends **///