Custom Logger Plug-in

3 min read

3 min read

3 min read

When you create a communicator in your own code, install a custom logger by setting InitializationData.logger.

A logger plug-in installs a custom logger through configuration, during communicator initialization. Use a logger plug-in when you don't create the communicator yourself, for example in an IceBox service, or when you want to install a custom logger without changing any source code.

Adding a logger plug-in factory to InitializationData.pluginFactories works too, but it is more work for the same result as setting InitializationData.logger.

Ice provides a C++ plug-in class, Ice::LoggerPlugin, that installs a logger into the communicator in its constructor:

C++
namespace Ice
{
class LoggerPlugin : public Plugin
{
public:
LoggerPlugin(const CommunicatorPtr& communicator,
const LoggerPtr& logger);
void initialize() override;
void destroy() override;
};
}

The initialize and destroy methods do nothing.

Now, assuming you wrote a CustomLogger class that implements Ice::Logger, you can create a plug-in factory function that creates a LoggerPlugin and installs your logger into the communicator:

C++
extern "C" ICE_DECLSPEC_EXPORT Ice::Plugin* createCustomLoggerPlugin(
const Ice::CommunicatorPtr& communicator,
const std::string&,
const Ice::StringSeq&)
{
return new Ice::LoggerPlugin(communicator, std::make_shared<CustomLogger>());
}

Then, package your CustomLogger implementation and createCustomLoggerPlugin in a shared library or DLL, and configure your communicator to load it at runtime. For example:

Properties
Ice.Plugin.CustomLogger=customlogger,0:createCustomLoggerPlugin

With customlogger,0, Ice loads customlogger0.dll on Windows, libcustomlogger.so.0 on Linux, and libcustomlogger.0.dylib on macOS. See Ice.Plugin.name for the format of this entry point.

Ice provides a plug-in class, Ice.LoggerPlugin, that installs a logger into the communicator in its constructor:

C#
namespace Ice;
public class LoggerPlugin : Plugin
{
public LoggerPlugin(Communicator communicator, Logger logger)
{
...
}
public void initialize()
{
}
public void destroy()
{
}
}

The initialize and destroy methods do nothing. The communicator takes ownership of the logger and disposes it when the communicator is destroyed.

Now, assuming you wrote a CustomLogger class that implements Ice.Logger, you can create a plug-in factory that creates a LoggerPlugin and installs your logger into the communicator:

C#
namespace ClearSky;
public class CustomLoggerPluginFactory : Ice.PluginFactory
{
public string pluginName => "CustomLogger";
public Ice.Plugin create(
Ice.Communicator communicator,
string name,
string[] args) =>
new Ice.LoggerPlugin(communicator, new CustomLogger());
}

Then, package your CustomLogger implementation and CustomLoggerPluginFactory in a .NET assembly, and configure your communicator to load it at runtime. For example:

Properties
Ice.Plugin.CustomLogger=CustomLogger.dll:ClearSky.CustomLoggerPluginFactory

Ice provides a plug-in class, com.zeroc.Ice.LoggerPlugin, that installs a logger into the communicator in its constructor:

Java
package com.zeroc.Ice;
public class LoggerPlugin implements Plugin
{
public LoggerPlugin(Communicator communicator, Logger logger) {
...
}
@Override
public void initialize() {}
@Override
public void destroy() {}
}

The initialize and destroy methods do nothing. The communicator takes ownership of the logger and closes it when the communicator is destroyed.

Now, assuming you wrote a CustomLogger class that implements com.zeroc.Ice.Logger, you can create a plug-in factory that creates a LoggerPlugin and installs your logger into the communicator:

Java
package com.example.clearsky;
import com.zeroc.Ice.Communicator;
import com.zeroc.Ice.LoggerPlugin;
import com.zeroc.Ice.Plugin;
import com.zeroc.Ice.PluginFactory;
public class CustomLoggerPluginFactory implements PluginFactory {
@Override
public String getPluginName() {
return "CustomLogger";
}
@Override
public Plugin create(Communicator communicator, String name, String[] args) {
return new LoggerPlugin(communicator, new CustomLogger());
}
}

Then, package your CustomLogger implementation and CustomLoggerPluginFactory in a JAR file, and configure your communicator to load it at runtime. For example:

Properties
Ice.Plugin.CustomLogger=customlogger.jar:com.example.clearsky.CustomLoggerPluginFactory

You implement a logger plug-in in C++, as shown in the C++ version of this page, and load its shared library through configuration:

Properties
Ice.Plugin.CustomLogger=customlogger,0:createCustomLoggerPlugin

With customlogger,0, Ice loads customlogger0.dll on Windows and libcustomlogger.so.0 on Linux. See Ice.Plugin.name for the format of this entry point.

You implement a logger plug-in in C++, as shown in the C++ version of this page, and load its shared library through configuration:

Properties
Ice.Plugin.CustomLogger=customlogger,0:createCustomLoggerPlugin

With customlogger,0, Ice loads libcustomlogger.so.0 on Linux and libcustomlogger.0.dylib on macOS. See Ice.Plugin.name for the format of this entry point.

You implement a logger plug-in in C++, as shown in the C++ version of this page, and load its shared library through configuration:

Properties
Ice.Plugin.CustomLogger=customlogger,0:createCustomLoggerPlugin

With customlogger,0, Ice loads customlogger0.dll on Windows, libcustomlogger.so.0 on Linux, and libcustomlogger.0.dylib on macOS. See Ice.Plugin.name for the format of this entry point.

You implement a logger plug-in in C++, as shown in the C++ version of this page, and load its shared library through configuration:

Properties
Ice.Plugin.CustomLogger=customlogger,0:createCustomLoggerPlugin

With customlogger,0, Ice loads libcustomlogger.0.dylib. See Ice.Plugin.name for the format of this entry point.