Logging for a C library wrapper?

Hi all,

I'm working on a C wrapper for Rustls. One of the main uses will be an optional backend for libcurl. Rustls uses the log crate for logging. I'd like to plumb through those log messages to libcurl, and in turn to any users of libcurl. For instance, users of libcurl can receive debug information by setting CURLOPT_DEBUGFUNCTION and CURLOPT_DEBUGDATA.

I think what I need to do is define an implementation of the Log trait in my wrapper, define a global instance of it, and provide a pair of functions register_log_callback and unregister_log_callback, so that clients like libcurl can register a callback that is specific to their implementation.

A few questions:

  • Does this make sense?
  • Has anyone implemented something similar?
  • Is there any good way to deal with the fact that a given binary might depend on crustls through multiple paths, and would therefore potentially get debug logs twice? For instance, a git client might depend on libcurl->crustls, and also libgit->crustls, each of which could potentially register a log callback.

Thanks,
Jacob

3 Likes

The approach does make sense, although I'd try to avoid globals as much as possible. You can wrap creation and destruction of Rust types into C functions as long as they only interact with opaque pointers.

A possible solution to the diamond problem can be to register every callback using its own unique identifier, so duplicate callbacks either overwrite earlier ones or fail to register (that's up to you).

1 Like

In general I'm trying to do so, but in this case, set_logger only allows one logger for the lifetime of a program: log::set_logger - Rust, so I think I need to set a global one that can multiplex and do registration / deregistration.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.