|
|
@@ -1,15 +1,118 @@
|
|
|
+import os
|
|
|
+import sys
|
|
|
import pathlib
|
|
|
+import asyncio
|
|
|
|
|
|
class handler:
|
|
|
- def __init__(self, target: pathlib.Path) -> None:
|
|
|
- if target.is_file():
|
|
|
- self.__create(target)
|
|
|
+ """
|
|
|
+ That is used to appending data into log files, stdout and stderr.
|
|
|
+ It requires file which is used to store logs.
|
|
|
|
|
|
- self.__target = target
|
|
|
+ Methods
|
|
|
+ -------
|
|
|
+ async _to_file(content: str) : None
|
|
|
+ That add content, as new line, to the file.
|
|
|
+
|
|
|
+ async _to_stdout(content: str) : None
|
|
|
+ That add content, as new line, to the stdout.
|
|
|
+
|
|
|
+ async _to_stderr(content: str) : None
|
|
|
+ That add content, as new line, to the stderr.
|
|
|
+ """
|
|
|
+
|
|
|
+ def __init__(self, target: pathlib.Path | None) -> None:
|
|
|
+ """
|
|
|
+ That create required locks, and log file when it is not exists.
|
|
|
|
|
|
- def __create(self, target: pathlib.Path) -> None
|
|
|
- try:
|
|
|
+ Parameters
|
|
|
+ ----------
|
|
|
+ target : pathlib.Path | None
|
|
|
+ File which would be used to store logs. If it is set to None, then
|
|
|
+ only stdout and stderr could be used.
|
|
|
+ """
|
|
|
+
|
|
|
+ self.__file_lock = asyncio.Lock()
|
|
|
+ self.__stderr_lock = asyncio.Lock()
|
|
|
+ self.__stdout_lock = asyncio.Lock()
|
|
|
+
|
|
|
+ self.__target = target
|
|
|
+ self.__pipe = None
|
|
|
+
|
|
|
+ if target is not None and not target.exists():
|
|
|
target.touch()
|
|
|
|
|
|
- except:
|
|
|
- RuntimeError("Can not create log file: " + str(target) + ".")
|
|
|
+ async def _to_file(self, content: str) -> None:
|
|
|
+ """
|
|
|
+ That adding given content as new line in the file.
|
|
|
+
|
|
|
+ Parameters
|
|
|
+ ----------
|
|
|
+ content : str
|
|
|
+ Content which would be added as new line in the file.
|
|
|
+ """
|
|
|
+
|
|
|
+ if self.__target is None:
|
|
|
+ return
|
|
|
+
|
|
|
+ async with self.__file_lock:
|
|
|
+ await asyncio.to_thread(self.__add_file, content)
|
|
|
+
|
|
|
+ def __add_file(self, content: str) -> None:
|
|
|
+ """
|
|
|
+ That adding given content as new line to the file. It is synchronized
|
|
|
+ function, running in new thread. When file is not open, that open it.
|
|
|
+
|
|
|
+ Parameters
|
|
|
+ ----------
|
|
|
+ content : str
|
|
|
+ Content to append into file as new line.
|
|
|
+ """
|
|
|
+
|
|
|
+ if self.__pipe is None or self.__pipe.closed:
|
|
|
+ self.__pipe = self.__target.open("a")
|
|
|
+
|
|
|
+ self.__pipe.write(content + os.linesep)
|
|
|
+
|
|
|
+ async def _to_stdout(self, content: str) -> None:
|
|
|
+ """
|
|
|
+ That add content to stdout fifo as new line.
|
|
|
+
|
|
|
+ Parameters
|
|
|
+ ----------
|
|
|
+ content : str
|
|
|
+ New content which would be add to stdout.
|
|
|
+ """
|
|
|
+
|
|
|
+ content = content + os.linesep
|
|
|
+
|
|
|
+ async with self.__stdout_lock:
|
|
|
+ await asyncio.to_thread(sys.stdout.write, content)
|
|
|
+
|
|
|
+ async def _to_stderr(self, content: str) -> None:
|
|
|
+ """
|
|
|
+ That add content to stderr fifo as new line.
|
|
|
+
|
|
|
+ Parameters
|
|
|
+ ----------
|
|
|
+ content : str
|
|
|
+ New content, which would be add to stderr.
|
|
|
+ """
|
|
|
+
|
|
|
+ content = content + os.linesep
|
|
|
+
|
|
|
+ async with self.__stderr_lock:
|
|
|
+ await asyncio.to_thread(sys.stderr.write, content)
|
|
|
+
|
|
|
+ def __del__(self) -> None:
|
|
|
+ """
|
|
|
+ That is object destructor, which close log file, when it is not
|
|
|
+ closed yet.
|
|
|
+ """
|
|
|
+
|
|
|
+ if self.__pipe is None:
|
|
|
+ return
|
|
|
+
|
|
|
+ if self.__pipe.closed:
|
|
|
+ return
|
|
|
+
|
|
|
+ self.__pipe.close()
|