Esta plantilla ejecuta Autopilot en una alerta de New Relic y envía el análisis de causa raíz como un correo electrónico en formato HTML. Si Autopilot no devuelve una respuesta útil, el flujo de trabajo envía un aviso de error en su lugar. Para conocer los requisitos previos compartidos y las notas de configuración, consulte las plantillas de flujo de trabajo de RCA de Autopilot.
Antes de usar este flujo de trabajo, asegúrese de tener:
- Un destino de correo electrónico configurado en New Relic —consulte Crear destinos
- El UUID del destino
Este flujo de trabajo completa los siguientes pasos:
- Ejecuta Autopilot con un símbolo de análisis de causa raíz limitado al ID del problema de la alerta
- Comprueba si Autopilot devolvió una respuesta utilizable
- Si Autopilot tiene éxito, formatea la respuesta como HTML y la envía al destino de correo electrónico
- Si Autopilot falla, envía un correo electrónico de error con el ID del problema
Este flujo de trabajo usa newrelic.autopilot.run y newrelic.notification.sendEmail.
name: autopilotEmailRCAdescription: Automatically analyze New Relic alerts with Autopilot and send a formatted incident analysis report via emailworkflowInputs: issueId: type: String required: true validations: - errorMessage: Must be a valid New Relic issue ID in UUID format pattern: '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$' type: regex emailDestinationId: type: String required: true validations: - pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ errorMessage: "Invalid format. Please provide a valid UUID." type: regexsteps: - name: runAutopilot type: action action: newrelic.autopilot.run version: 1 inputs: prompt: >- Investigate New Relic issue ${{ .workflowInputs.issueId }}. Produce an incident analysis report covering: what triggered the alert, likely root cause, affected entities, supporting evidence, and recommended next steps. IMPORTANT: Output your final answer DIRECTLY as clean, basic HTML. Use <h2> for section headers, <b> for bold text, <p> for paragraphs, <code> for logs/IDs, and standard <table>/<tr>/<td> tags with simple borders for tabular data. Do NOT use markdown. selectors: - name: agentResponse expression: .response.finalAnswer - name: agentResponseBlocks expression: '(.response.finalAnswer // "") as $r | (if ($r|type)=="string" then ($r | try fromjson catch null) else $r end) as $json | if ($json|type)=="object" and ($json.card.body|type)=="array" then $json.card.body elif ($json|type)=="array" then $json elif ($json|type)=="object" and ($json.text|type)=="string" then [{"type":"Text","value":$json.text}] else [{"type":"Text","value":($r|tostring)}] end' ignoreErrors: true
- name: checkAutopilotResponse type: switch switch: - condition: ${{ (.steps.runAutopilot.outputs.agentResponse // "") != "" }} next: sendRcaEmail next: sendAutopilotError
- name: sendRcaEmail type: action action: newrelic.notification.sendEmail version: 1 inputs: destinationId: ${{ .workflowInputs.emailDestinationId }} subject: Autopilot RCA Report - Issue ${{ .workflowInputs.issueId }} message: '${{ def sanitizeHtml: gsub("(?i)<script\\b[^>]*>[\\s\\S]*?</\\s*script\\s*>"; "") | gsub("(?i)<\\s*script\\b[^>]*/?\\s*>"; "") | gsub("(?i)<style\\b[^>]*>[\\s\\S]*?</\\s*style\\s*>"; "") | gsub("(?i)<\\s*(iframe|object|embed|link|meta|form|svg)\\b[^>]*/?\\s*>"; "") | gsub("(?i)</\\s*(iframe|object|embed|form|svg)\\s*>"; "") | gsub("(?i)\\son\\w+\\s*=\\s*[^\\s>]+"; "") | gsub("(?i)javascript\\s*:"; ""); (.steps.runAutopilot.outputs.agentResponseBlocks // []) as $blocks | [ $blocks[] | if .type == "CodeBlock" then "<pre><code>" + ((.code // "") | gsub("&";"&") | gsub("<";"<") | gsub(">";">")) + "</code></pre>" else ((.value // "") | gsub("\\*\\*";"") | sanitizeHtml) as $clean | [ $clean / "\n" | .[] | select((. | gsub("^\\s+|\\s+$";"")) != "") ] as $lines | (reduce $lines[] as $line ([]; ($line | test("^\\s*\\|?\\s*:?-+:?\\s*(\\|\\s*:?-+:?\\s*)+\\|?\\s*$")) as $isSep | ($line | contains("|")) as $isPipe | if $isSep then . elif $isPipe then if (length > 0 and .[-1].type == "table") then .[0:-1] + [ .[-1] + {rows: (.[-1].rows + [$line])} ] else . + [ {type:"table", rows: [$line]} ] end else . + [ {type:"line", value: $line} ] end )) as $rawSegments | [ $rawSegments[] | if .type == "table" and (.rows | length) < 2 then {type:"line", value: .rows[0]} else . end ] as $segments | [ $segments[] | if .type == "table" then "<table style=\"width:100%;border-collapse:collapse;font-family:Arial,sans-serif;\">" + ([ .rows | to_entries[] | . as {key: $i, value: $row} | ($row | sub("^\\s*\\|";"") | sub("\\|\\s*$";"")) as $trimmed | [ $trimmed / "|" | .[] | gsub("^\\s+|\\s+$";"") ] as $cells | (if $i == 0 then "th" else "td" end) as $tag | (if $i == 0 then "text-align:left;padding:8px;border-bottom:2px solid #ccc;" else "padding:8px;border-bottom:1px solid #eee;" end) as $style | "<tr>" + ([ $cells[] | "<" + $tag + " style=\"" + $style + "\">" + . + "</" + $tag + ">" ] | join("")) + "</tr>" ] | join("")) + "</table>" else .value as $line | ($line | sub("^\\s+";"")) as $t | if ($t | startswith("<")) then $line elif ($line | startswith("### ")) then "<h3>" + ($line | ltrimstr("### ")) + "</h3>" elif ($line | startswith("## ")) then "<h2>" + ($line | ltrimstr("## ")) + "</h2>" elif ($line | startswith("# ")) then "<h2>" + ($line | ltrimstr("# ")) + "</h2>" elif ($line | startswith("- ")) then "<p>• " + ($line | ltrimstr("- ")) + "</p>" else "<p>" + $line + "</p>" end end ] | join("\n") end ] | join("\n") }}' next: end
- name: sendAutopilotError type: action action: newrelic.notification.sendEmail version: 1 inputs: destinationId: ${{ .workflowInputs.emailDestinationId }} subject: Autopilot RCA Failed - Issue ${{ .workflowInputs.issueId }} message: >- Autopilot could not produce findings for issue ${{ .workflowInputs.issueId }}. Please investigate manually. next: endCómo funciona
El paso runAutopilot usa dos selectores para manejar la variabilidad de forma de finalAnswer en la capa de extracción de datos:
agentResponsecaptura el valorfinalAnswersin procesar. El pasocheckAutopilotResponseusa esto para determinar si Autopilot devolvió algo.agentResponseBlocksnormaliza el valor en una matriz de objetos de bloque tipados, y maneja tres posibles formas definalAnswer: una cadena simple, un objeto codificado en JSON con una matriz.card.bodyy una matriz simple. Esto proporciona al pasosendRcaEmailuna estructura coherente sobre la cual iterar, independientemente de cómo Autopilot haya formateado su respuesta.
sendRcaEmail procesa los bloques en línea:
CodeBlocklos elementos se renderizan como<pre><code>con las entidades HTML escapadas.- Otros bloques pasan por
sanitizeHtml, que elimina<script>,<style>, los controladores de eventos en línea y otro marcado potencialmente inseguro. - Las tablas de barras al estilo Markdown se detectan y convierten en elementos
<table>con estilos en línea básicos. - Los prefijos de encabezado (
#,##,###) y los marcadores de viñetas (-) se convierten en las etiquetas HTML correspondientes. - Todas las líneas restantes se envuelven en etiquetas
<p>.
A diferencia de la plantilla RCA de alerta con Autopilot y Slack, el formato HTML se gestiona por completo dentro del paso sendRcaEmail —no se necesita un paso assign independiente.
Temas relacionados
Plantillas de flujo de trabajo de RCA de Autopilot
Requisitos previos compartidos y notas de configuración para todas las plantillas de RCA de Autopilot
Descripción general de Autopilot
Aprenda cómo Autopilot investiga alertas e incidentes
Lógica condicional
Usar declaraciones de cambio para ramificar en caso de éxito o fracaso
Enviar notificaciones por correo electrónico
Referencia completa de la acción sendEmail
Crear destinos
Configure el destino de correo electrónico requerido por este flujo de trabajo
RCA de alerta con Autopilot y Slack
Publicar los hallazgos de RCA en Slack en lugar de por correo electrónico
Solucionar problemas de automatización de flujo de trabajo
Soluciones para problemas comunes de Autopilot y de integración de flujos de trabajo