Refactor logging implementation to use Loguru for improved logging management and add warnings for unknown leave values and worker site validation.

This commit is contained in:
Ross
2025-09-17 21:21:23 +01:00
parent 7cd2cec65c
commit 47bfb16891
2 changed files with 32 additions and 9 deletions
+3
View File
@@ -17,6 +17,7 @@ from rota.workers import (
OutOfProgramme, OutOfProgramme,
) )
from loguru import logger
app = typer.Typer() app = typer.Typer()
@@ -68,6 +69,8 @@ def extract_leave_and_rota_from_calender(calender_df):
"date": date, "date": date,
"worker": worker, "worker": worker,
}) })
else:
logger.warning(f"Unknown leave value for {worker} on {date}: {leave_val}")
#print(leave_requests) #print(leave_requests)
return leave_requests, work_requests, rota_data return leave_requests, work_requests, rota_data
+29 -9
View File
@@ -34,14 +34,9 @@ from rich.progress import track
from rich.panel import Panel from rich.panel import Panel
from rich import print from rich import print
import logging from loguru import logger
logging.basicConfig( logger.add("rota.log", rotation="1 MB", level="DEBUG")
filename="rota.log",
filemode="w",
format="%(name)s - %(levelname)s - %(message)s",
level=logging.DEBUG,
)
ShiftName = str ShiftName = str
DayStr = str DayStr = str
@@ -413,7 +408,7 @@ class RotaBuilder(object):
"Shift/invalid start date", "Shift/invalid start date",
"Shift/invalid end date", "Shift/invalid end date",
"Locum/no locum availability", "Locum/no locum availability",
"Force assignment/leave conflict", # Currently will always be infeasible #"Force assignment/leave conflict", # Currently will always be infeasible
] ]
self.results = None self.results = None
@@ -1515,7 +1510,7 @@ class RotaBuilder(object):
console.rule( console.rule(
f"Generate worker constraints: [bold blue]{worker.name}[/bold blue]" f"Generate worker constraints: [bold blue]{worker.name}[/bold blue]"
) )
logging.debug(f"Generate worker constraints: {worker.name}") logger.debug(f"Generate worker constraints: {worker.name}")
for week, day in self.get_week_day_combinations(): for week, day in self.get_week_day_combinations():
shifts_today = self.get_shift_names_by_week_day(week, day) shifts_today = self.get_shift_names_by_week_day(week, day)
@@ -3312,6 +3307,7 @@ class RotaBuilder(object):
if worker.site not in self.sites: if worker.site not in self.sites:
message = f"Worker with name '{worker.name}' ({worker.id}) has no valid shifts (site: {worker.site})" message = f"Worker with name '{worker.name}' ({worker.id}) has no valid shifts (site: {worker.site})"
logger.warning(message)
self.add_warning("Worker/no valid shifts", message) self.add_warning("Worker/no valid shifts", message)
@@ -4540,8 +4536,32 @@ class RotaBuilder(object):
f"Shift balance extra: {getattr(worker, 'shift_balance_extra', '')}", f"Shift balance extra: {getattr(worker, 'shift_balance_extra', '')}",
f"Non-working days: {getattr(worker, 'non_working_day_list', '')}", f"Non-working days: {getattr(worker, 'non_working_day_list', '')}",
f"OOP: {getattr(worker, 'oop', '')}", f"OOP: {getattr(worker, 'oop', '')}",
f"Unavailable: {''}",
f"Shift targets: {json.dumps(getattr(worker, 'shift_target_number', {}))}", f"Shift targets: {json.dumps(getattr(worker, 'shift_target_number', {}))}",
] ]
# Build unavailability list for this worker
unavail_list = []
for entry in sorted(self.unavailable_to_work):
wid, wk, d = entry
if wid != worker.id:
continue
date = self.get_date_by_week_day(wk, d)
reason = self.unavailable_to_work_reason.get((wid, wk, d), "")
if reason:
unavail_list.append(f"{date.isoformat()} ({d}) [week {wk}]: {reason}")
else:
# date may be a string if fallback used
if isinstance(date, str):
unavail_list.append(f"{date} ({d}) [week {wk}]")
else:
unavail_list.append(f"{date.isoformat()} ({d}) [week {wk}]")
# replace placeholder Unavailable entry
details = [line for line in details if not line.startswith("Unavailable:")]
details.insert(
-1, # before Shift targets
f"Unavailable: {', '.join(unavail_list) if unavail_list else ''}",
)
worker_details_human.append("\n".join(details)) worker_details_human.append("\n".join(details))
worker_details_human_str = "\n\n".join(worker_details_human) worker_details_human_str = "\n\n".join(worker_details_human)