# Custom Checks

A JavaScript based custom check is a powerful way to extend the core monitoring capabilities of Avantra by providing check logic that alerts you if any functionality your business relies on behaves incorrectly or needs attention.

We provide a rich API to report the status of the check back to Avantra along with detailed information or tabular results. Within a check we have access to powerful APIs depending on the monitored system type the check is run on. In addition, we always have access to the following building blocks:

- Using (Monitoring) Parameters

  Access parameters set in Avantra for the monitored object this action is run on to control the logic.

- Saving State

  Save calculated values to a local storage for use in subsequent executions of this check on a specific system.

- Calling Web Services

  Access to a simple HTTP client to call web services to validate operations or perform actions.

## Code Walkthrough

The check API is only present to allow you to report information back to Avantra on the status of the check and details on why it is that state to allow users of Avantra to investigate any issues that occur in the system.

Check out the building blocks relevant to the monitored system this check is run on for more information about ways of interrogating the system for information.

### Creating a new Custom Check

To develop a JavaScript based custom check, we’ll first create a blank check in the Avantra server. This can be done from the `Configuration` menu and selecting `Custom Checks`.

Click the `New` button in the toolbar. At the bottom of the left hand options, choose `All` then choose `RUN_JS` on the right hand side.

Enter a name for the check and optionally a customer, both of which can be changed later. Choose a system type which represents the monitored system that this check will be run on. To follow the examples on this page, choose `Server` as this is the most common type. And click `Create`.

In the properties for the Custom Check we now need to define which Servers this check will be active on. For our walkthrough simply select `Define specific 'Ad-Hoc' Custom Selection` and click the `Create` button that appears next to it. Simply click `Save and Close` on the window that opens and `OK` on the warning message.

Now click the `Apply` button and select `No` when the popup asks if you want to activate.

| This practice is OK for our testing on a non-productive Avantra since we don’t activate the check it is not sent to any agent as part of their regular check cycles. We will use a new feature in 21.11 to test execute on a specific server.

| If you’re using a productive Avantra or you have configured a lot of systems, define a system selector that prevents you from executing on the wrong system and improves the performance of the test function!

### Reporting Status

There are two core properties of the check global variable that allow you to control the status of a check and the message to display to users.

The first is status and this example illustrates the possible values that can be set:

    check.status = OK;
    check.status = WARNING;
    check.status = CRITICAL;
    check.status = UNKNOWN;
    check.status = DISABLED;

The value this property affects the check’s status reported back to Avantra.

A check should also report back a message to inform the user why the check did not work or that all was OK. This can be done like this:

    const numAdmins = 10; // Queried from the application some how
    const adminLimit = 5; // Or read from parameters (see using parameters)

    check.status = CRITICAL;
    check.message = `Too many admins logged in. ${numAdmins} exceeds limit ${adminLimit}`;

This will turn the check critical in Avantra and display the message `Too many admins logged in. 500 exceeds limit 400`. In this trivial example, the information provided to the Avantra user is enough to quickly determine what caused the check to be critical and how to fix it.

### Check Tables

A check can also return much more detailed information about what it has found in a tabular format. This is useful for checks where the next step of analysis for warning or critical checks would be to log into the system and, for example look at the list of admin users logged in and reach out to ask if they’ve forgotten to logout etc.

To display tabular data, it’s first necessary to create the table columns. This can be done using the addTableColumn(..) function passing the column name to display.

    check.addTableColumn("User ID");
    check.addTableColumn("User Name");

This creates a blank table with two columns named "User ID" and "User Name".

| When displaying tables in checks, the order in which the functions are called is very important as it controls the layout.

Adding data is easily done using the addCell(..) method (but only after columns have been added!) with newRow() to start a new row in the output.

For a simple example that outputs 2 columns with 2 rows:

    check.addTableColumn("User ID");
    check.addTableColumn("User Name");

    check.newRow();
    check.addCell(1);
    check.addCell("Jim Smith");

    check.newRow();
    check.addCell(2);
    check.addCell("Emma Smart");

| Always call newRow() before adding the content of the row to the table. If you run out of cells in the row, an error is thrown!

In lots of use cases adding rows to the table is done in a loop and you can see an example below.

| If you are handling SQL queries from a database using the database building block, there is also a convenience method result(..) that takes a SQL query result direcly and works out how to display it as a table. There is an example of this here.

### Performance Values

Recording performance values is an easy way for a check to report back changing information that can be then accessed in a graphical format on the Avantra Server.

First you must create a named custom `Performance Resource Type`. This can be done in the `Configuration` → `Performance Data` menu. Choose the `Types` tab (if not already selected) and click the `New` button in the toolbar.

Give the Performance Resource Type a name and select a system type in the dropdown. To follow along with this walkthrough, enter `CustomPRT` and `Server` respectively.

Leave the `Create default chart definition` check box ticked and click `Finish`.

In code we can now save values directly to the newly created Performance Resource Type by using the following snippet using the global variable performance:

    performance.writePerformanceValue("CustomPRT", 10);

That’s it! Once this simple check is deployed to servers and data is collected, a new chart will appear under the `Performance` tab for the relevant server for analysis.

| It may take some time before you see data returned as data is only sent every hour by the Agent to the Avantra Server.

## Examples

Example 1. Example: Full table format example

This simple example creates a trivial example to showcase table formatting of results without any complexities of querying a database or SAP system and is just for demonstration purposes and so can be run against any monitored object.

    // This could be read from a database table or SAP RFC
    const admins = [
        { id: 1,  name: "User 1"  },
        { id: 2,  name: "User 2"  },
        { id: 3,  name: "User 3"  },
        { id: 4,  name: "User 4"  },
        { id: 5,  name: "User 5"  },
        { id: 6,  name: "User 6"  },
        { id: 7,  name: "User 7"  },
        { id: 8,  name: "User 8"  },
        { id: 9,  name: "User 9"  },
        { id: 10, name: "User 10" }
    ];

    const numAdmins = admins.length;
    const adminLimit = 5; // Or read from parameters (see using parameters)

    if (numAdmins > adminLimit) {
        check.status = CRITICAL;
        check.message = `Too many admins logged in. ${numAdmins} exceeds limit ${adminLimit}`;
    } else {
        check.status = OK;
        check.message = `Only ${numAdmins} logged in (under ${adminLimit} limit)`;
    }

    // Create a table layout
    check.addTableColumn("User ID");
    check.addTableColumn("User Name");

    // Output table data
    admins.forEach(admin => {
        // Create a new row
        check.newRow();
        // Set the values (same order as columns)
        check.addCell(admin.id);
        check.addCell(admin.name);
    });

    // Graph the number of administrators logged in
    // -- Create a custom Performance Resource Type
    //    and uncomment the line below:
    // performance.writePerformanceValue("AdministratorCount", numAdmins);

## API Reference

### Global Variable check

The global variable check is used to set the check result status, message and (optionally) table format to be displayed to the user in Avantra.

Use method setStatus or property `status` to set the overall status of the check in Avantra. A check status can be one of `DISABLED`, `UNKNOWN`, `OK`, `WARNING`, or `CRITICAL`.

Use property `message` to set the textual description of the check. This should always be set to give a reason behind why the check failed or check succeeded to aid in problem resolution.

Methods addTableColumn and addCell can be used to create tabular results in Avantra to display more details about the information a check has found.

#### addCell(..)

    addCell(value: any): void

Add a cell with a specific value to the current row of the table. The cell will be added with the default of no status colors.

Use `addCell(value, status)` to add a cell with a status color.

This method requires there to be enough columns added with addTableColumn.

Parameters

  - `value`: any

    the value to display in the cell

#### addCell(..)

    addCell(value: any, cellStatus: CheckStatusType): void

Add a cell with a specific value to the current row of the table. The cell will be added with the color of the status set in the 2nd parameter. Use this to highlight specific values (i.e. if a condition fails) for ease of use for your Avantra users.

Use `addCell(value)` to add a cell with no status color.

This method requires there to be enough columns added with addTableColumn.

Parameters

  - `value`: any

    the value to display in the cell

  - `cellStatus`: CheckStatusType

    the status to set (e.g. `OK`, `WARNING`, `CRITICAL` etc.)

#### addTableColumn(..)

    addTableColumn(name: string): void

Add a new table column to the table to display texts/string content.

Table columns should be added before any data is added to the table with addCell to prevent an error.

Parameters

  - `name`: string

    the name to display for the column

#### addTableColumn(..)

    addTableColumn(name: string, type: string): void

Add a new table column to the table with a specified display type.

Table columns should be added before any data is added to the table with addCell to prevent an error.

Parameters

  - `name`: string

    the name to display for the column

  - `type`: string

    the column type to display

#### getMessage( )

    getMessage(): string

The check message to return to Avantra to explain the result.

Returns

  string

  the current check message

See Also

  - message

#### getStatus( )

    getStatus(): CheckStatusType

The current check status

Can be one of `DISABLED`, `UNKNOWN`, `OK`, `WARNING`, `CRITICAL`

Returns

  CheckStatusType

  the status of the check

See Also

  - status

#### newRow( )

    newRow(): void

Create a new row in the table.

This should be called before each row’s cells are added with addCell.

#### setMessage(..)

    setMessage(message: string): void

The check message to return to Avantra to explain the result.

Parameters

  - `message`: string

    the message to return as the check message

See Also

  - message

#### setNotifiableChange(..)

    setNotifiableChange(notifiableChange: Boolean): void

Force a notification to be sent for the check even if the status hasn’t changed since the last notification that was sent.

This must have an output channel configured for this check with the option `Resend When RTM Sub-Status Changes` marked as true

Since

  23.2

Parameters

  - `notifiableChange`: Boolean

    true iff a notification should be sent regardless of check status

See Also

  - notifiableChange

#### setResult(..)

    setResult(table: DataTable): void

This utility allows a user to output directly a database table result from a database query to be displayed in Avantra as the check results table. This is instead of manually creating the table using addTableColumn and addCell methods.

Parameters

  - `table`: DataTable

    the result table from a database query

See Also

  - result

#### setStatus(..)

    setStatus(status: CheckStatusType): void

Set the status of the check result.

Can be one of `DISABLED`, `UNKNOWN`, `OK`, `WARNING`, `CRITICAL`

Parameters

  - `status`: CheckStatusType

    the status to set

See Also

  - status

#### setStatusIfWorse(..)

    setStatusIfWorse(status: CheckStatusType): void

Set the status conditionally only if it is worse than the current status.

Can be one of `DISABLED`, `UNKNOWN`, `OK`, `WARNING`, `CRITICAL`. For example, if the current status is `WARNING` and this is called with `CRITICAL`, we change the status to `CRITICAL` but not if we are called with `OK` since this is less severe than `WARNING`.

This is useful in loops so that you don’t have to keep track of the current status.

Parameters

  - `status`: CheckStatusType

    the status to set if it worse than the current status.

See Also

  - statusIfWorse

#### message

    message: string

The check message to return to Avantra to explain the result.

See Also

  - getMessage()

  - setMessage(message: string)

Type

  string

#### notifiableChange

    notifiableChange: Boolean

Force a notification to be sent for the check even if the status hasn’t changed since the last notification that was sent.

This must have an output channel configured for this check with the option `Resend When RTM Sub-Status Changes` marked as true

See Also

  - setNotifiableChange(notifiableChange: Boolean)

Type

  Boolean

Since

  23.2

#### result

    result: DataTable

This utility allows a user to output directly a database table result from a database query to be displayed in Avantra as the check results table. This is instead of manually creating the table using addTableColumn and addCell methods.

See Also

  - setResult(table: DataTable)

Type

  DataTable

#### status

    status: CheckStatusType

The current check status

Can be one of `DISABLED`, `UNKNOWN`, `OK`, `WARNING`, `CRITICAL`

See Also

  - getStatus()

  - setStatus(status: CheckStatusType)

Type

  CheckStatusType

#### statusIfWorse

    statusIfWorse: CheckStatusType

Set the status conditionally only if it is worse than the current status.

Can be one of `DISABLED`, `UNKNOWN`, `OK`, `WARNING`, `CRITICAL`. For example, if the current status is `WARNING` and this is called with `CRITICAL`, we change the status to `CRITICAL` but not if we are called with `OK` since this is less severe than `WARNING`.

This is useful in loops so that you don’t have to keep track of the current status.

See Also

  - setStatusIfWorse(status: CheckStatusType)

Type

  CheckStatusType

### Global Variable performance

The global variable performance is used to report custom metrics back to Avantra that can be used in Charts and Reports.

| The used performance resource must first be defined in the Avantra UI in `Configuration → Performance Data` before using this API.

#### writePerformanceValue(..)

    writePerformanceValue(prt: any, value: any): void

Write one single performance value.

Parameters

  - `prt`: any

    the performance resource type to use (either name or id)

  - `value`: any

    the value to set

#### writePerformanceValue(..)

    writePerformanceValue(prt: any, value: any, resourceName: string): void

Write one single performance value and assign it to the resource specified.

Parameters

  - `prt`: any

    the performance resource type to use (either name or id)

  - `value`: any

    the value to set

  - `resourceName`: string

    the named resource to use

### Class CheckStatusType

This object is actually a set of constants that represent the different statuses that a check can be in.

#### DISABLED

A globally available constant that represents the disabled status. Can be used in checks simply with the `DISABLED` global variable.

This status should be used if you detect that displaying the check status makes no sense for this type of system / situation.

#### UNKNOWN

A globally available constant that represents the unknown status. Can be used in checks simply with the `UNKNOWN` global variable.

This status should be used only when the check logic cannot determine what status to assign to this check, and it doesn’t warrant investigation at this time. Consider using `WARNING` if there is investigation needed or if the function is critical to business operations, `CRITICAL` as a failure to determine the status could mean that it is masking a system failure that is affecting your business.

#### OK

A globally available constant that represents the OK status. Can be used in checks simply with the `OK` global variable. This is the default status for checks.

This status should be used to inform your Avantra users that this function of the system is operating well and no action is needed at present.

#### WARNING

A globally available constant that represents the warning status. Can be used in checks simply with the `WARNING` global variable.

This status should be used if you detect that there is some action that would be necessary to alert your users to, but it is not impacting business activity currently. For example, warning well in advance of an impending account expiry so that relevant approvals for the extension can be made before service is lost.

#### CRITICAL

A globally available constant that represents the critical status. Can be used in checks simply with the `CRITICAL` global variable.

This status should be used if you wish your Avantra users to pay urgent attention to the system and work on a resolution because it is impacting the business or will impact the business severely if no action is taken.

#### getName( )

    getName(): string

Return the name of the CheckStatusType for display

Returns

  string

  the status name

See Also

  - name

#### getValue( )

    getValue(): number

Return the value of the CheckStatusType for comparison

Returns

  number

  the numeric value

See Also

  - value

#### name

    readonly name: string

Return the name of the CheckStatusType for display

See Also

  - getName()

Type

  string

Modifiers

  Readonly

#### value

    readonly value: number

Return the value of the CheckStatusType for comparison

See Also

  - getValue()

Type

  number

Modifiers

  Readonly

### Class DataTable

This object represents a table of data that is read from the database. You can think of this object as an internal table. The property `rows` (and also the linked method) return an array of data that represent the rows of this table.

#### getRows( )

    getRows(): Row[]

Return the row data for this table.

Returns

  Row[]

  the rows of the data table

See Also

  - rows

#### rows

    readonly rows: Row[]

Return the row data for this table.

See Also

  - getRows()

Type

  Row[]

Modifiers

  Readonly