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:
@@ -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
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user