feat: add NGIT_LOG_LEVEL configuration option

Add proper log level configuration following standard approach:
- CLI flag: --log-level <level>
- Environment variable: NGIT_LOG_LEVEL
- Default: info
- Supports simple levels (error, warn, info, debug, trace)
- Supports filter expressions (e.g., ngit_grasp=debug,actix_web=info)

Configuration is now consistent across all four sources:
1. src/config.rs - Config struct with log_level field
2. docs/reference/configuration.md - Full documentation
3. nix/module.nix - NixOS module with logLevel option
4. .env.example - Example configuration file

This replaces the previous RUST_LOG approach with proper integration
into the ngit-grasp configuration system, enabling trace logging from
CLI, environment variables, or NixOS configuration.
This commit is contained in:
DanConwayDev
2026-01-27 20:38:15 +00:00
parent 87bd544b45
commit 1ae97cd85a
5 changed files with 51 additions and 25 deletions
+5 -2
View File
@@ -101,9 +101,12 @@
# LOGGING
# ============================================================================
# Rust log level (not a ngit-grasp config, but useful for debugging)
# Log level for application logging
# CLI: --log-level <level>
# Default: info
# Options: error, warn, info, debug, trace
# RUST_LOG=info
# Can also use filter expressions: ngit_grasp=debug,actix_web=info
# NGIT_LOG_LEVEL=info
# ============================================================================
# PROACTIVE SYNC (GRASP-02)
+25 -12
View File
@@ -1041,10 +1041,10 @@ Per-connection limits (built-in to relay-builder, not configurable):
### Logging Configuration
#### `RUST_LOG`
#### `NGIT_LOG_LEVEL`
**Description:** Logging level and filters (standard Rust environment variable)
**Type:** String (log level or filter)
**Description:** Logging level and filters for application logging
**Type:** String (log level or filter expression)
**Default:** `info`
**Required:** No
@@ -1052,17 +1052,17 @@ Per-connection limits (built-in to relay-builder, not configurable):
```bash
# Simple levels
RUST_LOG=error # Errors only
RUST_LOG=warn # Warnings and errors
RUST_LOG=info # Info, warnings, errors
RUST_LOG=debug # Debug and above
RUST_LOG=trace # Everything
NGIT_LOG_LEVEL=error # Errors only
NGIT_LOG_LEVEL=warn # Warnings and errors
NGIT_LOG_LEVEL=info # Info, warnings, errors (default)
NGIT_LOG_LEVEL=debug # Debug and above
NGIT_LOG_LEVEL=trace # Everything (very verbose)
# Module-specific
RUST_LOG=ngit_grasp=debug,actix_web=info
# Module-specific filtering
NGIT_LOG_LEVEL=ngit_grasp=debug,actix_web=info
# Complex filters
RUST_LOG=debug,hyper=info,tokio=warn
NGIT_LOG_LEVEL=debug,hyper=info,tokio=warn
```
**Log levels (most to least verbose):**
@@ -1073,12 +1073,25 @@ RUST_LOG=debug,hyper=info,tokio=warn
4. `warn` - Warnings about potential issues
5. `error` - Errors only
**CLI flag:**
```bash
ngit-grasp --log-level trace
```
**Production recommendation:**
```bash
RUST_LOG=info,ngit_grasp=debug
NGIT_LOG_LEVEL=info
```
**Notes:**
- Uses Rust's `tracing` crate filter syntax
- Supports module-level filtering (e.g., `ngit_grasp=debug,hyper=info`)
- `trace` level can significantly impact performance
- For production, `info` or `warn` is recommended
---
### Security Configuration (Planned)
+8 -3
View File
@@ -127,9 +127,14 @@ let
};
logLevel = mkOption {
type = types.enum [ "trace" "debug" "info" "warn" "error" ];
type = types.str;
default = "info";
description = "Logging level for RUST_LOG environment variable";
example = "debug";
description = ''
Logging level for application logging.
Can be a simple level (trace, debug, info, warn, error) or a filter expression.
Examples: "info", "debug", "ngit_grasp=debug,actix_web=info"
'';
};
syncMaxBackoffSecs = mkOption {
@@ -334,7 +339,7 @@ let
NGIT_REPOSITORY_BLACKLIST = concatStringsSep "," cfg.repositoryBlacklist;
NGIT_EVENT_BLACKLIST = concatStringsSep "," cfg.eventBlacklist;
NGIT_MAX_CONNECTIONS = toString cfg.maxConnections;
RUST_LOG = cfg.logLevel;
NGIT_LOG_LEVEL = cfg.logLevel;
} // optionalAttrs (cfg.relayName != null) {
NGIT_RELAY_NAME = cfg.relayName;
} // optionalAttrs (cfg.archiveReadOnly != null) {
+5
View File
@@ -500,6 +500,10 @@ pub struct Config {
/// Prevents connection exhaustion DoS attacks
#[arg(long, env = "NGIT_MAX_CONNECTIONS", default_value_t = 4096)]
pub max_connections: usize,
/// Log level for application logging
#[arg(long, env = "NGIT_LOG_LEVEL", default_value = "info")]
pub log_level: String,
}
impl Config {
@@ -782,6 +786,7 @@ impl Config {
repository_blacklist: String::new(),
event_blacklist: String::new(),
max_connections: 500,
log_level: "debug".to_string(),
}
}
}
+8 -8
View File
@@ -3,8 +3,8 @@ use std::{path::PathBuf, sync::Arc};
use anyhow::Result;
use tokio::signal;
use tracing::{error, info, warn, Level};
use tracing_subscriber::FmtSubscriber;
use tracing::{error, info, warn};
use tracing_subscriber::{EnvFilter, FmtSubscriber};
use ngit_grasp::{
config::{Config, DatabaseBackend},
@@ -17,16 +17,16 @@ use ngit_grasp::{
#[tokio::main]
async fn main() -> Result<()> {
// Initialize tracing
// Load configuration first (priority: CLI flags > env vars > .env file > defaults)
let config = Config::load()?;
// Initialize tracing with configured log level
let subscriber = FmtSubscriber::builder()
.with_max_level(Level::DEBUG)
.with_env_filter(EnvFilter::new(&config.log_level))
.finish();
tracing::subscriber::set_global_default(subscriber)?;
info!("Starting ngit-grasp with nostr-relay-builder...");
// Load configuration (priority: CLI flags > env vars > .env file > defaults)
let config = Config::load()?;
info!("Starting ngit-grasp with log level: {}", config.log_level);
// Validate configuration and fail fast on fatal errors
// Recoverable issues (e.g., malformed whitelist entries) are logged as warnings