@@ -15,6 +15,7 @@ import { getTaskIdentifiers } from "~/models/task.server";
1515import { ServiceValidationError } from "~/v3/services/baseService.server" ;
1616import { kindToLevel , type LogLevel , LogLevelSchema } from "~/utils/logUtils" ;
1717import { BasePresenter } from "~/presenters/v3/basePresenter.server" ;
18+ import { env } from "~/env.server" ;
1819import {
1920 convertDateToClickhouseDateTime ,
2021 convertClickhouseDateTime64ToJsDate ,
@@ -70,17 +71,6 @@ export const LogsListOptionsSchema = z.object({
7071 pageSize : z . number ( ) . int ( ) . positive ( ) . max ( 1000 ) . optional ( ) ,
7172} ) ;
7273
73- const DEFAULT_PAGE_SIZE = 50 ;
74-
75- // The list projection is wide (full attributes_text per row), so cap the effective page size
76- // well below the schema max of 1000 to keep per-page memory and payload bounded.
77- const MAX_PAGE_SIZE = 100 ;
78-
79- // Recent-first window stepping: probe the most recent windows before widening to the full
80- // requested range, so a dense env fills a page from a few recent parts instead of scanning
81- // the whole window. Days back from the page ceiling; the full requested window is always the
82- // final probe.
83- const PROBE_STEP_DAYS = [ 1 , 7 ] ;
8474const DAY_MS = 24 * 60 * 60 * 1000 ;
8575
8676export type LogsList = Awaited < ReturnType < LogsListPresenter [ "call" ] > > ;
@@ -132,10 +122,14 @@ function decodeCursor(cursor: string): LogCursor | null {
132122// requested floor (or undefined for an unbounded-below window). Because rows are returned
133123// newest-first, a narrow window that already fills a page returns the exact same top rows the
134124// full window would, so widening only happens when a page comes back short.
135- function buildProbeFloors ( ceil : Date , hardFloor : Date | undefined ) : ( Date | undefined ) [ ] {
125+ function buildProbeFloors (
126+ ceil : Date ,
127+ hardFloor : Date | undefined ,
128+ stepDays : number [ ]
129+ ) : ( Date | undefined ) [ ] {
136130 const floors : ( Date | undefined ) [ ] = [ ] ;
137131
138- for ( const days of PROBE_STEP_DAYS ) {
132+ for ( const days of stepDays ) {
139133 let candidate = new Date ( ceil . getTime ( ) - days * DAY_MS ) ;
140134 if ( hardFloor && candidate <= hardFloor ) {
141135 candidate = hardFloor ;
@@ -190,7 +184,7 @@ export class LogsListPresenter extends BasePresenter {
190184 from,
191185 to,
192186 cursor,
193- pageSize = DEFAULT_PAGE_SIZE ,
187+ pageSize = env . LOGS_LIST_DEFAULT_PAGE_SIZE ,
194188 defaultPeriod,
195189 retentionLimitDays,
196190 } : LogsListOptions
@@ -268,7 +262,7 @@ export class LogsListPresenter extends BasePresenter {
268262 ) ;
269263 }
270264
271- const effectivePageSize = Math . min ( pageSize , MAX_PAGE_SIZE ) ;
265+ const effectivePageSize = Math . min ( pageSize , env . LOGS_LIST_MAX_PAGE_SIZE ) ;
272266
273267 // Only honor a cursor scoped to this org+env; one copied from another scope would shift the
274268 // pagination anchor instead of resetting to the first page.
@@ -387,7 +381,11 @@ export class LogsListPresenter extends BasePresenter {
387381 ? convertClickhouseDateTime64ToJsDate ( decodedCursor . triggeredTimestamp )
388382 : clampedTo ?? new Date ( ) ;
389383
390- const probeFloors = buildProbeFloors ( ceil , effectiveFrom ?? undefined ) ;
384+ const probeFloors = buildProbeFloors (
385+ ceil ,
386+ effectiveFrom ?? undefined ,
387+ env . LOGS_LIST_RECENT_FIRST_PROBE_DAYS
388+ ) ;
391389
392390 let records : LogsSearchListResult [ ] = [ ] ;
393391 for ( const floor of probeFloors ) {
0 commit comments