Skip to content

Commit

Permalink
Add info logging via callback to C api.
Browse files Browse the repository at this point in the history
Summary:
Adds a very minimal derive of Logger around a C callback useful for FFI
interfaces from other languages to integrate infolog.

The infolog capabilities for C embeddings are quite spartan. LOG files were
generated involuntarily until redirection to stderr was added by #12262;
still insufficient for apps which cannot tolerate pollution of their stdio
and tend to have existing logging frameworks to tie into for that.

Signed-off-by: Jason Volk <jason@zemos.net>
  • Loading branch information
jevolk committed Apr 15, 2024
1 parent 6fbd02f commit f006711
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
45 changes: 45 additions & 0 deletions db/c.cc
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,42 @@ struct rocksdb_universal_compaction_options_t {
ROCKSDB_NAMESPACE::CompactionOptionsUniversal* rep;
};

struct rocksdb_callback_logger_t : public Logger {
static const ssize_t STACK_BUFSZ = 512;
rocksdb_callback_logger_t(InfoLogLevel log_level,
void (*logv_cb)(void*, unsigned, char*, size_t),
void* priv)
: Logger(log_level), logv_cb_(logv_cb), priv_(priv) {}

using Logger::Logv;
void Logv(const InfoLogLevel level, const char* fmt, va_list ap0) override {
char stack_buf[STACK_BUFSZ];
char* alloc_buf = nullptr;
char* buf = stack_buf;
int len = 0;
va_list ap1;
if (!logv_cb_) return;
va_copy(ap1, ap0);
if ((len = vsnprintf(buf, STACK_BUFSZ, fmt, ap0)) <= 0)
return;
else if (len >= STACK_BUFSZ) {
if (!(buf = alloc_buf = reinterpret_cast<char*>(malloc(len + 1)))) return;
if ((len = vsnprintf(buf, len + 1, fmt, ap1)) <= 0) {
va_end(ap1);
free(alloc_buf);
return;
}
}
logv_cb_(priv_, unsigned(level), buf, size_t(len));
va_end(ap1);
free(alloc_buf);
}

private:
void (*logv_cb_)(void*, unsigned, char*, size_t) = nullptr;
void* priv_ = nullptr;
};

static bool SaveError(char** errptr, const Status& s) {
assert(errptr != nullptr);
if (s.ok()) {
Expand Down Expand Up @@ -2945,6 +2981,15 @@ rocksdb_logger_t* rocksdb_logger_create_stderr_logger(int log_level,
return logger;
}

rocksdb_logger_t* rocksdb_logger_create_callback_logger(
int log_level, void (*callback)(void*, unsigned, char*, size_t),
void* priv) {
rocksdb_logger_t* logger = new rocksdb_logger_t;
logger->rep = std::make_shared<rocksdb_callback_logger_t>(
static_cast<InfoLogLevel>(log_level), callback, priv);
return logger;
}

void rocksdb_logger_destroy(rocksdb_logger_t* logger) { delete logger; }

void rocksdb_options_set_env(rocksdb_options_t* opt, rocksdb_env_t* env) {
Expand Down
5 changes: 5 additions & 0 deletions include/rocksdb/c.h
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,11 @@ extern ROCKSDB_LIBRARY_API int rocksdb_options_get_info_log_level(
rocksdb_options_t*);
extern ROCKSDB_LIBRARY_API rocksdb_logger_t*
rocksdb_logger_create_stderr_logger(int log_level, const char* prefix);
extern ROCKSDB_LIBRARY_API rocksdb_logger_t*
rocksdb_logger_create_callback_logger(int log_level,
void (*)(void* priv, unsigned lev,
char* msg, size_t len),
void* priv);
extern ROCKSDB_LIBRARY_API void rocksdb_logger_destroy(
rocksdb_logger_t* logger);
extern ROCKSDB_LIBRARY_API void rocksdb_options_set_write_buffer_size(
Expand Down

0 comments on commit f006711

Please sign in to comment.