-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
154 lines (130 loc) · 5.32 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import http.server
import socketserver
import json
from urllib.parse import urlparse
import logging
import sys
import os
import cursor
# Define the path for akashic.log
AKASHIC_LOG = "/var/log/akashic.log"
class CustomFormatter(logging.Formatter):
COLORS = {
"DEBUG": "\033[30m\033[102m", # Black text on green background
"INFO": "\033[30m\033[107m", # Black text on white background
"WARNING": "\033[30m\033[103m", # Black text on yellow background
"ERROR": "\033[97m\033[101m", # White text on red background
"CRITICAL": "\033[97m\033[41m", # White text on red background
}
RESET = "\033[0m"
SECONDARY_COLOR = "\033[94m" # Light blue as secondary color
BODY_COLOR = "\033[37m" # White color for message body
CRITICAL_BODY_COLOR = "\033[31m" # Red color for critical message body
def format(self, record):
color = self.COLORS.get(record.levelname, self.RESET)
body_color = (
self.CRITICAL_BODY_COLOR
if record.levelname == "CRITICAL"
else self.BODY_COLOR
)
return f" {color} {record.levelname} {self.RESET} [{self.SECONDARY_COLOR}{record.name}{self.RESET}]: {body_color}{record.getMessage()}{self.RESET}"
class DualHandler(logging.Handler):
def __init__(self, file_path):
super().__init__()
self.setLevel(logging.DEBUG) # Set the handler's level to DEBUG
try:
self.file_handler = logging.FileHandler(file_path)
self.file_handler.setFormatter(
logging.Formatter(
"%(asctime)s - %(levelname)s - %(name)s - %(message)s"
)
)
self.file_handler.setLevel(
logging.DEBUG
) # Set file handler's level to DEBUG
except PermissionError:
print(
f"Warning: Unable to write to {file_path}. Logs will only be printed to console."
)
self.file_handler = None
self.stream_handler = logging.StreamHandler(sys.stdout)
self.stream_handler.setFormatter(CustomFormatter())
self.stream_handler.setLevel(
logging.DEBUG
) # Set stream handler's level to DEBUG
def emit(self, record):
if self.file_handler:
self.file_handler.emit(record)
self.stream_handler.emit(record)
# Configure unified logging
akashic_handler = DualHandler(AKASHIC_LOG)
def get_logger(name):
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
logger.addHandler(akashic_handler)
return logger
# Get loggers
server_logger = get_logger("akashic")
class LoggingHandler(http.server.SimpleHTTPRequestHandler):
def do_OPTIONS(self):
self.send_response(200)
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
self.send_header("Access-Control-Allow-Headers", "Content-Type")
self.end_headers()
def do_POST(self):
parsed_path = urlparse(self.path)
if parsed_path.path == "/post":
content_length = int(self.headers["Content-Length"])
post_data = self.rfile.read(content_length)
try:
data = json.loads(post_data.decode("utf-8"))
level = data.get("level", "INFO").upper()
message = data.get("message", "")
name = data.get("name", "default")
# Log the message using the named logger
logger = get_logger(name)
log_func = getattr(logger, level.lower(), logger.info)
log_func(message)
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.send_header("Access-Control-Allow-Origin", "*")
self.end_headers()
self.wfile.write(b"Log received and processed")
except json.JSONDecodeError:
self.send_error(400, "Invalid JSON data")
server_logger.error("Received invalid JSON data")
else:
self.send_error(404, "Endpoint not found")
server_logger.warning(
f"Attempted access to non-existent endpoint: {self.path}"
)
def log_message(self, format, *args):
# Use server_logger for server operation logs
server_logger.info(format % args)
if __name__ == "__main__":
PORT = 5231
Handler = LoggingHandler
server_logger.info(f"Starting server on localhost:{PORT}")
if akashic_handler.file_handler:
server_logger.info(f"Logs will be written to {AKASHIC_LOG}")
else:
server_logger.warning(
f"Unable to write logs to {AKASHIC_LOG}. Logs will only be printed to console."
)
with socketserver.TCPServer(("localhost", PORT), Handler) as httpd:
print(f"Serving at port {PORT}")
if akashic_handler.file_handler:
print(f"Logs will be written to {AKASHIC_LOG}")
else:
print(
f"Unable to write logs to {AKASHIC_LOG}. Logs will only be printed to console."
)
try:
cursor.hide()
httpd.serve_forever()
except KeyboardInterrupt:
server_logger.info("Server stopped.")
finally:
cursor.show()
httpd.server_close()