mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
115
server/logger.py
115
server/logger.py
@@ -7,7 +7,6 @@ import time
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
# NetAlertX imports
|
# NetAlertX imports
|
||||||
|
|
||||||
import conf
|
import conf
|
||||||
from const import *
|
from const import *
|
||||||
|
|
||||||
@@ -39,87 +38,80 @@ debugLevels = [
|
|||||||
# use the LOG_LEVEL from the config, may be overridden
|
# use the LOG_LEVEL from the config, may be overridden
|
||||||
currentLevel = conf.LOG_LEVEL
|
currentLevel = conf.LOG_LEVEL
|
||||||
|
|
||||||
# tracking log levels
|
#-------------------------------------------------------------------------------
|
||||||
setLvl = 0
|
# Queue for log messages
|
||||||
reqLvl = 0
|
log_queue = queue.Queue(maxsize=1000) # Increase size to handle spikes
|
||||||
|
log_thread = None # Will hold the thread reference
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
class Logger:
|
# Custom logging handler
|
||||||
def __init__(self, LOG_LEVEL):
|
|
||||||
global currentLevel
|
|
||||||
|
|
||||||
currentLevel = LOG_LEVEL
|
|
||||||
conf.LOG_LEVEL = currentLevel
|
|
||||||
|
|
||||||
# Automatically set up custom logging handler
|
|
||||||
self.setup_logging()
|
|
||||||
|
|
||||||
def setup_logging(self):
|
|
||||||
root_logger = logging.getLogger()
|
|
||||||
# Clear existing handlers to prevent duplicates
|
|
||||||
if root_logger.hasHandlers():
|
|
||||||
root_logger.handlers.clear()
|
|
||||||
|
|
||||||
# Create the custom handler
|
|
||||||
my_log_handler = MyLogHandler()
|
|
||||||
# my_log_handler.setLevel(custom_to_logging_levels.get(currentLevel, logging.NOTSET))
|
|
||||||
|
|
||||||
# Optional: Add a formatter for consistent log message format
|
|
||||||
# formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
||||||
formatter = logging.Formatter('%(message)s', datefmt='%H:%M:%S')
|
|
||||||
my_log_handler.setFormatter(formatter)
|
|
||||||
|
|
||||||
# Attach the handler to the root logger
|
|
||||||
root_logger.addHandler(my_log_handler)
|
|
||||||
root_logger.setLevel(custom_to_logging_levels.get(currentLevel, logging.NOTSET))
|
|
||||||
|
|
||||||
# for python logging
|
|
||||||
class MyLogHandler(logging.Handler):
|
class MyLogHandler(logging.Handler):
|
||||||
def emit(self, record):
|
def emit(self, record):
|
||||||
log_entry = self.format(record)
|
log_entry = self.format(record)
|
||||||
log_queue.put(log_entry)
|
log_queue.put(log_entry)
|
||||||
|
|
||||||
def mylog(requestedDebugLevel, n):
|
#-------------------------------------------------------------------------------
|
||||||
global setLvl, reqLvl
|
# Logger class
|
||||||
|
class Logger:
|
||||||
|
def __init__(self, LOG_LEVEL):
|
||||||
|
global currentLevel
|
||||||
|
currentLevel = LOG_LEVEL
|
||||||
|
conf.LOG_LEVEL = currentLevel
|
||||||
|
|
||||||
# Get debug urgency/relative weight
|
# Numeric weights
|
||||||
|
self.setLvl = self._to_num(LOG_LEVEL)
|
||||||
|
self.reqLvl = None
|
||||||
|
|
||||||
|
# Setup Python logging
|
||||||
|
self.setup_logging()
|
||||||
|
|
||||||
|
def _to_num(self, level_str):
|
||||||
for lvl in debugLevels:
|
for lvl in debugLevels:
|
||||||
if currentLevel == lvl[0]:
|
if level_str == lvl[0]:
|
||||||
setLvl = lvl[1]
|
return lvl[1]
|
||||||
if requestedDebugLevel == lvl[0]:
|
return None
|
||||||
reqLvl = lvl[1]
|
|
||||||
|
|
||||||
if reqLvl <= setLvl:
|
def setup_logging(self):
|
||||||
file_print (*n)
|
root_logger = logging.getLogger()
|
||||||
|
if root_logger.hasHandlers():
|
||||||
|
root_logger.handlers.clear()
|
||||||
|
|
||||||
|
my_log_handler = MyLogHandler()
|
||||||
|
formatter = logging.Formatter('%(message)s', datefmt='%H:%M:%S')
|
||||||
|
my_log_handler.setFormatter(formatter)
|
||||||
|
|
||||||
|
root_logger.addHandler(my_log_handler)
|
||||||
|
root_logger.setLevel(custom_to_logging_levels.get(currentLevel, logging.NOTSET))
|
||||||
|
|
||||||
|
def mylog(self, requestedDebugLevel, *args):
|
||||||
|
self.reqLvl = self._to_num(requestedDebugLevel)
|
||||||
|
if self.reqLvl is not None and self.reqLvl <= self.setLvl:
|
||||||
|
file_print(*args)
|
||||||
|
|
||||||
|
def isAbove(self, requestedDebugLevel):
|
||||||
|
reqLvl = self._to_num(requestedDebugLevel)
|
||||||
|
return reqLvl is not None and self.setLvl >= reqLvl
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Queue for log messages
|
|
||||||
log_queue = queue.Queue(maxsize=1000) # Increase size to handle spikes
|
|
||||||
|
|
||||||
# Dedicated thread for writing logs
|
# Dedicated thread for writing logs
|
||||||
log_thread = None # Will hold the thread reference
|
|
||||||
|
|
||||||
def log_writer():
|
def log_writer():
|
||||||
buffer = []
|
buffer = []
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
log_entry = log_queue.get(timeout=1) # Wait for 1 second for logs
|
log_entry = log_queue.get(timeout=1)
|
||||||
if log_entry is None: # Graceful exit signal
|
if log_entry is None:
|
||||||
break
|
break
|
||||||
buffer.append(log_entry)
|
buffer.append(log_entry)
|
||||||
if len(buffer) >= 10: # Write in batches of 10
|
if len(buffer) >= 10:
|
||||||
with open(logPath + "/app.log", 'a') as log_file:
|
with open(logPath + "/app.log", 'a') as log_file:
|
||||||
log_file.write('\n'.join(buffer) + '\n')
|
log_file.write('\n'.join(buffer) + '\n')
|
||||||
buffer.clear()
|
buffer.clear()
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
# Flush buffer periodically if no new logs
|
|
||||||
if buffer:
|
if buffer:
|
||||||
with open(logPath + "/app.log", 'a') as log_file:
|
with open(logPath + "/app.log", 'a') as log_file:
|
||||||
log_file.write('\n'.join(buffer) + '\n')
|
log_file.write('\n'.join(buffer) + '\n')
|
||||||
buffer.clear()
|
buffer.clear()
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Function to start the log writer thread if it doesn't exist
|
|
||||||
def start_log_writer_thread():
|
def start_log_writer_thread():
|
||||||
global log_thread
|
global log_thread
|
||||||
if log_thread is None or not log_thread.is_alive():
|
if log_thread is None or not log_thread.is_alive():
|
||||||
@@ -129,34 +121,28 @@ def start_log_writer_thread():
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def file_print(*args):
|
def file_print(*args):
|
||||||
result = timeNowTZ().strftime('%H:%M:%S') + ' '
|
result = timeNowTZ().strftime('%H:%M:%S') + ' '
|
||||||
|
|
||||||
for arg in args:
|
for arg in args:
|
||||||
result += str(arg)
|
result += str(arg)
|
||||||
|
|
||||||
logging.log(custom_to_logging_levels.get(currentLevel, logging.NOTSET), result) # Forward to Python's logging system
|
logging.log(custom_to_logging_levels.get(currentLevel, logging.NOTSET), result)
|
||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
# Ensure the log writer thread is running
|
|
||||||
start_log_writer_thread()
|
start_log_writer_thread()
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def append_file_binary(file_path, input_data):
|
def append_file_binary(file_path, input_data):
|
||||||
with open(file_path, 'ab') as file:
|
with open(file_path, 'ab') as file:
|
||||||
if isinstance(input_data, str):
|
if isinstance(input_data, str):
|
||||||
input_data = input_data.encode('utf-8') # Encode string as bytes
|
input_data = input_data.encode('utf-8')
|
||||||
file.write(input_data)
|
file.write(input_data)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def logResult(stdout, stderr):
|
def logResult(stdout, stderr):
|
||||||
if stderr is not None:
|
if stderr is not None:
|
||||||
append_file_binary(logPath + '/stderr.log', stderr)
|
append_file_binary(logPath + '/stderr.log', stderr)
|
||||||
if stdout is not None:
|
if stdout is not None:
|
||||||
append_file_binary(logPath + '/stdout.log', stdout)
|
append_file_binary(logPath + '/stdout.log', stdout)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def append_line_to_file(pPath, pText):
|
def append_line_to_file(pPath, pText):
|
||||||
# append the line using the correct python version
|
|
||||||
if sys.version_info < (3, 0):
|
if sys.version_info < (3, 0):
|
||||||
file = io.open(pPath, mode='a', encoding='utf-8')
|
file = io.open(pPath, mode='a', encoding='utf-8')
|
||||||
file.write(pText.decode('unicode_escape'))
|
file.write(pText.decode('unicode_escape'))
|
||||||
@@ -165,3 +151,8 @@ def append_line_to_file(pPath, pText):
|
|||||||
file = open(pPath, 'a', encoding='utf-8')
|
file = open(pPath, 'a', encoding='utf-8')
|
||||||
file.write(pText)
|
file.write(pText)
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# Create default logger instance and backward-compatible global mylog
|
||||||
|
logger = Logger(conf.LOG_LEVEL)
|
||||||
|
mylog = logger.mylog
|
||||||
|
|||||||
Reference in New Issue
Block a user