f5-backup 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: f5-backup
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Automatic backups to S3-compatible storage
5
5
  License: MIT
6
6
  Author: Will Hinson
@@ -15,6 +15,7 @@ from rich.progress import (
15
15
  TaskID,
16
16
  )
17
17
 
18
+ from ..console import console
18
19
  from ..devices import Partition, PartitionRemoved
19
20
  from .filekey import FileKey
20
21
  from .s3config import S3Config
@@ -27,8 +28,6 @@ _logger: logging.Logger = logging.getLogger(__name__)
27
28
 
28
29
 
29
30
  def _make_progress() -> Progress:
30
- console: Console = rich.get_console()
31
-
32
31
  return Progress(
33
32
  TextColumn("[bold]{task.description}", justify="right"),
34
33
  BarColumn(),
@@ -0,0 +1,7 @@
1
+ import rich
2
+ from rich.console import Console
3
+
4
+ __all__ = ["console"]
5
+
6
+
7
+ console: Console = rich.get_console()
@@ -0,0 +1,73 @@
1
+ import logging
2
+ import sys
3
+ from datetime import datetime, timezone
4
+
5
+ from rich.logging import RichHandler
6
+
7
+ from .console import console
8
+
9
+ # attributes every LogRecord has; anything else came from `extra=`
10
+ _RESERVED: set[str] = set(vars(logging.makeLogRecord({}))) | {"message", "asctime"}
11
+
12
+
13
+ def _logfmt_value(value: object) -> str:
14
+ text = str(value)
15
+ if text == "" or any(c in text for c in ' ="\\\n\t'):
16
+ text = (
17
+ text.replace("\\", "\\\\")
18
+ .replace('"', '\\"')
19
+ .replace("\n", "\\n")
20
+ .replace("\t", "\\t")
21
+ )
22
+ return f'"{text}"'
23
+ return text
24
+
25
+
26
+ class LogfmtFormatter(logging.Formatter):
27
+ """Format records as logfmt: time=... level=INFO logger=... msg="..." key=value"""
28
+
29
+ def format(self, record: logging.LogRecord) -> str:
30
+ fields: dict[str, object] = {
31
+ "time": datetime.fromtimestamp(record.created, tz=timezone.utc)
32
+ .isoformat(timespec="milliseconds")
33
+ .replace("+00:00", "Z"),
34
+ "level": record.levelname,
35
+ "logger": record.name,
36
+ "msg": record.getMessage(),
37
+ }
38
+ for key, value in vars(record).items():
39
+ if key not in _RESERVED and not key.startswith("_"):
40
+ fields[key] = value
41
+ if record.exc_info:
42
+ fields["error"] = self.formatException(record.exc_info)
43
+ if record.stack_info:
44
+ fields["stack"] = self.formatStack(record.stack_info)
45
+
46
+ return " ".join(
47
+ f"{key}={_logfmt_value(value)}" for key, value in fields.items()
48
+ )
49
+
50
+
51
+ def setup_logging(level: int | str = logging.INFO) -> None:
52
+ """
53
+ Configure logging: Rich output in a terminal, logfmt otherwise.
54
+
55
+ Args:
56
+ level (int | str): The logging level to set. Default is logging.INFO.
57
+ """
58
+
59
+ handler: logging.Handler
60
+ if console.is_terminal:
61
+ handler = RichHandler(console=console, rich_tracebacks=True, markup=False)
62
+ handler.setFormatter(
63
+ logging.Formatter("[%(name)s] %(message)s", datefmt="[%X]")
64
+ )
65
+ else:
66
+ handler = logging.StreamHandler(sys.stderr)
67
+ handler.setFormatter(LogfmtFormatter())
68
+
69
+ logging.basicConfig(
70
+ level=level,
71
+ handlers=[handler],
72
+ force=True,
73
+ )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "f5-backup"
3
- version = "0.1.0"
3
+ version = "0.2.0"
4
4
  description = "Automatic backups to S3-compatible storage"
5
5
  authors = [
6
6
  {name = "Will Hinson",email = "will@hinson.sh"}
@@ -1,23 +0,0 @@
1
- import logging
2
- from rich.logging import RichHandler
3
-
4
-
5
- def setup_logging(level: logging._Level = logging.INFO) -> None:
6
- """
7
- Setup logging configuration with RichHandler for better console output.
8
-
9
- Args:
10
- level (logging._Level): The logging level to set. Default is logging.INFO.
11
- """
12
-
13
- logging.basicConfig(
14
- level=level,
15
- format="[%(name)s] %(message)s",
16
- datefmt="[%X]",
17
- handlers=[
18
- RichHandler(
19
- rich_tracebacks=True,
20
- markup=False,
21
- )
22
- ],
23
- )
File without changes
File without changes
File without changes
File without changes