Add logging facility

This commit is contained in:
Leo Koppelkamm 2015-08-08 11:27:25 +02:00
parent df8de717ce
commit a2098b1ace
3 changed files with 60 additions and 27 deletions

View File

@ -11,12 +11,17 @@
import os, os.path, shutil, glob, re, datetime import os, os.path, shutil, glob, re, datetime
import dateutil.parser, dateutil.relativedelta, dateutil.tz import dateutil.parser, dateutil.relativedelta, dateutil.tz
import rtyaml import rtyaml
import logging
from utils import exclusive_process, load_environment, shell, wait_for_service from utils import exclusive_process, load_environment, shell, wait_for_service
# Root folder # Root folder
backup_root = os.path.join(load_environment()["STORAGE_ROOT"], 'backup') backup_root = os.path.join(load_environment()["STORAGE_ROOT"], 'backup')
# Setup logging
log_path = os.path.join(backup_root, 'backup.log')
logging.basicConfig(filename=log_path, format='%(levelname)s at %(asctime)s: %(message)s')
# Default settings # Default settings
# min_age_in_days is the minimum amount of days a backup will be kept before # min_age_in_days is the minimum amount of days a backup will be kept before
# it is eligble to be removed. Backups might be kept much longer if there's no # it is eligble to be removed. Backups might be kept much longer if there's no
@ -236,6 +241,9 @@ def perform_backup(full_backup):
"--allow-source-mismatch" "--allow-source-mismatch"
], ],
get_env()) get_env())
logging.info("Backup successful")
except Exception as e:
logging.warn("Backup failed: {0}".format(e))
finally: finally:
# Start services again. # Start services again.
shell('check_call', ["/usr/sbin/service", "dovecot", "start"]) shell('check_call', ["/usr/sbin/service", "dovecot", "start"])
@ -247,29 +255,35 @@ def perform_backup(full_backup):
# Remove old backups. This deletes all backup data no longer needed # Remove old backups. This deletes all backup data no longer needed
# from more than 3 days ago. # from more than 3 days ago.
shell('check_call', [ try:
"/usr/bin/duplicity", shell('check_call', [
"remove-older-than", "/usr/bin/duplicity",
"%dD" % config["min_age_in_days"], "remove-older-than",
"--archive-dir", backup_cache_dir, "%dD" % config["min_age_in_days"],
"--force", "--archive-dir", backup_cache_dir,
config["target"] "--force",
], config["target"]
get_env()) ],
get_env())
except Exception as e:
logging.warn("Removal of old backups failed: {0}".format(e))
# From duplicity's manual: # From duplicity's manual:
# "This should only be necessary after a duplicity session fails or is # "This should only be necessary after a duplicity session fails or is
# aborted prematurely." # aborted prematurely."
# That may be unlikely here but we may as well ensure we tidy up if # That may be unlikely here but we may as well ensure we tidy up if
# that does happen - it might just have been a poorly timed reboot. # that does happen - it might just have been a poorly timed reboot.
shell('check_call', [ try:
"/usr/bin/duplicity", shell('check_call', [
"cleanup", "/usr/bin/duplicity",
"--archive-dir", backup_cache_dir, "cleanup",
"--force", "--archive-dir", backup_cache_dir,
config["target"] "--force",
], config["target"]
get_env()) ],
get_env())
except Exception as e:
logging.warn("Cleanup of backups failed: {0}".format(e))
# Change ownership of backups to the user-data user, so that the after-bcakup # Change ownership of backups to the user-data user, so that the after-bcakup
# script can access them. # script can access them.
@ -336,6 +350,16 @@ def get_backup_config():
merged_config.update(config) merged_config.update(config)
return config return config
def get_backup_log():
try:
fileHandle = open(log_path, 'r')
log = fileHandle.read()
fileHandle.close()
except:
log = ""
return log
def write_backup_config(newconfig): def write_backup_config(newconfig):
with open(os.path.join(backup_root, 'custom.yaml'), "w") as f: with open(os.path.join(backup_root, 'custom.yaml'), "w") as f:

View File

@ -4,7 +4,7 @@ import os, os.path, re, json
from functools import wraps from functools import wraps
from flask import Flask, request, render_template, abort, Response, send_from_directory from flask import Flask, request, render_template, abort, Response, send_from_directory, jsonify
import auth, utils import auth, utils
from mailconfig import get_mail_users, get_mail_users_ex, get_admins, add_mail_user, set_mail_password, remove_mail_user from mailconfig import get_mail_users, get_mail_users_ex, get_admins, add_mail_user, set_mail_password, remove_mail_user
@ -399,14 +399,14 @@ def do_updates():
@app.route('/system/backup/status') @app.route('/system/backup/status')
@authorized_personnel_only @authorized_personnel_only
def backup_status(): def backup_status():
from backup import backup_status from backup import backup_status, get_backup_log
return json_response(backup_status(env)) return jsonify(backups=backup_status(env), log=get_backup_log())
@app.route('/system/backup/config', methods=["GET"]) @app.route('/system/backup/config', methods=["GET"])
@authorized_personnel_only @authorized_personnel_only
def backup_get_custom(): def backup_get_custom():
from backup import get_backup_config from backup import get_backup_config
return json_response(get_backup_config()) return jsonify(get_backup_config())
@app.route('/system/backup/config', methods=["POST"]) @app.route('/system/backup/config', methods=["POST"])
@authorized_personnel_only @authorized_personnel_only

View File

@ -68,6 +68,11 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<h3>Backup logs</h3>
<pre id="backup-log"></pre>
<script> <script>
function toggle_form() { function toggle_form() {
@ -104,22 +109,24 @@ function show_system_backup() {
"GET", "GET",
{ }, { },
function(r) { function(r) {
$('#backup-location').text(r.directory); var status = r.backups;
$('#backup-encpassword-file').text(r.encpwfile); var log = r.log;
$('#backup-location').text(status.directory);
$('#backup-encpassword-file').text(status.encpwfile);
$('#backup-status tbody').html(""); $('#backup-status tbody').html("");
var total_disk_size = 0; var total_disk_size = 0;
if (r.backups.length == 0) { if (status.backups.length == 0) {
var tr = $('<tr><td colspan="3">No backups have been made yet.</td></tr>'); var tr = $('<tr><td colspan="3">No backups have been made yet.</td></tr>');
$('#backup-status tbody').append(tr); $('#backup-status tbody').append(tr);
} }
for (var i = 0; i < r.backups.length; i++) { for (var i = 0; i < status.backups.length; i++) {
var b = r.backups[i]; var b = status.backups[i];
var tr = $('<tr/>'); var tr = $('<tr/>');
if (b.full) tr.addClass("full-backup"); if (b.full) tr.addClass("full-backup");
tr.append( $('<td/>').text(b.date_str + " " + r.tz) ); tr.append( $('<td/>').text(b.date_str + " " + status.tz) );
tr.append( $('<td/>').text(b.date_delta + " ago") ); tr.append( $('<td/>').text(b.date_delta + " ago") );
tr.append( $('<td/>').text(b.full ? "full" : "increment") ); tr.append( $('<td/>').text(b.full ? "full" : "increment") );
tr.append( $('<td style="text-align: right"/>').text( nice_size(b.size)) ); tr.append( $('<td style="text-align: right"/>').text( nice_size(b.size)) );
@ -133,6 +140,8 @@ function show_system_backup() {
} }
$('#backup-total-size').text(nice_size(total_disk_size)); $('#backup-total-size').text(nice_size(total_disk_size));
$('#backup-log').text(log || 'No backup logs yet');
}) })
} }