mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 09:10:30 +08:00
pretty logging
This commit is contained in:
parent
54430fed31
commit
ed331feab1
@ -49,7 +49,7 @@ logging:
|
||||
(): contextlog.SmartFormatter
|
||||
style: "{"
|
||||
datefmt: "%H:%M:%S"
|
||||
format: "[{asctime}] {name:15.15} {levelname:>7} --- {message}"
|
||||
format: "[{asctime}] {name:20.20} {levelname:>7} --- {message}"
|
||||
|
||||
handlers:
|
||||
console:
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from .application import init
|
||||
from .logging import get_logger
|
||||
|
||||
from .atx import Atx
|
||||
from .streamer import Streamer
|
||||
@ -52,4 +52,4 @@ def main() -> None:
|
||||
host=config["server"]["host"],
|
||||
port=config["server"]["port"],
|
||||
)
|
||||
logging.getLogger(__name__).info("Bye-bye")
|
||||
get_logger().info("Bye-bye")
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from typing import Tuple
|
||||
|
||||
from .logging import get_logger
|
||||
|
||||
from . import gpio
|
||||
|
||||
|
||||
# =====
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Atx:
|
||||
def __init__(
|
||||
self,
|
||||
@ -39,15 +37,15 @@ class Atx:
|
||||
|
||||
async def click_power(self) -> None:
|
||||
if (await self.__click(self.__power_switch, self.__click_delay)):
|
||||
_logger.info("Clicked power")
|
||||
get_logger().info("Clicked power")
|
||||
|
||||
async def click_power_long(self) -> None:
|
||||
if (await self.__click(self.__power_switch, self.__long_click_delay)):
|
||||
_logger.info("Clicked power (long press)")
|
||||
get_logger().info("Clicked power (long press)")
|
||||
|
||||
async def click_reset(self) -> None:
|
||||
if (await self.__click(self.__reset_switch, self.__click_delay)):
|
||||
_logger.info("Clicked reset")
|
||||
get_logger().info("Clicked reset")
|
||||
|
||||
async def __click(self, pin: int, delay: float) -> bool:
|
||||
if not self.__lock.locked():
|
||||
|
||||
@ -1,28 +1,27 @@
|
||||
import subprocess
|
||||
import logging
|
||||
import time
|
||||
|
||||
from ...application import init
|
||||
from ...logging import get_logger
|
||||
|
||||
from ... import gpio
|
||||
|
||||
|
||||
# =====
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
config = init()
|
||||
_logger.info("Cleaning up ...")
|
||||
logger = get_logger(0)
|
||||
|
||||
logger.info("Cleaning up ...")
|
||||
with gpio.bcm():
|
||||
for (key, pin) in [
|
||||
*config["atx"]["switches"]["pinout"].items(),
|
||||
*config["video"]["pinout"].items(),
|
||||
]:
|
||||
_logger.info("Writing value=0 to pin=%d (%s)", pin, key)
|
||||
logger.info("Writing value=0 to pin=%d (%s)", pin, key)
|
||||
gpio.write(pin, False)
|
||||
|
||||
_logger.info("Trying to find and kill mjpg_streamer ...")
|
||||
logger.info("Trying to find and kill mjpg_streamer ...")
|
||||
try:
|
||||
subprocess.check_output(["killall", "mjpg_streamer"], stderr=subprocess.STDOUT)
|
||||
time.sleep(3)
|
||||
@ -30,4 +29,4 @@ def main() -> None:
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
_logger.info("Bye-bye")
|
||||
logger.info("Bye-bye")
|
||||
|
||||
@ -1,24 +1,23 @@
|
||||
import contextlib
|
||||
import logging
|
||||
|
||||
from typing import Generator
|
||||
|
||||
from RPi import GPIO
|
||||
|
||||
from .logging import get_logger
|
||||
|
||||
|
||||
# =====
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def bcm() -> Generator[None, None, None]:
|
||||
logger = get_logger(2)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
_logger.info("Configured GPIO mode as BCM")
|
||||
logger.info("Configured GPIO mode as BCM")
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
GPIO.cleanup()
|
||||
_logger.info("GPIO cleaned")
|
||||
logger.info("GPIO cleaned")
|
||||
|
||||
|
||||
def set_output(pin: int, initial: bool=False) -> int:
|
||||
|
||||
15
kvmd/kvmd/logging.py
Normal file
15
kvmd/kvmd/logging.py
Normal file
@ -0,0 +1,15 @@
|
||||
import sys
|
||||
import logging
|
||||
|
||||
|
||||
# =====
|
||||
def get_logger(depth: int=1) -> logging.Logger:
|
||||
frame = sys._getframe(1) # pylint: disable=protected-access
|
||||
frames = []
|
||||
while frame:
|
||||
frames.append(frame)
|
||||
frame = frame.f_back
|
||||
if len(frames) - 1 >= depth:
|
||||
break
|
||||
name = frames[depth].f_globals["__name__"]
|
||||
return logging.getLogger(name)
|
||||
@ -1,16 +1,14 @@
|
||||
import multiprocessing
|
||||
import multiprocessing.queues
|
||||
import queue
|
||||
import logging
|
||||
import time
|
||||
|
||||
from .logging import get_logger
|
||||
|
||||
from . import gpio
|
||||
|
||||
|
||||
# =====
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Ps2Keyboard(multiprocessing.Process):
|
||||
def __init__(self, clock: int, data: int, pulse: float) -> None:
|
||||
super().__init__(daemon=True)
|
||||
@ -23,11 +21,11 @@ class Ps2Keyboard(multiprocessing.Process):
|
||||
self.__event = multiprocessing.Event()
|
||||
|
||||
def start(self) -> None:
|
||||
_logger.info("Starting keyboard daemon ...")
|
||||
get_logger().info("Starting keyboard daemon ...")
|
||||
super().start()
|
||||
|
||||
def stop(self) -> None:
|
||||
_logger.info("Stopping keyboard daemon ...")
|
||||
get_logger().info("Stopping keyboard daemon ...")
|
||||
self.__event.set()
|
||||
self.join()
|
||||
|
||||
@ -35,17 +33,18 @@ class Ps2Keyboard(multiprocessing.Process):
|
||||
self.__queue.put(code)
|
||||
|
||||
def run(self) -> None:
|
||||
try:
|
||||
while not self.__event.is_set():
|
||||
try:
|
||||
code = self.__queue.get(timeout=0.1)
|
||||
except queue.Empty:
|
||||
pass
|
||||
else:
|
||||
self.__send_byte(code)
|
||||
except Exception:
|
||||
_logger.exception("Unhandled exception")
|
||||
raise
|
||||
with gpio.bcm():
|
||||
try:
|
||||
while not self.__event.is_set():
|
||||
try:
|
||||
code = self.__queue.get(timeout=0.1)
|
||||
except queue.Empty:
|
||||
pass
|
||||
else:
|
||||
self.__send_byte(code)
|
||||
except Exception:
|
||||
get_logger().exception("Unhandled exception")
|
||||
raise
|
||||
|
||||
def __send_byte(self, code: int) -> None:
|
||||
code_bits = list(map(bool, bin(code)[2:].zfill(8)))
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import os
|
||||
import signal
|
||||
import asyncio
|
||||
import logging
|
||||
import time
|
||||
|
||||
from typing import List
|
||||
@ -15,11 +14,10 @@ from .atx import Atx
|
||||
from .streamer import Streamer
|
||||
from .ps2 import Ps2Keyboard
|
||||
|
||||
from .logging import get_logger
|
||||
|
||||
|
||||
# =====
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _system_task(method: Callable) -> Callable:
|
||||
async def wrap(self: "Server") -> None:
|
||||
try:
|
||||
@ -27,7 +25,7 @@ def _system_task(method: Callable) -> Callable:
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
except Exception:
|
||||
_logger.exception("Unhandled exception, killing myself ...")
|
||||
get_logger().exception("Unhandled exception, killing myself ...")
|
||||
os.kill(os.getpid(), signal.SIGTERM)
|
||||
return wrap
|
||||
|
||||
@ -77,7 +75,7 @@ class Server: # pylint: disable=too-many-instance-attributes
|
||||
app=app,
|
||||
host=host,
|
||||
port=port,
|
||||
print=(lambda text: [_logger.info(line.strip()) for line in text.strip().splitlines()]), # type: ignore
|
||||
print=(lambda text: [get_logger().info(line.strip()) for line in text.strip().splitlines()]), # type: ignore
|
||||
)
|
||||
|
||||
async def __root_handler(self, _: aiohttp.web.Request) -> aiohttp.web.Response:
|
||||
@ -97,12 +95,14 @@ class Server: # pylint: disable=too-many-instance-attributes
|
||||
return ws
|
||||
|
||||
async def __on_shutdown(self, _: aiohttp.web.Application) -> None:
|
||||
_logger.info("Cancelling system tasks ...")
|
||||
logger = get_logger(0)
|
||||
|
||||
logger.info("Cancelling system tasks ...")
|
||||
for task in self.__system_tasks:
|
||||
task.cancel()
|
||||
await asyncio.gather(*self.__system_tasks)
|
||||
|
||||
_logger.info("Disconnecting clients ...")
|
||||
logger.info("Disconnecting clients ...")
|
||||
for ws in list(self.__sockets):
|
||||
await self.__remove_socket(ws)
|
||||
|
||||
@ -168,21 +168,21 @@ class Server: # pylint: disable=too-many-instance-attributes
|
||||
if method:
|
||||
await method()
|
||||
return None
|
||||
_logger.warning("Received an incorrect command: %r", command)
|
||||
get_logger().warning("Received an incorrect command: %r", command)
|
||||
return "ERROR incorrect command"
|
||||
|
||||
async def __register_socket(self, ws: aiohttp.web.WebSocketResponse) -> None:
|
||||
async with self.__sockets_lock:
|
||||
self.__sockets.add(ws)
|
||||
_logger.info("Registered new client socket: remote=%s; id=%d; active=%d",
|
||||
ws._req.remote, id(ws), len(self.__sockets)) # pylint: disable=protected-access
|
||||
get_logger().info("Registered new client socket: remote=%s; id=%d; active=%d",
|
||||
ws._req.remote, id(ws), len(self.__sockets)) # pylint: disable=protected-access
|
||||
|
||||
async def __remove_socket(self, ws: aiohttp.web.WebSocketResponse) -> None:
|
||||
async with self.__sockets_lock:
|
||||
try:
|
||||
self.__sockets.remove(ws)
|
||||
_logger.info("Removed client socket: remote=%s; id=%d; active=%d",
|
||||
ws._req.remote, id(ws), len(self.__sockets)) # pylint: disable=protected-access
|
||||
get_logger().info("Removed client socket: remote=%s; id=%d; active=%d",
|
||||
ws._req.remote, id(ws), len(self.__sockets)) # pylint: disable=protected-access
|
||||
await ws.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ -1,17 +1,15 @@
|
||||
import asyncio
|
||||
import asyncio.subprocess
|
||||
import logging
|
||||
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
|
||||
from .logging import get_logger
|
||||
|
||||
from . import gpio
|
||||
|
||||
|
||||
# =====
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Streamer: # pylint: disable=too-many-instance-attributes
|
||||
def __init__(
|
||||
self,
|
||||
@ -38,13 +36,13 @@ class Streamer: # pylint: disable=too-many-instance-attributes
|
||||
|
||||
async def start(self) -> None:
|
||||
assert not self.__proc_task
|
||||
_logger.info("Starting mjpg_streamer ...")
|
||||
get_logger().info("Starting mjpg_streamer ...")
|
||||
await self.__set_hw_enabled(True)
|
||||
self.__proc_task = self.__loop.create_task(self.__process())
|
||||
|
||||
async def stop(self) -> None:
|
||||
assert self.__proc_task
|
||||
_logger.info("Stopping mjpg_streamer ...")
|
||||
get_logger().info("Stopping mjpg_streamer ...")
|
||||
self.__proc_task.cancel()
|
||||
await asyncio.gather(self.__proc_task, return_exceptions=True)
|
||||
await self.__set_hw_enabled(False)
|
||||
@ -62,6 +60,8 @@ class Streamer: # pylint: disable=too-many-instance-attributes
|
||||
await asyncio.sleep(self.__sync_delay)
|
||||
|
||||
async def __process(self) -> None:
|
||||
logger = get_logger(0)
|
||||
|
||||
proc: Optional[asyncio.subprocess.Process] = None # pylint: disable=no-member
|
||||
while True:
|
||||
try:
|
||||
@ -70,13 +70,13 @@ class Streamer: # pylint: disable=too-many-instance-attributes
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.STDOUT,
|
||||
)
|
||||
_logger.info("Started mjpg_streamer pid=%d: %s", proc.pid, self.__cmd)
|
||||
logger.info("Started mjpg_streamer pid=%d: %s", proc.pid, self.__cmd)
|
||||
|
||||
empty = 0
|
||||
while proc.returncode is None:
|
||||
line = (await proc.stdout.readline()).decode(errors="ignore").strip()
|
||||
if line:
|
||||
_logger.info("mjpg_streamer: %s", line)
|
||||
logger.info("mjpg_streamer: %s", line)
|
||||
empty = 0
|
||||
else:
|
||||
empty += 1
|
||||
@ -90,9 +90,9 @@ class Streamer: # pylint: disable=too-many-instance-attributes
|
||||
break
|
||||
except Exception as err:
|
||||
if proc:
|
||||
_logger.error("Unexpected finished mjpg_streamer pid=%d with retcode=%d", proc.pid, proc.returncode)
|
||||
logger.exception("Unexpected finished mjpg_streamer pid=%d with retcode=%d", proc.pid, proc.returncode)
|
||||
else:
|
||||
_logger.error("Can't start mjpg_streamer: %s", err)
|
||||
logger.exception("Can't start mjpg_streamer: %s", err)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
if proc:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user