mirror of
https://codeberg.org/vlw/cloud-backup.git
synced 2025-09-14 01:53:42 +02:00
wip(22w10a): add logger
This commit is contained in:
parent
d9a6183d63
commit
e58bb45001
5 changed files with 78 additions and 17 deletions
16
.env.example
16
.env.example
|
@ -1,9 +1,15 @@
|
|||
# Path to the local folder to back up
|
||||
# (Required) Absolute path to the local folder to back up
|
||||
SOURCE_FOLDER=""
|
||||
# Name of the remote bucket (destination)
|
||||
# (Required) Name of the remote bucket or container
|
||||
TARGET_BUCKET=""
|
||||
|
||||
# Cloud provider (gcs, s3, azure)
|
||||
# (Required) Cloud provider (gcs, s3, azure)
|
||||
SERVICE_NAME=""
|
||||
# Cloud provider access string or path to key file
|
||||
SERVICE_KEY=""
|
||||
# (Required) Cloud provider access string or path to key file
|
||||
SERVICE_KEY=""
|
||||
|
||||
# -----------------------------------------------------------
|
||||
|
||||
# (Optional) Path to log file and level
|
||||
LOG_FILE=""
|
||||
LOG_LEVEL="WARNING"
|
|
@ -1,9 +1,24 @@
|
|||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from .db import Database, dbname
|
||||
from .fs import FileSystem, file_exists
|
||||
from .backup import Backup
|
||||
|
||||
# Required environment variables
|
||||
required_vars = (
|
||||
"SOURCE_FOLDER",
|
||||
"TARGET_BUCKET",
|
||||
"SERVICE_NAME",
|
||||
"SERVICE_KEY",
|
||||
"LOG_LEVEL"
|
||||
)
|
||||
|
||||
if not file_exists(".env"):
|
||||
raise FileNotFoundError("Environment variable file does not exist. Copy '.env.example' to '.env'")
|
||||
|
||||
load_dotenv()
|
||||
load_dotenv()
|
||||
|
||||
# Check that required environment variables are set
|
||||
if not all(map(lambda var: os.getenv(var), required_vars)):
|
||||
raise SystemExit("One or more required environment variables in '.env' have not been set")
|
|
@ -1,3 +1,6 @@
|
|||
import os
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from typing import Union
|
||||
|
||||
from .cloud import Storage as StorageClient
|
||||
|
@ -7,6 +10,7 @@ from . import dbname
|
|||
class Backup(FileSystem):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.enable_logging()
|
||||
|
||||
self.has_change = False
|
||||
|
||||
|
@ -15,6 +19,37 @@ class Backup(FileSystem):
|
|||
|
||||
self.compress = self.db.get_flag("COMPRESS")
|
||||
|
||||
# Configure logging
|
||||
def enable_logging(self):
|
||||
self.log = logging.getLogger(__name__)
|
||||
self.log.debug("Start console logging")
|
||||
log_format = logging.Formatter("[%(asctime)s][%(levelname)s]: %(name)s: %(message)s")
|
||||
|
||||
# Log to console
|
||||
log_console = logging.StreamHandler()
|
||||
log_console.setLevel(logging.INFO)
|
||||
log_console.setFormatter(log_format)
|
||||
|
||||
self.log.addHandler(log_console)
|
||||
|
||||
# Log to file
|
||||
log_file_path = os.getenv("LOG_FILE")
|
||||
if log_file_path:
|
||||
self.log.debug("Start file logging")
|
||||
log_file = RotatingFileHandler(
|
||||
log_file_path,
|
||||
mode = "a",
|
||||
maxBytes = 50 * 1024 * 1024,
|
||||
backupCount = 5,
|
||||
encoding = None,
|
||||
delay = False
|
||||
)
|
||||
|
||||
log_file.setLevel(os.getenv("LOG_LEVEL"))
|
||||
log_file.setFormatter(log_format)
|
||||
|
||||
self.log.addHandler(log_file)
|
||||
|
||||
# Backup a file or folder
|
||||
def backup_item(self, item: Union[list, str], silent: bool = True) -> bool:
|
||||
if isinstance(item, str):
|
||||
|
@ -32,31 +67,35 @@ class Backup(FileSystem):
|
|||
|
||||
self.has_change = True
|
||||
|
||||
print(f"⧖ | Uploading: '{item[0]}'", end="\r")
|
||||
self.log.info(f"'{item[0]}': Uploading")
|
||||
print(f"⏳ | Uploading: '{item[0]}'", end="\r")
|
||||
|
||||
blob = item
|
||||
# Upload as zip archive
|
||||
if self.compress:
|
||||
self.log.debug(f"'{item[0]}': Compressing")
|
||||
blob = FileSystem.zip(blob)
|
||||
|
||||
# Upload to cloud
|
||||
if self.cloud.upload(blob):
|
||||
print(f"✓ | Upload sucessful: '{item[0]}'")
|
||||
self.log.debug(f"'{item[0]}': Uploaded")
|
||||
print(f"✅ | Upload successful: '{item[0]}'")
|
||||
# Update local database
|
||||
if not self.db.set_item(item):
|
||||
print("🛈 | Failed to update database")
|
||||
self.log.warn(f"'{item[0]}': Failed to update database")
|
||||
print("⚠️ | Failed to update database")
|
||||
else:
|
||||
print(f"✕ | Upload failed: '{item[0]}'")
|
||||
if self.cloud.error:
|
||||
print("🛈 | " + str(self.cloud.error))
|
||||
|
||||
self.log.error(f"'{item[0]}': {self.cloud.error}")
|
||||
print(f"❌ | Upload failed: '{item[0]}'")
|
||||
|
||||
# Remove temp zip
|
||||
if self.compress:
|
||||
FileSystem.delete(blob)
|
||||
|
||||
# Deprecated: Run when a single item is backed up directly
|
||||
if not silent and not self.has_change:
|
||||
print("✓ | Up to date. No changes found")
|
||||
self.log.info("No changes found")
|
||||
print("✅ | Up to date. No changes found")
|
||||
|
||||
return
|
||||
|
||||
|
@ -67,4 +106,5 @@ class Backup(FileSystem):
|
|||
self.backup_item(item)
|
||||
|
||||
if not self.has_change:
|
||||
print("✓ | Up to date. No changes found")
|
||||
self.log.info("No changes found")
|
||||
print("✅ | Up to date. No changes found")
|
|
@ -27,5 +27,5 @@ class StorageClient:
|
|||
return True
|
||||
except Exception as e:
|
||||
if e.response.status_code == 403:
|
||||
self.error = "Account lacks 'storage.objects.create' permissions on this bucket "
|
||||
self.error = "Azure: Access key invalid or lacking required permissions"
|
||||
return False
|
|
@ -35,5 +35,5 @@ class StorageClient:
|
|||
return True
|
||||
except Exception as e:
|
||||
if e.response.status_code == 403:
|
||||
self.error = "Account lacks 'storage.objects.create' permissions on this bucket "
|
||||
self.error = "GCS: Forbidden: Account lacks 'storage.objects.create' role on target bucket"
|
||||
return False
|
Loading…
Add table
Reference in a new issue