# Creating custom monitors

To create a custom monitor, from **Alerts and Diagnostics** > **Manage alerts** in the navigation panel:

1. Click on the **New monitor** button in the top-right corner of the page to open the monitor configuration.
2. Fill in the fields under the **General** tab.
3. Define the **NQL Query and conditions** tab.
   * Including **Trigger condition** and **Scheduling frequency.**
4. [Configure Notifications via email or webhooks](/platform/user-guide/alerts-and-diagnostics/managing-alerts/configuring-email-and-webhook-notifications-for-alerts.md) for proactive alert management.

<figure><img src="/files/9364WHsX3Yx4wi8Sv4mc" alt=""><figcaption></figcaption></figure>

## Configuring General monitor settings

{% hint style="info" %}
Instead of creating a monitor from scratch, Nexthink recommends customizing built-in monitors, as they offer a wider range of features compared to custom monitors.
{% endhint %}

From the **New monitor** configuration page, fill in the following fields under the **General** tab.

<figure><img src="/files/HoH7qjjaGLqEWViPHqoT" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**Events trigger** and **Global detection** are only available for built-in monitors (system monitors or installed from Nexthink Library).
{% endhint %}

* **Trigger:** Custom monitors offer the **Schedule** trigger method used for periodic checks. Set specific intervals in the [scheduling frequency](#customizingbuilt-inmonitors-schedulingfrequency) section in the **Query and conditions** tab.
* **Type**: Custom monitors offer the following **Types** of detection modes:

<details>

<summary>Metric threshold</summary>

**Metric threshold** triggers an alert when the value of one or more metrics reaches a user-defined threshold.

</details>

<details>

<summary>Metric change</summary>

**Metric change** triggers when the current metric value differs from the rolling [7-day global average](/platform/user-guide/alerts-and-diagnostics/alerts-faq.md#how-does-the-system-compute-the-baseline-for-the-detection-methods-metric-change-and-metric-seasonal).

</details>

<details>

<summary>Metric Seasonal Change</summary>

**Metric seasonal change** triggers an alert when the current metric value falls outside its [time-of-day baseline](/platform/user-guide/alerts-and-diagnostics/alerts-faq.md#how-does-the-system-compute-the-baseline-for-the-detection-methods-metric-change-and-metric-seasonal) from the last 7 days, based on the configured standard deviation band.

</details>

{% hint style="info" %}
You can configure up to 5 custom monitors in total using either **Metric change** or **Metric seasonal change.**

You can create up to 50 monitors.
{% endhint %}

* **Name**: Provide a meaningful name for the monitor. The system uses this name to send notifications and visualize monitors on the Alerts overview page.
* **NQL ID**: The system automatically generates a unique identifier from the monitor **Name**. Use the NQL ID to query this monitor within Nexthink.
  * You can only edit the NQL ID during the monitor creation, using the following characters\
    `a-z, 0-9, _`.
  * You cannot create a monitor with an NQL ID that was used by a deleted monitor until there are no events in the system still associated with the deleted monitor (30 days max).
* **Priority:** Set the priority level. The default level is medium.
* **Tags**: Create custom tags for monitors. This enables you to filter alerts in the **Alerts overview** and in [Webhook](https://docs.nexthink.com/platform/user-guide/alerts-and-diagnostics/managing-alerts/configuring-email-and-webhook-notifications-for-alerts#configuringemailandwebhooknotificationsforalerts-webhooknotifications) integrations. Currently, you can define up to ten tags per monitor.

## Defining NQL Query and conditions for a custom monitor <a href="#creatingcustommonitors-definingannqlquery" id="creatingcustommonitors-definingannqlquery"></a>

From the monitor configuration page, fill in the following fields under the **Query and conditions** tab.

If needed, click the **Show in Investigations** button to view the query investigation results.

<figure><img src="/files/6lnk2XmAFxY71hj96Oth" alt=""><figcaption></figcaption></figure>

1. Write the **NQL query** to define the metrics to monitor. With NQL, you can:
   * Select one or multiple metrics.
   * Specify the scope using a `where` clause.
   * Define alert granularity with time aggregation and the `by` keyword for grouping.

{% hint style="warning" %}
The system displays an error message for NQL queries computing more than 10,000 result contexts/groups. In these cases, reduce granularity—simplify the `by` clause or add filters—as each group requires its own [baseline](/platform/user-guide/alerts-and-diagnostics/getting-started-with-alerts.md#baseline-computation-depending-on-the-alert-detection-mode).
{% endhint %}

<details>

<summary>NQL rules and limitations for monitor queries</summary>

The NQL query must follow several rules to support monitors:

1. The NQL query for monitors must include a computed or aggregated metric, which means every query requires a `compute` or `summarize` clause to be compatible with a monitor.

```
devices
| with device_performance.system_crashes during past 7d 
| compute 
  total_number_of_system_crashes = number_of_system_crashes.sum()
```

```
execution.crashes during past 24h
| summarize total_number_of_crashes = count()
```

2. Optionally, include more than one computed or aggregated metric in your query to set multiple conditions for triggering the alert.

```
execution.crashes during past 24h
| summarize 
  total_number_of_crashes = count(), 
  devices_with_crashes = device.count()
```

3. Use at least one metric to set a threshold for monitoring conditions. Create an additional metric if your original query does not include one.

Not compatible with monitors:

```
devices
| with antiviruses
| where is_up_to_date == no
```

Compatible with monitors:

```
devices
| with antiviruses
| where is_up_to_date == no
| compute device_count = count()
```

4. Do not add conditions to evaluated metrics at the NQL level. Instead, use the [Trigger condition](#creatingcustommonitors-definingtriggerconditionstriggercondition) section to define the condition.

Incorrect monitor NQL query:

```
execution.crashes during past 24h
| summarize total_number_of_crashes = count()
| where total_number_of_crashes >= 10
```

Correct monitor NQL query with conditions:

```
execution.crashes during past 24h
| summarize total_number_of_crashes = count()
```

5. Use the `where` clause to narrow the scope of your monitor to specific locations, applications and other categories.

```
execution.crashes during past 24h
| where binary.name == "excel.exe"
| summarize total_number_of_crashes = count()
```

6. Use `summarize... by` to define the right granularity for the alert context. In the following example, a single alert will be triggered per binary name.

```
execution.crashes during past 24h
| summarize total_number_of_crashes = count() by binary.name
```

Refer to the [Detecting issues impacting multiple devices](/platform/user-guide/alerts-and-diagnostics/managing-alerts/creating-custom-monitors/detecting-issues-impacting-multiple-devices.md) and [Detecting issues impacting a single device or user](/platform/user-guide/alerts-and-diagnostics/managing-alerts/creating-custom-monitors/detecting-issues-impacting-a-single-device-or-user.md) documentation to learn more about defining the NQL query.

</details>

2. Define **Trigger conditions** that activate alerts. Trigger conditions are sensitive to the chosen detection **Type** for the monitor.\
   Use each metric computed in the NQL query to narrow down the condition.

<details>

<summary>Trigger conditions for <strong>Metric threshold</strong></summary>

In **trigger conditions** for monitors with a **Metric threshold** detectio&#x6E;**,** the monitor triggers alerts when the metric value is **greater than or equal to**, or **less than or equal to**, the specified value.

The system triggers the alert when all trigger conditions are met.

<figure><img src="/files/AuplwBIdCKQahCEno1sw" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary>Trigger conditions for <strong>Metric change</strong></summary>

In **trigger conditions** for monitors with **Metric change** detection:

* The first trigger condition represents the deviation rule—**higher** or **lower**—that proportionally compares the current metric to the [baseline](/platform/user-guide/alerts-and-diagnostics/getting-started-with-alerts.md#baseline-computation-depending-on-the-alert-detection-mode) (7-day global average).
* Additional trigger conditions define the alert activation when the value is **greater than or equal to**, or **less than or equal to**, the defined threshold.

The system triggers the alert when all trigger conditions are met.

In the example below, the first trigger condition activates an alert when the **CPU Usage** value doubles the metric average over the last 7 days.

{% hint style="info" %}
These trigger conditions apply to both [Schedule and Events-trigger monitors](#customizingbuilt-inmonitors-general).
{% endhint %}

<figure><img src="/files/Pa7NktQOv91O7a6ZVCAB" alt=""><figcaption></figcaption></figure>

</details>

<details>

<summary>Trigger conditions for <strong>Metric seasonal change</strong></summary>

In **trigger conditions** for monitors with **Metric seasonal change** detection:

* The first trigger condition sets the sensitivity band or range computed the from [time-of-day baseline](https://docs.nexthink.com/platform/user-guide/alerts-and-diagnostics/getting-started-with-alerts#baseline-computation-depending-on-the-alert-detection-mode) from the last 7 days. The monitor triggers an alert when the current metric value falls outside the selected standard deviation range for that time slot:
  * **slightly** = one standard deviation (±1σ)
  * **moderately** = two times the standard deviation (±2σ)
  * **highly** = three times the standard deviation (±3σ)
* Additional trigger conditions define the alert activation when the value is **greater than or equal to**, or **less than or equal to**, the defined threshold.

The system triggers the alert when all trigger conditions are met.

In the example below, the first trigger condition activates an alert when the **Percentage of failed connections** is outside the band two standard deviations (±2σ) from the baseline.

<figure><img src="/files/nOKMk7A05bcB9bPOsH9P" alt=""><figcaption></figcaption></figure>

</details>

2. Set the **Scheduling frequency** of the monitor to determine how often the system evaluates the trigger condition.
   * The possible timeframes are 15 min, 1 hour, 3 hours, 6 hours, 12 hours, 24 hours, 48 hours and 7 days. These timeframes depend on the monitor [NQL query](#how-does-the-nql-query-affect-the-available-scheduling-timeframes) **(** `during past` clause) and the configured detection method:
     * For **Metric change,** the scheduling frequency ranges from **15 minutes** to several days.
     * For **Metric seasonal change,** the maximum scheduling frequency is **24 hours**, as more than 1-day frequency does not contribute to [computing the mean](/platform/user-guide/alerts-and-diagnostics/alerts-faq.md#how-does-the-system-compute-the-baseline-for-the-detection-methods-metric-change-and-metric-seasonal) for the same slot across the last 7 days.

{% hint style="warning" %}
Setting an alert **Scheduling frequency**, for example to **7 days**, means the monitor evaluates the alert every 7 days, starting on the 1st of each month.

This may cause the system to trigger alerts sooner than expected, such as one alert on the 28th of a specific month, but triggered again on the 1st of the month after.
{% endhint %}

<details>

<summary>How does the <strong>NQL query</strong> affect the available scheduling timeframes?</summary>

The availability of **Scheduling frequency** timeframes depends on the `during past` clause and the events defined in the monitor **NQL query.**

See the following examples to understand how setting monitor query determines the available scheduling frequency:

<table><thead><tr><th width="428">Monitored events with during past</th><th>Minimum frequency</th><th>Maximum frequency</th></tr></thead><tbody><tr><td><pre class="language-nql_/apigateway/nql-editor"><code class="lang-nql_/apigateway/nql-editor">device_performance.boots during past 24h
</code></pre></td><td>15 min</td><td>7 days</td></tr><tr><td><pre class="language-nql_/apigateway/nql-editor"><code class="lang-nql_/apigateway/nql-editor">device_performance.boots during past 7d
</code></pre></td><td>24 h</td><td>7 days</td></tr><tr><td><pre class="language-nql_/apigateway/nql-editor"><code class="lang-nql_/apigateway/nql-editor">session.events during past 1h
</code></pre></td><td>15 min</td><td>7 days</td></tr><tr><td><pre class="language-nql_/apigateway/nql-editor"><code class="lang-nql_/apigateway/nql-editor">session.events during past 24h
</code></pre></td><td>12h</td><td>7 days</td></tr><tr><td><pre class="language-nql_/apigateway/nql-editor"><code class="lang-nql_/apigateway/nql-editor">execution.events during past 1h
</code></pre></td><td>15 min</td><td>7 days</td></tr><tr><td><pre class="language-nql_/apigateway/nql-editor"><code class="lang-nql_/apigateway/nql-editor">execution.events during past 24h
</code></pre></td><td>12h</td><td>7 days</td></tr><tr><td><pre class="language-nql_/apigateway/nql-editor"><code class="lang-nql_/apigateway/nql-editor">execution.events during past 7d
</code></pre></td><td>7 days</td><td>7 days</td></tr><tr><td><pre><code>session.vdi_events during past 1h
</code></pre></td><td>15 min</td><td>7 days</td></tr><tr><td><pre><code>session.vdi_events during past 7d
</code></pre></td><td>24 h</td><td>7 days</td></tr></tbody></table>

</details>

4. Choose an alert **auto-recovery** option. In many alert scenarios, the monitor does not need to extend the recovery period by **72 hours**, as the **Trigger condition** is normalized:
   * In these cases, recover alerts **immediately** after the monitor's first evaluation returns no data due to inactivity.
   * On the contrary, you may decide to wait **72 hours** to, for example, account for a weekend break and keep the alert open during this inactivity period—instead of closing and opening a new alert.

***

## Creating custom monitors for virtual desktops (VDI) <a href="#creatingcustommonitors-importingacustommonitor" id="creatingcustommonitors-importingacustommonitor"></a>

{% hint style="warning" %}
Using built-in Nexthink Library VDI monitors for Alerts requires [Nexthink VDI experience](https://docs.nexthink.com/platform/user-guide/vdi-experience).
{% endhint %}

While built-in monitors for virtual desktops (VDI) provide out-of-the-box functionality with partial customization, you can create custom VDI monitors for specific organizational needs.

Consider the following when creating custom VDI monitors:

* Only the **Schedule** trigger, with a minimum granularity of **15 minutes** is available for custom VDI monitors.
* Use VDI-related NQL tables and fields in the **Query and conditions**. For example, the query below calculates the average network latency per desktop pool.
  * If needed, you may add trigger conditions to activate an alert when the average latency in the pool exceeds a threshold value, for example, 50ms.

```
session.vdi_events during past 15min
| where session.vdi_event.network_rtt != null
| summarize average_network_latency = network_rtt.avg(), 
total_number_of_sessions = vdi_session.count() by vdi_session.desktop_pool
```

***

RELATED TOPICS

* [Detecting issues impacting multiple devices](/platform/user-guide/alerts-and-diagnostics/managing-alerts/creating-custom-monitors/detecting-issues-impacting-multiple-devices.md)
* [Detecting issues impacting a single device or user](/platform/user-guide/alerts-and-diagnostics/managing-alerts/creating-custom-monitors/detecting-issues-impacting-a-single-device-or-user.md)
* [Nexthink Library](/platform/user-guide/nexthink-library.md)
* [Product configuration](/platform/user-guide/administration/system-configuration/product-configuration.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nexthink.com/platform/user-guide/alerts-and-diagnostics/managing-alerts/creating-custom-monitors.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
