You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
purecv already depends on the log facade and exposes thin set_log_level / get_log_level wrappers in core::utils, but it has no structured logging API comparable to OpenCV's cv::utils::logging (the CV_LOG_* family in opencv2/core/utils/logger.hpp).
Two concrete gaps:
Porting friction. OpenCV C/C++ sources are littered with CV_LOG_INFO(tag, ...), CV_LOG_WARNING(tag, ...), CV_LOG_ONCE_*, CV_LOG_IF_*, etc. Without 1:1 counterparts, every ported site has to be rewritten by hand, which is error-prone and loses the per-subsystem tag.
No subsystem tagging. There is currently no consistent way to attribute log messages to a module (core, imgproc, features2d, ...) so users can filter them. Describe the solution you'd like
Add a dedicated core::logging module that mirrors cv::utils::logging, built on top of the existing log facade (so the output backend stays the application's choice — env_logger / fern / tracing / console_log on WASM). The OpenCV tag maps onto the logtarget:, so downstream filtering uses standard tooling, e.g. RUST_LOG=purecv::imgproc=debug,purecv::core=warn.
Proposed surface:
A LogLevel enum mirroring cv::utils::logging::LogLevel (Silent, Fatal, Error, Warning, Info, Debug, Verbose). Since log has five levels, Fatal collapses onto Error and Verbose onto Trace (documented).
set_log_level(LogLevel) -> LogLevel (returns the previous level, matching setLogLevel) and get_log_level() -> LogLevel.
A tags submodule with one &'static str per subsystem, following the module_path!() convention ("purecv", "purecv::core", "purecv::imgproc", ...).
Use bare log::info!(target: ..., ...) everywhere. Idiomatic, but offers no ONCE/IF/VERBOSE variants and no source-level parity with the OpenCV macros, so ports stay manual.
Reimplement OpenCV's LogTagManager (in-library per-tag levels). Heavier and redundant: in the Rust ecosystem per-target filtering is the backend's job (RUST_LOG). Per-tag levels inside the library can be added later as an optional log::Log filter layer if a real need appears — out of scope here.
Adopt tracing instead of log. More powerful (spans), but a larger dependency and a departure from what the crate already uses. Not warranted for now. Additional context
A drop-in src/core/logging.rs already exists as a prototype; it compiles and passes unit + doc-tests against log 0.4 on edition 2021.
Open decision: core::utils already defines set_log_level / get_log_level taking log::LevelFilter. To avoid two diverging APIs, the LogLevel-based versions should be canonical in core::logging, with core::utils re-exporting them (pub use crate::core::logging::{get_log_level, set_log_level};). This changes the existing signature from log::LevelFilter to LogLevel — flagging it explicitly.
WASM (crates/wasm): the core stays backend-agnostic; the wasm entry point should initialize a console backend once (e.g. console_log / wasm-logger) so cv_log_* reach the browser console. Can be a follow-up.
Tasks:
Is your feature request related to a problem? Please describe.
purecvalready depends on thelogfacade and exposes thinset_log_level/get_log_levelwrappers incore::utils, but it has no structured logging API comparable to OpenCV'scv::utils::logging(theCV_LOG_*family inopencv2/core/utils/logger.hpp).Two concrete gaps:
CV_LOG_INFO(tag, ...),CV_LOG_WARNING(tag, ...),CV_LOG_ONCE_*,CV_LOG_IF_*, etc. Without 1:1 counterparts, every ported site has to be rewritten by hand, which is error-prone and loses the per-subsystemtag.core,imgproc,features2d, ...) so users can filter them.Describe the solution you'd like
Add a dedicated
core::loggingmodule that mirrorscv::utils::logging, built on top of the existinglogfacade (so the output backend stays the application's choice — env_logger / fern /tracing/console_logon WASM). The OpenCVtagmaps onto thelogtarget:, so downstream filtering uses standard tooling, e.g.RUST_LOG=purecv::imgproc=debug,purecv::core=warn.Proposed surface:
LogLevelenum mirroringcv::utils::logging::LogLevel(Silent,Fatal,Error,Warning,Info,Debug,Verbose). Sinceloghas five levels,Fatalcollapses ontoErrorandVerboseontoTrace(documented).set_log_level(LogLevel) -> LogLevel(returns the previous level, matchingsetLogLevel) andget_log_level() -> LogLevel.tagssubmodule with one&'static strper subsystem, following themodule_path!()convention ("purecv","purecv::core","purecv::imgproc", ...).#[macro_export]macros providing OpenCV parity:cv_log_fatal!,cv_log_error!,cv_log_warning!,cv_log_info!,cv_log_debug!,cv_log_verbose!(tag, v, ...)cv_log_once_warning!,cv_log_once_info!(implemented with acore::sync::atomic::AtomicBool,no_std-friendly)cv_log_if_error!,cv_log_if_warning!,cv_log_if_info!Mapping summary:
CV_LOG_ERROR(tag, ...)cv_log_error!(tag, ...)CV_LOG_WARNING(tag, ...)cv_log_warning!(tag, ...)CV_LOG_INFO(tag, ...)cv_log_info!(tag, ...)CV_LOG_DEBUG(tag, ...)cv_log_debug!(tag, ...)CV_LOG_VERBOSE(tag, v, ...)cv_log_verbose!(tag, v, ...)CV_LOG_ONCE_*cv_log_once_*!CV_LOG_IF_*cv_log_if_*!setLogLevel/getLogLevelset_log_level/get_log_leveltag(NULL, "global")target:(&str, seetags)CV_LOG_STRIP_LEVELlogcargo featuresmax_level_*/release_max_level_*Example:
Describe alternatives you've considered
Use bare
log::info!(target: ..., ...)everywhere. Idiomatic, but offers noONCE/IF/VERBOSEvariants and no source-level parity with the OpenCV macros, so ports stay manual.Reimplement OpenCV's
LogTagManager(in-library per-tag levels). Heavier and redundant: in the Rust ecosystem per-targetfiltering is the backend's job (RUST_LOG). Per-tag levels inside the library can be added later as an optionallog::Logfilter layer if a real need appears — out of scope here.Adopt
tracinginstead oflog. More powerful (spans), but a larger dependency and a departure from what the crate already uses. Not warranted for now.Additional context
A drop-in
src/core/logging.rsalready exists as a prototype; it compiles and passes unit + doc-tests againstlog 0.4on edition 2021.Open decision:
core::utilsalready definesset_log_level/get_log_leveltakinglog::LevelFilter. To avoid two diverging APIs, theLogLevel-based versions should be canonical incore::logging, withcore::utilsre-exporting them (pub use crate::core::logging::{get_log_level, set_log_level};). This changes the existing signature fromlog::LevelFiltertoLogLevel— flagging it explicitly.WASM (
crates/wasm): the core stays backend-agnostic; the wasm entry point should initialize a console backend once (e.g.console_log/wasm-logger) socv_log_*reach the browser console. Can be a follow-up.Tasks:
Add
src/core/logging.rs(LogLevel,set/get_log_level,tags, macros)Register
pub mod logging;insrc/core.rsRe-export
set_log_level/get_log_levelfromcore::utils(or keep both — decide)Optionally surface
LogLevel/tagsin the cratepreludeUnit tests for level round-trip and macro expansion (in module
tests)Document
CV_LOG_STRIP_LEVEL↔logrelease_max_level_*in the READMEFollow-up: console logger init in
crates/wasmVerification per
CONTRIBUTING.md:cargo test,cargo fmt -- --check,cargo clippy -- -D warnings. PR againstdev.