Boost Log Callback - boost

I have created a logger mechanism based on Boost Log.
My code is based on the trivial logger as shown in this example.
I was wondering how to automatically call system exit
exit(1)
(or any other custom callback function) whenever a fatal error occurs.
Any help is welcomed!
UPDATE:
The solution is to extend the backend sink by overloading the consume() method.

Example of a sink examining the severity level of the trivial logger:
#include <boost/log/trivial.hpp>
#include <boost/log/sinks/basic_sink_backend.hpp>
#include <boost/log/attributes/value_extraction.hpp>
#include <boost/log/sinks/async_frontend.hpp>
namespace sinks = boost::log::sinks;
void initBoostLog() {
struct Sink: public sinks::basic_formatted_sink_backend<char, sinks::concurrent_feeding> {
void consume (const boost::log::record_view& rec, const string& str) {
using boost::log::trivial::severity_level;
auto severity = rec.attribute_values()[boost::log::aux::default_attribute_names::severity()].extract<severity_level>();
if (!severity || severity.get() <= severity_level::info) {
std::cout << str << std::endl;
} else {
std::cerr << str << std::endl;
}
}
};
typedef sinks::asynchronous_sink<Sink> sink_t; boost::shared_ptr<sink_t> sink (new sink_t());
boost::shared_ptr<boost::log::core> logc = boost::log::core::get();
logc->add_sink (sink);
}

Related

UWP Server Socket not listening

I am creating a simple UWP console server app with reference to the contents of this and this links.
However, if i create code based on the examples and run it, I will not be able to connect to the server. Also, the port is not open when checked with a command such as "netstat -na".
Does anyone know how to solve it?
The code is shown below. I would appreciate if you find any errors in the code below.
#include "pch.h"
#include <sstream>
#include <iostream>
using namespace Platform;
using namespace Concurrency;
using namespace Windows::Foundation;
using namespace Windows::Networking;
using namespace Windows::Networking::Sockets;
using namespace Windows::Networking::Connectivity;
using namespace Windows::Storage::Streams;
namespace SocketTest {
public ref class Server sealed {
public:
Server();
void Run();
protected:
void Server::onConnReceived(
Windows::Networking::Sockets::StreamSocketListener^ listener,
Windows::Networking::Sockets::StreamSocketListenerConnectionReceivedEventArgs^ object);
};
}
using namespace SocketTest;
Server::Server() {
}
void Server::onConnReceived(
StreamSocketListener^ listener,
StreamSocketListenerConnectionReceivedEventArgs^ object)
{
try {
DataReader^ reader = ref new DataReader(object->Socket->InputStream);
//ReceiveStringLoop(reader, object->Socket);
delete object->Socket;
}
catch (Exception^ exception) {
std::cout << "onconnection error" << std::endl;
}
}
void Server::Run() {
StreamSocketListener^ listener = ref new StreamSocketListener();
listener->ConnectionReceived += ref new TypedEventHandler<Windows::Networking::Sockets::StreamSocketListener^, Windows::Networking::Sockets::StreamSocketListenerConnectionReceivedEventArgs^>(this, &Server::onConnReceived);
listener->Control->KeepAlive = true;
create_task(listener->BindServiceNameAsync(L"12345")).then(
[=]
{
try
{
std::cout << "Listening ..." << std::endl;
}
catch (Exception^ exception)
{
std::cout << "Bind error" << exception->Message->Data() << std::endl;
}
});
}
int main(Platform::Array<Platform::String^>^ args)
{
Server^ s = ref new Server();
s->Run();
getchar();
}
Or, if you have a better code example, let me know.

C++ 11 passing shared_pointer like with std::any

at the moment I'm facing following problem. I need a member function in a derived class that can handle different shared_ptr types and do custom stuff with it. The base class should make sure that such a member function is implemented but the specific shared_ptr types are only known when a other developer create a new derived class. Therefore, templates are not a solution due to the fact that c++ not support virtual template functions.
The shared_ptrs hold protobuf message specific publisher or subscriber. Here a snipped of code:
std::shared_ptr<Publisher<ProtobufMessageType1>> type1 = std::make_shared<ProtobufMessageType1>();
std::shared_ptr<Publisher<ProtobufMessageType2>> type2 = std::make_shared<ProtobufMessageType2>();
class derived : base
{
void takeThePointerAndDoSpecificStuff( std::shared_ptr<PubOrSub<SpecificProtobufMessage>>) override
{
// check type and bind specific callback
}
}
One solution could be casting shared_ptr to base class but it is not possible because the protobuf message base class is pure virtual. Another solution is to cast the raw pointer and only transfer this one but I need the share_ptr reference count also in the method ( due to binding).
So I look further for a solution and std::any could be one but the problem here is that c++11 not have a std::any (sure could use boost but I try to avoid that).
So now I'm out of ideas how to solve the problem but perhaps you have one and can help me.
Thank you for any answer in advance.
One solution could be casting shared_ptr to base class but it is not possible because the protobuf message base class is pure virtual
That's simply not true. You can have shared pointers to abstract bases just fine:
Live On Coliru
#include <memory>
#include <iostream>
struct Base {
virtual ~Base() = default;
virtual void foo() const = 0;
};
struct D1 : Base { virtual void foo() const override { std::cout << __PRETTY_FUNCTION__ << "\n"; } };
struct D2 : Base { virtual void foo() const override { std::cout << __PRETTY_FUNCTION__ << "\n"; } };
int main() {
std::shared_ptr<Base> b = std::make_shared<D1>();
std::shared_ptr<Base> c = std::make_shared<D2>();
b->foo();
c->foo();
}
Prints
virtual void D1::foo() const
virtual void D2::foo() const
More Ideas
Even in case you do not have a common base (or a base at all) you can still use shared_pointer. One particularly powerful idiom is to use shared_pointer<void>:
Live On Coliru
#include <memory>
#include <iostream>
struct D1 {
void foo() const { std::cout << __PRETTY_FUNCTION__ << "\n"; }
~D1() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
struct D2 {
void bar() const { std::cout << __PRETTY_FUNCTION__ << "\n"; }
~D2() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
int main() {
std::shared_ptr<void> b = std::make_shared<D1>();
std::shared_ptr<void> c = std::make_shared<D2>();
std::static_pointer_cast<D1>(b)->foo();
std::static_pointer_cast<D2>(c)->bar();
}
Prints
void D1::foo() const
void D2::bar() const
D2::~D2()
D1::~D1()
See: http://www.boost.org/doc/libs/1_66_0/libs/smart_ptr/doc/html/smart_ptr.html#techniques_using_shared_ptr_void_to_hold_an_arbitrary_object

segfault when accessing static std::map

I'm trying to refactor a rather complicated piece of code and run into segfaults during loading the library. This is a minimal example of what I could single out to be the source of the segfault:
#include <iostream>
#include <string>
#include <map>
class Manager {
public:
class Action{
};
static bool registerAction(const Action* a, const char* name);
};
namespace Actions {
class ExampleAction : public Manager::Action {
};
namespace {
static bool available = Manager::registerAction(new ExampleAction(),"ExampleAction");
}
}
namespace {
typedef std::map<const std::string,const Manager::Action*> ActionList;
static ActionList sActions;
}
bool Manager::registerAction(const Action* a, const char* name){
std::cout << "attempting to register action " << a << " as " << name << std::endl;
sActions[name] = a;
std::cout << "done" << std::endl;
return true;
}
int main(){
std::cout << "hello!" << std::endl;
for(auto it:sActions){
std::cout << it.first << std::endl;
}
std::cout << "world!" << std::endl;
return 0;
}
It compiles fine with g++ 4.8.4 using the --std=c++11 flag, but upon execution, this happens:
attempting to register action 0x1ebe010 as ExampleAction
Segmentation fault (core dumped)
The line attempting to register comes first, which is of course expected, but the line assigning the value to the static map instance causes the crash, and I don't understand the reason. I'm probably being stupid here, but still - any suggestions on how to fix this?

What is the best way to pass callback function to std::map?

I was trying to work on the below code but the program crashes:
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef void (*callBackMethod)(string);
class CTest
{
private:
map<string, callBackMethod> mapMethod;
void testMethod(string msg)
{
cout << msg << endl;
}
public:
CTest()
{
addFunction("AA", (callBackMethod) &CTest::testMethod);
}
void addFunction(string funName, callBackMethod methodName)
{
mapMethod[funName] = methodName;
}
callBackMethod getMethod(string funName)
{
auto fun = mapMethod.find(funName);
if(fun == mapMethod.end()) { return nullptr; }
return fun->second;
}
void runFunction(string funName)
{
getMethod(funName)("test");
}
};
int main()
{
CTest test;
test.runFunction("AA");
return 0;
}
I have a requirement where I need to pass private methods to a map. The program compiles with warning:
converting from 'void (CTest::*)(std::__cxx11::string) {aka void (CTest::*)(std::__cxx11::basic_string<char>)}' to 'callBackMethod {aka void (*)(std::__cxx11::basic_string<char>)}'
and when I execute this, it crashes.
When I move the callback method outside of the class it works. My requirement is to make the program flow this was (hide the methods from external call which needs to be added to a map).
Looking forward to your comments.
If you need to point to both CTest member functions and free functions, then you can use std::function<void(std::string)>.
#include <iostream>
#include <string>
#include <map>
#include <functional>
using namespace std;
using callBackFunction = std::function<void(string)>;
void testFunction(string msg)
{
cout << "[" << __PRETTY_FUNCTION__ << "] " << msg << endl;
}
class CTest
{
private:
map<string, callBackFunction> mapMethod;
void testMethod(string msg)
{
cout << "[" << __PRETTY_FUNCTION__ << "] " << msg << endl;
}
public:
CTest()
{
addFreeFunction("AA", testFunction);
addMemberFunction("BB", &CTest::testMethod);
}
void addMemberFunction(string funName, void(CTest::*methodName)(string))
{
using std::placeholders::_1;
mapMethod[funName] = std::bind(methodName, this, _1);
}
void addFreeFunction(string funName, void(*methodName)(string))
{
mapMethod[funName] = methodName;
}
callBackFunction getMethod(string funName)
{
auto fun = mapMethod.find(funName);
if(fun == mapMethod.end()) { return nullptr; }
return fun->second;
}
void runFunction(string funName)
{
getMethod(funName)("test");
}
};
int main()
{
CTest test;
test.runFunction("AA");
test.runFunction("BB");
return 0;
}
Notice that CTest must insert elements into the map in a different way depending on what type of function you are passing, since for member functions you must provide the object for which it is to be invoked, this in this example. This is achived by using std::bind.
Since you want to use member variables you need to specify the signature differently in your typedef:
In C++ Builder the following can be done:
typedef void(__closure *callBackMethod)(string);
If you do that, I do suggest that you keep a smart pointer to the object that the member belongs to so that you can check if the object is still valid before calling the function otherwise it will crash the application.
The __closure keyword is a C++ Builder extension to work around the requirement to use fully qualified member names source
To handle both global and member functions we have the following:
typedef void(__closure *callBackMethodMember)(string);
typedef void (*callBackMethodGlobal)(string);
/* And then on 2 overloaded functions */
void addFunction(string funName, callBackMethodMember methodName) {}
void addFunction(string funName, callBackMethodGlobal methodName) {}

set_option: Invalid argument when setting option boost::asio::ip::multicast::join_group inside lambda

This code is intended to receive UDP multicast messages using Boost.Asio. A Boost system_error exception is thrown by the code below when the second set_option() call inside receiver's constructor is made (to join the multicast group). The complaint is "Invalid argument". This seems to be related to the fact that the constructor occurs inside a lambda defined inside IO::doIO(), because using a member for the std::thread with identical functionality (IO::threadFunc()) instead results in the expected behavior (no exceptions thrown).
Why is this, and how can I fix it so that I may use a lambda?
//g++ -std=c++11 doesntWork.cc -lboost_system -lpthread
#include <iostream>
#include <thread>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
class IO
{
public:
class receiver
{
public:
receiver(
boost::asio::io_service &io_service,
const boost::asio::ip::address &multicast_address,
const unsigned short portNumber) : _socket(io_service)
{
const boost::asio::ip::udp::endpoint listen_endpoint(
boost::asio::ip::address::from_string("0.0.0.0"), portNumber);
_socket.open(listen_endpoint.protocol());
_socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));
_socket.bind(listen_endpoint);
std::cerr << " About to set option join_group" << std::endl;
_socket.set_option(boost::asio::ip::multicast::join_group(
multicast_address));
_socket.async_receive_from(
boost::asio::buffer(_data),
_sender_endpoint,
boost::bind(&receiver::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
void handle_receive_from(
const boost::system::error_code &error,
const size_t bytes_recvd)
{
if (!error)
{
for(const auto &c : _data)
std::cout << c;
std::cout << std::endl;
}
}
private:
boost::asio::ip::udp::socket _socket;
boost::asio::ip::udp::endpoint _sender_endpoint;
std::vector<unsigned char> _data;
}; // receiver class
void doIO()
{
const boost::asio::ip::address multicast_address =
boost::asio::ip::address::from_string("235.0.0.1");
const unsigned short portNumber = 9999;
// _io_service_thread = std::thread(
// &IO::threadFunc, this, multicast_address, portNumber);
_io_service_thread = std::thread([&, this]{
try {
// Construct an asynchronous receiver
receiver r(_io_service, multicast_address, portNumber);
// Now run the IO service
_io_service.run();
}
catch(const boost::system::system_error &e)
{
std::cerr << e.what() << std::endl;
throw e; //std::terminate()
}
});
}
void threadFunc(
const boost::asio::ip::address &multicast_address,
const unsigned short portNumber)
{
try {
// Construct an asynchronous receiver
receiver r(_io_service, multicast_address, portNumber);
// Now run the IO service
_io_service.run();
}
catch(const boost::system::system_error &e)
{
std::cerr << e.what() << std::endl;
throw e; //std::terminate()
}
}
private:
boost::asio::io_service _io_service;
std::thread _io_service_thread;
}; // IO class
int main()
{
IO io;
io.doIO();
std::cout << "IO Service is running" << std::endl;
sleep(9999);
}
There is a race condition that can result in dangling references being accessed, invoking undefined behavior. The lambda capture-list is capturing the automatic variables, multicast_address and portNumber, by reference. However, the lifetime of these objects may end before their usage within _io_service_thread:
void doIO()
{
const boost::asio::ip::address multicast_address = /* ... */;
const unsigned short portNumber = /* ... */;
_io_service_thread = std::thread([&, this] {
// multicast_address and portNumber's lifetime may have already ended.
receiver r(_io_service, multicast_address, portNumber);
// ...
});
} // multicast_address and portNumber are destroyed.
To resolve this, consider capturing by value so that the thread operates on copies whose lifetimes will remain valid until the end of the thread. Change:
std::thread([&, this] { /* ... */ }
to:
std::thread([=] { /* ... */ }
This issue does not present itself when std::thread is constructed with the function and all its arguments, as the std::thread constructor will copy/move all provided arguments into thread-accessible storage.
Also, be aware of the destruction of the _io_service_thread object will invoke std::terminate() if it is still joinable within IO's destructor. To avoid this behavior, consider explicitly joining the _io_service_thread from the main thread.

Resources