-
-
Notifications
You must be signed in to change notification settings - Fork 0
Colored Troubleshooting
Solutions to common colored output issues
This guide helps diagnose and resolve issues with colored terminal output in masterror.
- Colors Not Showing
- ANSI Codes in Logs
- Performance Issues
- Platform-Specific Problems
- CI/CD Issues
- Integration Problems
Symptoms:
Error: Internal server error
Code: INTERNAL
Message: Database connection failed
Plain text appears instead of colored output.
# Test if stderr is a TTY
cargo run --example colored_cli --features colored
# Compare with piped output (should show no colors)
cargo run --example colored_cli --features colored 2>&1 | catIf both show no colors, proceed to step 2.
echo $NO_COLORSolution: If set, unset it:
unset NO_COLOR
cargo run --example colored_cli --features coloredecho $TERMSolution: If TERM=dumb, change it:
export TERM=xterm-256color
cargo run --example colored_cli --features coloredCheck Cargo.toml:
[dependencies]
masterror = { version = "0.24", features = ["colored"] }Solution: If missing, add the colored feature:
cargo add masterror --features coloredSome old terminals don't support ANSI colors.
Test:
echo -e "\033[31mRed text\033[0m"If this doesn't show red text, your terminal doesn't support ANSI colors.
Solutions:
- Linux: Install a modern terminal (Alacritty, GNOME Terminal, Konsole)
- macOS: Use Terminal.app (built-in) or iTerm2
- Windows: Use Windows Terminal or ConEmu
- SSH: Ensure your local terminal supports colors
# Clean rebuild with colored feature
cargo clean
cargo build --features colored
cargo run --example colored_cli --features colored-
NO_COLORis not set:unset NO_COLOR -
TERMis not dumb:export TERM=xterm-256color - Running in interactive terminal (not piped)
-
coloredfeature enabled in Cargo.toml - Terminal emulator supports ANSI colors
Symptoms:
[2025-10-20T15:04:23.123Z ERROR] Error: ^[[31mInternal server error^[[0m
Raw ANSI codes like ^[[31m appear in logs.
Colors are being written to log files instead of just terminals.
If using tracing-subscriber:
use tracing_subscriber::fmt;
fn init_logging() {
// Separate layers for stdout and file
let file_appender = tracing_appender::rolling::daily("/var/log/app", "app.log");
let (file_writer, _guard) = tracing_appender::non_blocking(file_appender);
let file_layer = fmt::layer()
.with_writer(file_writer)
.with_ansi(false); // Disable colors for file
let stdout_layer = fmt::layer()
.with_writer(std::io::stdout)
.with_ansi(true); // Enable colors for terminal
tracing_subscriber::registry()
.with(file_layer)
.with(stdout_layer)
.init();
}If using env_logger:
use env_logger::Builder;
use std::io::Write;
fn init_logging() {
let mut builder = Builder::from_default_env();
builder.format(|buf, record| {
// Strip colors when writing to file
let message = format!("{}", record.args());
writeln!(buf, "[{}] {}", record.level(), message)
});
builder.init();
}# In production startup script
export NO_COLOR=1
./my-appOr in systemd unit file:
[Service]
Environment="NO_COLOR=1"
ExecStart=/usr/bin/my-appIf you can't modify the application:
# Strip ANSI codes when viewing logs
cat app.log | sed 's/\x1b\[[0-9;]*m//g'
# Or use a tool like ansistrip
cat app.log | ansistripSymptoms: Application runs slower with colored output enabled.
Profile your application:
cargo flamegraph --features coloredIf TTY detection or color formatting appears in profiles, proceed with optimization.
// Before: Verbose logging
for item in items {
trace!("Processing: {}", item); // Excessive formatting
}
// After: Reduced logging
info!("Processing {} items", items.len());use tracing::debug;
// Bad: Always formats, even if debug disabled
debug!("User data: {}", expensive_format(&user));
// Good: Only formats if debug enabled
debug!("User data: {}", tracing::field::debug(&user));# Cargo.toml for production builds
[profile.release]
strip = true
lto = true
[dependencies]
# Build without colored feature in production
masterror = "0.24" # No colored featureuse criterion::{black_box, criterion_group, criterion_main, Criterion};
use masterror::AppError;
fn bench_error_display(c: &mut Criterion) {
c.bench_function("error_display", |b| {
let err = AppError::internal("Test error");
b.iter(|| {
let _ = format!("{}", black_box(&err));
});
});
}
criterion_group!(benches, bench_error_display);
criterion_main!(benches);Expected performance: < 1μs per error format with colors enabled.
Cause: Old Windows versions don't support ANSI escape codes.
Solutions:
- Upgrade to Windows 10+ (recommended)
- Use Windows Terminal from Microsoft Store
- Disable colors:
set NO_COLOR=1
Cause: PowerShell 5.1 has limited ANSI support.
Solutions:
- Use PowerShell 7+ (full ANSI support)
- Use Windows Terminal instead of console host
- Set
$env:NO_COLOR=1to disable colors
Cause: Terminal color scheme has low contrast for dimmed text.
Solution: Change Terminal.app color scheme:
- Terminal > Preferences > Profiles
- Select "Pro" or "Novel" theme (better contrast)
- Or customize colors manually
Cause: SSH not allocating pseudo-TTY.
Diagnosis:
# On remote host
tty
# Should show: /dev/pts/0 (or similar)
# If shows: not a tty, proceed belowSolution:
# Force TTY allocation
ssh -t user@host cargo run --example colored_cli --features coloredCause: Docker not allocating TTY.
Solution:
# Use -it flags
docker run -it my-app
# Or just -t for TTY without interactive
docker run -t my-appIn docker-compose.yml:
services:
app:
image: my-app
tty: true # Allocate TTY
stdin_open: true # Keep stdin openProblem: ANSI codes appear in GitHub Actions logs.
Solution: Disable colors in workflow:
name: CI
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Run tests
run: cargo test --features colored
env:
NO_COLOR: "1" # Disable colors in CIProblem: Want colors in GitLab CI logs (they support ANSI).
Solution: GitLab CI supports colors by default. Ensure NO_COLOR is not set:
test:
script:
- cargo test --features colored
variables:
TERM: "xterm-256color"Problem: Jenkins shows ^[[31m instead of colors.
Solution: Install AnsiColor plugin:
pipeline {
agent any
options {
ansiColor('xterm')
}
stages {
stage('Test') {
steps {
sh 'cargo test --features colored'
}
}
}
}Symptoms: API clients receive JSON with ANSI codes:
{
"error": "Error: \u001b[31mInternal server error\u001b[0m"
}Cause: Error Display implementation used in HTTP response body.
Solution: Use separate error representation for HTTP:
use axum::{response::IntoResponse, Json};
use masterror::AppError;
use tracing::error;
impl IntoResponse for AppError {
fn into_response(self) -> axum::response::Response {
// Log with colors
error!("Request error: {}", self);
// Return clean JSON (use error fields, not Display)
let body = Json(serde_json::json!({
"error": {
"code": self.code().to_string(),
"message": self.message().unwrap_or("An error occurred"),
}
}));
(self.kind().status_code(), body).into_response()
}
}Symptoms: Test assertions fail with ANSI codes.
#[test]
fn test_error_message() {
let err = AppError::internal("test");
// Fails because output contains ANSI codes
assert_eq!(err.to_string(), "Error: Internal server error");
}Solution: Set NO_COLOR in tests:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_message() {
// Disable colors for predictable test output
std::env::set_var("NO_COLOR", "1");
let err = AppError::internal("test");
let output = err.to_string();
// Now assertion works
assert!(output.contains("Internal server error"));
assert!(!output.contains("\x1b[")); // No ANSI codes
}
}Or use contains instead of eq:
#[test]
fn test_error_message() {
let err = AppError::internal("test");
let output = err.to_string();
// Works with or without colors
assert!(output.contains("Internal server error"));
}Cause: tracing_subscriber JSON formatter receiving colored strings.
Solution: Disable ANSI in JSON layer:
use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter};
fn init_logging() {
let json_layer = fmt::layer()
.json()
.with_ansi(false); // Never use colors in JSON
tracing_subscriber::registry()
.with(EnvFilter::from_default_env())
.with(json_layer)
.init();
}# Hexdump to see raw bytes
cargo run --example colored_cli --features colored 2>&1 | hexdump -C | head
# Look for escape sequences: 1b 5b (ESC [)# Use cat -A to show all control characters
cargo run --example colored_cli --features colored 2>&1 | cat -A
# ANSI codes appear as ^[[31mfn main() {
use std::io::IsTerminal;
if std::io::stderr().is_terminal() {
eprintln!("stderr IS a TTY");
} else {
eprintln!("stderr is NOT a TTY");
}
eprintln!("NO_COLOR: {:?}", std::env::var("NO_COLOR"));
eprintln!("TERM: {:?}", std::env::var("TERM"));
}use owo_colors::{OwoColorize, Stream};
fn main() {
let text = "Test";
let colored = text.if_supports_color(Stream::Stderr, |t| t.red());
eprintln!("Output: {}", colored);
eprintln!("Contains ANSI: {}", colored.to_string().contains("\x1b["));
}If none of these solutions work:
-
Check masterror version: Ensure you have the latest version
cargo update masterror
-
Verify owo-colors: Check dependency tree
cargo tree | grep owo-colors -
Open an issue: https://github.com/RAprogramm/masterror/issues
- Include your OS and terminal
- Provide
echo $TERMoutput - Show
cargo --versionandrustc --version - Include minimal reproduction code
Related Pages:
- Colored Terminal Output - Main colored output guide
- Terminal Detection Guide - How detection works
- Integration Guide - Framework integration
Previous: Integration Guide | Next: Migration Guide →