Custom Logger Plug-in
The preferred way to install a custom logger into a communicator is by setting the logger field of the communicator's IntializationData.
However, in some situations, you have no access to InitalizationData, for example:
you are writing an IceBox service
you want to install a custom logger without changing any source code
The plug-in facility allows you to inject your custom logger into the communicator at runtime, during communicator initialization.
Installing a Custom Logger
Ice provides a C++ plug-in class, Ice::LoggerPlugin, that installs a logger into the communicator in its constructor:
namespace Ice
{
class LoggerPlugin : public Plugin
{
public:
LoggerPlugin(const CommunicatorPtr& communicator,
const LoggerPtr& logger);
void initialize() override;
void destroy() override;
};
}
The implementation of initialize and destroy in LoggerPlugin are no-op.
Now, assuming you wrote a CustomLogger class that implements Ice::Logger, you can easily create a plug-in factory function that creates a LoggerPlugin and installs your logger into the communicator:
extern "C" Ice::Plugin* createCustomLoggerPlugin(
const Ice::CommunicatorPtr& communicator,
const std::string&,
const Ice::StringSeq&)
{
return new Ice::LoggerPlugin(communicator, make_shared<CustomLogger>());
}
Then, package your CustomLogger implementation and createCustomLoggerPluginin a shared library or DLL, and configure your communicator to load it at runtime. For example:
Ice.Plugin.CustomLogger=customlogger,0:createCustomLoggerPlugin
Even though you didn’t implement the plug-in class (Ice::LoggerPlugin), you are in effect creating a new plug-in since you choose the logger given to the LoggerPlugin constructor. As a result, you can pick any name for the plug-in factory function and the plug-in itself.