import { asStringArray, clean, datadogRequest, mutationPreview, positiveInt } from './core.ts'
import type { DatadogMonitorInput } from './types.ts'
function monitorId(params: DatadogMonitorInput): string {
const id = clean(params.monitorId ?? params.id)
if (!id) throw new Error('monitorId is required.')
return id
}
function summarizeMonitor(monitor: any) {
return {
id: monitor?.id ?? null,
name: monitor?.name ?? null,
type: monitor?.type ?? null,
overallState: monitor?.overall_state ?? monitor?.overallState ?? null,
query: monitor?.query ?? null,
tags: Array.isArray(monitor?.tags) ? monitor.tags : [],
priority: monitor?.priority ?? null,
created: monitor?.created ?? null,
modified: monitor?.modified ?? null,
creator: monitor?.creator?.handle ?? monitor?.creator?.email ?? null,
}
}
function monitorBody(params: DatadogMonitorInput): Record<string, unknown> {
if (params.body && typeof params.body === 'object') return params.body
const body: Record<string, unknown> = {}
if (clean(params.type)) body.type = clean(params.type)
if (clean(params.query)) body.query = clean(params.query)
if (clean(params.name)) body.name = clean(params.name)
if (clean(params.message)) body.message = clean(params.message)
const tags = asStringArray(params.tags)
if (tags.length) body.tags = tags
if (params.options && typeof params.options === 'object') body.options = params.options
if (params.priority != null) body.priority = params.priority
if (Array.isArray(params.restrictedRoles)) body.restricted_roles = params.restrictedRoles
if (clean(params.draftStatus)) body.draft_status = clean(params.draftStatus)
return body
}
/** List monitors. GET /api/v1/monitor */
export async function listMonitors(params: DatadogMonitorInput = {}) {
const query: Record<string, unknown> = {}
if (clean(params.name)) query.name = clean(params.name)
const tags = asStringArray(params.tags)
if (tags.length) query.tags = tags.join(',')
const monitorTags = asStringArray(params.monitorTags)
if (monitorTags.length) query.monitor_tags = monitorTags.join(',')
const groupStates = asStringArray(params.groupStates)
if (groupStates.length) query.group_states = groupStates.join(',')
if (params.withDowntimes === true) query.with_downtimes = true
if (params.page != null) query.page = positiveInt(params.page, 0, 10_000)
if (params.pageSize != null || params.perPage != null) {
query.page_size = positiveInt(params.pageSize ?? params.perPage, 30, 1000)
}
const body = await datadogRequest('/api/v1/monitor', { ...params, query })
const monitors = Array.isArray(body) ? body : Array.isArray(body?.monitors) ? body.monitors : []
return {
count: monitors.length,
monitors: monitors.map(summarizeMonitor),
}
}
/** Get one monitor. GET /api/v1/monitor/{monitor_id} */
export async function getMonitor(params: DatadogMonitorInput = {}) {
const id = monitorId(params)
const monitor = await datadogRequest('/api/v1/monitor/' + encodeURIComponent(id), params)
return { monitor: summarizeMonitor(monitor), raw: monitor }
}
/** Search monitors. GET /api/v1/monitor/search */
export async function searchMonitors(params: DatadogMonitorInput = {}) {
const query: Record<string, unknown> = {}
if (clean(params.query)) query.query = clean(params.query)
if (params.page != null) query.page = positiveInt(params.page, 0, 10_000)
if (params.perPage != null || params.pageSize != null) {
query.per_page = positiveInt(params.perPage ?? params.pageSize, 30, 200)
}
const body = await datadogRequest('/api/v1/monitor/search', { ...params, query })
const monitors = Array.isArray(body?.monitors) ? body.monitors : []
return {
count: monitors.length,
total: body?.metadata?.total_count ?? body?.metadata?.total ?? monitors.length,
monitors: monitors.map((item: any) => summarizeMonitor(item)),
counts: body?.counts ?? null,
}
}
/** Create a monitor. Requires confirm. Pass dryRun: true to preview. */
export async function createMonitor(params: DatadogMonitorInput = {}) {
const body = monitorBody(params)
if (!clean(body.type) || !clean(body.query)) {
throw new Error('Creating a monitor requires type and query (or a full body).')
}
const preview = mutationPreview(params, {
action: 'create monitor ' + (clean(body.name) || clean(body.query)),
method: 'POST',
path: '/api/v1/monitor',
body,
})
if (preview) return preview
const created = await datadogRequest('/api/v1/monitor', { ...params, method: 'POST', body })
return { ok: true, action: 'create', monitor: summarizeMonitor(created), raw: created }
}
/** Update a monitor. Requires confirm. Pass dryRun: true to preview. */
export async function updateMonitor(params: DatadogMonitorInput = {}) {
const id = monitorId(params)
const body = monitorBody(params)
const preview = mutationPreview(params, {
action: 'update monitor ' + id,
method: 'PUT',
path: '/api/v1/monitor/' + encodeURIComponent(id),
body,
})
if (preview) return preview
const updated = await datadogRequest('/api/v1/monitor/' + encodeURIComponent(id), {
...params,
method: 'PUT',
body,
})
return { ok: true, action: 'update', monitor: summarizeMonitor(updated), raw: updated }
}
/** Delete a monitor. Requires confirm. Pass dryRun: true to preview. */
export async function deleteMonitor(params: DatadogMonitorInput = {}) {
const id = monitorId(params)
const preview = mutationPreview(params, {
action: 'delete monitor ' + id,
method: 'DELETE',
path: '/api/v1/monitor/' + encodeURIComponent(id),
})
if (preview) return preview
const deleted = await datadogRequest('/api/v1/monitor/' + encodeURIComponent(id), {
...params,
method: 'DELETE',
})
return { ok: true, action: 'delete', monitorId: id, raw: deleted }
}
/** Mute a monitor. Requires confirm. Pass dryRun: true to preview. */
export async function muteMonitor(params: DatadogMonitorInput = {}) {
const id = monitorId(params)
const body: Record<string, unknown> = {}
if (clean(params.scope)) body.scope = clean(params.scope)
if (params.end != null) body.end = params.end
const preview = mutationPreview(params, {
action: 'mute monitor ' + id,
method: 'POST',
path: '/api/v1/monitor/' + encodeURIComponent(id) + '/mute',
body: Object.keys(body).length ? body : undefined,
})
if (preview) return preview
const muted = await datadogRequest('/api/v1/monitor/' + encodeURIComponent(id) + '/mute', {
...params,
method: 'POST',
body: Object.keys(body).length ? body : undefined,
})
return { ok: true, action: 'mute', monitor: summarizeMonitor(muted), raw: muted }
}
/** Unmute a monitor. Requires confirm. Pass dryRun: true to preview. */
export async function unmuteMonitor(params: DatadogMonitorInput = {}) {
const id = monitorId(params)
const body: Record<string, unknown> = {}
if (clean(params.scope)) body.scope = clean(params.scope)
if (params.allScopes === true) body.all_scopes = true
const preview = mutationPreview(params, {
action: 'unmute monitor ' + id,
method: 'POST',
path: '/api/v1/monitor/' + encodeURIComponent(id) + '/unmute',
body: Object.keys(body).length ? body : undefined,
})
if (preview) return preview
const unmuted = await datadogRequest('/api/v1/monitor/' + encodeURIComponent(id) + '/unmute', {
...params,
method: 'POST',
body: Object.keys(body).length ? body : undefined,
})
return { ok: true, action: 'unmute', monitor: summarizeMonitor(unmuted), raw: unmuted }
}
/**
* List, search, or get Datadog monitors. Mutations live on named exports.
* @example
* import { listMonitors } from 'kody:@kody/datadog/monitors'
* const result = await listMonitors({ pageSize: 20 })
*/
export default async function monitors(params: DatadogMonitorInput = {}) {
if (params.monitorId || params.id) return await getMonitor(params)
if (clean(params.query)) return await searchMonitors(params)
return await listMonitors(params)
}