Skip to content

Commit 4380b4c

Browse files
authored
Fix logger and support colors
Fix logger and support colors
2 parents 703b4c8 + 376aa31 commit 4380b4c

File tree

5 files changed

+145
-26
lines changed

5 files changed

+145
-26
lines changed

container/cluster.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import utils
1818
import stats
1919
import web
20-
from logger import logger
20+
import logger
2121
from tqdm import tqdm
2222

2323
PY_VERSION = "1.0.0"
@@ -127,7 +127,7 @@ async def check_file(self):
127127
total = len(filelist)
128128
byte = 0
129129
miss = []
130-
pbar = tqdm(total=total, unit=' file(s)', unit_scale=True)
130+
pbar = tqdm(file=logger.PRINTSTDOUT, total=total, unit=' file(s)', unit_scale=True)
131131
pbar.set_description("Checking files")
132132
for i, file in enumerate(filelist):
133133
filepath = str(self.dir) + f"/{file.hash[:2]}/{file.hash}"

container/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def __init__(self, path: str) -> None:
1111

1212
def load(self):
1313
with open(self.file, "r", encoding="utf-8") as f:
14-
self.cfg = yaml.load(f.read(), Loader=yaml.FullLoader)
14+
self.cfg = yaml.load(f.read(), Loader=yaml.FullLoader) or {}
1515

1616
def get(self, key, default_):
1717
value = self.cfg.get(key, default_)

container/logger.py

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,48 @@
1-
from loguru import logger
2-
from pathlib import Path
1+
from enum import Enum
2+
import inspect
3+
import io
4+
import sys
5+
import time
6+
STDOUT = sys.stdout
7+
class Stdout(io.StringIO):
8+
def write(self, __s: str) -> int:
9+
return STDOUT.write(__s)
10+
def flush(self) -> None:
11+
return STDOUT.flush()
12+
def seek(self, __cookie: int, __whence: int = 0) -> int:
13+
return STDOUT.seek(__cookie, __whence)
14+
sys.stdout = Stdout()
315

4-
logger.add(Path("./logs/{time}.log"), rotation="3 hours")
16+
class PrintStdout(io.StringIO):
17+
def write(self, __s: str) -> int:
18+
info(__s.lstrip("\r"), flush=True)
19+
return len(__s)
20+
PRINTSTDOUT = PrintStdout()
21+
22+
class Level(Enum):
23+
DEBUG = 0
24+
INFO = 1
25+
WARNING = 2
26+
ERROR = 3
27+
LevelColors: dict[Level, str] = {
28+
Level.DEBUG: "reset",
29+
Level.INFO: "green",
30+
Level.WARNING: "yellow",
31+
Level.ERROR: "red"
32+
}
33+
34+
def logger(*values, level: Level, flush: bool = False, stack: list[inspect.FrameInfo]):
35+
stackname = stack[1].function + str(stack[1].lineno)
36+
print(*(f"<<<flush:{flush},time:{time.time()},stack:{stackname},color:{LevelColors.get(level, 'reset')}>>>[{level.name.upper()}]", *values))
37+
38+
def info(*values, flush: bool = False):
39+
return logger(*values, flush=flush, level=Level.INFO, stack=inspect.stack())
40+
41+
def error(*values, flush: bool = False):
42+
return logger(*values, flush=flush, level=Level.ERROR, stack=inspect.stack())
43+
44+
def warning(*values, flush: bool = False):
45+
return logger(*values, flush=flush, level=Level.WARNING, stack=inspect.stack())
46+
47+
def debug(*values, flush: bool = False):
48+
return logger(*values, flush=flush, level=Level.DEBUG, stack=inspect.stack())

container/web.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import config
2020
import filetype
2121
import urllib.parse as urlparse
22-
from logger import logger
22+
import logger
2323

2424

2525
class Route:
@@ -556,6 +556,7 @@ async def main():
556556
if server:
557557
server.close()
558558
logger.error(traceback.format_exc())
559+
await asyncio.sleep(2)
559560

560561
@app.get("/favicon.ico")
561562
async def _():

main.py

Lines changed: 93 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,67 @@
1+
import os
12
from pathlib import Path
23
import queue
4+
import re
35
import subprocess
46
import threading
7+
import traceback
58
from typing import Optional
69
import sys
710
import time
811
from watchdog.observers import Observer
912
from watchdog.events import FileSystemEvent, FileSystemEventHandler
13+
14+
class PrintColor:
15+
def __init__(self) -> None:
16+
self.ansi = (
17+
(sys.platform != 'Pocket PC') and
18+
(
19+
(sys.platform != 'win32') or
20+
('ANSICON' in os.environ)
21+
) and
22+
(
23+
sys.stdout.isatty() or
24+
(sys.platform == 'win32')
25+
) and
26+
(
27+
'TERM' not in os.environ or
28+
(
29+
os.environ['TERM'].lower() in ('xterm', 'linux', 'screen', 'vt100', 'cygwin', 'ansicon') and
30+
os.environ['TERM'].lower() not in ('dumb', 'emacs', 'emacs-24', 'xterm-mono')
31+
)
32+
)
33+
)
34+
self.colors = {
35+
'reset': '\033[0m',
36+
'red': '\033[31m',
37+
'green': '\033[32m',
38+
'yellow': '\033[33m',
39+
'blue': '\033[34m',
40+
'magenta': '\033[35m',
41+
'cyan': '\033[36m',
42+
'white': '\033[37m',
43+
'black': '\033[30m',
44+
}
45+
self.open_tag_pattern = r'<(\w+)>'
46+
self.close_tag_pattern = r'<(\w+)/>'
47+
48+
def parse(self, text: str):
49+
current_color = self.colors['reset']
50+
open_tags = re.findall(self.open_tag_pattern, text)
51+
for tag in open_tags:
52+
if tag in self.colors:
53+
text = text.replace(f'<{tag}>', self.colors[tag], 1)
54+
current_color = self.colors[tag]
55+
else:
56+
text = text.replace(f'<{tag}>', '', 1)
57+
close_tags = re.findall(self.close_tag_pattern, text)
58+
for tag in close_tags:
59+
if tag == tag.lower() and self.colors.get(tag.lower(), '') == current_color:
60+
text = text.replace(f'<{tag}/>', self.colors['reset'], 1)
61+
current_color = self.colors['reset']
62+
return text
63+
64+
printColor = PrintColor()
1065
encoding = sys.getdefaultencoding()
1166
process: Optional[subprocess.Popen] = None
1267
stdout = None
@@ -55,10 +110,23 @@ def _err():
55110
else:
56111
output.put(line)
57112

58-
def _parse(params):
113+
def _parse(params: str):
59114
kwargs = {}
60-
if "flush" in params:
61-
kwargs["flush"] = True
115+
for item in params.split(","):
116+
k, v = item.split(":", 1)
117+
if v == "True":
118+
v = True
119+
elif v == "False":
120+
v = False
121+
else:
122+
try:
123+
v = float(v)
124+
except:
125+
try:
126+
v = int(v)
127+
except:
128+
...
129+
kwargs[k] = v
62130
return kwargs
63131
def _print():
64132
global output, last_output_length, last_flush
@@ -71,22 +139,28 @@ def _print():
71139
msg = msg.decode("gbk")
72140
except:
73141
msg = repr(msg)
74-
msg = msg.removesuffix("\n")
75-
date = time.localtime()
76-
date = f"[{date.tm_year:04d}-{date.tm_mon:02d}-{date.tm_mday:02d} {date.tm_hour:02d}:{date.tm_min:02d}:{date.tm_sec:02d}]"
77-
kwargs: dict = {}
78-
flush: bool = False
79-
if msg.startswith("<<<") and ">>>" in msg:
80-
kwargs = _parse(msg[3:msg.find(">>>")])
81-
msg = msg[msg.find(">>>") + 3:]
82-
flush = kwargs.get("flush", False)
83-
text = f"{date} {msg}"
84-
if flush:
85-
sys.stdout.write('\r' + ' ' * (last_output_length + 16) + '\r')
86-
sys.stdout.flush()
87-
last_output_length = len(text)
88-
print(text + ('\n' if not flush else ''), end='', flush=flush)
89-
last_flush = flush
142+
try:
143+
msg = msg.removesuffix("\n")
144+
date = time.localtime()
145+
kwargs: dict = {}
146+
flush: bool = False
147+
if msg.startswith("<<<") and ">>>" in msg:
148+
kwargs = _parse(msg[3:msg.find(">>>")])
149+
msg = msg[msg.find(">>>") + 3:]
150+
flush = kwargs.get("flush", False)
151+
if 'time' in kwargs:
152+
date = time.localtime(kwargs["time"])
153+
date = f"[{date.tm_year:04d}-{date.tm_mon:02d}-{date.tm_mday:02d} {date.tm_hour:02d}:{date.tm_min:02d}:{date.tm_sec:02d}]"
154+
text = printColor.parse(f"<{kwargs.get('color', 'reset')}>{date} {msg}")
155+
if flush:
156+
sys.stdout.write('\r' + ' ' * (last_output_length + 16) + '\r')
157+
sys.stdout.flush()
158+
last_output_length = len(text)
159+
print(text + ('\n' if not flush else ''), end='', flush=flush)
160+
last_flush = flush
161+
except:
162+
traceback.print_exc()
163+
...
90164

91165
class MyHandler(FileSystemEventHandler):
92166
def on_any_event(self, event: FileSystemEvent) -> None:

0 commit comments

Comments
 (0)