diff --git a/osbuild/monitor.py b/osbuild/monitor.py index 79b7d084..4c7a2e4e 100644 --- a/osbuild/monitor.py +++ b/osbuild/monitor.py @@ -149,31 +149,21 @@ class Progress: return d -class LogLine: - """A single JSON serializable log line - - 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. +def log_entry(message: Optional[str] = None, + context: Optional[Context] = None, + progress: Optional[Progress] = None) -> dict: """ - - def __init__(self, *, - message: Optional[str] = None, - error: Optional[str] = None, - context: Optional[Context] = None, - progress: Optional[Progress] = None): - self.message = message - self.error = error - self.context = context - self.progress = progress - - 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(), - }) + Create a single log entry dict with a given message, context, and progress objects. + All arguments are optional. A timestamp is added to the message. + """ + # we probably want to add an (optional) error message here too once the + # monitors support that + return omitempty({ + "message": message, + "context": context.as_dict() if context else None, + "progress": progress.as_dict() if progress else None, + "timestamp": time.time(), + }) class TextWriter: @@ -331,16 +321,15 @@ class JSONSeqMonitor(BaseMonitor): oo = self._context.origin if origin is not None: self._context.origin = origin - line = LogLine(message=message, context=self._context, progress=self._progress) - self._jsonseq(line.as_dict()) - # needs to be here as LogLine has a ref to self._context so updates - # before line.as_dict() will be have a different context + entry = log_entry(message=message, context=self._context, progress=self._progress) + self._jsonseq(entry) + # restore old origin self._context.origin = oo - def _jsonseq(self, data): + def _jsonseq(self, entry): # follow rfc7464 (application/json-seq) self.out.write("\x1e") - json.dump(data, self.out) + json.dump(entry, self.out) self.out.write("\n") diff --git a/test/mod/test_monitor.py b/test/mod/test_monitor.py index 5880a2a9..c0302b8f 100644 --- a/test/mod/test_monitor.py +++ b/test/mod/test_monitor.py @@ -7,13 +7,14 @@ import json import os import sys import tempfile +import time import unittest from collections import defaultdict import osbuild import osbuild.meta 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.pipeline import Runner @@ -241,3 +242,21 @@ def test_json_progress_monitor(): assert logitem["message"] == "pipeline 2 starting" assert logitem["context"]["origin"] == "org.osbuild" 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