Helper: XLog (versatile logging approach for DO scripting)

XLog - a tiny function that helps managing script output. You may have noticed that some of my scripts feature a "XLog" commandline switch and a matching script config item. Here are some more details about it and a full demonstration of how XLog can be used.

XLog Button:
All output from scripts that make use of XLog, can be adjusted at once with this button/dialog:


XLog.dcf (3.81 KB)
Features:

  • Self-initializating
  • Level of output can be overriden by script, global DO variable or script config
  • Various output-levels to adjust the amount of output (regular use vs. tracing)
  • Prefixing messages at specific levels to make them stand out
  • Triggering of DOs "red warning" icon for error/exception messages
  • Indentation support (semi-automatic)
  • Pause mode

Usage:

To output a regular message:
Log("This is a regular message.");

To output an error:
Log("An error occured.", 'E');
You may also use "e" or "error" to set the level btw.

To output trace information and increase indentation for all following messages:
Log("OnScriptCommand()", 'T', 1);

To silenty decrease (or increase) the indentation (always make sure to decrease after increasing of course):
Log("-", 'T', -1);

You can specify what type of messages are going to be printed by setting a global variable "XLog". In general though, there's no need to do so, as XLog will print messages of type "normal" and all higher priorized messages by default (so trace and dump information won't show up). Setting the scripts internal variable is strongly suggested if your script command features a switch "XLOG" (and it should! o). You gain full control of the script commands output from whereever you start or test-drive the command. To set the scripts internal var to "trace", because XLOG=trace was given on the command line e.g., do this:

XLog = "trace";

Please notice: If no script internal XLog level has been defined, the global or script.config defined level take over if they exist (covered in detail below).

The various output-levels stack like this:

0 = off               // no output
1 = xception, xit     // exceptions only
2 = error             // errors and exceptions
3 = warning           // warnings and errors and exceptions
4 = info              // info and warnings and errors and everything above (you get the idea? o)
5 = normal            // regular output and all above
6 = trace             // trace information and all above
7 = dump              // dump & verbose messages and all above
8 = all               // the most detailed bits and all above

Controlling level of output by script config or global variable:

If there is a global variable called "XLog", it will override whatever your script has set (internally or by script.config).

DOpus.Vars.Set("XLog")="dump"; will set output of all scripts that use "XLog" to dump-level.

If the global variable does not exist and no XLog level has been set internally, Script.Config.XLog will take over.

The settings override like this: "normal" < scripts XLog < Script.Config.XLog < global Vars.XLog.

You can also override the global setting by setting XLogForce=true somewhere in the script. That allows for global muting of all other scripts, while the one you're working on will still print nicely to the console.

Logging can also be paused by setting XLog.paused = true.

DemoScript-Output at Loglevel "normal":

I suggest to not output in "normal" level for event-driven scripts, as it will spam the script console easily. Use it rarely. The moment your script is initializing e.g., is a matching situation from my point of view.


DemoScript-Output at Loglevel "xception":

General output has been skipped, showing only the most important message(s)


DemoScript-Output at Loglevel "dump":

Notice how the indentation increases "magically", to help keep track of what happens where


The code:

Put this snippet somewhere in your script and you're ready to roll (butr consider adding the matching script config items as well):

function Log(text, lvl, ind){ //XLog v0.42 (non-casesensitive options)
    var u,lvs={o:0,x:1,e:2,w:3,i:4,n:5,t:6,d:7,a:8},i=["","X","E","W","I","","","",""];
	if (typeof XLog==(u="undefined")){var v=DOpus.Vars; if (v.Exists("XLog") && typeof XLogForce==u) {XLog=v.Get("XLog"); }}
	if (typeof XLog==u){var c=Script.Config; if(typeof c!="undefined" && typeof c.XLog!=u){ XLog=c.XLog; }}
	if (typeof XLog==u){XLog="normal";} if(XLog.paused===undefined){ if(XLog===true) var L=5; else if(!isNaN(parseInt(XLog,10)))
		var L=XLog*1; else var L=lvs[(""+XLog).toLowerCase().substring(0,1)]; XLog={paused:false,I:0,L:L};}
	lvl=(lvl==undefined?5:lvs[lvl.substring(0,1).toLowerCase()]);
	if (!(lvl && XLog.L && !XLog.paused && (lvl<=XLog.L))){ return;} var pad = (XLog.I==0?"":new Array(XLog.I+1).join("    "));
	if (i[lvl])pad = i[lvl]+(!pad?"   ":pad.substring(1)); if (text!="-"){ var d=DOpus; if (d.Version.AtLeast("11.13.1"))
	d.Output(pad+text,((lvl==1||lvl==2)?1:0)); else d.Output(pad+text);}
	ind=(ind!==undefined?ind:0);XLog.I+=ind;if(XLog.I<0)throw new Error("XLog indent went sub-zero.");
}

Cya, tbone

XLog DemoScript:

This script features a "XLogDemo" command. The output-level can be set by commandline switch (XLOG=dump e.g.) or by opening the script configuration dialog and setting the "XLog" item or by setting the global XLog variable (consider using the button provided to set/remove this variable easily from a toolbar).

Xtra.Demo_XLog.js.txt (18.2 KB)

1 Like

XLog stays helpful and handy here, so I thought I'd update this thread to reflect the latest changes and improvements.

Update:

  • Log() snippet updated to v0.42 (various fixes and support for non-casesensitive cmdline options ("XLog=DuMp" now works as well)
  • Button updated (dropdown pre-selection added and requester text fixed)
  • Xtra.Demo_XLog.js.txt demonstrational script updated (script config items renamed slightly to fully match cmdline)

Thanks again to Kundal for finding these little issues! o)