diff --git a/norg.nimble b/norg.nimble index 89f62c1..9d07872 100644 --- a/norg.nimble +++ b/norg.nimble @@ -14,3 +14,4 @@ bin = @["norg"] requires "nim >= 2.0.0" requires "parsetoml >= 0.7.1" requires "argparse >= 4.0.1" +requires "threadlogging" diff --git a/norg/borg/borg.nim b/norg/borg/borg.nim index 4119631..cee47cc 100644 --- a/norg/borg/borg.nim +++ b/norg/borg/borg.nim @@ -1,6 +1,7 @@ import ../model/config_type import ../model/command_type import ../utils/actions +import ../model/log_type import execute import prune @@ -9,6 +10,7 @@ import mount import extract + proc initRepo(nc: NorgConfig, repo: Repository): int = return runDiscard genCommand(cmd = "init", repo = repo.path, further_args = nc.args.further_args) @@ -16,43 +18,43 @@ proc listArchives(nc: NorgConfig, repo: Repository): int = return run genCommand(cmd = "list", repo = repo.path, further_args = nc.args.further_args) proc compactRepo(nc: NorgConfig, repo: Repository): int = - echo "Not Yet Implemented." + error "Not Yet Implemented." discard proc checkRepo(nc: NorgConfig, repo: Repository): int = - echo "Not Yet Implemented." + error "Not Yet Implemented." discard proc execute*(nc: NorgConfig, repo: Repository): int {.discardable.} = case nc.args.command of INIT: - echo "Initializing repo: ", repo.label + info "Initializing repo: ", repo.label discard initRepo(nc, repo) of CREATE: run_actions(norg_config.actions.before_backup) - echo "Creating archive on ", repo.label + info "Creating archive on ", repo.label discard createBackup(nc, repo) run_actions(norg_config.actions.after_backup) of LIST: - echo "Listing Archives on ", repo.label + info "Listing Archives on ", repo.label discard listArchives(nc, repo) of MOUNT: - echo "Mounting Archive from ", repo.label + info "Mounting Archive from ", repo.label discard mountArchive(nc, repo) of UMOUNT: discard unmountArchive(nc) of EXTRACT: run_actions(norg_config.actions.before_extract) - echo "Extracting archive from ", repo.label + info "Extracting archive from ", repo.label discard extractArchive(nc, repo) run_actions(norg_config.actions.after_extract) of PRUNE: run_actions(norg_config.actions.before_prune) - echo "Pruning repo: ", repo.label + info "Pruning repo: ", repo.label discard pruneRepo(nc, repo) run_actions(norg_config.actions.after_prune) of DELETE: - echo "Deleting Archive ", nc.args.archive + info "Deleting Archive ", nc.args.archive discard deleteArchive(nc, repo) of COMPACT: run_actions(norg_config.actions.before_compact) diff --git a/norg/borg/create.nim b/norg/borg/create.nim index f20ec89..fce9f58 100644 --- a/norg/borg/create.nim +++ b/norg/borg/create.nim @@ -1,6 +1,7 @@ import ../model/config_type import ../model/state_type import ../notifier/notifier +import ../model/log_type import execute import prune @@ -19,6 +20,7 @@ proc createArchive(nc: NorgConfig, repo: Repository, archivename: string, retry: let further_args = nc.args.further_args let res = run genCreateCommand(repo = archivename, sources = nc.source_directories, stats=nc.args.stats, further_args = further_args) if res != 0: + info "Failed to run Restic. Waiting 15 seconds and trying again" sleep 15 * 1000 # 15 seconds if retry == nc.retries: return 1 @@ -30,6 +32,7 @@ proc createBackup*(nc: NorgConfig, repo: Repository): int = let start_time = now() notify(nc.notifiers, state=Running) let archivename = repo.path & "::" & genArchiveName() + debug "Creating Archive: ", archivename let res = createArchive(nc, repo, archivename) let end_time = now() let total = (end_time - start_time).inMilliSeconds() diff --git a/norg/borg/extract.nim b/norg/borg/extract.nim index 17f9a6b..dde79c9 100644 --- a/norg/borg/extract.nim +++ b/norg/borg/extract.nim @@ -1,4 +1,6 @@ import ../model/config_type +import ../model/log_type + import execute import strformat import os @@ -17,8 +19,8 @@ proc extractArchive*(nc: NorgConfig, repo: Repository): int = setCurrentDir(nc.args.extract_destination) let dir = getCurrentDir() if dir.isEmpty(): - echo "Restoring..." + info "Restoring..." let ok = run genCommand(cmd = "extract", repo = archive, further_args = further_args) return ok else: - echo "Not restoring to non-empty destination\r\nPlease use the --destination flag or cd to an empty directory." + error "Not restoring to non-empty destination\r\nPlease use the --destination flag or cd to an empty directory." diff --git a/norg/borg/mount.nim b/norg/borg/mount.nim index e4c132f..89a06a1 100644 --- a/norg/borg/mount.nim +++ b/norg/borg/mount.nim @@ -1,4 +1,6 @@ import ../model/config_type +import ../model/log_type + import execute import strformat @@ -7,13 +9,13 @@ proc mountArchive*(nc: NorgConfig, repo: Repository): int = let further_args = nc.args.further_args let ok = runDiscard genCommand(cmd = "mount", repo = archive, further_args = further_args) if ok == 0: - echo fmt"Mounted {archive} at {further_args[0]}" + info fmt"Mounted {archive} at {further_args[0]}" else: - echo "Failed to mount ", archive + error "Failed to mount ", archive proc unmountArchive*(nc: NorgConfig): int = let ok = runDiscard genCommand(cmd = "umount", repo = "", further_args = nc.args.further_args) if ok == 0: - echo "Unmounted ", nc.args.further_args[0] + info "Unmounted ", nc.args.further_args[0] else: - echo "Failed to unmount ", nc.args.further_args[0] + error "Failed to unmount ", nc.args.further_args[0] diff --git a/norg/config/init.nim b/norg/config/init.nim index fc85936..87ab790 100644 --- a/norg/config/init.nim +++ b/norg/config/init.nim @@ -39,6 +39,13 @@ proc parseEncryption*(enc_conf: TomlValueRef) = setEncryptionPassphraseFile(enc_conf{"encryption_passphrase_file"}.getStr("")) setEncryptionPassCommand(enc_conf{"encryption_passcommand"}.getStr("")) +proc parseLogging(nc: var NorgConfig, log_conf: TomlValueRef) = + let ll = log_conf{"log_level"}.getStr() + if ll != "": + nc.log_info.level = ll.toLogLevel() + nc.log_info.file = log_conf{"log_file"}.getStr() + discard + proc addConfigBinaries*(current: var Binaries, bin_conf: TomlValueRef) = let borg = bin_conf{"borg_bin"}.getStr() @@ -61,6 +68,7 @@ proc parseConfigFile*(file: string): NorgConfig = norg_config.maintenance = parseMaintenance(in_conf{"maintenance"}) norg_config.bins.addConfigBinaries(in_conf{"binaries"}) norg_config.bins.setBinaryLocations() + norg_config.parseLogging(in_conf{"logging"}) return norg_config diff --git a/norg/model/config_type.nim b/norg/model/config_type.nim index 93fcc49..689e3e7 100644 --- a/norg/model/config_type.nim +++ b/norg/model/config_type.nim @@ -4,6 +4,7 @@ import actions_type import maintenance_type import binary_type import args_type +import log_type export repository_type export notifier_types @@ -11,8 +12,10 @@ export actions_type export maintenance_type export binary_type export args_type +export log_type import ../utils/version + const VERSION*: string = getVersion() type @@ -26,11 +29,13 @@ type actions*: Actions args*: NorgArgs bins*: Binaries + log_info*: LogInfo proc newNorgConfig*(): NorgConfig = var nc = NorgConfig() nc.maintenance = newMaintenance() nc.bins = newBinaries() + nc.log_info = newLogInfo() return nc var norg_config*: NorgConfig = newNorgConfig() diff --git a/norg/model/log_type.nim b/norg/model/log_type.nim new file mode 100644 index 0000000..c51634b --- /dev/null +++ b/norg/model/log_type.nim @@ -0,0 +1,22 @@ +import logging +import threadlogging + +export logging.newConsoleLogger +export logging.newFileLogger +export threadlogging + +type + LogInfo* = object + level*: Level + file*: string + +proc newLogInfo*(): LogInfo = + var log = LogInfo() + log.level = lvlInfo + log.file = "" + return log + +proc toLogLevel*(s: string): Level = + for l in Level.items: + if s == $l: return l + return lvlInfo diff --git a/norg/norg.nim b/norg/norg.nim index f215189..bd02de9 100644 --- a/norg/norg.nim +++ b/norg/norg.nim @@ -4,11 +4,16 @@ import borg/borg import restic/restic import model/encryption_type import utils/actions +import model/log_type +import os proc showVersion() = echo "Norg Version: ", VERSION quit(0) +proc startLogger(nc: NorgConfig) = + initLogThread("[$levelname] ", nc.log_info.level) + proc start() = parseArgs() norg_config.args = norg_args @@ -16,6 +21,7 @@ proc start() = showVersion() elif norg_args.config_file != "": norg_config = parseConfigFile(norg_args.config_file) + startLogger(norg_config) if norg_config.source_directories.len > 0 and norg_config.repositories.len > 0: run_actions(norg_config.actions.before_everything) for repo in norg_config.repositories: @@ -33,3 +39,5 @@ proc start() = when isMainModule: start() + # sleep for a bit to let logs finish + sleep 5 diff --git a/norg/notifier/uptimekuma_notifier.nim b/norg/notifier/uptimekuma_notifier.nim index 257496e..7784191 100644 --- a/norg/notifier/uptimekuma_notifier.nim +++ b/norg/notifier/uptimekuma_notifier.nim @@ -1,5 +1,6 @@ import ../model/state_type import ../model/notifier_type +import ../model/log_type import strformat import ../utils/httprequest @@ -19,7 +20,7 @@ proc send_notify*(uk: UptimeKuma, state: State, runtime: int = 0, msg: string = message &= fmt":{msg}" let url = fmt"{uk.base_url}?status={status}&msg={message}&ping={runtime}" - echo "Sending notification to " & url + debug "Sending notification to " & url let res = sendHttpRequest(HttpGet, url) if res.status == $Http200: return 0 diff --git a/norg/restic/mount.nim b/norg/restic/mount.nim index 00d195b..52d821c 100644 --- a/norg/restic/mount.nim +++ b/norg/restic/mount.nim @@ -2,11 +2,13 @@ import ../model/config_type import execute import strformat +import threadlogging + proc mountSnapshot*(nc: NorgConfig, repo: Repository): int = #let further_args = nc.args.further_args[1..^1] let further_args = nc.args.further_args let ok = runDiscard genCommand(cmd = "mount", repo = repo.path, further_args = further_args) if ok == 0: - echo fmt"Mounted {repo.path} at {further_args[0]}" + info fmt"Mounted {repo.path} at {further_args[0]}" else: - echo "Failed to mount ", repo.path + error "Failed to mount ", repo.path diff --git a/norg/restic/restic.nim b/norg/restic/restic.nim index 7f6fba0..67fc575 100644 --- a/norg/restic/restic.nim +++ b/norg/restic/restic.nim @@ -8,34 +8,36 @@ import mount import restore import prune +import threadlogging + proc execute*(nc: NorgConfig, repo: Repository) = case nc.args.command of INIT: - echo "Initializing repo: ", repo.label + info "Initializing repo: ", repo.label discard initRepo(nc, repo) of CREATE: run_actions(norg_config.actions.before_backup) - echo "Backing up to ", repo.label + info "Backing up to ", repo.label discard createBackup(nc, repo) run_actions(norg_config.actions.after_backup) of LIST: - echo "Listing Snapshots at ", repo.label + info "Listing Snapshots at ", repo.label discard listSnapshots(nc, repo) of MOUNT: - echo "Mounting Snapshot from ", repo.label + info "Mounting Snapshot from ", repo.label discard mountSnapshot(nc, repo) of EXTRACT: run_actions(norg_config.actions.before_extract) - echo "Restoring snapshot from ", repo.label + info "Restoring snapshot from ", repo.label discard restoreSnapshot(nc, repo) run_actions(norg_config.actions.after_extract) of PRUNE: run_actions(norg_config.actions.before_prune) - echo "Pruning repo: ", repo.label + info "Pruning repo: ", repo.label discard pruneRepo(nc, repo) run_actions(norg_config.actions.after_prune) of DELETE: - echo "Forgetting snapshot: ", nc.args.archive + info "Forgetting snapshot: ", nc.args.archive discard forgetSnapshot(nc, repo) else: discard diff --git a/norg/restic/restore.nim b/norg/restic/restore.nim index 903e3b3..b600d6b 100644 --- a/norg/restic/restore.nim +++ b/norg/restic/restore.nim @@ -3,6 +3,8 @@ import execute import strformat import os +import threadlogging + proc isEmpty(dir: string): bool = var count = 0 for idx, f in walkDir(dir): return false @@ -17,8 +19,8 @@ proc restoreSnapshot*(nc: NorgConfig, repo: Repository): int = setCurrentDir(nc.args.extract_destination) let dir = getCurrentDir() if dir.isEmpty(): - echo "Restoring..." + info "Restoring..." let ok = run genRestoreCommand(repo_snapshot = repo_snapshot, destination = nc.args.extract_destination, further_args = further_args) return ok else: - echo "Not restoring to non-empty destination\r\nPlease use the --destination flag or cd to an empty directory." + error "Not restoring to non-empty destination\r\nPlease use the --destination flag or cd to an empty directory." diff --git a/norg/utils/run.nim b/norg/utils/run.nim index 05784d9..c4d951c 100644 --- a/norg/utils/run.nim +++ b/norg/utils/run.nim @@ -1,21 +1,22 @@ import strformat import osproc +import threadlogging proc run*(cmd: string): int = - echo fmt"Trying to run : {cmd}" + debug fmt"Trying to run : {cmd}" try: let res = execCmd(cmd) return res except: - echo getCurrentExceptionMsg() + error getCurrentExceptionMsg() return 1 proc runDiscard*(cmd: string): int = - echo fmt"Trying to run : {cmd}" + debug fmt"Trying to run : {cmd}" try: let res = execCmd(cmd) return res except: - echo getCurrentExceptionMsg() + error getCurrentExceptionMsg() return 1