Skip to content

Commit

Permalink
feat: email log alerts
Browse files Browse the repository at this point in the history
  • Loading branch information
mvayngrib committed Jul 26, 2018
1 parent 4b493f1 commit ef18b6d
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ export const topics = {
create: new EventTopic('user:create'),
online: new EventTopic('user:online'),
offline: new EventTopic('user:offline'),
},
logging: {
logs: new EventTopic('logs:logs'),
alert: new EventTopic('logs:alert'),
}
}

Expand Down
15 changes: 13 additions & 2 deletions src/in-house-bot/lambda/log-alert-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
LogProcessor,
parseLogAlertsTopicArn,
fromLambda,
sendLogAlert,
} from '../log-processor'

const lambda = fromSNS({ event: LOG_ALERTS })
Expand All @@ -13,11 +14,21 @@ let processor: LogProcessor
lambda.use(async (ctx) => {
const { event, components } = ctx
if (!processor) {
const conf = components.conf.bot.logging
processor = fromLambda({ lambda, components })
bot.hookSimple('logs:alerts', processor.handleAlertEvent)
bot.hook(bot.events.topics.logging.alert, async (ctx, next) => {
const alert = ctx.event = await processor.handleAlertEvent(ctx.event)
if (conf) {
await sendLogAlert({ bot, conf, alert })
} else {
logger.debug('logging conf not present, not emailing anyone')
}

await next()
})
}

await bot.fire('logs:alerts', event)
await bot.fire(bot.events.topics.logging.alert, event)
})

export const handler = lambda.handler
6 changes: 4 additions & 2 deletions src/in-house-bot/lambda/log-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ lambda.use(async (ctx) => {
const { event, components } = ctx
if (!processor) {
processor = fromLambda({ lambda, components })
bot.hookSimple('logs', processor.handleLogEvent)
bot.hook(bot.events.topics.logging.logs, async (ctx, next) => {
ctx.event = await processor.handleLogEvent(ctx.event)
})
}

await bot.fire('logs', event)
await bot.fire(bot.events.topics.logging.logs, event)
})

export const handler = lambda.handler
33 changes: 32 additions & 1 deletion src/in-house-bot/log-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { TRADLE } from './constants'
import { sha256 } from '../crypto'
import {
Env,
Bot,
IPBLambda,
SNSEvent,
SNSEventRecord,
Expand All @@ -17,6 +18,7 @@ import {
IKeyValueStore,
Logger,
IBotComponents,
ILoggingConf,
} from './types'

import { Level, noopLogger } from '../logger'
Expand Down Expand Up @@ -232,7 +234,8 @@ export class LogProcessor {
const filename = getLogEventKey(event)
const key = `${filename}.${this.ext}`
this.logger.debug(`saving ${entries.length} entries to ${key}`)
await this.store.put(key, { ...event, entries })
const formatted = { ...event, entries }
await this.store.put(key, formatted)
}

public handleAlertEvent = async (event: SNSEvent) => {
Expand All @@ -246,6 +249,7 @@ export class LogProcessor {
}

await this.saveAlertEvent(parsed)
return parsed
}

public saveAlertEvent = async (event: ParsedAlertEvent) => {
Expand Down Expand Up @@ -479,3 +483,30 @@ export const getAlertEventKey = (event: ParsedAlertEvent) => {

// export const getLogsFolder = (env: Env) => `$logs/{env.STAGE}`
// export const getAlertsFolder = (env: Env) => `alerts/${env.STAGE}`

export const sendLogAlert = async ({ bot, conf, alert }: {
bot: Bot
conf: ILoggingConf
alert: ParsedAlertEvent
}) => {
const { senderEmail, destinationEmails } = conf
const body = JSON.stringify(alert, null, 2)
await bot.mailer.send({
subject: 'logging alert',
from: senderEmail,
to: destinationEmails,
body,
format: 'text',
})
}

export const validateConf = async ({ bot, conf }: {
bot: Bot
conf: ILoggingConf
}) => {
const { senderEmail, destinationEmails } = conf
const resp = await bot.mailer.canSendFrom(senderEmail)
if (!resp.result) {
throw new Errors.InvalidInput(resp.reason)
}
}
6 changes: 6 additions & 0 deletions src/in-house-bot/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,18 @@ export interface KVMap {
[key: string]: any
}

export interface ILoggingConf {
senderEmail: string
destinationEmails: string[]
}

export interface IBotConf {
products: IProductsConf
tours?: ITours
sandbox?: boolean
graphqlAuth?: boolean
credentials?: KVMap
logging?: ILoggingConf
// exposed directly in /info
// publicConfig: any
}
Expand Down

0 comments on commit ef18b6d

Please sign in to comment.