spdl: A consistent C++ and R interface to spdlog

CI CRAN Dependencies Downloads License Last Commit

About

The RcppSpdlog repository (and CRAN package) provides access to the wonderful spdlog library along with the fmt library.

This permits use in C++ extensions for R by offering the spdlog (header-only) library along with the (header-only) fmt library (by using LinkingTo as described in Section 1.1.3 of WRE). More recently, RcppSpdlog was extended so that it provides a set of key functions directly for use by other R functions (as described in Section 5.4.3 of WRE).

However, now the use of, say, a debug logging message from C++ looks like

// in C++
spdlog::debug("Text with {} text {} which is {}", "auto", "expansion", 42);

whereas in R, given the RcppSpdlog package and namespace, it looks like this (if we use sprintf() to assemble the message)

# in R
RcppSpdlog::log_debug(sprintf("Text with %s text %s which is %s", "auto", "expansion", 42L)

and that irked us. Enter this package! By owning the spld namespace (in R) and an easily overlayed namespace in C++ of the same name we can do

// in C++
spdl::debug("Text with {} text {} which is {}", "auto", "expansion", 42);

as well as (still using sprintf())

# in R
spdl::debug(sprintf("Text with %s text %s which is %s", "auto", "expansion", 42L))

which is much better as it avoids context switching. Better still, with the internal formatter we can write the same format string as in C++ and not worry about format details:

# in R
spdl::debug("Text with {} text {} which is {}", "auto", "expansion", 42L)

Details

We use a simple mechanism in which all R arguments are passed through format() by default to render strings, and then pass a single vector of strings argument through the restrictive C language Foreign Function Interface to RcppSpdlog where it can be passed to the C++ layer available there.

This also means we use the fmt library in both languages as the formatter. We prefer this is over other string-interpolating libraries in R which are similar but subtly different. Should their use be desired, they can of course be used: the default call to any of the loggers is just a single-argument call with a text variable so users are free to expand strings as they please. Anything starting from paste and sprintf works.

As of release 0.0.2, we also expose helpers spdl::fmt() (to format) and spdl::cat() (to display).

Namespace

Note that because the package uses functions names also present in the base R packages (namely cat, debug, drop, trace) we do not recommend loading the package. Instead, call it with the explicit prefix as e.g. spdl::debug("Some message {}", foo). As a selective importFrom one can always do importFrom("spdl", "setup") combined with the explicit pre-fix use.

Author

Dirk Eddelbuettel

License

spdl is released under the GNU GPL, version 2 or later, just like R itself.