refactor(build): code analysis engine
fix(nfo): deep code analysis engine with 5 supporting modules
feat(tests): multi-language support with 3 supporting modules
feat(tests): configuration management system
feat(tests): deep code analysis engine
fix(docs): deep code analysis engine with 6 supporting modules
feat(pipeline): PipelineSink, @decision_log, global auto_extract_meta
PipelineSink (nfo/pipeline_sink.py) — groups LogEntry objects by
pipeline_run_id and renders pipeline ticks as box-drawing terminal blocks
with step timings, metrics, decisions, costs, and error context.@decision_log decorator (nfo/decorators.py) — logs conditional
decisions with structured decision/reason fields in entry.extra.auto_extract_meta — _maybe_extract() in decorators now
falls back to the global auto_extract_meta flag from configure(),
so all @log_call sites automatically extract metadata for large args
without per-decorator changes.get_global_auto_extract_meta() in nfo/configure.py.PipelineSink, decision_log added to __init__.py and __all__.tests/test_pipeline_sink.py (basic, rendering, color,
timeout, multi-run, footer, delegate).feat(config): configuration management system
refactor(config): CLI interface improvements
refactor(goal): CLI interface improvements
feat(meta): Binary data logging strategy — log metadata instead of raw data
ThresholdPolicy (nfo/meta.py) — size-based policy deciding when to log full data vs extracted metadata; configurable max_arg_bytes, max_return_bytes, max_total_bytes, binary_thresholdMetaExtractor (nfo/extractors.py) — intelligent type detection and metadata extraction for binary payloads:
register_extractor() / unregister_all_extractors() for custom type support@meta_log (nfo/meta_decorators.py) — dedicated decorator for binary data pipelines; never logs raw bytes/bytearray above threshold; supports sync + async, custom extract_fields, per-argument extractorsBinaryAwareRouter (nfo/binary_router.py) — sink that routes log entries based on payload characteristics: meta-log entries → lightweight sink, large binary data → heavy sink, normal entries → full sink@log_call(extract_meta=True) — opt-in metadata extraction in existing decorator; zero breaking changes; optional meta_policy parameter@catch(extract_meta=True) — same integration for @catch decoratorconfigure(meta_policy=..., auto_extract_meta=True) — global configuration for metadata extractionNFO_META_THRESHOLD (bytes), NFO_META_EXTRACT (true/false)AsyncBufferedSink (nfo/buffered_sink.py) — background-thread batched writes; configurable buffer_size, flush_interval, flush_on_error; auto-flush on ERROR/CRITICAL; manual flush() and pending propertyRingBufferSink (nfo/ring_buffer_sink.py) — in-memory ring buffer (configurable capacity) that flushes context to delegate on ERROR/CRITICAL; zero disk I/O during normal operation; customizable trigger_levels and include_triggersample_rate parameter on @log_call, @catch, and @meta_log — fraction of calls to log (0.0–1.0); errors are always logged regardless of samplingtest_meta.py (20), test_extractors.py (30), test_meta_decorators.py (20), test_binary_router.py (9), test_buffered_sink.py (11), test_ring_buffer_sink.py (13), sampling tests in test_decorators.py (8)__init__.py: exports ThresholdPolicy, extract_meta, register_extractor, meta_log, BinaryAwareRouter, AsyncBufferedSink, RingBufferSinkconfigure.py: accepts meta_policy and auto_extract_meta; reads NFO_META_THRESHOLD and NFO_META_EXTRACT env varsdecorators.py: @log_call and @catch accept sample_rate (sampling check deferred after function execution for zero overhead on skipped calls)meta_decorators.py: @meta_log accepts sample_ratefeat(docs): docs module improvements
feat(docs): code analysis engine
feat(docs): comprehensive project analysis with function index
project.functions.toon) - comprehensive analysis of 46 modules and 448 functionsfix(docs): CLI interface with 3 supporting modules
args, kwargs, return_value, and kwarg_types via LogEntry.safe_repr + max_repr_length (default: 2048)Logger._format_stdlib() now uses truncated LogEntry repr helpers instead of raw !rLLMSink now builds prompts from truncated argument representationsmax_repr_length option for @log_call, @catch, @logged, auto_log(), and auto_log_by_name()feat(docs): deep code analysis engine with 6 supporting modules
All notable changes to nfo are documented here.
bump2version config — synced .bumpversion.cfg to track pyproject.toml, VERSION, and nfo/__init__.py; all three files now bump atomicallyenv_tagger_usage.py — fixed sqlite3.Row.get() → dict(row).get() (Python 3.13 compat)site-packages shadowing local sourcenfo CLI — universal command proxy with automatic logging:
nfo run -- <cmd> — run any command with nfo logging (args, stdout/stderr, return code, duration, language auto-detection)nfo logs [db] [--errors] [--level] [--last 24h] [--function] — query SQLite logs with color outputnfo serve [--port] [--host] — start centralized HTTP logging service (built-in FastAPI, no external file needed)nfo version — print versionpyproject.toml ([project.scripts])nfo/__main__.py — python -m nfo supportnfo serve — inline HTTP logging service with POST /log, POST /log/batch, GET /logs, GET /healthexamples/grpc_server.py) — high-performance Python gRPC logging service implementing LogCall, BatchLog, StreamLog (bidirectional), QueryLogsexamples/grpc_client.py) — Python gRPC client demo for all 4 RPCs[grpc] optional dependency — pip install nfo[grpc] installs grpcio + grpcio-toolsDockerfile — used by examples/docker-compose-service.yml for centralized logging service.env.example files — root + examples/ with all NFO_* variables documentedexamples/http_service.py — standalone FastAPI centralized logging service with .env supportexamples/bash_wrapper.py — nfo-bash proxy for shell scripts → SQLiteexamples/bash_client.sh — zero-dependency Bash HTTP client (nfo_log, nfo_run, nfo_query)examples/env_config_usage.py — .env file configuration with python-dotenvexamples/async_usage.py, auto_log_usage.py, configure_usage.py, env_tagger_usage.py — new Python examplesPrometheusSink — export function call metrics (duration histogram, call count, error rate) to Prometheus; auto /metrics endpoint; optional dep pip install nfo[prometheus]WebhookSink — HTTP POST alerts to Slack, Discord, or Microsoft Teams on ERROR; fire-and-forget with format templates; zero external dependencies (stdlib urllib)JSONSink — structured JSON Lines output for ELK/Grafana Loki/Fluentd; zero external dependenciesnfo-demo (FastAPI) + Prometheus + Grafana with pre-built dashboarddemo/load_generator.py for populating metricsconfigure() now supports json:path and prometheus:port sink specsPrometheusSink, WebhookSink, JSONSink (114 total)[prometheus], [dashboard]pyproject.toml: added [prometheus] and [dashboard] optional dependency groups[dev] group now includes pytest-asyncio and prometheus_clientpropagate=False on stdlib logger to prevent double outputconfigure() now returns cached logger on repeated calls (use force=True to override)__init__.py and pyproject.toml__version__ in __init__.py synced with pyproject.toml (was out of date)@log_call, @catch, and @logged now transparently handle async def functions via inspect.iscoroutinefunction()@log_call and @catchauto_log_by_name() — like auto_log() but accepts module name strings; resolves from sys.modulesauto_log() — one-call module-level patching: wraps all functions in a module with @log_call or @catch without individual decoratorsLogEntry sinks now persist environment, trace_id, version, llm_analysis fieldsLLMSink — LLM-powered log analysis via litellm (OpenAI, Anthropic, Ollama)detect_prompt_injection() — regex-based prompt injection detection in function argsEnvTagger — auto-tags logs with environment (prod/dev/ci/k8s/docker), trace_id, versionDynamicRouter — routes logs to different sinks based on env/level/custom rulesDiffTracker — detects output changes between function versions (A/B testing)LogEntry extended with environment, trace_id, version, llm_analysis fieldsconfigure() extended with llm_model, environment, version, detect_injection paramslitellm as optional dependency: pip install nfo[llm]pyproject.toml: added [llm] and [all] optional dependency groupsconfigure() — one-liner project-wide logging setup with sink specs and stdlib bridge@logged — class decorator that auto-wraps all public methods with @log_call@skip — exclude specific methods from @logged_StdlibBridge — forwards stdlib logging.getLogger() records to nfo sinksimport nfo.setup — zero-config auto-setup on importbasic_usage.py, sqlite_sink.py, csv_sink.py, markdown_sink.py, multi_sink.pynfo_config.py) and pactown-com (nfo_config.py)lg to nfo (PyPI: pip install nfo)lg to nfo@log_call — decorator that logs function entry/exit, args, types, return value, exceptions, duration@catch — like @log_call but suppresses exceptions (returns configurable default)Logger — central dispatcher with multiple sinks + optional stdlib forwardingSQLiteSink — persist logs to SQLite database (queryable)CSVSink — append logs to CSV fileMarkdownSink — write human-readable Markdown log filesLogEntry dataclass with full function call metadata