Writing to the modo event log and debugger

Introduction

This article provides C++ source code for writing to the modo event log and the debug output.

This code should be easily adaptable, providing simple methods for writing out information for debugging purposes.

Code

plugin_debug.hpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
*  This header file provides the classes for writing to the modo event log and debug output.
*/

// Include the required modo SDK headers
#include <lx_plugin.hpp>
#include <lx_log.hpp>
#include <lxu_log.hpp>

// Set any namespaces
using namespace std;

#define PLUGIN_DEBUG_LOG        "myPlugin"
#define PLUGIN_VERSION          "601"
#define PLUGIN_COPYRIGHT        "Copyright 2012, My Company"

//--------------------------------------------------------------
//  Define the classes and methods for the debug and event log output.
//--------------------------------------------------------------

class plugin_logMessage : public CLxLogMessage
{
        public:
                plugin_logMessage               (char *subSys = NULL) : CLxLogMessage (PLUGIN_DEBUG_LOG) { Setup(); }
                virtual ~plugin_logMessage      () {}

                const char * GetFormat          () { return PLUGIN_DEBUG_LOG;                   }
                const char * GetVersion         () { return PLUGIN_VERSION;                     }
                char * GetCopyright             () { return PLUGIN_COPYRIGHT;                   }
};

class plugin_debug
{
        /*
        *  This function creates a CLxUser_LogService item and defines functions for writing out to the debug output.
        *  The debug output is defined using the -Debug: Verbose, Trace, filename.txt ... etc when launching modo.
        */

        public:
                CLxUser_LogService              plugin_debug_log;
                plugin_logMessage               plugin_event_log;

                void debug                      (const char * message, int level=2);
                void debug                      (string message, int level=2);

                void eventLog                   (const char * message, int level=1);
                void eventLog                   (string message, int level=1);
};

plugin_debug.cpp

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
/*
*  This source file implements the methods for writing to the modo event log and debug output.
*/

// Include the header
#include "plugin_debug.hpp"

//--------------------------------------------------------------

void plugin_debug::debug(const char * message, int level)
{
        /*
        This function writes out to the debugger.
        (Optional Int) Level defines:
        LXi_DBLOG_ERROR         = 1
        LXi_DBLOG_NORMAL        = 2
        LXi_DBLOG_TRACE         = 3
        LXi_DBLOG_VERBOSE       = 4
        */

        if(level > 4 || level < 1) {
                // If level isn't within the correct range, we redefine it.
                // However, we also write an error to the debug log so that it doesn't get missed.
                plugin_debug_log.DebugOut(LXi_DBLOG_NORMAL, "Note: The incorrect level has been set in plugin_debug::debug(). Assuming LXi_DBLOG_NORMAL.\n");
                level = 2;
        }

        // Write out to the debug.
        plugin_debug_log.DebugOut(level, message);
}

void plugin_debug::debug(string message, int level)
{
        /*
        This function writes out to the debugger.
        (Optional Int) Level defines:
        LXi_DBLOG_ERROR         = 1
        LXi_DBLOG_NORMAL        = 2
        LXi_DBLOG_TRACE         = 3
        LXi_DBLOG_VERBOSE       = 4
        */

        if(level > 4 || level < 1) {
                // If level isn't within the correct range, we redefine it.
                // However, we also write an error to the debug log so that it doesn't get missed.
                plugin_debug_log.DebugOut(LXi_DBLOG_NORMAL, "Note: The incorrect level has been set in plugin_debug::debug(). Assuming LXi_DBLOG_NORMAL.\n");
                level = 2;
        }

        // Write out to the debug.
        plugin_debug_log.DebugOut(level, message.c_str());
}

void plugin_debug::eventLog(const char * message, int level)
{
        /*
        This functions writes out to the modo event log.
        (Optional Int) Level defines:
        LXe_INFO                = 1
        LXe_WARNING             = 2
        */

        if(level > 2 || level < 1) {
                // If level isn't within the correct range, we redefine it.
                // However, we also write an error to the debug log so that it doesn't get missed.
                plugin_debug_log.DebugOut(LXi_DBLOG_NORMAL, "Note: The incorrect level has been set in plugin_debug::eventLog(). Assuming Info.\n");
                level = 1;
        }

        // Write out to the event log.
        if(level == 1) {
                plugin_event_log.Message(LXe_INFO, PLUGIN_DEBUG_LOG, "Plugin", message);
        } else if(level == 2) {
                plugin_event_log.Message(LXe_WARNING, PLUGIN_DEBUG_LOG, "Plugin", message);
        } else {
                plugin_debug_log.DebugOut(LXi_DBLOG_NORMAL, "Error: Unable to write to the modo event log.\n");
        }
}

void plugin_debug::eventLog(string message, int level)
{
        /*
        This functions writes out to the modo event log.
        (Optional Int) Level defines:
        LXe_INFO                = 1
        LXe_WARNING             = 2
        */

        if(level > 2 || level < 1) {
                // If level isn't within the correct range, we redefine it.
                // However, we also write an error to the debug log so that it doesn't get missed.
                plugin_debug_log.DebugOut(LXi_DBLOG_NORMAL, "Note: The incorrect level has been set in plugin_debug::eventLog(). Assuming Info.\n");
                level = 1;
        }

        // Write out to the event log.
        if(level == 1) {
                plugin_event_log.Message(LXe_INFO, PLUGIN_DEBUG_LOG, "Plugin", message.c_str());
        } else if(level == 2) {
                plugin_event_log.Message(LXe_WARNING, PLUGIN_DEBUG_LOG, "Plugin", message.c_str());
        } else {
                plugin_debug_log.DebugOut(LXi_DBLOG_NORMAL, "Error: Unable to write to the modo event log.\n");
        }
}

Server Tags

One final change must be made to your plugins source code, before it can write to the modo event log.

The plugin must use server tags to inform modo of the log subsystem that will be used for output.

In your plugin implementation, ensure that you are setting the LXsSRV_LOGSUBSYSTEM tag to define the debug log. For example:

1
2
3
4
LXtTagInfoDesc   plugin::descInfo[] = {
        { LXsSRV_LOGSUBSYSTEM, PLUGIN_DEBUG_LOG },
        { 0 }
};

More information is available in the Server Tags section of the wiki.

Writing to the log

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
void someFunction()
{
        // To use the source code provided and write out to the event log or the debugger, first create an instance of the plugin_debug class.
        // I usually call this debug, to keep things simple.
        plugin_debug_class      debug;

        // To write out to the modo event log, simply use the following function:
        debug.eventLog("Hello World!");

        // You can customise the event log message. For example the following will display as a warning in the event log and the text will be orange.
        debug.eventLog("This is a warning", 2);

        // To write out the debug log, use this function:
        debug.debug("Hello world!");

        // Note: to read the debug output, modo will need to be launched from Visual Studio (or equivalent debugger), using the flag: -debug:verbose.
        // Alternatively, you can write out the log to a file, using -dblog:/Path/to/log.txt
}