Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callback sink #205

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 29 additions & 0 deletions example/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
// spdlog usage example
//
#include "spdlog/spdlog.h"
#include "spdlog/sinks/callback_sink.h"

#include <cstdlib> // EXIT_FAILURE
#include <iostream>
#include <memory>

void async_example();
void syslog_example();
void callback_example();

namespace spd = spdlog;
int main(int, char*[])
Expand Down Expand Up @@ -68,6 +70,8 @@ int main(int, char*[])
// syslog example. linux/osx only..
syslog_example();

// Callback example.
callback_example();

// Release and close all loggers
spdlog::drop_all();
Expand Down Expand Up @@ -116,3 +120,28 @@ void custom_class_example()
spdlog::get("console")->info() << "custom class with operator<<: " << c << "..";
}

// Example of callback sink
void callback_function(void* /*userdata*/,
const char* logger_name,
int level,
size_t thread_id,
const char* msg)
{
// Normally this callback function would be used to redirect the log output
// to some other location (e.g., another logging system that isn't yet
// directly supported by spdlog).
std::cout << "--------------------" << std::endl;
std::cout << "Logger name: " << logger_name << std::endl;
std::cout << "Level: " << level << std::endl;
std::cout << "Thread ID: " << thread_id << std::endl;
std::cout << "Message: " << msg;
std::cout << "--------------------" << std::endl;
}

void callback_example()
{
auto callback_logger = spdlog::create<spdlog::sinks::callback_sink_mt>("callback_logger", &callback_function);
callback_logger->info("info sent to callback sink");
callback_logger->error("error sent to callback sink");
}

73 changes: 73 additions & 0 deletions include/spdlog/sinks/callback_sink.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// Copyright (c) 2016 Kevin M. Godby.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

#pragma once

//
// This sink will call a callback function any time it's told to log something.
//

#include <spdlog/sinks/base_sink.h>
#include <spdlog/common.h>
#include <spdlog/details/log_msg.h>

#include <mutex>

namespace spdlog {
namespace sinks {

typedef void(*LogCallback)(void* /*userdata*/,
const char* /*logger_name*/,
int /*level*/,
size_t /*thread_id*/,
const char* /*msg*/);


template<class Mutex>
class callback_sink : public base_sink<Mutex> {
public:
callback_sink(LogCallback callback = nullptr, void* userdata = nullptr) : _callback(callback), _userdata(userdata)
{
// do nothing
}

// noncopyable
callback_sink(const callback_sink&) = delete;
callback_sink& operator=(const callback_sink&) = delete;

virtual ~callback_sink() = default;

virtual void flush() override
{
// do nothing
}

void set_callback(LogCallback& callback, void* userdata)
{
_callback = callback;
_userdata = userdata;
}

protected:
void _sink_it(const details::log_msg& msg) override
{
if (!_callback)
return;

_callback(_userdata, msg.logger_name.c_str(),
static_cast<int>(msg.level), msg.thread_id,
msg.formatted.c_str());
}

LogCallback _callback;
void* _userdata;
};

typedef callback_sink<std::mutex> callback_sink_mt;
typedef callback_sink<details::null_mutex> callback_sink_st;

} // end namespace sinks
} // end namespace spdlog