Files
ginxsom/plans/unified-logging-migration.md

6.7 KiB

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

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
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

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

  1. Add LOG_TRACE level to log_level_t enum in ginxsom.h
  2. Add a global g_log_level variable to control minimum log level
  3. 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

  1. Add #include "nostr_core/nostr_core.h" (or nostr_log.h) to main.c if not already present
  2. Create nostr_log_cb() callback function that maps nostr log levels to app_log() levels and prefixes messages with [nostr:component]
  3. 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)
  4. In shutdown path, call nostr_set_log_callback(NULL, NULL) before nostr_cleanup()

Phase 4: Eliminate debug.log

  1. Remove validator_debug_log() function from request_validator.c
  2. Replace all validator_debug_log() calls with app_log(LOG_DEBUG, "VALIDATOR: %s", ...) calls
  3. Delete stale logs/app/debug.log and nostr_core_lib/debug.log references from .gitignore or docs if present
  4. 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):

  1. src/admin_auth.c (~28 fprintf calls) - Replace with app_log(LOG_ERROR, "AUTH: ...") etc.
  2. src/request_validator.c (~2 fprintf calls) - Replace with app_log(LOG_DEBUG, "VALIDATOR: ...")
  3. 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

  1. 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

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

Phase 8: Update Makefile and build

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

Phase 9: Verify and test

  1. 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
  2. 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