monitor: refactor class LogLine to log_entry()

The class LogLine() is purely used as a dataclass with no state
and the only function on it is `as_dict()`. This got refactored
into a new function `log_entry()` because there is no need for
this to be a class. The function that takes the same inputs.
This commit is contained in:
Michael Vogt 2023-11-22 08:53:41 +01:00 committed by Ondřej Budai
parent 16c1768780
commit ac16590838
2 changed files with 39 additions and 31 deletions

View file

@ -149,31 +149,21 @@ class Progress:
return d return d
class LogLine: def log_entry(message: Optional[str] = None,
"""A single JSON serializable log line context: Optional[Context] = None,
progress: Optional[Progress] = None) -> dict:
Create a single log line with a given message, error message, context, and progress objects.
All arguments are optional. A timestamp is added to the dictionary when calling the 'as_dict()' method.
""" """
Create a single log entry dict with a given message, context, and progress objects.
def __init__(self, *, All arguments are optional. A timestamp is added to the message.
message: Optional[str] = None, """
error: Optional[str] = None, # we probably want to add an (optional) error message here too once the
context: Optional[Context] = None, # monitors support that
progress: Optional[Progress] = None): return omitempty({
self.message = message "message": message,
self.error = error "context": context.as_dict() if context else None,
self.context = context "progress": progress.as_dict() if progress else None,
self.progress = progress "timestamp": time.time(),
})
def as_dict(self):
return omitempty({
"message": self.message,
"error": self.error,
"context": self.context.as_dict(),
"progress": self.progress.as_dict(),
"timestamp": time.time(),
})
class TextWriter: class TextWriter:
@ -331,16 +321,15 @@ class JSONSeqMonitor(BaseMonitor):
oo = self._context.origin oo = self._context.origin
if origin is not None: if origin is not None:
self._context.origin = origin self._context.origin = origin
line = LogLine(message=message, context=self._context, progress=self._progress) entry = log_entry(message=message, context=self._context, progress=self._progress)
self._jsonseq(line.as_dict()) self._jsonseq(entry)
# needs to be here as LogLine has a ref to self._context so updates # restore old origin
# before line.as_dict() will be have a different context
self._context.origin = oo self._context.origin = oo
def _jsonseq(self, data): def _jsonseq(self, entry):
# follow rfc7464 (application/json-seq) # follow rfc7464 (application/json-seq)
self.out.write("\x1e") self.out.write("\x1e")
json.dump(data, self.out) json.dump(entry, self.out)
self.out.write("\n") self.out.write("\n")

View file

@ -7,13 +7,14 @@ import json
import os import os
import sys import sys
import tempfile import tempfile
import time
import unittest import unittest
from collections import defaultdict from collections import defaultdict
import osbuild import osbuild
import osbuild.meta import osbuild.meta
from osbuild.monitor import LogMonitor from osbuild.monitor import LogMonitor
from osbuild.monitor import JSONSeqMonitor, Context, Progress, LogLine from osbuild.monitor import JSONSeqMonitor, Context, Progress, log_entry
from osbuild.objectstore import ObjectStore from osbuild.objectstore import ObjectStore
from osbuild.pipeline import Runner from osbuild.pipeline import Runner
@ -241,3 +242,21 @@ def test_json_progress_monitor():
assert logitem["message"] == "pipeline 2 starting" assert logitem["message"] == "pipeline 2 starting"
assert logitem["context"]["origin"] == "org.osbuild" assert logitem["context"]["origin"] == "org.osbuild"
assert logitem["context"]["pipeline"]["name"] == "test-pipeline-second" assert logitem["context"]["pipeline"]["name"] == "test-pipeline-second"
def test_log_line_empty_is_fine():
empty = log_entry()
assert len(empty) == 1
assert empty["timestamp"] > time.time()-60
assert empty["timestamp"] < time.time()+60
def test_log_line_with_entries():
ctx = Context("some-origin")
progress = Progress(name="foo", total=2)
entry = log_entry("some-msg", ctx, progress)
assert len(entry) == 4
assert entry["message"] == "some-msg"
assert isinstance(entry["context"], dict)
assert isinstance(entry["progress"], dict)
assert entry["timestamp"] > 0