Skip to content

Commit e4c614a

Browse files
committed
fix(splunk,datadog): stop truncating searches and send mute/unmute as query params
Splunk run_search: revert the `max_count=1000` default added last pass. It was wrong on both halves. Splunk documents the parameter as "the number of events that can be accessible in any given status bucket. Also, in transforming mode, the maximum number of results to store" — so for a non-transforming oneshot it bounds status buckets, not the response, and for a transforming search (`| stats`, `| timechart`, which is what the block's own skills generate) it capped results at 1000 where Splunk would have stored 10000, silently. The block's `maxCount` placeholder already read `10000`, contradicting the code. Send `max_count` only when the caller sets it and restate the description in Splunk's own terms, matching create_search_job. The real guidance — a oneshot buffers the whole result set, so use Create Search Job + Get Search Results for anything large — moves into the tool description and the search-splunk-logs skill. Datadog mute/unmute: send `scope`, `end`, and `all_scopes` as query parameters. `MuteMonitor` and `UnmuteMonitor` declare no `requestBody` in the authoritative spec (docs.datadoghq.com/resources/json/full_spec_v1.json — the generated datadog-api-client-go v1 schema omits both operations and is a subset, not the authority); all three parameters are `in: query`. Sent as a JSON body they are dropped, so a scoped, time-boxed mute becomes an indefinite mute across every scope and unmute's "all scopes" never applies — answered with a 200 and the full monitor object, so nothing surfaces. Datadog list_monitors: imply `page=0` when a page size is set without a page. Datadog "returns all monitors without a `page_size` limit" when `page` is absent, so Page Size was inert from a control that reads as a bound. `page` is not defaulted when neither is set — that would silently truncate a caller relying on the documented return-everything behavior. Also: - Note in get_fired_alerts that `name=-` returns every saved search's fired alerts and the endpoint documents "Request parameters: None", so there is no count/offset to bound it. - Fix the Splunk block's `messages` output blurb: `[{type, text}]` holds for the search and job-control operations, but get_search_job returns an object. - Generalize the Datadog block's numeric coercion (`datadogPageNumber` → `datadogNumber`) over all 32 bare `Number()` mappings, so a typo or unresolved reference is omitted rather than sent as `NaN`/`null`, and an explicit `0` survives the old truthiness guard. - Disclose create_event's documented 18-hour `date_happened` ceiling, and that send_logs' `ddsource: "custom"` is a Sim default rather than a Datadog one.
1 parent 883a2a2 commit e4c614a

16 files changed

Lines changed: 341 additions & 138 deletions

File tree

apps/docs/content/docs/en/integrations/datadog.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Post an event to the Datadog event stream. Use for deployment notifications, ale
9595
| `tags` | string | No | Comma-separated list of tags \(e.g., "env:production,service:api", "team:backend,priority:high"\) |
9696
| `aggregationKey` | string | No | Key to aggregate events together |
9797
| `sourceTypeName` | string | No | Source type name for the event |
98-
| `dateHappened` | number | No | Unix timestamp in seconds when the event occurred \(e.g., 1705320000, defaults to now\) |
98+
| `dateHappened` | number | No | Unix timestamp in seconds when the event occurred \(e.g., 1705320000, defaults to now\). Datadog limits this to events no older than 18 hours. |
9999
| `apiKey` | string | Yes | Datadog API key |
100100
| `site` | string | No | Datadog site/region \(default: datadoghq.com\) |
101101

@@ -197,8 +197,8 @@ List all monitors in Datadog with optional filtering by name, tags, or state.
197197
| `tags` | string | No | Comma-separated list of tags to filter by \(e.g., "env:prod,team:backend"\) |
198198
| `monitorTags` | string | No | Comma-separated list of monitor tags to filter by \(e.g., "service:api,priority:high"\) |
199199
| `withDowntimes` | boolean | No | Include downtime data with monitors |
200-
| `page` | number | No | Page number for pagination \(0-indexed, e.g., 0, 1, 2\) |
201-
| `pageSize` | number | No | Number of monitors per page \(e.g., 50, max: 1000\) |
200+
| `page` | number | No | Page to start paginating from \(0-indexed, e.g., 0, 1, 2\). Datadog returns every monitor in the org without pagination when this is not specified, so set it to bound the response. Setting Page Size alone implies page 0. |
201+
| `pageSize` | number | No | Number of monitors per page \(e.g., 50, max: 1000\). Datadog only applies this when a page is specified — otherwise it returns all monitors with no page size limit — so setting this alone sends page 0. With a page but no page size, Datadog defaults to 100. |
202202
| `apiKey` | string | Yes | Datadog API key |
203203
| `applicationKey` | string | Yes | Datadog Application key |
204204
| `site` | string | No | Datadog site/region \(default: datadoghq.com\) |
@@ -312,7 +312,7 @@ Send log entries to Datadog for centralized logging and analysis.
312312

313313
| Parameter | Type | Required | Description |
314314
| --------- | ---- | -------- | ----------- |
315-
| `logs` | string | Yes | JSON array of log entries. Each entry should have message and optionally ddsource, ddtags, hostname, service. |
315+
| `logs` | string | Yes | JSON array of log entries. Each entry should have message and optionally ddsource, ddtags, hostname, service. Sim fills in ddsource="custom" when an entry omits it — that is a Sim default, not a Datadog one; set ddsource yourself to have Datadog apply the matching integration log pipeline. |
316316
| `apiKey` | string | Yes | Datadog API key |
317317
| `site` | string | No | Datadog site/region \(default: datadoghq.com\) |
318318

apps/docs/content/docs/en/integrations/splunk.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Integrate Splunk Enterprise or Splunk Cloud into workflows. Run SPL searches syn
2020

2121
### Splunk Run Search
2222

23-
Run an SPL search synchronously and return its results in a single call (oneshot mode). Use for short searches; use Create Search Job for long-running ones.
23+
Run an SPL search synchronously and return its results in a single call (oneshot mode). A oneshot search buffers the whole result set in one response with no paging, so use it for short searches; for anything large use Create Search Job with Get Search Results, which defaults to 100 rows and pages with offset.
2424

2525
#### Input
2626

@@ -37,7 +37,7 @@ Run an SPL search synchronously and return its results in a single call (oneshot
3737
| `latestTime` | string | No | Latest \(exclusive\) time bound — relative \(e.g. now\) or absolute time |
3838
| `adhocSearchLevel` | string | No | Search mode: verbose, fast, or smart. Defaults to fast. |
3939
| `autoCancel` | number | No | Cancel the search after this many seconds of inactivity \(e.g. 60\). 0 never auto-cancels. |
40-
| `maxCount` | number | No | Maximum number of results the search stores and returns. Defaults to 1000 here; Splunk itself defaults to 10000, which a oneshot search returns in a single unbounded response. Raise it deliberately. |
40+
| `maxCount` | number | No | Number of events accessible in any given status bucket, and in transforming mode the maximum number of results to store. Defaults to 10000. |
4141

4242
#### Output
4343

@@ -336,7 +336,7 @@ List the unexpired triggered instances of a Splunk alert by saved search name, i
336336
| `password` | string | No | Splunk password, used for basic authentication when no token is supplied |
337337
| `owner` | string | No | Namespace owner for /servicesNS requests \(e.g. admin, or nobody for app-shared objects\). Leave both this and the app empty to use the authenticated user context; set only one and the other becomes the - wildcard. |
338338
| `app` | string | No | Namespace app context for /servicesNS requests \(e.g. search\). Leave both this and the owner empty to use the authenticated user context; set only one and the other becomes the - wildcard. |
339-
| `name` | string | Yes | Name of the alerting saved search \(e.g. Errors in the last 24 hours\). Use - to return the fired alerts of every saved search. |
339+
| `name` | string | Yes | Name of the alerting saved search \(e.g. Errors in the last 24 hours\). Use - to return the fired alerts of every saved search — this endpoint documents "Request parameters: None", so there is no count or offset to bound that with. Name one saved search unless you really want all of them. |
340340

341341
#### Output
342342

apps/sim/blocks/blocks/datadog.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,63 @@ describe('datadog list_monitors params', () => {
103103
expect(subBlock?.condition).toEqual({ field: 'operation', value: 'datadog_list_monitors' })
104104
}
105105
})
106+
107+
/**
108+
* Both controls sit under Advanced with no help text, so Page Size reads as a
109+
* bound while Datadog ignores it unless a page is also sent.
110+
*/
111+
it('tells the user that a page size only applies with a page', () => {
112+
const pageSize = DatadogBlock.subBlocks.find((c) => c.id === 'listMonitorPageSize')
113+
const page = DatadogBlock.subBlocks.find((c) => c.id === 'listMonitorPage')
114+
115+
expect(pageSize?.tooltip).toMatch(/page number/i)
116+
expect(page?.tooltip).toMatch(/every monitor/i)
117+
})
118+
119+
it('states the same rule on the inputs the model reads', () => {
120+
expect(String(DatadogBlock.inputs.listMonitorPageSize.description)).toMatch(/page number/i)
121+
expect(String(DatadogBlock.inputs.listMonitorPage.description)).toMatch(/every monitor/i)
122+
})
123+
})
124+
125+
/**
126+
* A bare `Number()` on a free-text field turns a typo or an unresolved reference
127+
* into `NaN`, which `JSON.stringify` writes as `null` and a query string carries
128+
* as the literal "NaN" — Datadog then rejects the call naming nothing the user
129+
* typed. Every numeric mapping goes through the shared coercion, not just the
130+
* two List Monitors fields.
131+
*/
132+
describe('datadog numeric coercion', () => {
133+
it.each([
134+
['datadog_mute_monitor', { muteMonitorId: '123', end: 'tomorrow' }, 'end'],
135+
['datadog_query_logs', { logLimit: 'lots' }, 'limit'],
136+
['datadog_query_timeseries', { from: 'yesterday', to: 'now' }, 'from'],
137+
['datadog_list_incidents', { incidentPageSize: '{{unresolved}}' }, 'pageSize'],
138+
['datadog_list_slos', { sloLimit: 'many' }, 'limit'],
139+
['datadog_list_dashboards', { dashboardCount: 'n/a' }, 'count'],
140+
['datadog_search_spans', { spanLimit: 'lots' }, 'limit'],
141+
['datadog_list_services', { servicePageSize: 'big' }, 'pageSize'],
142+
['datadog_list_security_rules', { rulePageNumber: 'first' }, 'pageNumber'],
143+
['datadog_list_synthetics_tests', { syntheticsPageSize: 'all' }, 'pageSize'],
144+
])('drops a non-numeric %s input rather than sending NaN', (operation, inputs, key) => {
145+
const params = mergedParams({ ...baseInputs, operation, ...inputs })
146+
147+
expect(params[key]).toBeUndefined()
148+
})
149+
150+
/**
151+
* An explicit 0 is a real offset/page/threshold. A `<Block.output>` reference
152+
* resolves to the number `0`, which the old truthiness guard dropped outright.
153+
*/
154+
it.each([
155+
['datadog_list_downtimes', { downtimeOffset: 0 }, 'offset'],
156+
['datadog_list_slos', { sloOffset: 0 }, 'offset'],
157+
['datadog_list_dashboards', { dashboardStart: 0 }, 'start'],
158+
])('keeps an explicit zero on %s', (operation, inputs, key) => {
159+
const params = mergedParams({ ...baseInputs, operation, ...inputs })
160+
161+
expect(params[key]).toBe(0)
162+
})
106163
})
107164

108165
describe('datadog create_monitor params', () => {

0 commit comments

Comments
 (0)