The Console object provides access to the browser's debugging console. The Console object can be accessed from any global object.

Console output streams are redirected to standard output and standard error or wired to dbstudio console according the script execution context.

1 Log

Copy
<script>
    console.log("hello world");
</script>
Hello world

1.1 Wiring log to objects

Many Ax library objecs have internal debugging. You can enable it by wiring console logger to the object instance.

In the following example we enable debug log on database connection.

Copy
<script>

    // Wire console logger to database
    Ax.db.setLogger(console.getLogger());
    // The next statements will be logged to console
    Ax.db.executeQuery("SELECT COUNT(*) FROM systables WHERE tabid = 1");
    Ax.db.executeQuery(`
        SELECT COUNT(*) 
          FROM systables 
         WHERE tabid = ?
`, 
1
    );
</script>
00:00:00.015:              JSConnection - 
SELECT COUNT(*) FROM systables WHERE tabid = 1
00:00:00.024:              JSConnection - 
     SELECT COUNT(*) 
       FROM systables 
      WHERE tabid = ?

[1]
00:00:00.033:              JSConnection - Releasing connection 'a' with 2 open resultSets
00:00:00.047:              JSConnection - Connection a released
00:00:00.047:              JSConnection - Commit work
00:00:00.047:              JSConnection - Closing resultset on commit
00:00:00.047:              JSConnection - Closing resultset on commit

2 Debug

The console debug method mimics log method but it's only enabled when console debug it's enables. You can place console debug statements in application that will not be logged unless console debug is enabled.

Copy
<script>
    console.log("Hello1");
    console.debug("Hello2")
    console.setDebug(true);
    console.debug("Hello3");
</script>
Hello1
Hello3

3 Mail

The console.mail method allows sending by email the log generated by the other console logging methods. The content logged will be sent at script finalization.

To enable this feature the instruction should be called at some point in the script giving the email subject. Then a call to to() must be executed to specify the recipient. Other calls to cc() and bcc() are optional.

Copy
...
console.mail('E-mail subject')
    .to('anna@example.com')
    .cc('bob@example.com')
    .cc('x@example.com');
...

Consider the following example script:

Copy
console.log('start debug log entry (stdout)');
console.mail('Debug process').to('user@deister.es');
var rs = Ax.db.executeQuery(`SELECT FIRST 10 * FROM systables`);
for (var row of rs)
    console.info(`Processing table ${row.tabname}`);
console.log('final debug log entry');

The script will produce no return value and the following output:

Copy
first debug log entry (stdout)

Also an an email will be sent to "user@deister.es" with the following content:

Copy
Processing table systables
Processing table syscolumns
Processing table sysindices
Processing table systabauth
Processing table syscolauth
Processing table sysviews
Processing table sysusers
Processing table sysdepend
Processing table syssynonyms
Processing table syssyntable
final debug log entry

4 Timing

The console.time() method starts a timer in the console view. This method allows you to time certain operations in your code for testing purposes. Use the console.timeEnd() method to show in the console.view the time elapsed since last call to console.time().

Copy
<script>
console.time();
// do some ops
console.timeEnd();
// Reset timer
console.time();
// do some ops
console.timeEnd();
</script>
default: 0.002000 ms
default: 0.002000 ms

4.1 Named timers

Use the label parameter to name the timer, then you are able to have many timers on the same engine.

Copy
<script>
console.time("test");
// do some ops
console.timeEnd("test");
// do some ops 
console.timeEnd("test");
</script>
test: 0.002000 ms
test: 0.004000 ms

5 Groups

The console.group() method indicates the start of a message group. All messages will from now on be written inside this group. Use the console.groupEnd() method to end the group.

Copy
<script>

    console.log("Hello from Earth");
    console.group("Mars");
    console.log("Going to Mars");
    console.group("Jupiter");
    console.log("Going to Jupiter");
    console.group("Saturn");
    console.log("Going to Saturn");
    console.groupEnd();
    console.log("Returning to Jupiter");
    console.groupEnd();
    console.log("Returning to Mars");
    console.groupEnd();
    console.log("Returning to Earh");
    console.log("...");

</script>
Hello from Earth
   +Mars
   Going to Mars
      +Jupiter
      Going to Jupiter
         +Saturn
         Going to Saturn
      Returning to Jupiter
   Returning to Mars
Returning to Earh
...

6 Table

The console.table() method writes a table in the console view. The first parameter is required, and must be either an object, or an array, containing data to fill the table.

Copy

Using an object as the first parameter

console.table({ firstname : "John", lastname : "Doe" });
+---------+-----+
|key      |value|
+---------+-----+
|firstname|John |
|lastname |Doe  |
+---------+-----+
Copy

Using an array of arrays

var people = [["John", "Smith"], ["Jane", "Doe"], ["Emily", "Jones"]]
console.table(people);
+-----+-----+
|0    |1    |
+-----+-----+
|John |Smith|
|Jane |Doe  |
|Emily|Jones|
+-----+-----+
Copy

Using an array of objects

var car1 = { name : "Audi",  model : "A4" }
var car2 = { name : "Volvo", model : "XC90" }
var car3 = { name : "Ford",  model : "Fusion" }

var cars = [car1, car2, car3];

console.table(cars);
+-----+------+
|name |model |
+-----+------+
|Audi |A4    |
|Volvo|XC90  |
|Ford |Fusion|
+-----+------+

7 HTML Table

The console.HTMLTable() method defines an HTML Table structure to create beauty logs.

Copy

Using an object as the first parameter

var t1 = console.HTMLTable("Performance test", ["table", "tabid"]);

t1.addRow(["systables", 1]);

		var t2 = t1.addTable("row 1", ["column", "colno1"]);
		t2.addRow(["tabid2",   ['Step 11', 'Step 12']]);
		t2.addRow(["tabname1", 122]);
		t2.addRow(["colname1", 123]);

t1.addRow(["sysindexes", 2]);

		var t2 = t1.addTable(["column", "colno2"]);
		t2.addRow(["tabid2",   ['Step 21', 'Step 22']]);
		t2.addRow(["tabname2", 122]);
		t2.addRow(["colname2", 123]);

console.log(t1);

8 Progress

You can use a progress bar with ETA (Estimated Time of Arrival) indicator in long loops.

All information logged using progress will be redirected to console monitor (dbstudio console, webapp dialogs).

Copy
<script>
    var progress = console.getProgress(3, "Loading row(s)");
    for (var idx = 0; idx < 3; idx++) {
       	progress.worked(1, "Step " + idx);
        // Do some job
    }
</script>
Loading row(s)
       1 of 3,  33% completed, ETA = 0.01 sec(s) Step 0
       2 of 3,  66% completed, ETA = 0.00 sec(s) Step 1
       3 of 3, 100% completed, ETA = 0.00 sec(s) Step 2

8.1 Nested progress

Progress can be nested. This may be the case of a script calling a nested script both of them having a progress. In that case each progress is an indepenent object. The display shows the relative indentation accoding the hierarchy.

Copy
<script>
    var progress1 = console.getProgress(3, "Processing invoices");
    for (var idx1 = 0; idx1 < progress1.getGoal(); idx1++) {
    
        // 
        // Do some job [1]
        // 
    
    	var progress2 = console.getProgress(5, "Processing items");
    	for (var idx2 = 0; idx2 < progress2.getGoal(); idx2++) {
    
            // 
            // Do some job [2]
            // 

            // Mark job [2] completed
            progress2.worked(1, "step " + idx2);
    	}
    
        // Mark job [1] completed
        progress1.worked(1, "step " + idx1);
    }
</script>
...
        0 of 3,   0% completed, Processing invoices
           0 of 5,   0% completed, Processing items
           1 of 5,  20% completed, step 0
           2 of 5,  40% completed, step 1
           3 of 5,  60% completed, step 2
           4 of 5,  80% completed, step 3
           5 of 5, 100% completed, step 4
        1 of 3,  33% completed, step 0
           0 of 5,   0% completed, Processing items
           1 of 5,  20% completed, step 0
           2 of 5,  40% completed, step 1
           3 of 5,  60% completed, step 2
           4 of 5,  80% completed, step 3
           5 of 5, 100% completed, step 4
        2 of 3,  66% completed, step 1
           0 of 5,   0% completed, Processing items
           1 of 5,  20% completed, step 0
           2 of 5,  40% completed, step 1
           3 of 5,  60% completed, step 2
           4 of 5,  80% completed, step 3
           5 of 5, 100% completed, step 4
        3 of 3, 100% completed, step 2

Notice that ResultSets from database have no valid row count (is unknown and set to -1) while memory ResultSets have. Progress will only work with values >= 0.

9 Redirect

As the primary target of any script it to be run attached to a database connection, console streams (stdout and stdout) are by default attached to database console.

Database console provides an in memory limited string buffer that can be inspected by tools like dbstudio.

During production or test (running outside dbstudio) you may want to retrieve or redirect console output.

9.1 Redirect to stdout+stderr

Simply call setStdOut() or setStdErr() with no arguments to force console to be redirected to stdout and stderr.

9.2 Redirect to file

Simply call setStdOut(file) or setStdErr(file) to redirect streams to the specific file.

Copy
<script>
    console.log("=========== Redirecting streams");    
    
    // You will see a log showing stream is redirected.
    console.setStdOut(new Ax.io.File("/tmp/stdout.log"));
    console.setStdErr(new Ax.io.File("/tmp/stderr.log"));
    
    // Log is sent to file
    console.log("hello stdout");
    console.log("hello stderr");
    
    // Set streams to stdout+stderr (to see content of files...)
    console.setStdOut();
    console.setStdErr();

    // See content of files into standard console
    console.log(new Ax.io.File("/tmp/stdout.log").asText());
    console.log(new Ax.io.File("/tmp/stderr.log").asText());
</script>
=========== Redirecting streams
StdErr redirected to System.err
StdErr redirected to /tmp/stderr.log
hello stdout
hello stderr