Writing to the Event Log

Status of the running plug-in can be written to the event log, either for the user or for the developer to examine debug state.

When to use the Event Log

The event log should be used to report useful state for an advanced user. It should be used relatively sparingly. Otherwise you’re just going to overload the user with a flood of information.

If you choose to use the event log for debugging purposes, you should make sure that you’ve disabled this in shipping builds. Otherwise you will just be polluting the event log with information that isn’t relevant to the user.

Things that should not go to the event log:

  • Status messages like “Plug-in has been added”, or “File saved” when it’s a direct result of a user’s action (like saving an image or scene).

  • Errors from commands (use the command’s ILxMessage (CLxUser_Message) interface instead, obtained via the command’s basic_Message() method).

  • Progress updates (use ILxMonitor (CLxUser_Monitor) instead).

./CLxLogMessage (index)

This utility class is the easiest way to write to the log, although it was designed for file I/O and still has some of that legacy. You need to declare your own sub-class which implements the Format() and Version() methods for your plug-in.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 class CMyLogMessage : public CLxLogMessage
 {
     public:
         const char * GetFormat ()
         {
                 return "My Format";
         }

         const char * GetVersion ()
         {
                 return "My Version";
         }
 };

Declare your class as a persistent object somewhere, and you can then output info and errors to the event log.

1
2
3
4
5
         CMyLogMessage        my_log;
         ...

         my_log.Error ("Help! Something scary!");
         my_log.Info ("Nevermind -- just my own shadow");

These messages will be tagged with your format and version. If you don’t care for that you can compose messages more directly. It’s also possible to append sub-messages in the log, which will be appear as collapsible sub-items in the event log viewport.

1
2
3
         my_log.Message ("CMyPlug", "MyMethod", "Multiple values already set:");
         my_log.SubMessage (0, 0, "Value 1");
         my_log.SubMessage (0, 0, "Value 2");

Custom Logs

By default the CLxLogMessage implementation writes to the “io-status” event log. That can be overwritten in the constructor:

1
2
3
4
5
 class CMyLogMessage : public CLxLogMessage
 {
     public:
         CMyLogMessage() : CLxLogMessage ("myLog") {}
         ...

The name can be any existing log, but if the log doesn’t otherwise exist it has to be declared by the server. This can be done by adding the name(s) of logs that the server wants to use to the server’s tags.

1
    { LXsSRV_LOGSUBSYSTEM,  "myLog" },

Direct Log System Access

If the log message helper class is unsuitable or you want more control over the formatting of your events, you can access the log more directly. You initialize a Log Interface wrapper by using the allocate-by-name method.

1
2
3
         CLxUser_Log       my_log;

         my_log.setByName ("myLog");

You can then allocate log entries from the service and post them to the log.

1
2
3
4
5
         CLxUser_LogService log_svc;
         CLxUser_LogEntry   entry;

         log_svc.NewEntry (LXe_INFO, "My Info Message", entry);
         my_log.AddEntry (entry);

Adding sub-entries is done by making the same AddEntry() call on the parent entry.

1
2
3
4
         CLxUser_LogEntry   sub;

         log_svc.NewEntry (LXe_INFO, "My Sub-message", sub);
         entry.AddEntry (sub);