Skip to main content

Use Cases

The system uses templates when assigning incidents in the following scenarios:
ScenarioDescription
Manual incident creationManually create and assign incident
Auto-generated incidentReport alert event, system auto-generates incident, assigns per matched escalation rule
ReassignmentAfter incident creation, manually change assignment
EscalationBased on escalation rule settings, system auto-escalates assignment
Reopen assignmentAfter incident closed and reopened, reassigns per previous settings
The system uses Golang template syntax to parse data, supporting logic, loops, pipelines, and common functions. For more functions, refer to sprig function library.

Configuring Templates

1

Create Custom Template

Go to Template Management page, click Create Custom Template or Copy Default Template
2

Edit Template Content

Edit content by notification channel, can reference fields from the variable list below
3

Save Template

Click Save to complete creation

Apply Template

1

Enter Escalation Rules

Go to ChannelEscalation Rules, click Edit
2

Select Template

In rule configuration, select which template to use for notifications
3

Save Configuration

Click Save to complete configuration. See Configure Escalation Rules

Variable Reference

Reference Examples

// Reference incident title
{{.Title}}

// Reference creator name
{{.Creator.PersonName}}

// Reference resource label value
{{.Labels.resource}}

// Reference label with "." (e.g., "A.B")
{{index .Labels "A.B"}}

Incident Variables

Complete variable list for incident objects:
FieldTypeRequiredDescription
IDstringIncident ID
TitlestringIncident title
DescriptionstringIncident description, may be empty
DetailUrlstringIncident detail page URL
NumstringIncident short identifier, for visual recognition only
IncidentSeveritystringSeverity: Critical / Warning / Info
IncidentStatusstringIncident status: Critical / Warning / Info / Ok
ProgressstringProcessing progress: Triggered / Processing / Closed
StartTimeint64Trigger time, Unix timestamp in seconds
LastTimeint64Latest event time, Unix timestamp in seconds
EndTimeint64Recovery time, Unix timestamp in seconds
SnoozedBeforeint64Snooze end time, Unix timestamp in seconds
AckTimeint64First acknowledgment time, Unix timestamp in seconds
CloseTimeint64Close time, Unix timestamp in seconds
CreatorPersonCreator info, doesn’t exist for auto-generated
CloserPersonCloser info, doesn’t exist for auto-recovered
AssignedToAssignmentAssignment configuration
Responders[]ResponderResponders list
ChannelIDint64Channel ID
ChannelNamestringChannel name
GroupMethodstringGrouping method: n (none) / p (rule-based) / i (intelligent)
LabelsmapLabel KV, both Key and Value are strings
AlertCntint64Associated alert count
Alerts[]AlertAssociated alert details
FireTypestringNotification type: fire (notify) / refire (loop notify)
IsFlappingboolWhether in flapping state
ImpactstringIncident impact, filled after closure
RootCausestringIncident root cause, filled after closure
ResolutionstringResolution, filled after closure
FieldTypeRequiredDescription
person_idint64Person ID
person_namestringPerson name
emailstringEmail address
FieldTypeRequiredDescription
PersonIDs[]stringPerson ID list, only exists when assigned by person
EscalateRuleIDstringEscalation rule ID
EscalateRuleNamestringEscalation rule name
LayerIdxstringAssignment level, starts from 0
TypestringAssignment type: assign / reassign / escalate / reopen
FieldTypeRequiredDescription
PersonIDint64Person ID
PersonNamestringPerson name
EmailstringEmail address
AssignedAtint64Assignment time, Unix timestamp in seconds
AcknowledgedAtint64Acknowledgment time, Unix timestamp in seconds
FieldTypeRequiredDescription
TitlestringAlert title
DescriptionstringAlert description, may be empty
AlertSeveritystringSeverity: Critical / Warning / Info
AlertStatusstringAlert status: Critical / Warning / Info / Ok
ProgressstringProcessing progress: Triggered / Processing / Closed
StartTimeint64Trigger time, Unix timestamp in seconds
EndTimeint64Recovery time, Unix timestamp in seconds
CloseTimeint64Close time, Unix timestamp in seconds
LabelsmapLabel KV

FAQ

  • Manually created incidents have no labels
  • Auto-created incidents have labels, same as the first merged alert’s labels
Go to Incident List → view incident details to see all label information.
When creating custom templates, the system uses mock data to check syntax. Mock data covers limited scenarios; rendering may fail at runtime, and system falls back to default template.
Recommend checking if variable exists before referencing:
// ❌ Wrong: Read label directly
{{.Labels.resource}}

// ✅ Recommended: Check then read
{{if .Labels.resource}}{{.Labels.resource}}{{end}}
Use toHtml function to handle:
// Escape HTML characters
{{toHtml .Title}}

// Render with first non-empty value
{{toHtml .Title .TitleEnglish}}
// date function: Convert timestamp to readable format
{{date "2006-01-02 15:04:05" .StartTime}}

// ago function: Convert time difference to readable format (e.g., "5 minutes ago")
{{ago .StartTime}}
Add $ before external variable:
{{range .Responders}}
  {{if eq $.Progress "Triggered"}}
Pending】{{.Email}}
  {{end}}
{{end}}
Use index function:
{{index .Labels "obj.instance"}}
// alertLabels: Get deduplicated array
{{alertLabels . "resource"}}

// joinAlertLabels: Deduplicate and join with delimiter as string
{{joinAlertLabels . "resource" ", "}}
// Complete iteration
{{range $k, $v := .Labels}}
  {{$k}} : {{toHtml $v}}
{{end}}

// Exclude single label
{{range $k, $v := .Labels}}
  {{if ne $k "resource"}}
    {{$k}} : {{toHtml $v}}
  {{end}}
{{end}}

// Exclude multiple labels
{{range $k, $v := .Labels}}
  {{if not (in $k "resource" "body_text")}}
    {{$k}} : {{toHtml $v}}
  {{end}}
{{end}}
Use jsonGet function to extract values by path from valid JSON. Syntax reference at gjson.dev.
// Extract detail_url field from rule_note label
{{jsonGet .Labels.rule_note "detail_url"}}

// Extract name field of first element in JSON array
{{jsonGet .Labels.slice "0.name"}}

// Iterate array, match instanceId field where userId==7777
{{jsonGet .Labels.rule_note "#(userId==7777)#.instanceId"}}
imageSrcToURL: Convert image_key or URL to accessible address (for Dingtalk/Slack App)
{{ $root := . }}
{{ range $i, $v := .Images }}
  {{ $imageURL := imageSrcToURL $root $v.Src }}
  {{ if $imageURL }}![]({{$imageURL}}){{ end }}
{{ end }}
transferImage: Upload image to third-party platform (for Feishu/Lark App)
{{ $root := . }}
{{ range $i, $v := .Images }}
  {{ $transferURL := transferImage $root $v.Src }}
  {{ if $transferURL }}![]({{$transferURL}}){{ end }}
{{ end }}
Image size cannot exceed 10 MB, supports JPG, PNG, WEBP, GIF, BMP formats.
FunctionDescriptionExample
andLogical AND{{if and (eq .A "x") (eq .B "y")}}
orLogical OR{{if or (eq .A "x") (eq .A "y")}}
notLogical NOT{{if not (eq .A "x")}}
eqEqual{{if eq .A "x"}}
neNot equal{{if ne .A "x"}}
gt / geGreater than / Greater or equal{{if gt .AlertCnt 1}}
lt / leLess than / Less or equal{{if lt .AlertCnt 10}}

Channel Templates

Different notification channels support different template formats and limitations.
Requires Feishu/Lark integration configured first. Supports message card format; system auto-removes empty render lines caused by non-existent labels.Default Template (render all labels):
{{if .Labels.body_text}}{{.Labels.body_text}}{{else if .Description}}{{.Description}}{{end}}
{{if .Labels.resource}}**resource** : {{(joinAlertLabels . "resource" ", ")}}{{end}}
{{range $k, $v := .Labels}}
{{if not (in $k "resource" "body_text" "body_text_with_table")}}**{{$k}}** : {{$v}}{{end}}{{end}}
{{ $root := . }}
{{ range $i, $v := .Images }}
  {{ $transferURL := transferImage $root $v.Src }}
  {{ if $transferURL }}![]({{$transferURL}}){{ end }}
{{ end }}
Feishu/Lark App Notification
Minimal Template (show key labels only):
{{if (index .Labels "resource")}}resource:{{toHtml (joinAlertLabels . "resource" ", ")}}{{end}}
{{if (index .Labels "check")}}check:{{toHtml (index .Labels "check")}}{{end}}
{{if (index .Labels "metric")}}metric:{{index .Labels "metric"}}{{end}}
{{if (index .Labels "trigger_value")}}trigger_value:{{index .Labels "trigger_value"}}{{end}}
{{if (index .Labels "region")}}region:{{index .Labels "region"}}{{end}}
{{if (index .Labels "cluster")}}cluster:{{index .Labels "cluster"}}{{end}}
{{if (index .Labels "service")}}service:{{index .Labels "service"}}{{end}}
{{if (index .Labels "env")}}env:{{index .Labels "env"}}{{end}}

Bot Templates

Template formats supported by group chat bots.
Supports message card, rich text, and plain text formats. Max message 4000 bytes, truncated if exceeded.
{
  "msg_type": "interactive",
  "card": {
    "config": {
      "wide_screen_mode": true,
      "enable_forward": true
    },
    "header": {
      "template": "{{if eq .IncidentSeverity \"Critical\"}}red{{else if eq .IncidentSeverity \"Warning\"}}orange{{else}}yellow{{end}}",
      "title": {
        "content": "{{fireReason .}}INC #{{.Num}} {{toHtml .Title}}",
        "tag": "plain_text"
      }
    },
    "elements": [{
      "tag": "div",
      "fields": [{
        "text": {
          "tag": "lark_md",
          "content": "**🏢 Channel:**{{.ChannelName}}"
        }
      },
      {
        "text": {
          "tag": "lark_md",
          "content": "**⏰ Trigger Time:**{{date \"2006-01-02 15:04:05\" .StartTime}}"
        }
      }]
    },
    {
      "tag": "action",
      "actions": [{
        "tag": "button",
        "text": { "tag": "plain_text", "content": "Details" },
        "type": "primary",
        "url": "{{.DetailUrl}}"
      },
      {
        "tag": "button",
        "text": { "tag": "plain_text", "content": "Acknowledge" },
        "type": "primary",
        "url": "{{.DetailUrl}}?ack=1"
      }]
    }]
  }
}
{
  "msg_type": "post",
  "post": {
    "zh_cn": {
      "title": "{{if eq .IncidentSeverity \"Critical\"}}🔴{{else if eq .IncidentSeverity \"Warning\"}}⚠️{{else}}ℹ️{{end}} {{fireReason .}}INC #{{.Num}} {{toHtml .Title}}",
      "content": [
        [{"tag": "text", "text": "🏢 "}, {"tag": "text", "text": "Channel: ", "style": ["bold"]}, {"tag": "text", "text": "{{.ChannelName}}"}],
        [{"tag": "text", "text": "⏰ "}, {"tag": "text", "text": "Trigger Time: ", "style": ["bold"]}, {"tag": "text", "text": "{{date \"2006-01-02 15:04:05\" .StartTime}}"}],
        [{"tag": "a", "href": "{{.DetailUrl}}", "text": "Details"}, {"tag": "text", "text": "  "}, {"tag": "a", "href": "{{.DetailUrl}}?ack=1", "text": "Acknowledge"}]
      ]
    }
  }
}
{{fireReason .}}INC #{{.Num}} {{toHtml .Title}}
-----
Channel: {{if .ChannelName}}{{.ChannelName}}{{else}}None{{end}}
Severity: {{.IncidentSeverity}}
Trigger Time: {{date "2006-01-02 15:04:05" .StartTime}}
Duration: {{ago .StartTime}}
<br />Details: {{.DetailUrl}}

Other Channels

Default Template:
You have a pending incident: {{toHtml .Title}}, Channel: {{.ChannelName}}, Severity: {{.IncidentSeverity}}{{if gt .AlertCnt 1}}, {{.AlertCnt}} alerts grouped{{end}}