Skip to content

Commit

Permalink
logs: use less heavy structure for journald logging
Browse files Browse the repository at this point in the history
  • Loading branch information
orndorffgrant committed Feb 21, 2024
1 parent ca782c1 commit 3bbbe5b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
2 changes: 1 addition & 1 deletion features/unattached_commands.feature
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ Feature: Command behaviour when unattached
"""
Then stdout matches regexp:
"""
"WARNING", "ubuntupro.apt", "fail", \d+, "Failed to fetch ESM Apt Cache item: https://esm.ubuntu.com/apps/ubuntu/dists/<release>-apps-security/InRelease", {}]
WARNING|ubuntupro.apt|fail|\d+|Failed to fetch ESM Apt Cache item: https://esm.ubuntu.com/apps/ubuntu/dists/<release>-apps-security/InRelease|{}
"""
When I run `ls /var/crash/` with sudo
Then stdout does not contain substring:
Expand Down
51 changes: 44 additions & 7 deletions uaclient/log.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import abc
import json
import logging
import os
import pathlib
from collections import OrderedDict
from typing import Any, Dict, List, Union # noqa: F401
from typing import Any, Dict, List, Tuple, Union # noqa: F401

from uaclient import defaults, system, util
from uaclient.config import UAConfig
Expand All @@ -17,9 +18,10 @@ def filter(self, record: logging.LogRecord):
return True


class JsonArrayFormatter(logging.Formatter):
"""Json Array Formatter for our logging mechanism
Custom made for Pro logging needs
class BaseProFormatter(logging.Formatter, metaclass=abc.ABCMeta):
"""Formatter class that collects all the fields we care about in the
correct order and calls a subclass defined formatter function to turn
it into a string.
"""

default_time_format = "%Y-%m-%dT%H:%M:%S"
Expand All @@ -31,7 +33,7 @@ class JsonArrayFormatter(logging.Formatter):
"funcName",
"lineno",
"message",
)
) # type: Tuple[str, ...]

def format(self, record: logging.LogRecord) -> str:
record.message = record.getMessage()
Expand Down Expand Up @@ -60,7 +62,42 @@ def format(self, record: logging.LogRecord) -> str:
local_log_record[field] = value

local_log_record["extra"] = extra_message_dict
return json.dumps(list(local_log_record.values()))
return self.subformatter(local_log_record)

@abc.abstractmethod
def subformatter(self, d: Dict[str, Any]) -> str:
pass


class JsonArrayFormatter(BaseProFormatter):
def subformatter(self, d: Dict[str, Any]) -> str:
return json.dumps(list(d.values()))


class JournaldFormatter(BaseProFormatter):
"""Logging to journald in json format is considered unideal
This formatter includes all the same fields, separated by `|`
characters to maintain structure
"""

required_fields = (
# no need for asctime because journald already has the time
"levelname",
"name",
"funcName",
"lineno",
"message",
)

def subformatter(self, d: Dict[str, Any]) -> str:
values = []
for v in d.values():
if isinstance(v, str):
values.append(v)
else:
# json format only for non string types
values.append(json.dumps(v))
return "|".join(values)


def get_user_or_root_log_file_path() -> str:
Expand Down Expand Up @@ -104,7 +141,7 @@ def setup_journald_logging():
logger.setLevel(logging.INFO)
logger.addFilter(RedactionFilter())
console_handler = logging.StreamHandler()
console_handler.setFormatter(JsonArrayFormatter())
console_handler.setFormatter(JournaldFormatter())
console_handler.setLevel(logging.INFO)
logger.addHandler(console_handler)

Expand Down

0 comments on commit 3bbbe5b

Please sign in to comment.