Appearance
Server Pretty Logs (Runtime Banner)
This guide explains vix::utils::RuntimeBanner and vix::utils::ServerReadyInfo from ServerPrettyLogs.hpp.
Goal: print a clean "server ready" banner on startup, with terminal-friendly colors, optional OSC-8 hyperlinks, and safe output in multithreaded apps.
What this component does
When your server becomes ready, call:
RuntimeBanner::emit_server_ready(info)
It prints (to stderr) a banner that includes:
- current local time (12h format)
- app identity + mode tag (
devorrun) - status pill (READY / RUNNING / LISTENING / WARN / ERROR)
- HTTP URL
- optional WebSocket URL
- optional config path and thread hints
- a hint line (
Ctrl+C ...)
It also uses vix::utils::console_mutex() so banner output does not interleave with other threads.
Include
cpp
#include <vix/utils/ServerPrettyLogs.hpp>Basic usage
Create a ServerReadyInfo, set fields you care about, then emit the banner.
cpp
#include <vix/utils/ServerPrettyLogs.hpp>
int main()
{
vix::utils::ServerReadyInfo info;
info.app = "my-app";
info.version = "v1.0.0";
info.mode = vix::utils::RuntimeBanner::mode_from_env(); // "run" or "dev"
info.status = "ready";
info.scheme = "http";
info.host = "127.0.0.1";
info.port = 8080;
info.base_path = "/";
info.show_ws = false; // hide WS row
vix::utils::RuntimeBanner::emit_server_ready(info);
return 0;
}HTTP + WebSocket example
cpp
#include <vix/utils/ServerPrettyLogs.hpp>
int main()
{
vix::utils::ServerReadyInfo info;
info.app = "vix.cpp";
info.version = "v1.34.0";
info.ready_ms = 42;
info.mode = "dev";
info.status = "listening";
info.scheme = "http";
info.host = "localhost";
info.port = 8080;
info.base_path = "/";
info.show_ws = true;
info.ws_scheme = "ws";
info.ws_host = "localhost";
info.ws_port = 9090;
info.ws_path = "/";
info.show_hints = true;
vix::utils::RuntimeBanner::emit_server_ready(info);
return 0;
}Environment controls
Colors
Colors follow these rules:
- If
NO_COLORis set (non-empty), colors are disabled. - If
VIX_COLORis set:never|0|falsedisables colorsalways|1|trueenables colors
- Otherwise, colors are enabled by default.
Examples:
bash
# Disable colors
vix run main.cpp --log-color=neverbash
# Force colors (even if terminal detection is weird)
vix run main.cpp --log-color=alwaysMode
RuntimeBanner::mode_from_env() reads VIX_MODE and normalizes it:
dev|watch|reload->dev- everything else ->
run
bash
vix dev examples/http/server.cppHyperlinks (OSC 8)
If supported, the banner prints URLs as clickable links. It is controlled by:
VIX_NO_HYPERLINK(set to disable)- terminal detection and allowlist checks
bash
VIX_NO_HYPERLINK=1 vix run main.cppAnimations
The [dev] tag can pulse when animations are allowed. It is controlled by:
VIX_NO_ANIM(set to disable)- stderr must be a TTY
NO_COLORdisables animations too
bash
VIX_NO_ANIM=1 vix run main.cppThread safety and output ordering
emit_server_ready() does two important things:
- It calls
console_reset_banner()andconsole_mark_banner_done()so other threads can coordinate with the banner. - It prints under
console_mutex()so other console output will not interleave.
If you also print startup logs from worker threads, the banner stays readable.
Field reference
ServerReadyInfo fields you will commonly set:
appandversionready_msmodeandstatus- HTTP:
scheme,host,port,base_path - WS:
show_ws,ws_scheme,ws_host,ws_port,ws_path config_paththreads,max_threadsshow_hints
Typical pattern in a server
A clean approach is:
- Start the server
- When bind/listen succeeds, fill
ServerReadyInfo - Emit the banner once
cpp
void on_server_ready(int port, int startup_ms)
{
vix::utils::ServerReadyInfo info;
info.app = "my-app";
info.version = "v1.0.0";
info.mode = vix::utils::RuntimeBanner::mode_from_env();
info.status = "ready";
info.ready_ms = startup_ms;
info.host = "0.0.0.0";
info.port = port;
info.base_path = "/";
info.show_ws = false;
vix::utils::RuntimeBanner::emit_server_ready(info);
}Troubleshooting
- If you see no colors: check
NO_COLORandVIX_COLOR. - If links are not clickable: your terminal may not support OSC 8 or you are inside tmux/screen.
- If the banner interleaves with other output: ensure other console writes also respect
console_mutex()when needed.
Keep it minimal. No hidden magic. Just explicit C++.