Add proper logging

This commit is contained in:
Fabian 2022-09-29 17:56:51 +02:00
parent 4761d4b82f
commit 832e768a4e
10 changed files with 62 additions and 38 deletions

View File

@ -8,6 +8,7 @@ pyside6 = "~=6.3"
requests = "~=2.28"
requests-futures = "~=1.0"
packaging = "~=21.3"
loguru = "~=0.6"
[dev-packages]
pyinstaller = "~=5.1"

10
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "633aca7e0b43a295ce3429d3e12976a4c16dcf422cee53e37d266f8000ef5feb"
"sha256": "b04dfa0eda7fd2df5b6d27d5a1f7d71168c984c74ce363c45a888430bca7b7d8"
},
"pipfile-spec": 6,
"requires": {
@ -40,6 +40,14 @@
"markers": "python_version >= '3.5'",
"version": "==3.4"
},
"loguru": {
"hashes": [
"sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c",
"sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"
],
"index": "pypi",
"version": "==0.6.0"
},
"packaging": {
"hashes": [
"sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb",

View File

@ -22,6 +22,7 @@ install_requires =
requests
requests-futures
packaging
loguru
[options.packages.find]
where = src

View File

@ -1,22 +1,22 @@
import sys
import traceback
from copy import copy
from pathlib import Path
from textwrap import dedent
from threading import Lock
from typing import Optional
from loguru import logger
from packaging.version import Version
from requests_futures.sessions import FuturesSession
from fime.progressindicator import ProgressIndicator
from fime.util import get_icon
try:
from PySide6 import QtCore, QtGui, QtWidgets
except ImportError:
from PySide2 import QtCore, QtGui, QtWidgets
import fime
from fime.progressindicator import ProgressIndicator
from fime.util import get_icon
URL = "https://gitlab.com/faerbit/fime/-/releases/permalink/latest"
@ -51,8 +51,7 @@ class UpdateChecker:
else:
self.result = f"Newer fime version available: {latest_version}"
except Exception:
print("Could not get update info:\n", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
logger.exception("Could not get update info")
finally:
with self.lock:
self._done = True
@ -63,6 +62,8 @@ class About(QtWidgets.QDialog):
super().__init__(parent, *args, **kwargs)
self.setWindowTitle("About")
log_dir_path = Path(QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppDataLocation)) / "logs"
text = dedent(f"""\
fime
Copyright (c) 2020 - 2022 Faerbit
@ -71,6 +72,8 @@ class About(QtWidgets.QDialog):
fime Version {fime.__version__}
Qt Version {QtCore.__version__}
Python Version {sys.version}
Log directory: {log_dir_path}
""")
text = text.replace("\n", "<br/>")
version_label = QtWidgets.QLabel(self)

View File

@ -1,6 +1,8 @@
from configparser import ConfigParser
from pathlib import Path
from loguru import logger
try:
from PySide6 import QtCore
except ImportError:
@ -22,7 +24,7 @@ class Config:
config_dir_path = Path(QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppConfigLocation))
config_path = config_dir_path / "fime.conf"
if config_path.exists():
print(f'Reading config file "{config_path}"')
logger.info(f'Reading config file "{config_path}"')
with open(config_path) as f:
config_text = f.read()
config_text = "[DEFAULT]\n" + config_text
@ -30,7 +32,7 @@ class Config:
if (not self._configparser.has_option("DEFAULT", "jira_url") or
not self._configparser.has_option("DEFAULT", "jira_token")):
raise FimeException(f'Please add config file {config_path} '
f'with config keys "jira_url" and "jira_token" in INI style')
f'with config keys "jira_url" and "jira_token" in INI style')
@property
def jira_url(self):

View File

@ -8,6 +8,8 @@ from datetime import datetime, date, timedelta, time
from threading import Thread, Event
from typing import List, Tuple, Dict, Union
from loguru import logger
try:
from PySide6 import QtCore
except ImportError:
@ -63,7 +65,7 @@ class Data(MutableMapping):
def _save(self):
for key in self._hot_keys:
print(f"... saving dict {key} ...")
logger.info(f"saving dict {key}")
to_write = self._cache[key] # apparently thread-safe
with open(self.data_path.format(key), "w+") as f:
f.write(json.dumps(to_write))

View File

@ -1,11 +1,11 @@
#!/usr/bin/env python3
import os
import signal
import sys
from functools import partial
from pathlib import Path
from fime.about import About
from fime.config import Config
from fime.worklog import WorklogDialog
from loguru import logger
try:
from PySide6 import QtCore, QtWidgets
@ -14,6 +14,9 @@ except ImportError:
from PySide2 import QtCore, QtWidgets
PYSIDE_6 = False
from fime.about import About
from fime.config import Config
from fime.worklog import WorklogDialog
from fime.data import Tasks, Log, Data, LogCommentsData, Worklog, Report
from fime.exceptions import FimeException
from fime.import_task import ImportTask
@ -143,7 +146,7 @@ class App:
action.triggered.connect(item[1])
def sigterm_handler(self, signo, _frame):
print(f'handling signal "{signal.strsignal(signo)}"')
logger.debug(f'handling signal "{signal.strsignal(signo)}"')
self.app.quit()
def run(self):
@ -164,19 +167,27 @@ class App:
self.taskEdit.show()
def excepthook(original, e_type, e_value, tb_obj):
def init_logging():
log_dir_path = Path(QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppDataLocation)) / "logs"
logger.add(log_dir_path / "fime_{time:YYYY-MM-DD}.log", rotation="1d", retention="30d", compression="zip", level="INFO")
def excepthook(e_type, e_value, tb_obj):
if e_type is FimeException:
QtWidgets.QMessageBox.critical(None, "Error", str(e_value), QtWidgets.QMessageBox.Ok)
elif issubclass(e_type, KeyboardInterrupt):
sys.__excepthook__(e_type, e_value, tb_obj)
else:
original(e_type, e_value, tb_obj)
logger.critical("Unhandled exception", exc_info=(e_type, e_value, tb_obj))
sys.__excepthook__(e_type, e_value, tb_obj)
def main():
# important for QStandardPath to be correct
QtCore.QCoreApplication.setApplicationName("fime")
init_logging()
# also catches exceptions in other threads
original_excepthook = sys.excepthook
sys.excepthook = partial(excepthook, original_excepthook)
sys.excepthook = excepthook
app = App()
app.run()

View File

@ -1,11 +1,11 @@
import os
import sys
import threading
import traceback
from enum import Enum, auto
from functools import reduce, partial
from queue import Queue, Empty
from loguru import logger
try:
from PySide6 import QtCore, QtWidgets
except ImportError:
@ -105,12 +105,11 @@ class TaskCompleter(QtWidgets.QCompleter):
})
else:
if not self.escalate:
print("No picker results. Escalating")
logger.debug("No picker results. Escalating")
self.escalate = True
self.update_search()
except Exception:
print("Ignoring exception, as it only breaks autocompletion:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
logger.exception("Ignoring exception, as it only breaks autocompletion")
return
def update_search(self):
@ -144,6 +143,5 @@ class TaskCompleter(QtWidgets.QCompleter):
"result": extracted,
})
except Exception:
print("Ignoring exception, as it only breaks autocompletion:", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
logger.exception("Ignoring exception, as it only breaks autocompletion")
return

View File

@ -1,5 +1,7 @@
import enum
from loguru import logger
try:
from PySide6 import QtCore, QtGui, QtWidgets
except ImportError:
@ -13,7 +15,7 @@ def get_screen_height(qobject):
if hasattr(qobject, "screen"):
return qobject.screen().size().height()
else:
print("unable to detect screen height falling back to default value of 1080")
logger.info("unable to detect screen height falling back to default value of 1080")
return 1080
@ -21,7 +23,7 @@ def get_screen_width(qobject):
if hasattr(qobject, "screen"):
return qobject.screen().size().width()
else:
print("unable to detect screen width falling back to default value of 1920")
logger.info("unable to detect screen width falling back to default value of 1920")
return 1920

View File

@ -1,6 +1,4 @@
import os
import sys
import traceback
from concurrent.futures import Future
from datetime import date, datetime, timedelta, time
from functools import partial
@ -9,6 +7,7 @@ from threading import Lock
from typing import List, Dict, Tuple, Optional
import requests
from loguru import logger
from requests_futures.sessions import FuturesSession
from fime.config import Config
@ -42,12 +41,9 @@ class WorklogRest:
future.add_done_callback(self._resp_user)
return future
@logger.catch(message="Could not get user key")
def _resp_user(self, future):
try:
self._user = future.result().json()["key"]
except Exception:
print("Could not get user key:\n", file=sys.stderr)
print(traceback.format_exc(), file=sys.stderr)
self._user = future.result().json()["key"]
def get_issues_state(self, issue_keys: List[str], pdate: date) -> List[Tuple[Status, str, Optional[str]]]:
ret = []
@ -114,9 +110,9 @@ class WorklogRest:
worklog_found = True
break
if worklog_found:
print(f"Found existing worklog for issue {issue_key}")
logger.debug(f"Found existing worklog for issue {issue_key}")
else:
print(f"Did not find existing worklog for issue {issue_key}")
logger.debug(f"Did not find existing worklog for issue {issue_key}")
self._issue_state[issue_key] = (Status.OK, issue_title)
def _upload_sanity_check(self, issue_keys: List[str]):
@ -183,7 +179,7 @@ class WorklogRest:
with self._issues_lock:
if resp.status_code in (200, 201):
self._issue_state[issue_key] = (Status.OK, "Successfully uploaded")
print(f"Successfully uploaded issue {issue_key}")
logger.info(f"Successfully uploaded issue {issue_key}")
else:
msg = dedent(f"""\
Worklog upload failed:
@ -193,4 +189,4 @@ class WorklogRest:
Response: {resp.text}
""")
self._issue_state[issue_key] = (Status.ERROR, msg)
print(msg, file=sys.stderr)
logger.error(msg)