mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 01:26:11 -08:00
129
server/logger.py
129
server/logger.py
@@ -7,7 +7,6 @@ import time
|
||||
import logging
|
||||
|
||||
# NetAlertX imports
|
||||
|
||||
import conf
|
||||
from const import *
|
||||
|
||||
@@ -39,87 +38,80 @@ debugLevels = [
|
||||
# use the LOG_LEVEL from the config, may be overridden
|
||||
currentLevel = conf.LOG_LEVEL
|
||||
|
||||
# tracking log levels
|
||||
setLvl = 0
|
||||
reqLvl = 0
|
||||
#-------------------------------------------------------------------------------
|
||||
# Queue for log messages
|
||||
log_queue = queue.Queue(maxsize=1000) # Increase size to handle spikes
|
||||
log_thread = None # Will hold the thread reference
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
class Logger:
|
||||
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
|
||||
# Custom logging handler
|
||||
class MyLogHandler(logging.Handler):
|
||||
def emit(self, record):
|
||||
log_entry = self.format(record)
|
||||
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
|
||||
for lvl in debugLevels:
|
||||
if currentLevel == lvl[0]:
|
||||
setLvl = lvl[1]
|
||||
if requestedDebugLevel == lvl[0]:
|
||||
reqLvl = lvl[1]
|
||||
# Numeric weights
|
||||
self.setLvl = self._to_num(LOG_LEVEL)
|
||||
self.reqLvl = None
|
||||
|
||||
if reqLvl <= setLvl:
|
||||
file_print (*n)
|
||||
# Setup Python logging
|
||||
self.setup_logging()
|
||||
|
||||
def _to_num(self, level_str):
|
||||
for lvl in debugLevels:
|
||||
if level_str == lvl[0]:
|
||||
return lvl[1]
|
||||
return None
|
||||
|
||||
def setup_logging(self):
|
||||
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
|
||||
log_thread = None # Will hold the thread reference
|
||||
|
||||
def log_writer():
|
||||
buffer = []
|
||||
while True:
|
||||
try:
|
||||
log_entry = log_queue.get(timeout=1) # Wait for 1 second for logs
|
||||
if log_entry is None: # Graceful exit signal
|
||||
log_entry = log_queue.get(timeout=1)
|
||||
if log_entry is None:
|
||||
break
|
||||
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:
|
||||
log_file.write('\n'.join(buffer) + '\n')
|
||||
buffer.clear()
|
||||
except queue.Empty:
|
||||
# Flush buffer periodically if no new logs
|
||||
if buffer:
|
||||
with open(logPath + "/app.log", 'a') as log_file:
|
||||
log_file.write('\n'.join(buffer) + '\n')
|
||||
buffer.clear()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Function to start the log writer thread if it doesn't exist
|
||||
def start_log_writer_thread():
|
||||
global log_thread
|
||||
if log_thread is None or not log_thread.is_alive():
|
||||
@@ -128,40 +120,39 @@ def start_log_writer_thread():
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def file_print(*args):
|
||||
result = timeNowTZ().strftime('%H:%M:%S') + ' '
|
||||
|
||||
for arg in args:
|
||||
result += str(arg)
|
||||
result = timeNowTZ().strftime('%H:%M:%S') + ' '
|
||||
for arg in args:
|
||||
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)
|
||||
|
||||
# Ensure the log writer thread is running
|
||||
start_log_writer_thread()
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def append_file_binary(file_path, input_data):
|
||||
with open(file_path, 'ab') as file:
|
||||
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)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def logResult(stdout, stderr):
|
||||
if stderr is not None:
|
||||
append_file_binary(logPath + '/stderr.log', stderr)
|
||||
if stdout is not None:
|
||||
append_file_binary(logPath + '/stdout.log', stdout)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def append_line_to_file(pPath, pText):
|
||||
# append the line using the correct python version
|
||||
if sys.version_info < (3, 0):
|
||||
file = io.open(pPath, mode='a', encoding='utf-8')
|
||||
file.write(pText.decode('unicode_escape'))
|
||||
file.close()
|
||||
file.close()
|
||||
else:
|
||||
file = open(pPath, 'a', encoding='utf-8')
|
||||
file = open(pPath, 'a', encoding='utf-8')
|
||||
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