Skip to content

Commit

Permalink
Send peril logs to slack
Browse files Browse the repository at this point in the history
  • Loading branch information
orta committed Aug 26, 2018
1 parent 7548c7d commit 2d05ee0
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 10 deletions.
4 changes: 4 additions & 0 deletions source/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ export const sendMessageToConnectionsWithAccessToInstallation = (iID: number, me
})
}

/**
* This is a lazy loaded version of the above, the callback func will only get called
* if there is a connected websocket.
*/
export const sendAsyncMessageToConnectionsWithAccessToInstallation = (
iID: number,
callback: (spark: any) => Promise<any>
Expand Down
33 changes: 26 additions & 7 deletions source/api/graphql/mutations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getDB } from "../../../db/getDB"
import { MongoDB } from "../../../db/mongo"

import { GitHubInstallation } from "../../../db"
import { sendLogsToSlackForInstallation } from "../../../infrastructure/installationSlackMessaging"
import logger from "../../../logger"
import {
getRecordedWebhook,
Expand Down Expand Up @@ -191,25 +192,43 @@ export const mutations = {
// TODO: Store the time in some kind of per-installation analytics document

// Wait 2 seconds for the container to finish
setTimeout(() => {
setTimeout(async () => {
let dangerfileLog: MSGDangerfileLog | undefined

// Get Hyper logs
// Send another message
sendAsyncMessageToConnectionsWithAccessToInstallation(installation.iID, async spark => {
// TODO: Cache the hyper call, because the logs will disappear after the first
// connected client gets access to them.
const getLogs = async () => {
let logs = null
try {
logs = await getHyperLogs(opts.hyperCallID)
} catch (error) {
logger.error(`Requesting the hyper logs for ${installation.iID} with callID ${opts.hyperCallID} - ${error}`)
return
}
const logMessage: MSGDangerfileLog = {
event: opts.name,
action: "log",
filenames: opts.dangerfiles,
log: logs,
log: logs as string,
}
return logMessage
}

// If you have a connected slack webhook, then always grab the logs
// and store the value somewhere where the websocket to admin connections
// can also read.
if (installation.installationSlackUpdateWebhookURL) {
dangerfileLog = await getLogs()
sendLogsToSlackForInstallation("Received logs from Peril", dangerfileLog!, installation)
}

// Callback inside is lazy loaded and only called if there are people
// in the dashboard
sendAsyncMessageToConnectionsWithAccessToInstallation(installation.iID, async spark => {
// If the slack trigger above didn't grab the logs, then re-grab them.
if (!dangerfileLog) {
dangerfileLog = await getLogs()
}
spark.write(logMessage)
spark.write(dangerfileLog)
})
}, 2000)

Expand Down
35 changes: 33 additions & 2 deletions source/infrastructure/installationSlackMessaging.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { IncomingWebhook } from "@slack/client"
import { sentence } from "danger/distribution/runner/DangerUtils"
import { MSGDangerfileLog } from "../api/api"
import { GitHubInstallation } from "../db"
import { getDB } from "../db/getDB"
import { MongoDB } from "../db/mongo"
Expand All @@ -14,8 +16,7 @@ export const replaceAllKeysInString = (obj: any, message: string) => {
let mutableMessage = message
const keys = Object.keys(obj)
keys.forEach(key => {
const re = new RegExp(obj[key], "g")
mutableMessage = mutableMessage.replace(re, `[${key}]`)
mutableMessage = mutableMessage.split(obj[key]).join(`[${key}]`)
})

return mutableMessage
Expand Down Expand Up @@ -53,3 +54,33 @@ export const sendSlackMessageToInstallation = async (message: string, installati
}
}
}

export const sendLogsToSlackForInstallation = async (
message: string,
logs: MSGDangerfileLog,
installation: GitHubInstallation
) => {
if (installation.installationSlackUpdateWebhookURL) {
let filteredLogs = replaceAllKeysInString(globals, logs.log)
filteredLogs = replaceAllKeysInString(installation.envVars, filteredLogs)

// Doesn't matter if it fails, so long as it's logged. Shouldn't take down the server.
try {
const webhook = new IncomingWebhook(installation.installationSlackUpdateWebhookURL)

await webhook.send({
unfurl_links: false,
username: `Peril for ${installation.login}`,
text: message,
attachments: [
{
title: `${logs.event}.${logs.action} - ${sentence(logs.filenames)}`,
text: `\`\`\`\n${filteredLogs}\n\`\`\``,
},
],
})
} catch (error) {
logger.error(`Sending a slack logs failed for ${installation.login}`)
}
}
}
2 changes: 1 addition & 1 deletion source/peril.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const peril = () => {

// Error logging
process.on("unhandledRejection", (reason: string, _: any) => {
logger.error("Error: ", reason)
logger.error("UnhandledRejection Error: ", reason)
throw reason
})

Expand Down

0 comments on commit 2d05ee0

Please sign in to comment.