Add proper logging
This commit is contained in:
parent
4761d4b82f
commit
832e768a4e
1
Pipfile
1
Pipfile
@ -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
10
Pipfile.lock
generated
@ -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",
|
||||
|
@ -22,6 +22,7 @@ install_requires =
|
||||
requests
|
||||
requests-futures
|
||||
packaging
|
||||
loguru
|
||||
|
||||
[options.packages.find]
|
||||
where = src
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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))
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user