The Logger Facet
7 min read
7 min read
7 min read
7 min read
7 min read
7 min read
7 min read
7 min read
7 min read
The RemoteLogger Interface
RemoteLogger InterfaceAn administrator may find it useful to view the log of a running Ice application, without going through an intermediary file. This is especially useful for Ice services that use a system log, such as the Windows Event Log.
The Logger facet allows remote applications (such as administrative clients) to attach one or more remote loggers to the local logger of any Ice application (provided this application enables the admin object with a Logger facet). The implementation of the Logger facet installs its own logger, which intercepts the log messages sent to the local logger, caches the most recent log messages, and forwards these log messages (after optional filtering) to the attached remote loggers.
A remote logger is an Ice object that implements the Ice::RemoteLogger interface. Such object is typically implemented by an administrative client.
module Ice{ enum LogMessageType { PrintMessage, TraceMessage, WarningMessage, ErrorMessage } sequence<LogMessageType> LogMessageTypeSeq;
struct LogMessage { LogMessageType type; long timestamp; string traceCategory; string message; } sequence<LogMessage> LogMessageSeq;
interface RemoteLogger { void init(string prefix, LogMessageSeq logMessages); void log(LogMessage message); }}The LogMessage represents log messages sent to a local logger. Its timestamp field is the number of microseconds since the Unix Epoch (January 1st, 1970 at 0:00 UTC).
When a remote logger is attached to a local logger, its init operation is called with the local logger's prefix and a list of recent log messages (see the LoggerAdmin interface below). Then, each time a log message is sent to the local logger, the Logger facet forwards this message to the remote logger's log operation.
The LoggerAdmin Interface
LoggerAdmin InterfaceThe Logger facet implements the Ice::LoggerAdmin interface:
module Ice{ interface LoggerAdmin { void attachRemoteLogger( RemoteLogger* prx, LogMessageTypeSeq messageTypes, StringSeq traceCategories, int messageMax) throws RemoteLoggerAlreadyAttachedException;
bool detachRemoteLogger(RemoteLogger* prx);
LogMessageSeq getLog( LogMessageTypeSeq messageTypes, StringSeq traceCategories, int messageMax, out string prefix); }}The operation attachRemoteLogger attaches a remote logger (prx) to the local logger with the following optional filters:
messageTypesspecifies the types of log messages this remote logger wants to receive. An empty sequence means no filtering–theLoggerfacet will forward all log message types.traceCategoriesis a sequence of categories for trace messages. An empty sequence means no filtering–theLoggerfacet will forward all trace categories.messageMaxis the maximum number of log messages sent to init. IfmessageMaxis negative, all available log messages will be sent toinit(provided they satisfy themessageTypesandtraceCategoriesfilters). If messageMax is 0, no log message will be sent toinit. IfmessageMaxis greater than 0, the most recentmessageMaxlog messages that satisfy themessageTypesandtraceCategoriesfilters will be sent toinit.
For example, in C++, you can attach a remote logger with no filtering at all as follows:
// my remote logger, typically an object implemented by the local applicationRemoteLoggerPrx remoteLogger = ...
// get a proxy to the logger admin facet for the target applicationIce::ObjectPrx admin = ...auto loggerAdmin = admin.ice_facet<Ice::LoggerAdminPrx>("Logger");
loggerAdmin->attachRemoteLogger( remoteLogger, Ice::LogMessageTypeSeq{}, Ice::StringSeq{}, -1);If you are interested only in errors and trace messages for category Network with no more than 10 such messages sent to init, you could write instead:
RemoteLoggerPrx remoteLogger = ...Ice::ObjectPrx admin = ...auto loggerAdmin = admin.ice_facet<Ice::LoggerAdminPrx>("Logger");
Ice::LogMessageTypeSeq messageTypes{ Ice::LogMessageType::ErrorMessage, Ice::LogMessageType::TraceMessage};
Ice::StringSeq traceCategories{"Network"};
loggerAdmin->attachRemoteLogger(remoteLogger, messageTypes, traceCategories, 10);The operation detachRemoteLogger detaches a remote logger (prx) from the local logger. prx does not need to match exactly the proxy provided to attachRemoteLogger: the Logger facet uses only the identity in this proxy. detachRemoteLogger returns true if this remote logger was found (and is now detached), and false otherwise.
The Logger facet automatically detaches a remote logger when a request sent to this remote logger fails. As a result, if an administrative client forgets to call detachRemoteLogger after destroying its remote logger, or crashes, this remote logger will remain attached only as long as it's not used.
The operation getLog retrieves the most recent messageMax log messages that match the optional messageTypes and traceCategories filters. These parameters have the same meaning as in the attachRemoteLogger operation described above. For example, if you want to retrieve only the 10 most recent errors and trace messages for category Network, you could write:
RemoteLoggerPrx remoteLogger = ...Ice::ObjectPrx admin = ...auto loggerAdmin = admin.ice_facet<Ice::LoggerAdminPrx>("Logger");
Ice::LogMessageTypeSeq messageTypes{ Ice::LogMessageType::ErrorMessage, Ice::LogMessageType::TraceMessage };
Ice::StringSeq traceCategories{"Network"};
string prefix;auto logMessages = loggerAdmin->getLog(messageTypes, traceCategories, 10, prefix);Configuring the Logger Facet
Logger FacetThe Logger facet caches the most recent log messages sent to application's Logger, to be able to provide these log messages to remote loggers (in the init operation) and to administrative clients that call getLog (see the LoggerAdmin Interface above). You can configure how many log messages are cached by the Logger facet with the Ice.Admin.Logger.KeepLogs and Ice.Admin.Logger.KeepTraces properties. The default is to keep the most recent 100 log messages other than trace messages plus the most recent 100 trace messages.