Skip to content

Commit

Permalink
feat: unxpected error messages point to correct log path if not root
Browse files Browse the repository at this point in the history
added util function to get proper log path based on if currently root or not
  • Loading branch information
a-dubs committed Jan 3, 2024
1 parent 9771152 commit 808ffa9
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 9 deletions.
7 changes: 5 additions & 2 deletions uaclient/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
)
from uaclient.files import notices, state_files
from uaclient.files.notices import Notice
from uaclient.log import JsonArrayFormatter
from uaclient.log import JsonArrayFormatter, get_user_or_root_log_file_path
from uaclient.timer.update_messaging import refresh_motd, update_motd_messages
from uaclient.yaml import safe_dump, safe_load

Expand Down Expand Up @@ -1764,7 +1764,10 @@ def wrapper(*args, **kwargs):
LOG.exception("Unhandled exception, please file a bug")
lock.clear_lock_file_if_present()
event.info(
info_msg=messages.UNEXPECTED_ERROR.format(error_msg=str(e)),
info_msg=messages.UNEXPECTED_ERROR.format(
error_msg=str(e),
log_path=get_user_or_root_log_file_path(),
),
file_type=sys.stderr,
)
event.error(
Expand Down
8 changes: 7 additions & 1 deletion uaclient/cli/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,12 +492,17 @@ class TestMain:
(
TypeError("'NoneType' object is not subscriptable"),
messages.UNEXPECTED_ERROR.format(
error_msg="'NoneType' object is not subscriptable"
error_msg="'NoneType' object is not subscriptable",
log_path="fake_log_path",
),
"Unhandled exception, please file a bug",
),
),
)
@mock.patch(
"uaclient.log.get_user_or_root_log_file_path",
return_value="fake_log_path",
)
@mock.patch(M_PATH_UACONFIG + "delete_cache_key")
@mock.patch("uaclient.cli.event.info")
@mock.patch("uaclient.cli.LOG.exception")
Expand All @@ -510,6 +515,7 @@ def test_errors_handled_gracefully(
m_log_exception,
m_event_info,
m_delete_cache_key,
_m_get_user_or_root_log_path,
event,
exception,
expected_error_msg,
Expand Down
10 changes: 9 additions & 1 deletion uaclient/cli/tests/test_cli_attach.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,11 +515,18 @@ def test_attach_config_enable_services(
),
(
Exception("error"),
messages.UNEXPECTED_ERROR.format(error_msg="error"),
messages.UNEXPECTED_ERROR.format(
error_msg="error",
log_path="fake_log_path",
),
messages.E_ATTACH_FAILURE_UNEXPECTED,
),
),
)
@mock.patch(
"uaclient.log.get_user_or_root_log_file_path",
return_value="fake_log_path",
)
@mock.patch("uaclient.files.state_files.attachment_data_file.write")
@mock.patch("uaclient.entitlements.entitlements_enable_order")
@mock.patch("uaclient.contract.process_entitlement_delta")
Expand All @@ -534,6 +541,7 @@ def test_attach_when_one_service_fails_to_enable(
m_process_entitlement_delta,
m_enable_order,
_m_attachment_data_file_write,
_m_get_user_or_root_log_path,
expected_exception,
expected_msg,
expected_outer_msg,
Expand Down
5 changes: 4 additions & 1 deletion uaclient/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,10 @@ def process_entitlements_delta(
failed_services=[
(
name,
messages.UNEXPECTED_ERROR.format(error_msg=str(exception)),
messages.UNEXPECTED_ERROR.format(
error_msg=str(exception),
log_path=util.get_user_or_root_log_file_path(),
),
)
for name, exception in zip(failed_services, unexpected_errors)
]
Expand Down
9 changes: 9 additions & 0 deletions uaclient/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Any, Dict, List # noqa: F401

from uaclient import defaults, system, util
from uaclient.config import UAConfig


class RedactionFilter(logging.Filter):
Expand Down Expand Up @@ -61,6 +62,14 @@ def format(self, record: logging.LogRecord) -> str:
return json.dumps(list(local_log_record.values()))


def get_user_or_root_log_file_path() -> str:
"""Gets the correct log_file storage location adjusting for whether the user is root or not"""
if util.we_are_currently_root():
return UAConfig().log_file
else:
return "~/.cache/" + defaults.USER_CACHE_SUBDIR + "/ubuntu-pro.log"


def get_user_log_file() -> str:
"""Gets the correct user log_file storage location"""
return system.get_user_cache_dir() + "/ubuntu-pro.log"
Expand Down
7 changes: 3 additions & 4 deletions uaclient/messages/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1538,10 +1538,9 @@ def __repr__(self):
"unexpected-error",
t.gettext(
"""\
Unexpected error(s) occurred: {error_msg}
For more details, see the log: ~/.cache/ubuntu-pro/ubuntu-pro.log
First, try searching online for solutions to this error.
Otherwise, file a bug using the command: ubuntu-bug ubuntu-advantage-tools"""
An unexpected error occurred: {error_msg}
For more details, see the log: {log_path}
If you think this is a bug, please run: ubuntu-bug ubuntu-advantage-tools"""
),
)

Expand Down
28 changes: 28 additions & 0 deletions uaclient/tests/test_log.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import json
import logging
from io import StringIO
import mock

import pytest

from uaclient import log as pro_log
from uaclient import util
from uaclient.util import we_are_currently_root
from uaclient.config import UAConfig

LOG = logging.getLogger(util.replace_top_level_logger_name(__name__))
LOG_FMT = "%(asctime)s%(name)s%(funcName)s%(lineno)s\
Expand Down Expand Up @@ -158,3 +161,28 @@ def test_valid_json_output(
assert val[6].get("key") == extra.get("key")
else:
assert 7 == len(val)

def test_get_user_or_root_log_file_path():
"""Gets the correct log_file storage location adjusting for whether the user is root or not"""
# test root log file path
with mock.patch("uaclient.util.we_are_currently_root", return_value=True):
assert (
pro_log.get_user_or_root_log_file_path()
== "/var/log/ubuntu-advantage.log"
)
# test default user log file path
with mock.patch("uaclient.util.we_are_currently_root", return_value=False):
assert (
pro_log.get_user_or_root_log_file_path()
== "~/.cache/ubuntu-pro/ubuntu-pro.log"
)
# test custom user log file path
with mock.patch("uaclient.config.UAConfig.log_file", new_callable=mock.PropertyMock) as mock_log_file:
expected_log_file = "/tmp/foo.log"
mock_log_file.return_value = expected_log_file
with mock.patch("uaclient.util.we_are_currently_root", return_value=True) as mock_root:
result = pro_log.get_user_or_root_log_file_path()
mock_root.assert_called()
mock_log_file.assert_called()
assert expected_log_file == result

7 changes: 7 additions & 0 deletions uaclient/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,10 @@ def print_package_list(
)
)
print("")


def get_user_or_root_log_path() -> str:
if we_are_currently_root():
return "/var/log/ubuntu-advantage.log"
else:
return "~/.cache/ubuntu-pro/ubuntu-pro.log"

0 comments on commit 808ffa9

Please sign in to comment.