# Unified Logging Migration Plan

## Overview

Migrate ginxsom to use nostr_core_lib v0.4.13's callback-based logging API and unify all application logging into a single sink (`logs/app/app.log`).

## Architecture Context

```mermaid
graph TD
    subgraph Current State - v0.4.8
        A[ginxsom app] -->|fprintf stderr ~122 calls| B[nginx error_log]
        A -->|app_log ~80+ calls| C[logs/app/app.log]
        A -->|validator_debug_log ~10 calls| D[logs/app/debug.log]
        E[nostr_core_lib] -->|direct file write| F[nostr_core_lib/debug.log]
        G[systemd journald] -->|spawn-fcgi parent only| H[journal]
    end
```

```mermaid
graph TD
    subgraph Target State - v0.4.13
        A2[ginxsom app] -->|stderr: pre-init fatal only ~10 calls| B2[nginx error_log]
        A2 -->|app_log: all operational logs| C2[logs/app/app.log]
        E2[nostr_core_lib] -->|callback| A2
        G2[systemd journald] -->|spawn-fcgi parent only| H2[journal]
    end
```

## Logging Policy

| Sink | Purpose | When Used |
|------|---------|-----------|
| `stderr` -> nginx error_log | Pre-init fatal errors only | Before `app_log` is available, or truly unrecoverable errors during early `main` |
| `logs/app/app.log` via `app_log` | All application operational logging | Everything after logger init: app events, nostr_core_lib callback, validator, relay, admin |
| `logs/app/debug.log` | **ELIMINATED** | Replaced by `app_log(LOG_DEBUG, ...)` |
| `nostr_core_lib/debug.log` | **ELIMINATED** | v0.4.13 removes direct file logging; callback replaces it |

## Log Levels

```c
typedef enum {
    LOG_TRACE = 0,  // NEW: maps to NOSTR_LOG_LEVEL_TRACE
    LOG_DEBUG = 1,  // maps to NOSTR_LOG_LEVEL_DEBUG
    LOG_INFO  = 2,  // maps to NOSTR_LOG_LEVEL_INFO
    LOG_WARN  = 3,  // maps to NOSTR_LOG_LEVEL_WARN
    LOG_ERROR = 4   // maps to NOSTR_LOG_LEVEL_ERROR
} log_level_t;
```

**Note:** Existing code uses `LOG_DEBUG=0, LOG_INFO=1, LOG_WARN=2, LOG_ERROR=3`. Adding `LOG_TRACE` at 0 shifts all values up by 1. All existing call sites use the enum names (not raw integers), so this is safe.

## Implementation Steps

### Phase 1: Update nostr_core_lib submodule

1. Update the `nostr_core_lib` git submodule to v0.4.13
2. Rebuild `libnostr_core_x64.a` from the updated source
3. Verify the new headers exist: `nostr_core/nostr_log.h` (or equivalent in `nostr_core.h`)
4. Verify build still compiles with `make clean && make`

### Phase 2: Enhance app_log in ginxsom.h and main.c

5. Add `LOG_TRACE` level to `log_level_t` enum in `ginxsom.h`
6. Add a global `g_log_level` variable to control minimum log level
7. Update `app_log()` in `main.c` to:
   - Check message level against `g_log_level` before writing
   - Handle the new `LOG_TRACE` level string
   - Keep the existing file-based sink (`logs/app/app.log`)

### Phase 3: Register nostr_core_lib log callback

8. Add `#include "nostr_core/nostr_core.h"` (or `nostr_log.h`) to `main.c` if not already present
9. Create `nostr_log_cb()` callback function that maps nostr log levels to `app_log()` levels and prefixes messages with `[nostr:component]`
10. In `main()`, after `nostr_init()` / `nostr_crypto_init()`, call:
    - `nostr_set_log_callback(nostr_log_cb, NULL)`
    - `nostr_set_log_level(NOSTR_LOG_LEVEL_INFO)` (or TRACE for debug builds)
11. In shutdown path, call `nostr_set_log_callback(NULL, NULL)` before `nostr_cleanup()`

### Phase 4: Eliminate debug.log

12. Remove `validator_debug_log()` function from `request_validator.c`
13. Replace all `validator_debug_log()` calls with `app_log(LOG_DEBUG, "VALIDATOR: %s", ...)` calls
14. Delete stale `logs/app/debug.log` and `nostr_core_lib/debug.log` references from `.gitignore` or docs if present
15. Remove `debug.log` from project root if it was generated by nostr_core_lib

### Phase 5: Migrate fprintf(stderr) calls to app_log

Migrate post-startup `fprintf(stderr, ...)` calls file-by-file. Keep only pre-init and truly fatal stderr calls in early `main()`.

**Files to migrate (by priority):**

16. `src/admin_auth.c` (~28 fprintf calls) - Replace with `app_log(LOG_ERROR, "AUTH: ...")` etc.
17. `src/request_validator.c` (~2 fprintf calls) - Replace with `app_log(LOG_DEBUG, "VALIDATOR: ...")`
18. `src/main.c` - Categorize ~90 fprintf calls:
    - **Keep as stderr** (~10): Pre-logger-init errors in early `main()`, help text output, keypair display banner
    - **Migrate to app_log** (~80): All post-init startup messages, database operations, request logging, upload handling, shutdown messages

### Phase 6: Remove duplicate log_level_t declarations

19. Remove the duplicate `typedef enum { LOG_DEBUG... } log_level_t` and `void app_log(...)` forward declarations from `src/relay_client.c` and `src/admin_commands.c` — these files should just `#include "ginxsom.h"` instead

### Phase 7: Update nostr_crypto_init to nostr_init

20. Replace `nostr_crypto_init()` calls with `nostr_init()` in `main.c` and `request_validator.c` if v0.4.13 consolidates initialization under `nostr_init()`
21. Add `nostr_cleanup()` call in shutdown path if not already present

### Phase 8: Update Makefile and build

22. Verify `Makefile` CFLAGS and LIBS are compatible with v0.4.13 (check if new link flags needed)
23. Remove any `LOGGING_FLAGS` build-time defines that are no longer needed
24. Run `make clean && make` and verify clean build

### Phase 9: Verify and test

25. Run the application and verify:
    - `logs/app/app.log` contains both app logs and `[nostr:websocket]` / `[nostr:nip013]` tagged lines
    - `logs/app/debug.log` is no longer created
    - `nostr_core_lib/debug.log` is no longer created
    - `logs/nginx/error.log` only contains pre-init errors and nginx's own messages
26. Run existing test suite to verify no regressions

## Files Modified

| File | Changes |
|------|---------|
| `nostr_core_lib/` | Submodule updated to v0.4.13 |
| `src/ginxsom.h` | Add LOG_TRACE, add g_log_level extern |
| `src/main.c` | Enhanced app_log, nostr_log_cb, callback registration, fprintf migration |
| `src/request_validator.c` | Remove validator_debug_log, replace with app_log |
| `src/admin_auth.c` | Replace fprintf(stderr) with app_log |
| `src/relay_client.c` | Remove duplicate log_level_t typedef |
| `src/admin_commands.c` | Remove duplicate log_level_t typedef |
| `Makefile` | Verify/update build flags |
| `.gitignore` | Add/update debug.log exclusions |

## Risk Mitigation

- **Backward compatibility**: Enum names are used everywhere, not raw integers, so shifting values is safe
- **Build breakage**: Phase 1 verifies build before any code changes
- **Runtime breakage**: Callback registration is additive — if it fails, app still works, just without nostr_core_lib log routing
- **stderr removal safety**: Only post-init calls are migrated; pre-init fatal errors stay on stderr for nginx capture
