Log
This page explains the logging helper exposed by rix/debug.
The examples use the public Rix facade:
#include <rix.hpp>and access the debug logger through:
rix.debug.logImportant:
rix.debug.log is a small development helper.
For real application logging, prefer the Vix logging system.
rix.debug.log -> examples, quick tools, local diagnostics
vix::log -> application logs, production logs, service diagnosticsWhen to use rix.debug.log
Use rix.debug.log when you need a small formatted log-like output in examples or local tools.
It is useful for:
documentation examples
small command-line demos
local diagnostics
quick package tests
development-only outputDo not treat it as the main production logging API.
For Vix.cpp applications, prefer vix::log.
Basic example
Create a file:
mkdir -p ~/rix-debug-log
cd ~/rix-debug-log
touch log.cppAdd:
#include <rix.hpp>
int main()
{
rix.debug.log("loaded {} rows", 3);
rix.debug.log.info("package {} is ready", "rix/debug");
rix.debug.log.warn("slow path: {}", "csv import");
rix.debug.log.error("failed to open {}", "missing.csv");
return 0;
}Run it:
vix run log.cppIf Rix is not available yet for single-file usage:
vix install -g rix/rix
vix run log.cppExpected output
The output should look similar to this:
[debug] loaded 3 rows
[info] package rix/debug is ready
[warn] slow path: csv import
[error] failed to open missing.csvThe error level writes to stderr.
The other levels write to stdout.
Default debug log
Calling rix.debug.log(...) writes a debug-level message:
rix.debug.log("loaded {} rows", 3);Output:
[debug] loaded 3 rowsUse this for local diagnostics.
Info logs
Use:
rix.debug.log.info(...)Example:
rix.debug.log.info("package {} is ready", "rix/debug");Output:
[info] package rix/debug is readyUse info for simple status messages in examples.
Warning logs
Use:
rix.debug.log.warn(...)Example:
rix.debug.log.warn("slow path: {}", "csv import");Output:
[warn] slow path: csv importUse warn for local warnings.
Error logs
Use:
rix.debug.log.error(...)Example:
rix.debug.log.error("failed to open {}", "missing.csv");Output shape:
[error] failed to open missing.csverror writes to stderr.
Formatting
rix.debug.log uses the same simple placeholder format as rix.debug.format.
Supported placeholders:
{} automatic argument indexing
{0} explicit positional indexing
{{ escaped opening brace
}} escaped closing braceExample:
rix.debug.log.info(
"{0} builds on {1}",
"Rix",
"Vix.cpp");Output:
[info] Rix builds on Vix.cppDo not mix placeholder styles
Wrong:
rix.debug.log("{} {0}", "Rix");Use automatic placeholders:
rix.debug.log("{} {}", "Rix", "Debug");or explicit placeholders:
rix.debug.log("{0} {1}", "Rix", "Debug");Unsupported format specifiers
rix.debug.log does not support advanced format specifiers.
Wrong:
rix.debug.log("value: {:.2f}", 3.14159);Use simple placeholders:
rix.debug.log("value: {}", 3.14159);For advanced formatting, use another formatting tool or format the value before logging.
Use vix::log for applications
For real Vix.cpp applications, prefer Vix logging.
Use Vix logging for:
HTTP request logs
service startup logs
deployment diagnostics
production logs
structured application logs
runtime observabilityUse rix.debug.log only when you need a small helper for examples or local diagnostics.
A good rule:
If the message belongs to the running application, use vix::log.
If the message belongs to a small example, rix.debug.log is acceptable.Example with CSV
rix.debug.log can be useful in a small CSV example:
#include <rix.hpp>
int main()
{
const auto table = rix.csv.parse(
"name,language\n"
"Ada,C++\n"
"Gaspard,Vix\n");
rix.debug.log("loaded {} rows", table.size());
for (const auto &row : table)
{
rix.debug.log.info("row has {} fields", row.size());
}
return 0;
}Run:
vix run log.cppExample with Auth errors
For Auth examples, rix.debug.log.error can show failures:
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
auto login = auth.login({
"ada@example.com",
"wrong-password"});
if (login.failed())
{
const auto &error = login.error();
rix.debug.log.error(
"auth error: {}: {}",
rix.auth.error.to_string(error),
error.message());
return 1;
}
return 0;
}Do not log authentication secrets.
Avoid logging:
plain-text passwords
password hashes
session ids
raw token valuesExample with PDF generation
rix.debug.log can report whether a PDF was created:
#include <rix.hpp>
int main()
{
auto saved = rix.pdf.make_text(
"hello.pdf",
"Hello from rix.pdf",
"Rix PDF");
if (saved.failed())
{
rix.debug.log.error(
"pdf error: {}: {}",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.log.info("created {}", "hello.pdf");
return 0;
}Prefer rix.debug.print for simple examples
For many documentation examples, rix.debug.print is enough:
rix.debug.print("created:", "hello.pdf");Use rix.debug.log only when the level prefix is useful:
rix.debug.log.info("created {}", "hello.pdf");For simple output:
rix.debug.print -> simpler
rix.debug.log -> level-prefixedUse in a Vix project
Create a Vix application:
vix new debug-log --app
cd debug-logAdd Rix:
vix add rix/rix
vix installIn vix.app, make sure Rix is listed under deps:
deps = [
"rix/rix",
]A small vix.app can look like this:
name = "debug-log"
type = "executable"
standard = "c++20"
output_dir = "bin"
sources = [
"src/main.cpp",
]
include_dirs = [
"include",
"src",
]
deps = [
"rix/rix",
]
packages = [
"vix",
]
links = [
"vix::vix",
]Then use the debug logger in src/main.cpp:
#include <rix.hpp>
int main()
{
rix.debug.log.info("package {} is ready", "rix/debug");
return 0;
}Build and run:
vix build
vix runFor a real Vix application, move application logs to the Vix logging system.
Single-file usage
For small scripts, examples, and experiments:
vix run log.cppIf Rix is installed globally for single-file usage:
vix install -g rix/rix
vix run log.cppFor project usage, prefer:
vix add rix/rix
vix installand keep the dependency in vix.app:
deps = [
"rix/rix",
]Use only Debug with the facade
If you want the rix.* facade style but only want Debug mounted, define the feature macro before including rix.hpp:
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
rix.debug.log.info("Hello from {}", "rix/debug");
return 0;
}When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
Use the independent package
For independent usage, install:
vix add rix/debug
vix installIn vix.app:
deps = [
"rix/debug",
]Then include the independent package header:
#include <rix/debug.hpp>Use this style when a project only needs Debug and does not need the full unified Rix facade.
For most application documentation, prefer:
#include <rix.hpp>Common mistakes
Using rix.debug.log as production logging
rix.debug.log is a development helper.
For deployed applications, prefer Vix logging.
Logging secrets
Do not log:
plain-text passwords
password hashes
session ids
raw token values
private keys
API tokensThis matters especially when using rix/auth.
Expecting advanced format specifiers
Wrong:
rix.debug.log.info("price: {:.2f}", 12.5);Use simple placeholders:
rix.debug.log.info("price: {}", 12.5);Mixing automatic and explicit placeholders
Wrong:
rix.debug.log.info("{} {0}", "Rix");Use one placeholder style per message.
Forgetting deps
For a Vix project, do not put Rix packages in packages.
Use:
deps = [
"rix/rix",
]packages is for CMake package discovery.
deps is for Vix Registry packages.
What you should remember
Use debug log for local examples:
rix.debug.log("loaded {} rows", 3);Use levels:
rix.debug.log.info("ready: {}", true);
rix.debug.log.warn("slow path: {}", "import");
rix.debug.log.error("failed: {}", "missing file");Use simple placeholders only.
Do not log secrets.
Prefer Vix logging for real application logs:
rix.debug.log -> development helper
vix::log -> application loggingFor a Vix project, install Rix:
vix add rix/rix
vix installand use:
deps = [
"rix/rix",
]Next step
Learn inspection.
Next: Inspect