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 asresources
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.
{{alert.resourcesByLink}}
Section¶
You can access the unique resource specified by the link label. This has all the same fields except the iteration context fields isFirst
and isLast
.
{{#alert.resourcesByLink.User}}
Render this for user {{value}}
{{/alert.resourcesByLink.User}}