Autopsy Debugger Tutorial

Tutorial Overview

This tutorial guides a developer through an overview of the capabilities of the “Autopsy Debugger”. This is a tool in VANTIQ Modelo that allows you to examine the execution of a Rule in detail after it has completed. It requires the creation of a Type and Rule to put the debugger through its paces.

All lessons assume the developer has a working knowledge of VANTIQ Modelo. It is recommended that a new developer completes the lessons in the Introductory Tutorial before starting the lessons in this tutorial.

1: Creating a Debugging Project

The first task in learning about VANTIQ debugging is to create a project in VANTIQ Modelo to assemble all the debugging components.

Use the Projects button, select Create New Project and title the project “Debugging”:

        DebugProject

The rest of the lessons take place inside this Modelo project.

2: Creating a Type and Rule

In order to demonstrate the capabilities of the Autopsy Debugger we must first to create a dummy Type and dummy Rule to provide a predictable environment. Neither of these perform any actual function; they will just help you understand the debugger operations.

You will need to create a Type called TutorialExampleType. (This procedure is explained in the Introductory Tutorial as 2: Creating Data Types.) The Type has only two Integer properties, “age” and “weight”:

        SourcesTab

Next you will need to create a Rule called TutorialExampleRule. Use the Add button to select Rule…:

        AddRule

Use the New Rule button to create your sample rule. You can just copy and paste this text into the Rule editor:

RULE TutorialExampleRule
WHERE (t.age > 5)
WHEN INSERT OCCURS ON TutorialExampleType AS t

var ageStatus = "Unknown"

if (t.age >= 21) {
   ageStatus = "Adult"
} else {
   ageStatus = "Child"
}

SELECT TutorialExampleType AS allPeople

var total = 0

for (person IN allPeople) {
   total = total + person.weight
}

var averageWeight = total / allPeople.size()

3: Turn on Tracing

In production, you want your rules and procedures to execute with minimum overhead. Normally when a rule or procedure executes, it runs as quickly as possible and leaves no traces behind (other than its expected actions and side-effects, of course).

In order to debug a rule, you must turn on “Tracing” for that rule. When Tracing is active for a rule, it causes that rule to create “Rule Snapshots” as it executes. (These correspond to instances of the ArsRuleSnapshot system type.) In general, there is one snapshot generated for every “statement” executed in your Rule. Since Rules can be complicated (containing loops and IF/THEN logic) there are usually many more snapshots produced than the rule has statements. (A FOR loop, for example, could produce thousands.)

After the Rule has completed execution, the Autopsy Debugger will process the snapshots that were produced when the Rule executed, allowing you to investigate the details (after the fact) of the Rule’s operation. In this way you can check it for logical flaws and fix possible problems when it doesn’t act the way you expect. Note that Procedures can be debugged in the same way.

Because the overhead of producing the snapshots can be substantial, you should not leave Tracing on during normal production operation. You should only turn it on to capture one or two autopsies for the target rule or procedure, and then turn it off again. Once you have captured an autopsy, it can be examined at your leisure without impacting normal system performance.

Turning Tracing on and off for a rule (or procedure) is simple. Open the rule or procedure in Modelo, then use the Edit with Full Editor icon button (small pencil at the top, right of the pane). In the full editor, check the checkbox called Tracing Enabled so it looks like this:

        SourcesTab

Then click Save. Once enabled, Tracing will stay on for that rule until you edit the rule and turn it off again.

Leave Tracing on now, since we are next going to generate some Rule executions.

4: Capture Some Rule Executions

The simple dummy rule we created watches for records to be inserted into the TutorialExampleType. This makes it easy to cause the Rule to execute; we simply insert some data into the Type. Modelo provides an easy way to do this manually. Use the Show button to select Add Record…, then use the Type pull-down menu to create two TutorialExampleType records.

        AddRecord

For the purposes of this tutorial we need to insert two TutorialExampleType records. First fill in the fields like this and click the Add New Record button:

        AddRecord1

Now create a second one with these values:

        AddRecord2

To verify that the two records have been saved, use the Show button to select Find Records to display the Find Records query pane:

        FindRecords

Select TutorialExampleType from the Type menu, then use the Run Query button to display the list of TutorialExampleType records:

        RecordList

Since we inserted two TutorialExampleType records, we expect that two Autopsies were created. Let’s go see what they look like.

5: The Captured Autopsies

Use the Debug button to select Autopsies, then use the Run Query button:

        AutopsiesQuery

The “Autopsy Query Results” pane will display like this:

        Autopsies

You should probably see two Autopsies for the TutorialExampleRule in the list, created by the inserts we did in Lesson 4. They are displayed in reverse time order, so the ones that executed most recently are at the top. The “Start Time” column tells you when that particular Rule execution started.

Notice that in the “Triggered” column they look different. Why is that? Let’s find out.

You can click in the “Name” column of this table to open the Autopsy for a particular Rule execution; click the older of the two (the one that contains the little red “Not” icon in the “Triggered” column). This should cause the Autopsy Debugger to open, letting us see what happened during this execution.

6: Untriggered Rules

Here is what you should be seeing:

        Untriggered

At the top of the page is general information about this particular execution of TutorialExampleRule. Of most interest is the line in red which says, “The WHERE clause prevented the WHEN from triggering the rule.” That’s why the two rule executions were different; although this Rule executed it didn’t actually “trigger”. (That is, it didn’t actually run the Rule.) Let’s look further to see why.

The lower section of the page is divided into two columns; on the left (called “the display area”) is shown the current values of various variables, objects and lists being manipulated by the Rule. In the right hand column is the text of the rule itself.

Note that the “WHEN” for this Rule is preceeded by a WHERE clause that says, “the rule should only trigger if the inserted object had an ‘age’ field greater than 5”. Did it?

Look at the top item in the display area; it tells us the current contents of the object referenced by the “t” correlation variable. In particular we can see that the “age” property was “4” so in fact this rule did exactly what we asked it to do.

Notice that this little table only shows the value of the “age” property; remember that the TutorialExampleType also contained a “weight” property as well. Where is it? In order to keep the display from getting too cluttered, the debugger tries by default to show you only the values which are actually referenced by the rule. In this case t.weight was not used so it is not shown by default. But you can still see it if necessary; click the little open star to the left of the “Name” column label and the debugger will show all the properties. Click it once more to hide the unused ones again.

        SourcesTab

That’s all this autopsy has to tell us; the Rule didn’t fully trigger because the WHERE clause told it not to.

Now hit the browser’s “Back” button and return to the “Autopsy Query Results” list.

A little digression for advanced users

You can skip this section if you don’t care about some subtle points concerning how rules get triggered.

We could have described the triggering condition for the rule like this instead, specifying the WHERE as part of the WHEN clause:

WHEN INSERT OCCURS ON TutorialExampleType AS t WHERE (t.age > 5)

When the WHERE clause is attached to the WHEN like this, it means that the “filtering” happens much earlier, such that this rule never even starts at all. If we did it that way there would have been no snapshot generated unless t.age was greater than 5. This would be more efficient and generate less “noise”. For this tutorial we did it a different way:

WHERE (t.age > 5)
WHEN INSERT OCCURS ON TutorialExampleType AS t

This distinction becomes important when using advanced “compound condition” rules in which the WHEN clauses can get much more complex; for the purposes of this tutorial we wanted to force a “non-triggered” snapshot.

7: Debugging a Rule

Once you have returned to the “Autopsy Query Results” list, we can select the other autopsy, which (as we can tell by the green check in the “Triggered” column) actually did something. The debugger display for this Rule execution should look more interesting:

        Triggered

There is more to see now. First notice that there are 4 buttons at the top of the display; underneath the middle two is the legend “Step 1 of 11”. This tells us that this Rule execution produced 11 Snapshots, each representing the execution of a statement in the Rule.

Because this is an “autopsy” debugger we already know the entire execution history of the Rule. That means we can step forwards and backwards to examine the Rule execution. We can fast-forward all the way to the end (by clicking the “End” button) and then step backwards or click “Start” and “rewind” all the way to the initial state. This ability can be helpful when trying to understand what your rule did (and where it may have gone wrong).

The body of your rule has been teased apart into its individual statements and displayed on the right hand side. The statements which are executable (and not just part of the statement syntax, like “ELSE” and “END”) have two little icons to their left:

        Statement

The rightwards-pointing arrow tells us where we are in the execution flow. The statement that is about to be executed (but hasn’t executed yet) has a black arrow, and the text of the rule is blue. For other rules, the arrow is grey and the text is black.

The greyed-out star represents a breakpoint; you can toggle it to indicate that the debugger should stop at that point. (This is irrelevant if you are just “single-stepping” through the Rule, but if you click “Start” or “End” these breakpoints will take effect.)

This first statement sets the value of a variable called “ageStatus” to “Unknown”. But it hasn’t executed yet; find the current value of “ageStatus” in the “Variables” list and you will see that it is currently “<UNDEFINED>“. If you click the “Forward” button at the top of the display you should see several things happen.

Remember that you can always click the “Step Back” button and you will see things go back to where you started. Then hit “Step Forward” again, so the current statement point is on the “IF” statement.

What should happen next? Since t.age is “35” (as we can see from the WHEN section of the display area) we would expect the expression to be “true”. Click “Step Forward” again and let’s see.

        WasTrue

Note that the “IF” statement now shows “green” indicating that it evaluated to “true”. (If it had been “false” it would show “red”.) The current statement has advanced to the THEN block, where we would expect. This color highlighting can help orient you when your logic is inside some kind of loop and the same statement gets executed multiple times.

Okay, let’s jump ahead. Find the FOR statement and toggle its breakpoint icon so it looks like this:

        ForLoop

Now click the “End” button at the top of the page. This would normally let the rule run all the way to the “Execution Completed” point at the bottom, but because we set a breakpoint it will stop at the “FOR” (Step 6).

A few statements before, the Rule loaded all the instances of TutorialExampleType into the “allPeople” list using a SELECT. You should now be able to see those in the display area on the left:

        AllPeople

We have clicked the little star to reveal all the contents. Notice that it says we are seeing record “1/2”; you can click on the little left and right arrow icons that bracket the title to scroll forwards and backwards through the list.

You can also click the “JSON” button inside the title bar to popup a viewer which allows you to see the entire object in JSON format:

        Viewer

Now we can iterate through these two TutorialExampleType instances in the FOR loop using the “person” variable.

Since the “person” variable only has meaning inside the FOR loop it doesn’t appear in the display area until we step in. Do that now by clicking once on the “Step Forward” button and you will see the value of person.weight change as you step through the loop. As you keep clicking the “Step Forward” button you will eventually exist the FOR loop.

Of course, at any time you can click the “End” button and zip all the way to the “Execution Completed” point. This means the Rule has completed executing all statements and is about to exit.

Once you are done studying the autopsy you can hit your browser’s “Back” button to return to the “Autopsy Query Results” list.

8: Cleaning up Autopsies

In the process of debugging a Rule, you may capture many execution instances. As you work with more than one rule, the list can get rather long. After you are done with a debugging session you will probably want to clean up the ones you no longer need.

        Autopsies

You can delete individual autopsies by checking the checkbox to the left of the autopsy name, then using the Delete Selected icon button (small trashcan at the top, right of the pane). This can get tedious if you have more than a handful to delete, so a more efficient way has been provided. You can delete all these at once by using the Delete All Autopsy Records button in the “Autopsies Query” pane, using the Name Containing and Filter fields to select exactly which autopsy records to delete.

Note: there is also an Errors pane in Modelo that shows errors that have occurred in rules, procedures, or sources run by the system. These errors are collected and saved whether Tracing is enabled or not. To retrieve existing errors, use the Debug button to select Errors, then use the “Errors Query” pane to select which errors to display:

        Errors