import { asStringArray, clean, datadogRequest, positiveInt } from './core.ts'
import type { DatadogLogsInput } from './types.ts'
function summarizeLog(item: any) {
const attributes = item?.attributes ?? item ?? {}
const extra = attributes.attributes ?? {}
return {
id: item?.id ?? null,
timestamp: attributes.timestamp ?? extra.timestamp ?? null,
message: attributes.message ?? extra.message ?? null,
status: attributes.status ?? extra.status ?? null,
service: attributes.service ?? extra.service ?? null,
host: attributes.host ?? extra.host ?? null,
tags: Array.isArray(attributes.tags) ? attributes.tags : [],
}
}
/**
* Search logs. POST /api/v2/logs/events/search
*
* Pass a Logs Explorer query, plus `from` / `to` (ISO-8601 or `now-15m`).
* Read-only — never writes logs.
*
* @example
* import { searchLogs } from 'kody:@kody/datadog/logs'
* const result = await searchLogs({ query: 'status:error', from: 'now-15m', to: 'now' })
*/
export async function searchLogs(params: DatadogLogsInput = {}) {
const query = clean(params.query) || '*'
const from = clean(params.from) || 'now-15m'
const to = clean(params.to) || 'now'
const indexes = asStringArray(params.indexes)
const filter: Record<string, unknown> = { query, from, to }
if (indexes.length) filter.indexes = indexes
if (clean(params.storageTier)) filter.storage_tier = clean(params.storageTier)
const body: Record<string, unknown> = {
filter,
sort: clean(params.sort) || '-timestamp',
page: {
limit: positiveInt(params.limit, 10, 1000),
},
}
if (clean(params.cursor)) (body.page as Record<string, unknown>).cursor = clean(params.cursor)
const response = await datadogRequest('/api/v2/logs/events/search', {
...params,
method: 'POST',
body,
label: 'Datadog logs search',
})
const events = Array.isArray(response?.data) ? response.data : []
return {
count: events.length,
query,
from,
to,
logs: events.map(summarizeLog),
nextCursor: response?.meta?.page?.after ?? null,
}
}
export default searchLogs