Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/supernova/src/hooks/useAlertmanagerAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const createWorker = (path) => {
// create workers
const alertsWorker = createWorker("workers/alerts.js")
const silencesWorker = createWorker("workers/silences.js")
const alertsAndsilencesWorker = createWorker("workers/alertsAndSilences.js")

const useAlertmanagerAPI = (apiEndpoint) => {
const {
Expand All @@ -49,6 +50,10 @@ const useAlertmanagerAPI = (apiEndpoint) => {
useEffect(() => {
let cleanupAlertsWorker
let cleanupSilencesWorker
let cleanupAlertsAndSilencesWorker

alertsAndsilencesWorker.then(({ createWorker, stopWorker }) => {


alertsWorker.then(({ createWorker, stopWorker }) => {
const worker = createWorker()
Expand Down
83 changes: 83 additions & 0 deletions apps/supernova/src/workers/alertsAndSilences.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import ApiService from "../api/apiService"
import { get } from "../api/client"
import { sortAlerts, countAlerts } from "../lib/utils"

/**
* @param {string} endpoint
* @param {object} options
* @returns {function} fetch function
*/
const fetchAction = (endpoint, options = {}) => {
return new Promise((resolve, reject) => {
Promise.all([
// get alerts
get(`${endpoint}/alerts`, { params: options?.params }).then((items) => {
// sort alerts
let alerts = sortAlerts(items)

// copy additional filter options to labels for easier filter selection
// because the alert object is nested this makes it a lot easier to filter, since we only use what is present in alert.labels
alerts.forEach((alert) => {
if (alert.labels) {
alert.labels.status = alert.status?.state
}
})

// count alerts
const counts = countAlerts(alerts)

// resolve promise
resolve({ alerts, counts })
}),
// get silences
get(`${endpoint}/silences`, {}).then((items) => {
// convert items to hash to easear access
const itemsHash = items.reduce((itemsHash, silence) => {
itemsHash[silence.id] = silence
return itemsHash
}, {})

// split items by state (active, pending and expired)
// https://github.com/prometheus/alertmanager/blob/main/types/types.go#L434
const itemsByState = sortSilencesByState(items)

resolve({
silences: items,
silencesHash: itemsHash,
silencesByState: itemsByState,
})
}),
]).then((data) => {
console.log("alertsAndSilencesService::fetchAction: data", data)
})
})
}

const alertsAndSilencesService = new ApiService({
serviceName: "alerts&Silences",
debug: true,
onFetchStart: () => self.postMessage({ action: "ALERTS_FETCH_START" }),
onFetchEnd: () => self.postMessage({ action: "ALERTS_FETCH_END" }),
})

self.onmessage = (e) => {
const action = e.data.action

switch (action) {
case "ALERTS&SILENCES_CONFIGURE":
// require at least apiEndpoint to update the fetch method
if (e.data?.fetchVars?.apiEndpoint) {
// update the fetch function
e.data["fetchFn"] = () =>
fetchAction(
e.data?.fetchVars.apiEndpoint,
e.data?.fetchVars.options || {}
)
}
alertsService.configure(e.data)
break
case "ALERTS&SILENCES_FETCH":
alertService.fetch()
break
}
}