diff --git a/README.md b/README.md index 48d13b1..adc9dd4 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ it's just targetting Deno as a runtime (Typescript, URL imports, fetch, etc). * For a full example of metrics submission, see `examples/emit-metrics.ts` * `v1Monitors`: get by id, get all, search by query * `v1ServiceChecks`: submit 'check run' statuses to Datadog +* `v1Events`: submit events to Datadog * `v1UsageMetering`: get billable summary, get top custom metrics * `v2Roles`: list and describe roles & permissions * `v2Users`: list, search, and describe datadog users diff --git a/mod.ts b/mod.ts index 5059db6..b03c839 100644 --- a/mod.ts +++ b/mod.ts @@ -5,6 +5,7 @@ import v1MonitorsApi from "./v1/monitors.ts"; import v1ServiceChecksApi from "./v1/service_checks.ts"; export {CheckStatus} from './v1/service_checks.ts'; import v1UsageMeteringApi from "./v1/usage_metering.ts"; +import v1EventsApi from "./v1/events.ts"; import v2RolesApi from "./v2/roles.ts"; import v2UsersApi from "./v2/users.ts"; @@ -66,6 +67,15 @@ export default class DatadogApi extends ApiClient { return new v1ServiceChecksApi(this); } + /** + * The events API allows you to post events to Datadog. + * Event titles are limited to 100 characters. + * Event text are limited to 4000 characters. + */ + get v1Events(): v1EventsApi { + return new v1EventsApi(this); + } + /** * The usage metering API allows you to get hourly, daily, and monthly usage * across multiple facets of Datadog. diff --git a/v1/events.ts b/v1/events.ts new file mode 100644 index 0000000..fd4cc89 --- /dev/null +++ b/v1/events.ts @@ -0,0 +1,66 @@ +type TODO = unknown; + +// Common API client contract +interface ApiClient { + fetchJson(opts: { + method: "GET" | "POST"; + path: string; + query?: URLSearchParams; + body?: unknown; + }): Promise; +} + +export default class DatadogEventsApi { + #api: ApiClient; + constructor(api: ApiClient) { + this.#api = api; + } + + async submit(data: Event): Promise { + const json = await this.#api.fetchJson({ + path: `/api/v1/events`, + method: "POST", + body: { + text: data.text, + title: data.title, + aggregation_key: data.aggregation_key, + alert_type: data.alert_type, + date_happened: data.date_happened + ? Math.floor(data.date_happened.valueOf() / 1000) + : undefined, + device_name: data.device_name, + host: data.host, + priority: data.priority, + related_event_id: data.related_event_id, + source_type_name: data.source_type_name, + tags: data.tags ?? [], + }, + }); + return (json as { status: string }).status; + } +} + +export interface Event { + /** max length: 4000 **/ + text: string; + /** max length: 100 **/ + title: string; + aggregation_key?: string; + alert_type?: AlertType; + date_happened?: Date; + device_name?: string; + host?: string; + priority?: "normal" | "low"; + related_event_id?: number; + source_type_name?: string; + tags?: Array; +} + +export type AlertType = + | "error" + | "warning" + | "info" + | "success" + | "user_update" + | "recommendation" + | "snapshot";