Skip to content

Commit

Permalink
chore: implement logging system (DEV-132) (#335)
Browse files Browse the repository at this point in the history
  • Loading branch information
jnussbaum committed Mar 20, 2023
1 parent f440bda commit c92e943
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 79 deletions.
12 changes: 7 additions & 5 deletions docs/developers/user-data.md
Expand Up @@ -6,11 +6,13 @@ DSP-TOOLS saves user data in the user's home directory,
in the folder `.dsp-tools`.
Here is an overview of its structure:

| folder | command using it | description |
| :--------- | :--------------- | :----------------------------------------------------------------------------------------- |
| xmluploads | `xmlupload` | saves id2iri mappings and error reports |
| docker | `start-stack` | files necessary to startup Docker containers |
| rosetta | `rosetta` | a clone of [the rosetta test project](https://github.com/dasch-swiss/082e-rosetta-scripts) |
| file/folder | command using it | description |
| :------------------------- | :--------------- | :----------------------------------------------------------------------------------------- |
| xmluploads | `xmlupload` | saves id2iri mappings and error reports |
| docker | `start-stack` | files necessary to startup Docker containers |
| rosetta | `rosetta` | a clone of [the rosetta test project](https://github.com/dasch-swiss/082e-rosetta-scripts) |
| logging.log, logging.log.1 | several ones | These two grow up to 3MB, then the oldest entries are deleted |


Remark: Docker is normally not able to access files
stored in the `site-packages` of a Python installation.
Expand Down
16 changes: 16 additions & 0 deletions src/dsp_tools/dsp_tools.py
Expand Up @@ -3,6 +3,9 @@
"""
import argparse
import datetime
import logging
import logging.handlers
from pathlib import Path
import sys
from importlib.metadata import version

Expand Down Expand Up @@ -306,6 +309,19 @@ def call_requested_action(

def main() -> None:
"""Main entry point of the program as referenced in pyproject.toml"""
logging.basicConfig(
format="{asctime} {filename: <20} {levelname: <8} {message}",
style="{",
level=logging.INFO,
handlers=[
logging.handlers.RotatingFileHandler(
filename=Path.home() / Path(".dsp-tools") / "logging.log",
maxBytes=3*1024*1024,
backupCount=1
)
]
)

parser = make_parser()
try:
success = call_requested_action(user_args=sys.argv[1:], parser=parser)
Expand Down
31 changes: 16 additions & 15 deletions src/dsp_tools/utils/shared.py
Expand Up @@ -2,6 +2,7 @@
import copy
import importlib.resources
import json
import logging
from pathlib import Path
import time
import unicodedata
Expand All @@ -18,6 +19,9 @@
from dsp_tools.models.propertyelement import PropertyElement


logger = logging.getLogger(__name__)


def login(server: str, user: str, password: str) -> Connection:
"""
Logs in and returns the active connection.
Expand Down Expand Up @@ -50,8 +54,7 @@ def try_network_action(
requests.exceptions.RequestException, which lead to a waiting time and a retry. The waiting times are 1,
2, 4, 8, 16, 32, 64 seconds.
In case of a BaseError or Exception, a BaseError is raised with failure_msg, followed by the original
error message.
In case of a BaseError or Exception, a BaseError is raised with failure_msg.
If there is no success at the end, a BaseError with failure_msg is raised.
Expand Down Expand Up @@ -82,20 +85,13 @@ def try_network_action(
print(f'{datetime.now().isoformat()}: Try reconnecting to DSP server, next attempt in {2 ** i} seconds...')
time.sleep(2 ** i)
continue
if hasattr(err, 'message'):
err_message = err.message
else:
err_message = str(err).replace('\n', ' ')
err_message = err_message[:150] if len(err_message) > 150 else err_message
raise UserError(f"{failure_msg}.\nOriginal error message for diagnostic purposes:\n{err_message}") from None
except Exception as exc:
if hasattr(exc, 'message'):
exc_message = exc.message
else:
exc_message = str(exc).replace('\n', ' ')
exc_message = exc_message[:150] if len(exc_message) > 150 else exc_message
raise UserError(f"{failure_msg}.\nOriginal error message for diagnostic purposes:\n{exc_message}") from None
logger.exception(failure_msg)
raise BaseError(failure_msg) from None
except Exception:
logger.exception(failure_msg)
raise BaseError(failure_msg) from None

logger.error(failure_msg)
raise BaseError(failure_msg)


Expand All @@ -118,6 +114,7 @@ def validate_xml_against_schema(input_file: Union[str, Path, etree._ElementTree[
try:
doc = etree.parse(source=input_file)
except etree.XMLSyntaxError as err:
logger.exception(f"The XML file contains the following syntax error: {err.msg}")
raise UserError(f"The XML file contains the following syntax error: {err.msg}") from None
else:
doc = input_file
Expand All @@ -127,6 +124,7 @@ def validate_xml_against_schema(input_file: Union[str, Path, etree._ElementTree[
for error in xmlschema.error_log:
error_msg = error_msg + f"\n Line {error.line}: {error.message}"
error_msg = error_msg.replace("{https://dasch.swiss/schema}", "")
logger.error(error_msg)
raise UserError(error_msg)

# make sure there are no XML tags in simple texts
Expand All @@ -143,9 +141,12 @@ def validate_xml_against_schema(input_file: Union[str, Path, etree._ElementTree[
if regex.search(r'<([a-zA-Z/"]+|\S.*\S)>', str(text.text)) or len(list(text.iterchildren())) > 0:
lines_with_illegal_xml_tags.append(text.sourceline)
if lines_with_illegal_xml_tags:
logger.exception(f"XML-tags are not allowed in text properties with encoding=utf8. "
f"The following lines of your XML file are affected: {lines_with_illegal_xml_tags}")
raise UserError(f"XML-tags are not allowed in text properties with encoding=utf8. "
f"The following lines of your XML file are affected: {lines_with_illegal_xml_tags}")

logger.info("The XML file is syntactically correct and passed validation.")
print("The XML file is syntactically correct and passed validation.")
return True

Expand Down

0 comments on commit c92e943

Please sign in to comment.