Fix search API bugs: timeZone defaulting, epoch time format, aggregate results, and circuit breaker semantics#2
Open
akeyx wants to merge 7 commits into
Open
Conversation
When search_logs is called without a time_zone, the SearchRequest model sets time_zone=None. This None value gets passed into search_params as timeZone=None. The validator then tries to type-check None as a string, which raises an APIParameterError. The fix skips None values during validation so they are treated as "not provided", allowing the default value (UTC) to be applied in the subsequent defaults loop. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Sumo Logic search jobs API (/api/v1/search/jobs) requires time values as epoch milliseconds, not ISO 8601 strings. Sending ISO format results in: "The 'from' field contains an invalid time." This changes to_sumo_api_format and to_sumo_time_format to output epoch milliseconds, and adds epoch time pattern validation to the API validator so it accepts the format it now produces. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The search results endpoint always fetched /messages, which fails for aggregate queries (count by, sum by, etc.) with "requireRawMessages is false". Aggregate query results are served from /records instead. This changes get_search_results to try /records first, then fall back to /messages. Both endpoints are handled gracefully when empty, so queries that match nothing return an empty result set instead of raising an error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The tool layer passes filter_type to the API client, but the client method didn't accept it. Add the parameter and filter client-side since the Sumo Logic API doesn't support it as a query param. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Sumo Logic Collector API does not support filter_type as a query parameter. Remove it from the tool schema, tool method, and API client rather than faking it with client-side filtering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two changes to the sumologic-api circuit breaker: 1. resilience.py: reset failure_count to 0 on a success in CLOSED state. Previously failure_count was monotonic in CLOSED state, so any process accumulating ~5 transient errors over its lifetime was guaranteed to trip the breaker eventually — "5 ever" rather than "5 consecutive." That's the wrong semantics for an MCP server doing dozens of small queries per session. 2. api_client.py: narrow expected_exception from bare Exception to the same transient set the retry layer already uses (APIError, RateLimitError, TimeoutError, ConnectionError, OSError, httpx.RequestError). User errors like 4xx-from-bad-query no longer count toward opening the breaker. Updated CircuitBreakerConfig.expected_exception's type annotation to reflect that a tuple is supported (Python's except clause accepts either form at runtime). Validated with three async test cases: - failure_count resets on success in CLOSED state - non-transient exceptions are propagated but don't count - 3 consecutive transient errors still open the breaker (intended behavior preserved) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR upstreams the fixes from @nicolagi's
fix/search-api-bugsbranch, which make the search tooling (search_logs/execute_query) actually work against the Sumo Logic Search Job API. All commits are authored by @nicolagi; I'm opening the PR (from a fork of their branch) to get the work upstreamed since the commits are unchanged.Without these fixes,
search_logsfails out of the box, so this restores core functionality of the server.Changes
Fix
timeZonedefault not applied when value isNone(900096c)When
search_logsis called without atime_zone,SearchRequestsets it toNone, which then reaches the validator and raisesAPIParameterError(it type-checksNoneas a string). The validator now skipsNoneparams so the existing defaults loop appliesUTC.Fix time format: use epoch milliseconds for the search jobs API (
5f66f3d)/api/v1/search/jobsrejects ISO 8601 strings with "The 'from' field contains an invalid time."to_sumo_api_format/to_sumo_time_formatnow emit epoch milliseconds, and the API validator accepts the epoch pattern it now produces.Fix result retrieval for aggregate queries and empty results (
fab2a72)Results were always fetched from
/messages, which fails for aggregate queries (count by,sum by, …) with "requireRawMessages is false".get_search_resultsnow tries/recordsfirst and falls back to/messages, and handles empty results gracefully instead of raising.Remove unsupported
filter_typefromlist_collectors(afe78fd)The Collector API doesn't support
filter_typeas a query param; removed from the tool schema, tool method, and API client.Stop circuit breaker tripping on benign batches of work (
8945b35)Reset
failure_counton success in theCLOSEDstate (previously monotonic → "5 ever" rather than "5 consecutive"), and narrowexpected_exceptionto the transient set the retry layer already uses so user errors (e.g. bad-query 4xx) don't count toward opening the breaker.Test plan
search_logswith notime_zonesucceeds (defaults to UTC) instead of raisingAPIParameterError... | count by foo) returns records instead of failing withrequireRawMessages is falselist_collectorsworks without the removedfilter_typeparamCredit: all changes authored by @nicolagi on
nicolagi:fix/search-api-bugs.