--- phase: 15-logging plan: 02 type: execute wave: 1 depends_on: ["15-01"] files_modified: - nlog.config - Program.cs autonomous: true --- ## Goal Replace all `Console.Write`/`Console.WriteLine` calls in Program.cs with `_log.Info(...)` and reconfigure the NLog console target so operator output is plain text (Info only), while Warn/Error routes to logfile only. ## Purpose Operator output currently bypasses NLog — no timestamps, no log file record of what was shown on screen. Moving all output through NLog means every operator interaction is in the log file with a timestamp, while the console still shows plain text identical to the current experience. ## Output - `nlog.config` — console target: layout=`${message}`, rule limited to Info level only - `Program.cs` — zero `Console.Write`/`Console.WriteLine` calls; all replaced with `_log.Info(...)` @.paul/PROJECT.md @.paul/phases/15-logging/15-01-SUMMARY.md @nlog.config @Program.cs ## AC-1: Console output unchanged for operator ```gherkin Given Program.cs has no Console.Write/Console.WriteLine calls When any operator-facing message is emitted (startup, progress, error text) Then operator sees exactly the same text on screen as before And no level/logger prefix appears on any message ``` ## AC-2: All operator output recorded in log file ```gherkin Given nlog.config file target captures Info+ When any operator-facing message is emitted Then that same message appears in logs/nc_program_manager.log with timestamp ``` ## AC-3: Warn/Error stay out of operator console ```gherkin Given _log.Warn and _log.Error calls in machine classes and Program.cs When those calls execute Then they do NOT appear on the operator console (file only) And they DO appear in the log file ``` Task 1: Reconfigure nlog.config console target to Info-only plain layout nlog.config Make two changes to nlog.config: **A. Console target layout** — change from level+logger prefix to plain message: Current: ```xml ``` Replace with: ```xml ``` **B. Console rule** — restrict to Info level only (not Warn/Error): Current: ```xml ``` Replace with: ```xml ``` Constraints: - File target and its rule (`minlevel="Debug" writeTo="logfile"`) MUST NOT change — file still captures everything - `levels="Info"` (not `minlevel`) — this restricts console to exactly Info, so Warn/Error go to file only - Layout `${message}` with no newline suffix — NLog appends newline automatically - Read nlog.config: console target layout is `${message}` - Read nlog.config: console rule uses `levels="Info"` - Read nlog.config: file target rule unchanged (`minlevel="Debug"`) AC-1 partial (layout ready), AC-3 satisfied: Warn/Error no longer route to console Task 2: Replace all Console.Write/WriteLine with _log.Info in Program.cs Program.cs Replace every `Console.Write` and `Console.WriteLine` call with `_log.Info(...)`. **Step 1 — Merge the one Console.Write (non-Line) pair at lines 25-26:** Current: ```csharp Console.Write("Gestore Programmi FANUC: "); Console.WriteLine(e.Message); ``` Replace with: ```csharp _log.Info("Gestore Programmi FANUC: {0}", e.Message); ``` **Step 2 — Replace all remaining Console.WriteLine calls:** Pattern rules: - `Console.WriteLine("literal string")` → `_log.Info("literal string")` - `Console.WriteLine(variable)` → `_log.Info("{0}", variable)` — safe against variables containing `{` - `Console.WriteLine("literal {0}", arg)` → `_log.Info("literal {0}", arg)` — format args pass through unchanged - `Console.WriteLine()` (empty — blank line) → `_log.Info("")` **Step 3 — For the 3 existing error catch blocks** (lines ~163, ~259 after prior edits): The pattern is now: ```csharp _log.Error(ex, "Scarica failed"); Console.WriteLine(ex.Message); ``` `Console.WriteLine(ex.Message)` → `_log.Info("{0}", ex.Message)` This is correct: _log.Error goes to file only (Warn/Error not on console per Task 1); _log.Info shows ex.Message on console — same behavior as the original Console.WriteLine. Constraints: - Do NOT change `_log.Error(...)` or `_log.Warn(...)` calls — those were added in 15-01 and must stay - Do NOT change `VediErrore(...)` calls - Do NOT change `MostraAiuto()` or any non-Console calls - `Console.WriteLine()` with no args (blank separator lines, if any) → `_log.Info("")` - After replacement, `grep -c "Console\." Program.cs` MUST return 0 - `grep -c "Console\." Program.cs` → 0 - `grep -c "_log.Info" Program.cs` → 98 (97 former WriteLine + 1 merged from Console.Write pair) - Read lines 22-30 Program.cs: single `_log.Info("Gestore Programmi FANUC: {0}", e.Message)` present; no Console.Write calls AC-1 satisfied: all operator output through NLog; AC-2 satisfied: Info goes to file target too ## DO NOT CHANGE - `nlog.config` file target and its rule — file still captures Debug+ - `_log.Error(...)` and `_log.Warn(...)` calls added in 15-01 — correct, leave alone - `NcProgramManager.Tests/` — no test changes - All machine classes — no changes needed (they have no Console.WriteLine) - `Licensing/`, `Cnc/`, `ArgParser.cs`, `InputArgs.cs` — not in scope ## SCOPE LIMITS - Only `nlog.config` and `Program.cs` modified - No new NLog targets beyond updating the existing console target - No changes to log levels on the file target - No changes to the `_log` field or `using NLog` already in Program.cs Before declaring plan complete: - [ ] `grep -c "Console\." Program.cs` → 0 - [ ] `grep -c "_log.Info" Program.cs` → 98 - [ ] `grep -c "_log.Error" Program.cs` → 3 (unchanged from 15-01) - [ ] nlog.config console target: layout=`${message}` - [ ] nlog.config console rule: `levels="Info"` (not minlevel) - [ ] nlog.config file rule: `minlevel="Debug"` (unchanged) - Both tasks completed - All 3 ACs covered - Zero Console.Write/Console.WriteLine remain in Program.cs - Operator console experience identical (plain text, no level prefix) - All output now in log file - No existing _log.Error/_log.Warn calls modified After completion, create `.paul/phases/15-logging/15-02-SUMMARY.md`