A Logger for JS scripting
Latest release
V0.9.2:
CommonLogger.opusscriptinstall (27.8 KB)
UIiconset_SAL (32px & 22px).dis (35.0 KB)
Why ?
Starting to have multiple scripts in DOpus to do various things, I felt missing a proper logger function to avoid some issues and shortcomings of DOpus.Output (no file logging, interlacing logs when multiple instances of the same script run in parallel, ...).
So, this is my attempt to a more advanced logger.
Main concept
I wanted it customizable but quick to set up in a script.
So, I made something that revolves around the concept of targets (something I already saw in other languages logging framework) :
- One logger can handle multiples targets with the same log action (mostly, you will have a Console target and/or a File target).
- To some extent, behavior may be customized from one target to another (formatting, level filtering, ...).
- Targets configuration can be held (Opus global var) in templates that you can instantiate quickly.
- All the logger objects (targets, configurations, etc ...) are stored in an include file in a specific namespace (LoggerNS).
Here's a preview at what Console logging can look like :
And instantiation of a logger (with multiple targets) can be as simple as :
logger = LoggerNS.BuildDefaultLogger("MyScriptName");
or a little more complicated like :
var consoleLog = new LoggerNS.LoggerTarget("ConfigLogger console", LoggerNS.LogLevel.Trace, LoggerNS.LogLevel.Fatal, LoggerNS.TargetType.Console);
consoleLog.layout.IncludeDateTime = false;
var fileLog = new LoggerNS.LoggerTarget("ConfigLogger file", LoggerNS.LogLevel.Trace, LoggerNS.LogLevel.Fatal, LoggerNS.TargetType.File, "/cLoggerPath", "MyScriptName");
logger = new LoggerNS.Logger(consoleLog, fileLog);
Here is also a screenshot of the template configuration manager :
Main Features
Below a non exhaustive list of the main features
Log levels and per target log filtering
Logger offers traditional levels of logging : trace / debug / info / warn / error / fail.
Each target attached to one logger can have a min and a max log level which act as filters (e.g. if console target has min log level to info, it will not display logs on trace and debug level).
Some specific things can also be done with minimum log levels by defining local or global log levels. See description of V0.9.1 below for more details.
Customizable output fields choice
Each log will be displayed on a line that can integrate (user definable per target) :
- Date/Hour of the log
- An ID (randomly chosen at logger construct time) to identify logs from multiple instances of a script running/logging at the same time
- The function from which the request for logging was made
- The log level
Output Coloring (console target only)
Each token/field described before plus the log message itself can have their coloring (front & background) customized.
The coloring can differ depending on the log level.
Output spacing/alignment
LogLevel and Caller function fileds can be set to fixed length for better alignment.
It is possible to increase/decrease indentation of log messages.
See V0.9.1 description below for more precise information about this.
Customizable archiving & deletion delays (file targets only)
To help manage automatically log files that may end up piling up in the logging folder(s), file target logging will perform on each logger instantiation a "cleanup" task (launched asynchronously) :
- All log files for this script older than the archiving delay will be zipped
- All log and/or archive files for this script older than the deleting delay will be ... deleted

This can serve a use case where you keep online logs for say one month, then they get zipped (to save space), and after a year, you consider you will not need them anymore and they get deleted (save space, remove "garbage" and limit the number of files in script log folder(s)).
A GUI to configure the targets templates easily
This editor will allow, most probably once and for all, configuration of the templates you will then be able to use everytime.
Each target can be made "Default Configuration" which is then used in the first construct described above (logger = LoggerNS.BuildDefaultLogger("MyScriptName");) : it will create a logger with every "Default Configuration" targets inside, only customizing the script name which is used in the log filename definition.
This editor also offers the ability to export and import full configurations (JSON) containing all target templates.
This can be usefull for backup purposes or more likely to share a configuration between multiple instances of Opus on multiple computers.
How to set-up
Minimum Opus version : 13.19
- Icons for the editor (to install : drag & drop in Preferences / Toolbars / Icons). Icon names are all prefixed by "cLogger_", no risk of clashing with other iconsets (and can be placed at any rank of the iconsets list).
See link to .disfile at the top of this post. - Script installer:
See link to .opusscriptinstallfile at the top of this post.
The script installer will install :- inc_Logger.js : the include script with the logger logic. To include in any script file you intend to use the logger.
- inc_commonSAL.js : another include file with helper functions, extensions to some objects prototypes (to provide methods that are only available in more advanced versions of javascript).
Thanks to many users of this forum from which I borrowed ideas or direct code so useful that it ended up in this file. If anyone wants credit listed for their contribution, just let me know. - inc_MsgLoopHandler.js : an include file provided by @Felix.Froemel (thanks) that helped cleanup the code for the template editor.
- CommonLogger.js : the script file which contains the command to open the GUI Template Editor (
ConfigLogger) and also the command used to do cleanup (archive/delete) in old log files (called asynchronously from the logger). GUI Template Editor can also be invoked through script settings in a dedicated tab/button:
How to use
Targets configurations
That is optionnal, since if no configuration is found, a default one is created, containing 2 targets : "Default Console" and "Default File".
The "Default File" target template is configured to log to /cLoggerPath/. You can either change that (in the editor), or create that alias, referencing whatever folder you wish to use for your log files.
Use in script
You need to include the "inc_Logger.js"
Then, in the "entry point" of your script (usualy "OnXXXX" corresponding to your command), you need to create an instance of LoggerNS.logger that needs to be a global variable so it can be used anywhere from there in your script. To achieve that, just declare it without prepending the var keyword.
A few examples :
Building a logger based on all "Default Configuration" targets for MyScriptName
logger = LoggerNS.BuildDefaultLogger("MyScriptName");
Building a logger based on two targets built from their constructors and modified accessing their properties if needed
var consoleLog = new LoggerNS.LoggerTarget("ConfigLogger console", LoggerNS.LogLevel.Info, LoggerNS.LogLevel.Fatal, LoggerNS.TargetType.Console);
consoleLog.layout.IncludeDateTime = false;
var fileLog = new LoggerNS.LoggerTarget("ConfigLogger file", LoggerNS.LogLevel.Trace, LoggerNS.LogLevel.Fatal, LoggerNS.TargetType.File, "/cLoggerPath", "MyScriptName");
logger = new LoggerNS.Logger(consoleLog, fileLog);
Building a logger based targets built from their templates names (here "Console 1" and "File details")
var consoleLog = LoggerNS.BuildTargetFromTemplate("Console 1");
var fileLog = LoggerNS.BuildTargetFromTemplate("File details", "MyScriptName");
logger = new LoggerNS.Logger(consoleLog, fileLog);
Note : LoggerNS.logger can accept multiple types of arguments :
- One LoggerNS.LoggerTarget, or 2, or 3, ...
- An array containing any number of LoggerNS.LoggerTarget
- One LoggerNS.LoggerConfiguration (which is an object which primary goal is to hold multiple targets, that can also load the saved configuration and save itself to disk (as an Opus global var), and can export/import itself to text/json).
Once this is done, you can use the method to generate the logs :
logger = LoggerNS.BuildDefaultLogger("MyTestScript");
logger.info("TestScript : start");
logger.debug("Searching for test file");
logger.trace("Something to log on trace level ...");
var t = SearchTestFile("myTestFile.txt");
logger.debug("Found test file : true");
logger.warn("Testfile extension is not natively supported.")
logger.error("Unable to find mirrored file.");
logger.fatal("Can not perform action. Exiting");
Release history
V0.9.2
Added:
New optional (last) parameter added to the following functions of Logger: log, trace, debug, info, warn, error, fatal. This signed integer parameter triggers indentation (as in Logger.AdjustIndentation).
New aliases for the following Logger functions:
| New Function | is an alias of |
|---|---|
| inc() | AdjustIndentation(+1) |
| dec() | AdjustIndentation(-1) |
| trc(msg, indent) | trace(msg, indent) |
| dbg(msg, indent) | debug(msg, indent) |
| inf(msg, indent) | info(msg, indent) |
| wrn(msg, indent) | warn(msg, indent) |
| err(msg, indent) | error(msg, indent) |
| fat(msg, indent) | fatal(msg, indent) |
V0.9.1
Changelog :
3 new features (more detail below):
- the logger now has methods to handle indentation
- spacing/alignement: the loglevel and the caller function fields can now be fixed length so that logs align in a nicer way
- Global (via UI or code) and local (code only) min log levels introduced to suit specific needs.
This settings only apply to Console type targets. The File type targets remain unaffected by these settings. 
In order to use/set these features, besides code additions, the Configuration Manager has evolved:
And the specific tab that can be accessed from Settings/Script/Cog Wheel has changed its name (to "Advanced Config") and provides a way to set the Global Minimum LogLevel:
In more details:
Indentation
Indentation can be accessed through the logger object, with a new method AdjustIndentation which takes one (signed) argument to increase or decrease (when parameter is lower than zero) indentation.
This is a "fluent" method, which means it returns the logger itself: this allows one liners like this:
logger.AdjustIndentation(1).debug("Some message");
// (...) some other actions and logs
logger.AdjustIndentation(-1);
Spacing/Alignment
This is a per target setting, so it is configured in the Configuration Manager (see screenshot above).
Fixed Length LogLevel: when activated, every LogLevel field is taking as much space as any other (e.g. as the longest loglevel).
In order to manage alignment, you can also define a fixed length for the Callsite (or caller function) field. Every shorter callsite will be right padded with spaces, every longer callsite will be truncated.
The result can be seen in the Configuration Manager screenshot.
Global and Local min log levels
This settings only apply to Console type targets. The File type targets remain unaffected by these settings. ![]()
Global MinLevel
The global min loglevel can either be set from the script config Advanced Config tab and lets you define a new min loglevel that applies to all loggers whatever the script.
It can also be set from the code:
LoggerNS.ForceGlobalConsoleMinLogLevel(LoggerNS.LogLevel.Info);
// (...) some other actions and logs
LoggerNS.DisableForcedGlobalConsoleMinLogLevel();
Local MinLevel
The local min loglevel can only be accessed from the code and acts directly on the logger object:
logger.EnableForcedLocalConsoleMinLevel(LoggerNS.LogLevel.Trace);
// (...) some other actions and logs
logger.DisableForcedLocalConsoleMinLevel(); // Not mandatory. Since it is tied to logger object, this is reset at every script launch.
What level prevails over the others?
- When Local LogLevel is set: a console log occurs only when its level is above the Local LogLevel
- Without Local LogLevel, but with a Global LogLevel: a console log occurs when level is both above the global log level and the target log level
- Without Global nor Local log levels activated: this is the standard way, the log occurs when level is above the target min log level
What use cases these levels are for?
- The global level can be used to raise (temporarily) the log level of all script. This can be useful when you find too many (low level) logs are populating the console. This can especially the case when you're working on one script, and others are populating the console.
- In that case, you'll raise the global level, but you need to keep low level logs for the "work in progress" script. That's where the local level comes into play: you specifically for that very script set up the local level lower so you can get all the logs for this script.
V0.9
Changelog :
CommonLogger
-
Settings are split in two groups:
Iconswhich holds the previous parameters, andOld Logs Managementwhich holds two new parameters:
-
Introduces 2 new parameters:
Log To Console&Log To File: Let you decide how/if you want the common logger commandManageOldLogFilesto log its actions. This command is called whenever a script logs its first entry within a script execution and manages previously created log files to check whether their execution date was prior to archiving delay or deleting delay. -
Since
ManageOldLogFilescan now log to file, this command is now protected against some kind of recursivity (one script logs, which triggers this command for this script, which logs, which triggers this command for OldLogsManager, which logs, which triggers this command for OldLogsManager, ...).- Note: This is achieved by using a Map Script Variable which stores the calling script when triggered and removes it just before exiting. If any other call occurs while it is being processing the old archives, it will not be processed.
-
The CommonLogger UI (used to create the target types, their color scheme, ...) can now be called from the standard Script configuration window in a new tab (in addition to the previous way, through
ConfigLoggercommand):
-
Opus min version raised to 13.19 in order to support usage of these two Opus features (Settings Groups & custom tabs in script configs settings).
inc_logger:
- Logger has a new propery (
disabled) which lets you fully disabling logging and bypass former behaviour: if a logger is asked to log but has no valid target, a fallback console logger is created to ensure at least one console log.
V0.8.2
Changelog :
CommonLogger
- Fix issue where CommonLogger UI would try and create a folder nammed cLoggerPath if the alias /cLoggerPath does not exists
inc_Logger.js
- Added test that ManageOldLogFiles command is installed before calling it (use case of a shared script using inc_Logger but without CommonLogger "installed").
V0.8.1
Initial release
Final warning : this is still beta. Do not hesitate to report if you encounter problems, including this description (which does not cover the whole thing in all the details).








