Skip to content

Logging and Debug Output

PDF Oxide emits internal debug, trace, warn, and error logs through the Rust log crate. Since v0.3.24 every binding exposes a global set_log_level / get_log_level function that controls these messages consistently across Python, Node.js, Go, C#, and Rust.

Since v0.3.21 Python’s logging integration is fully respected — messages no longer bypass logging.basicConfig via eprintln!.

Log levels

Level Value Description
OFF 0 Silence all log output
ERROR 1 Panics, parse failures that stop extraction
WARN 2 Recovered errors, malformed content we worked around
INFO 3 High-level operations (open, save, authenticate)
DEBUG 4 Internal decisions (column detection, reading order)
TRACE 5 Per-object operator parsing, per-glyph metrics

Default: WARN.

Python

PDF Oxide’s log macros forward to logging.getLogger("pdf_oxide"):

Python

import logging
import pdf_oxide

logging.basicConfig(level=logging.DEBUG)
# Equivalent to:
pdf_oxide.set_log_level("debug")

doc = pdf_oxide.PdfDocument("tricky.pdf")
doc.extract_text(0)  # emits debug logs to root handler

Route just PDF Oxide output to its own logger:

Python

import logging

handler = logging.FileHandler("pdf_oxide.log")
handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))

log = logging.getLogger("pdf_oxide")
log.addHandler(handler)
log.setLevel(logging.DEBUG)

Node.js

Node.js

const { setLogLevel } = require("pdf-oxide");

setLogLevel("debug");          // one of "off"|"error"|"warn"|"info"|"debug"|"trace"

Logs go to stderr formatted as [LEVEL] message. Pipe to your logger of choice:

Node.js

const { pipeline } = require("stream");

pipeline(
  process.stderr,
  myBunyanSink,
  (err) => err && console.error("log pipe failed", err)
);

Go

Go

import pdfoxide "github.com/yfedoseev/pdf_oxide/go"

pdfoxide.SetLogLevel(pdfoxide.LogDebug)

To capture the output, set the RUST_LOG environment variable before your binary starts:

RUST_LOG=pdf_oxide=debug ./my-app

C#

C#

using PdfOxide.Core;

PdfOxide.Logging.SetLogLevel(LogLevel.Debug);

Wire to ILogger:

C#

var logger = loggerFactory.CreateLogger("PdfOxide");
PdfOxide.Logging.OnLog += (level, message) =>
{
    logger.Log(Map(level), message);
};

Rust

Use any log-compatible backend (env_logger, tracing-log, slog-stdlog, etc.). PDF Oxide emits through the pdf_oxide target:

Rust

fn main() {
    env_logger::builder()
        .filter_module("pdf_oxide", log::LevelFilter::Debug)
        .init();

    let doc = pdf_oxide::PdfDocument::open("tricky.pdf").unwrap();
    let _ = doc.extract_text(0);
}

What does DEBUG reveal?

Common debug messages worth knowing about:

  • Detected document script: Latin / Arabic / CJK — reading-order heuristic pick.
  • is_single_column_region = true — column detector falling back to single-column layout.
  • Falling back to system font DejaVu Sans for ArialMT — font resolution miss.
  • Authenticating with user password — after authenticate() succeeds.
  • Table detector: rejected 3 edges via coverage filter — edge filtering applied.

What does TRACE reveal?

TRACE includes per-object content stream parsing and per-glyph font metric resolution — useful when a single page extracts wrong and you want to see which operator produced what. Expect thousands of lines per page.