Table of Contents Previous Next
Logo
The Ice Run Time in Detail : 32.18 The Ice::Logger Interface
Copyright © 2003-2007 ZeroC, Inc.

32.18 The Ice::Logger Interface

Depending on the setting of various properties (see Chapter 30), the Ice run time produces trace, warning, or error messages. These messages are written via the Ice::Logger interface:
module Ice {
    local interface Logger {
        void print(string message);
        void trace(string category, string message);
        void warning(string message);
        void error(string message);
    };
};

32.18.1 The Default Logger

A default logger is instantiated when you create a communicator. The default logger logs to the standard error output. The trace operation accepts a category parameter in addition to the error message; this allows you to separate trace output from different subsystems by sending the output through a filter.
You can obtain the logger that is attached to a communicator:
module Ice {
    local interface Communicator {
        Logger getLogger();
    };
};

32.18.2 Custom Loggers

To install a logger other than the default one, you can pass it in an InitializationData parameter to initialize (see Section 32.3) when you create a communicator. You can also replace the logger used by an existing application via the Ice.LoggerPlugin configuration property (see Appendix C).
Changing the Logger object that is attached to a communicator allows you to integrate Ice messages into your own message handling system. For example, for a complex application, you might have an already existing logging framework. To integrate Ice messages into that framework, you can create your own Logger implementation that logs messages to the existing framework.
When you destroy a communicator, its logger is not destroyed. This means that you can safely use a logger even beyond the lifetime of its communicator.

32.18.3 Built‑In Loggers

For convenience, Ice provides two platform-specific logger implementations: one that logs its messages to the Unix syslog facility, and another that uses the Windows event log. You can activate the syslog implementation by setting the Ice.UseSyslog property. On Windows, subclasses of Ice::Service use the Windows application event log by default (see Section 8.3.2).
The syslog logger implementation is available in C++, Java, and C#, whereas the Windows event log implementation is only available in C++.

32.18.4 The Per-Process Logger

Ice allows you to install a per-process custom logger. This logger is used by all communicators that do not have their own specific logger established at communicator creation time.
You can set a per-process logger by calling Ice::setProcessLogger, and you can retrieve the per-process logger by calling Ice::getProcessLogger:
LoggerPtr getProcessLogger();
void setProcessLogger(const LoggerPtr&);
If you call getProcessLogger without having called setProcessLogger first, the Ice run time installs a default per-process logger. Note that if you call setProcessLogger, only communicators created after that point will use this per-process logger; communicators created earlier use whatever logger was in effect at the time they were created. (This also means that you can setProcessLogger multiple times; communicators created after that point will use whatever logger was last established by the last call to setProcessLogger.)
getProcessLogger and setProcessLogger are language-specific APIs that are not defined in Slice. Therefore, for Java and C#, these methods appear in the Ice.Util class.

32.18.5 C++ Utility Classes

The Ice run time supplies a collection of utility classes that make use of the logger facility simpler and more convenient. Each of the logger’s four operations has a corresponding helper class:
namespace Ice {
class Print {
public:
    Print(const LoggerPtr&);
    void flush();
    ...
};

class Trace {
public:
    Trace(const LoggerPtr&, const std::string&);
    void flush();
    ...
};

class Warning {
public:
    Warning(const LoggerPtr&);
    void flush();
    ...
};

class Error {
public:
    Error(const LoggerPtr&);
    void flush();
    ...
};
}
The only notable difference among these classes is the extra argument to the Trace constructor; this argument represents the trace category.
To use one of the helper classes in your application, you simply instantiate it and compose your message:
if (errorCondition) {
    Error err(communicator>getLogger());
    err << "encountered error condition: " << errorCondition;
}
The Ice run time defines the necessary stream insertion operators so that you can treat an instance of a helper class as if it were a standard C++ output stream. When the helper object is destroyed, its destructor logs the message you have composed. If you want to log more than one message using the same helper object, invoke the flush method on the object to log what you have composed so far and reset the object for a new message.
Table of Contents Previous Next
Logo