commit
3dd8bdc669
9 changed files with 313 additions and 0 deletions
@ -0,0 +1,24 @@
|
||||
import yaml |
||||
import json |
||||
import logging |
||||
|
||||
logger = logging.getLogger("fds") |
||||
|
||||
class Config(): |
||||
def __init__(self, config_file: str): |
||||
with open(config_file, "r") as cfile: |
||||
self.__dict__ = yaml.safe_load(cfile) |
||||
self.set_params(self.__dict__) |
||||
|
||||
def set_params(self, config: dict): |
||||
for k, v in config.items(): |
||||
# if type(v) is dict: |
||||
# set_params(v) |
||||
setattr(self, k, v) |
||||
|
||||
def __repr__(self): |
||||
return json.dumps(self.__dict__, indent=4) |
||||
|
||||
class LogConfig(Config): |
||||
... |
||||
|
||||
@ -0,0 +1,79 @@
|
||||
import os |
||||
import logging |
||||
from logging.handlers import RotatingFileHandler |
||||
|
||||
# COLORED_FORMAT = '%(asctime)-15s [%(levelname)s] %(threadName)-12s ' |
||||
# NORMAL_FORMAT = '%(filename)s %(funcName)s, line %(lineno)s: %(message)s' |
||||
COLORED_FORMAT = '[%(levelname)s] %(threadName)-12s ' |
||||
NORMAL_FORMAT = '%(message)s' # '%(filename)s %(funcName)s, line %(lineno)s: %(message)s' |
||||
FORMAT = COLORED_FORMAT + NORMAL_FORMAT |
||||
|
||||
class ColoredFormatter(logging.Formatter): |
||||
|
||||
grey = "\x1b[38;20m" |
||||
yellow = "\x1b[33;20m" |
||||
red = "\x1b[31;20m" |
||||
bold_red = "\x1b[31;1m" |
||||
white = "\x1b[33;97m" |
||||
green = "\x1b[33;92m" |
||||
reset = "\x1b[0m" |
||||
|
||||
FORMATS = { |
||||
logging.DEBUG: white + COLORED_FORMAT + reset + NORMAL_FORMAT, |
||||
logging.INFO: green + COLORED_FORMAT + reset + NORMAL_FORMAT, |
||||
logging.WARNING: yellow + COLORED_FORMAT + reset + NORMAL_FORMAT, |
||||
logging.ERROR: red + COLORED_FORMAT + reset + NORMAL_FORMAT, |
||||
logging.CRITICAL: bold_red + COLORED_FORMAT + reset + NORMAL_FORMAT |
||||
} |
||||
|
||||
def format(self, record): |
||||
log_fmt = self.FORMATS.get(record.levelno) |
||||
formatter = logging.Formatter(log_fmt, datefmt='%Y-%m-%d %I:%M:%S%p') |
||||
return formatter.format(record) |
||||
|
||||
def set_log_folder(path: str): |
||||
dir = os.path.dirname(path) |
||||
if len(dir) == 0: |
||||
dir = "./" |
||||
|
||||
os.makedirs(dir, exist_ok=True) |
||||
|
||||
def set_logger(name: str = "fds", filename: str = "main.log", level: str = "info", logtest=False): |
||||
set_log_folder(filename) |
||||
logging_levels = ( |
||||
logging.CRITICAL, |
||||
logging.ERROR, |
||||
logging.WARNING, |
||||
logging.INFO, |
||||
logging.DEBUG, |
||||
) |
||||
log_level = getattr(logging, level.upper()) |
||||
|
||||
assert log_level in logging_levels |
||||
|
||||
|
||||
log = logging.getLogger(name) |
||||
log.setLevel(log_level) |
||||
|
||||
file_handler = RotatingFileHandler(filename, maxBytes=100000000, backupCount=10) |
||||
file_handler.setLevel(logging.DEBUG) |
||||
file_handler.setFormatter(logging.Formatter(FORMAT)) |
||||
log.addHandler(file_handler) |
||||
|
||||
stream_handler = logging.StreamHandler() |
||||
# stream_handler.setLevel(log_level) |
||||
stream_handler.setLevel(logging.DEBUG) |
||||
stream_handler.setFormatter(ColoredFormatter()) |
||||
log.addHandler(stream_handler) |
||||
|
||||
if logtest: |
||||
t_log = getattr(log, level) |
||||
t_log(f"Logging level: {level.upper()}") |
||||
log.info("You can see below log labels") |
||||
log.debug("DEBUG level") |
||||
log.info("INFO level") |
||||
log.warning("WARNING level") |
||||
log.error("ERROR level") |
||||
log.critical("CRITICAL level") |
||||
|
||||
return log |
||||
@ -0,0 +1,10 @@
|
||||
Config: |
||||
- name: ttyUSB2 |
||||
device: /dev/ttyUSB2 |
||||
baudrate: 115200 |
||||
- name: ttyUSB1 |
||||
device: /dev/ttyUSB1 |
||||
baudrate: 115200 |
||||
- name: ttyUSB3 |
||||
device: /dev/ttyUSB3 |
||||
baudrate: 115200 |
||||
@ -0,0 +1,140 @@
|
||||
import os |
||||
import sys |
||||
import json |
||||
import serial |
||||
import signal |
||||
import logging |
||||
import argparse |
||||
from threading import Thread |
||||
from contextlib import contextmanager, ExitStack |
||||
from signal import SIGINT, SIGTERM |
||||
from serial.tools import list_ports |
||||
from datetime import datetime as dt |
||||
|
||||
from lib.logger import set_logger |
||||
from lib.config import LogConfig |
||||
|
||||
|
||||
def parsing_argument(): |
||||
parser = argparse.ArgumentParser(description="USB-UART Serial logging.") |
||||
# parser.add_argument('-p', '--serial-path', type=str, default="/dev/ttyUSB2", help="Path to device file") |
||||
# parser.add_argument('-b', '--baudrate', type=int, default=115200, help="Baudrate") |
||||
parser.add_argument('-f', '--log-file', type=str, default="logs/main.log", help="Name of log file") |
||||
parser.add_argument('-d', '--log-level', type=str, default="info", choices=['notset', 'info', 'debug', 'warning', 'error', 'critical'], help="Set log level") |
||||
parser.add_argument('-c', '--log-config', type=str, default="log-config.yml", help="Config for logging") |
||||
args = parser.parse_args() |
||||
# device = os.path.basename(args.serial_path) |
||||
# if len(args.log_file) == 0: |
||||
# args.log_file = f"{device}.log" |
||||
return args |
||||
|
||||
class SerialLogger(): |
||||
def __init__(self, config): |
||||
self.set_params(config) |
||||
# self.name = |
||||
if not hasattr(self, 'log_file') or len(self.log_file) == 0: |
||||
self.log_file = f"logs/{self.name}.log" |
||||
if not hasattr(self, 'log_level'): |
||||
self.log_level='info' |
||||
|
||||
self.logger = set_logger(name=self.name, filename=self.log_file, level=self.log_level) |
||||
|
||||
self.stop=False |
||||
|
||||
print("") |
||||
self.logger.info("-----------------------------------------------") |
||||
self.logger.info(f"Logger launched {dt.now().strftime('%Y/%m/%d %a %H:%M:%S')}") |
||||
self.logger.info(f"Target device: {self.device}, Baudrate: {self.baudrate}") |
||||
self.logger.info(f"Log level: {self.log_level.upper()}, saved in \'{self.log_file}\'") |
||||
self.logger.info("-----------------------------------------------\n") |
||||
|
||||
def set_params(self, config: dict): |
||||
for k, v in config.items(): |
||||
# if type(v) is dict: |
||||
# set_params(v) |
||||
setattr(self, k, v) |
||||
|
||||
@contextmanager |
||||
def run(self): |
||||
thread = Thread(target=self.listen, name=f"{self.name}") |
||||
thread.start() |
||||
try: |
||||
yield |
||||
finally: |
||||
self.stop = True |
||||
thread.join() |
||||
|
||||
def listen(self): |
||||
tmp="" |
||||
with serial.Serial(self.device, self.baudrate) as dev: |
||||
while not self.stop: |
||||
data = dev.readline(dev.inWaiting()).decode("latin1") |
||||
if data: |
||||
if "Ramdisk addr" in data: |
||||
self.logger.info("") |
||||
self.logger.info("-----------------------------------------") |
||||
self.logger.info(f"FPGA Initialized. {dt.now().strftime('%Y/%m/%d %a %H:%M:%S')}") |
||||
self.logger.info("-----------------------------------------") |
||||
if data[-1] == '\n': |
||||
tmp += data.strip() |
||||
self.logger.info(tmp) |
||||
tmp = "" |
||||
else: |
||||
tmp+= data.strip() |
||||
|
||||
#self.logger.info(data.strip()) |
||||
|
||||
|
||||
def main(args=None): |
||||
LOG = set_logger(filename=args.log_file, level=args.log_level) |
||||
LOG.info("-----------------------------------------------") |
||||
LOG.info(f"Logger launched {dt.now().strftime('%Y/%m/%d %a %H:%M:%S')}") |
||||
LOG.info(f"Logging configs: {args.log_config}") |
||||
LOG.info(f"Log level: {args.log_level.upper()}, saved in \'{args.log_file}\'") |
||||
LOG.info("-----------------------------------------------\n") |
||||
|
||||
LOG.info("Available ports") |
||||
for i, p in enumerate(list_ports.comports()): |
||||
LOG.info(f"{i+1}) Deivce: {p.device}") |
||||
LOG.info(f"\tDescription : {p.description}") |
||||
LOG.info(f"\tHWID : {p.hwid}") |
||||
LOG.info(f"\tSerial # : {p.serial_number}") |
||||
LOG.info(f"\tLocation : {p.location}") |
||||
LOG.info(f"\tManufacturer : {p.manufacturer}") |
||||
LOG.info(f"\tProduct : {p.product}") |
||||
LOG.info(f"\tInterface : {p.interface}\n") |
||||
|
||||
|
||||
def signal_handler(sig, frame): |
||||
sign = signal.Signals(sig) |
||||
print("") |
||||
LOG.info(f"Stop program by {signal.strsignal(sign)} ({sign.name})\n") |
||||
|
||||
configs = LogConfig(args.log_config).Config |
||||
with ExitStack() as stack: |
||||
for cfg in configs: |
||||
LOG.info(f"Logging config:\n{json.dumps(cfg, indent=4)}") |
||||
sl = SerialLogger(cfg) |
||||
stack.enter_context(sl.run()) |
||||
signal.signal(SIGINT, signal_handler) |
||||
signal.signal(SIGTERM, signal_handler) |
||||
print('\t To terminate the program, press Ctrl-c\n') |
||||
signal.pause() |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return 0 |
||||
|
||||
|
||||
def test(): |
||||
config = LogConfig("log-config.yml") |
||||
print(type(config.Config[0])) |
||||
pass |
||||
|
||||
if __name__ == "__main__": |
||||
# test() |
||||
sys.exit( |
||||
main(parsing_argument()) |
||||
) |
||||
@ -0,0 +1,10 @@
|
||||
[Unit] |
||||
Description=Python Serial Logger |
||||
|
||||
[Service] |
||||
Type=simple |
||||
WorkingDirectory=/home/fds-l1/Work/NVMe_Test/chaeeon.dev/sw |
||||
ExecStart=/home/fds-l1/Work/NVMe_Test/chaeeon.dev/sw/python/peta-venv/bin/python /home/fds-l1/Work/NVMe_Test/chaeeon.dev/sw/python/pyLogger.py --log-config /home/fds-l1/Work/NVMe_Test/chaeeon.dev/sw/python/log-config.yml |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
||||
@ -0,0 +1,44 @@
|
||||
#!/bin/bash |
||||
|
||||
|
||||
|
||||
DEVICE_NUM=${1:-"2"} |
||||
DEVICE=ttyUSB${DEVICE_NUM} |
||||
DEVICE_FILE=/dev/${DEVICE} |
||||
BAUDRATE=115200 |
||||
LOGDIR=logs |
||||
LOGFILE=${LOGDIR}/${DEVICE}.log |
||||
|
||||
TAG=${2:-"None"} |
||||
|
||||
log_message() { |
||||
msg=${1:-""} |
||||
echo ${msg} >> ${LOGFILE} |
||||
} |
||||
|
||||
launch_message() { |
||||
log_message |
||||
log_message "-----------------------------" |
||||
log_message " Logging launched: $(date)" |
||||
log_message " Get logs from \'${DEVICE_FILE}\'" |
||||
log_message " Logfile saved at \'${LOGFILE}\'" |
||||
log_message " TAG: ${TAG}" |
||||
log_message "-----------------------------" |
||||
} |
||||
|
||||
old_main() { |
||||
launch_message |
||||
|
||||
sudo screen -L -Logfile ${LOGFILE} ${DEVICE_FILE} ${BAUDRATE} |
||||
sudo chown $USER:$USER ${LOGFILE} |
||||
|
||||
log_message |
||||
log_message |
||||
} |
||||
|
||||
|
||||
main() { |
||||
sudo python3 python/pyLogger.py --log-config python/log-config.yml |
||||
} |
||||
|
||||
main |
||||
Loading…
Reference in new issue