Monitoring Mustache Template Reference

Observe Monitors allow for extensive customization via the use of the Mustache specification. In addition to supporting the standard behaviors, we also support some additional Observe-specific extensions.

Custom Function Support

Observe added the ability to treat sections of rendered template as mutable by a function. A specific use case is to apply formatting or encoding to a single scetion of a template, but not the whole template. The custom functions that Observe supports for monitoring include:

  • {{~urlpathescape}}: Used in the path part of a url to ensure it is encoded properly.

  • {{~urlqueryescape}}: Used in the query params of a url to ensure it is encoded properly.

For example, to use the urlpathescape function in a fragment of your template:

{{~urlpathescape}}
This text will be {{presented}} for mutation by the `urlpathescape` function.
{{#subsection}}
This text will also be {{.}} mutated.
{{/subsection}}
{{/urlpathescape}}

Array Indexing

When a section is an array, each item in the array will be invoked to render the section. However, you can target a specific index using an integer identifier.

{{#array.1}}The item at index 1 is {{.}}{{//array.1}}

This also allows for rendering logic, based on if an array has any elements or not.

{{#array.0}}This will only render if array has non-zero elements{{/array.0}}

{{#array}}This would render N times, one for each element{{/array}}

Fragments

At the API level, we accept a JSON object of “fragments” which are the same concept as mustache “partials”. These are accessed in the calling template using the partials syntax. So, if you add a fragment object like:

    "fragments": {
        "fruit": "<b>apple</b>",
        "vegetable": "{{veggie}}"
    }

Then you can access them in your template via the > prefix, for example:

Today, I really want to eat {{>fruit}} and skip eating {{>vegetable}}

In this example, the fruit fragment is allowed to contain formatting and will not be escaped. Also note that the vegetable fragment is still a full featured template itself, and will attempt lookups and rendering on the fly using the same options as the main template.

Iteration

A mustache section is rendered N times when the referenced field is an array of values. When the field is an array, a few additional fields will be added to the element to aid in iteration. These can be especially helpful if you are rendering things like JSON templates where “danging/trailing commas” are not permitted.

For example, to render a JSON array of the names in the captured values of an alert. Using the isFirst check, an array item can be prepended with a “, “ for all but the first item in the array.

{{#alert.values}}
[{{^isFirst}}, {{/isFirst}}{{name}}]
{{/alert.values}}

Top Level

Monitors have two top-level objects you can access for templating:

  • {{monitor}}: Items about the monitor

  • {{alert}}: Items about the alert

For all of the following examples, they are shown with the full path to the object, and all of the sub fields of that section.

{{monitor}} Section

  • {{name}}: The monitor name

  • {{description}}: The description saved with the monitor

  • {{id}}: The Observe object ID for this monitor.

  • {{type}}: One of “Count”, “Promote”, or “Threshold”

  • {{icon}}: The icon saved with the monitor

  • {{url}}: The link to the monitor in the Observe console.

{{alert}} Section

  • {{timestamp}}: The time the match was seen. Same as {{timestamp.rfc3339}}

  • {{start}}: The time the match condition started. Same as {{start.rfc3339}}

  • {{end}}: The time the match condition ended. This will only be set if isActive is false. Same as {{end.rfc3339}}

  • {{isActive}}: Indicates if the matching condition is still triggering.

  • {{url}}: A link to the Observe console for this alert.

  • {{id}}: The Observe object ID for this alert.

  • {{severity}}: The severity of the alert. Same as {{severity.level}}

  • {{type}}: The event type that created this notification. Same as {{type.friendly}}.

  • {{values}}: The values captured from the monitor match.

  • {{dataUrl}}: A link to the Observe console to explore the data and filtered context that generated this alert.

  • {{resources}}: An array of all the resources linked to this match.

  • {{resourcesByLink}}: The same resources as resources but you can index by the known resource type.

{{alert.start}} Section

This variable can be rendered directly, which prints the rfc3339 value or using one of the sub fields.

  • {{rfc3339}}: The RFC3339 Format (like 2024-06-01T12:34:56Z)

  • {{timePart}}: Just minutes and seconds (like 12:34 UTC)

  • {{datePart}}: Just the date without the year (like Jun 01)

  • {{epoch}}: The unix seconds since epoch in UTC (like 1717244636)

{{alert.end}} Section

Same as {{alert.start}}

{{alert.timestamp}} Section

Same as {{alert.start}}

{{alert.severity}} Section

This variable can be rendered directly, which prints the same as level or using the sub fields below.

  • {{level}}: One of “Critical”, “Error”, “Informational”, or “Warning”

  • {{isCritical}}: Indicates if the level is critical

  • {{isError}}: Indicates if the level is error

  • {{isWarning}}: Indicates if the level is warning

  • {{isInformational}}: Indicates if the level is info

{{alert.type}} Section

This variable can be rendered directly, which prints the same as friendly or using the sub fields below.

  • {{eventType}}: One of “NewAlarm”, “Reminder”, “AlarmEnded”

  • {{friendly}}: A more user-friendly version of eventType

  • {{isNewAlarm}}: Indicates if the event type is NewAlarm

  • {{isReminder}}: Indicates if the event type is Reminder

  • {{isAlarmEnded}}: Indicates if the event type is AlarmEnded

{{alert.values}} Section

This variable can be enumerated as a section and contains all values captured from the monitor match. You can filter by the type, which allows you to, for example, only print only the group-by values. Not all columns of a monitor match are captured. Values that are used to link to resources, to define the grouping, are part of the aggregation (like count), or are part of a promote monitor are captured.

{{#alert.values}}
Each Column Name: {{name}}
{{/alert.values}}

{{#alert.values}}
    {{type.isGroupBy}}Grouped By {{name}} : {{value}}{{/type.isGroupBy}}
{{/alert.values}}
  • {{type}}: The type contains sub fields you can use to test why the value was captured. A value can be multiple types.

  • {{name}}: A rendered name for the captured column value

  • {{value}}: The captured value in string form

  • {{isFirst}}: Indicates if this is the first in the iteration

  • {{isLast}}: Indicates if this is the last in the iteration

{{alert.values.type}} Section

This subtype that has “is*” flags for each of the types a value can be. These are not necessarily exclusive.

  • {{isGroupBy}}: The value is used in the grouping.

  • {{isAggregation}}: The value is part of the aggregation calculation.

{{alert.valuesByName}} Section

You can access the same elements as {{alerts.values}}, but using a lookup by their unique name. All of the same fields exist except for the iteration fields isFirst and isLast.

This would produce the same output in the previous example where {{alert.values.name}} is equal to value captured from “Flavor” column.

{{#alert.valuesByName.Flavor}}
My favorite ice cream flavor is {{value}}
{{/alert.valuesByName.Flavor}}

{{alert.resources}} Section

This variable can be enumerated as a section for each resource. Each resource contains:

  • {{label}}: The label or name of the resource

  • {{value}}: The label value dereferenced from the resource

  • {{url}}: A link in Observe to the resource explorer for this resource

  • {{isFirst}}: Indicates if this is the first in the iteration

  • {{isLast}}: Indicates if this is the last in the iteration

In order to render only by a known link type, you can use resourcesByLink instead.