@@ -177,6 +177,34 @@ func opsInsertErrorLogArgs(input *service.OpsInsertErrorLogInput) []any {
177177 }
178178}
179179
180+ // opsErrorLogsOrderBy builds the ORDER BY clause from a whitelist, mirroring
181+ // usageLogOrderBy semantics. Unknown SortBy falls back to created_at; e.id is
182+ // always appended as tiebreaker for stable pagination.
183+ func opsErrorLogsOrderBy (filter * service.OpsErrorLogFilter ) string {
184+ sortBy := ""
185+ sortOrder := ""
186+ if filter != nil {
187+ sortBy = strings .ToLower (strings .TrimSpace (filter .SortBy ))
188+ sortOrder = strings .ToLower (strings .TrimSpace (filter .SortOrder ))
189+ }
190+
191+ var column string
192+ switch sortBy {
193+ case "model" :
194+ column = "COALESCE(NULLIF(TRIM(e.requested_model), ''), e.model)"
195+ case "status_code" :
196+ column = "e.status_code"
197+ default :
198+ column = "e.created_at"
199+ }
200+
201+ dir := "DESC"
202+ if sortOrder == "asc" {
203+ dir = "ASC"
204+ }
205+ return fmt .Sprintf ("%s %s, e.id %s" , column , dir , dir )
206+ }
207+
180208func (r * opsRepository ) ListErrorLogs (ctx context.Context , filter * service.OpsErrorLogFilter ) (* service.OpsErrorLogList , error ) {
181209 if r == nil || r .db == nil {
182210 return nil , fmt .Errorf ("nil ops repository" )
@@ -233,13 +261,14 @@ SELECT
233261 COALESCE(a.name, ''),
234262 e.group_id,
235263 COALESCE(g.name, ''),
236- CASE WHEN e.client_ip IS NULL THEN NULL ELSE e.client_ip::text END,
264+ CASE WHEN e.client_ip IS NULL THEN NULL ELSE host( e.client_ip) END,
237265 COALESCE(e.request_path, ''),
238266 e.stream,
239267 COALESCE(e.inbound_endpoint, ''),
240268 COALESCE(e.upstream_endpoint, ''),
241269 COALESCE(e.requested_model, ''),
242270 COALESCE(e.upstream_model, ''),
271+ COALESCE(e.user_agent, ''),
243272 e.request_type,
244273 COALESCE(ak.name, ''),
245274 ak.deleted_at,
@@ -251,7 +280,7 @@ LEFT JOIN users u ON e.user_id = u.id
251280LEFT JOIN users u2 ON e.resolved_by_user_id = u2.id
252281LEFT JOIN api_keys ak ON ak.id = e.api_key_id
253282` + where + `
254- ORDER BY e.created_at DESC
283+ ORDER BY ` + opsErrorLogsOrderBy ( filter ) + `
255284LIMIT $` + itoa (len (args )+ 1 ) + ` OFFSET $` + itoa (len (args )+ 2 )
256285
257286 rows , err := r .db .QueryContext (ctx , selectSQL , argsWithLimit ... )
@@ -311,6 +340,7 @@ LIMIT $` + itoa(len(args)+1) + ` OFFSET $` + itoa(len(args)+2)
311340 & item .UpstreamEndpoint ,
312341 & item .RequestedModel ,
313342 & item .UpstreamModel ,
343+ & item .UserAgent ,
314344 & requestType ,
315345 & apiKeyName ,
316346 & apiKeyDeletedAt ,
@@ -417,7 +447,7 @@ SELECT
417447 COALESCE(a.name, ''),
418448 e.group_id,
419449 COALESCE(g.name, ''),
420- CASE WHEN e.client_ip IS NULL THEN NULL ELSE e.client_ip::text END,
450+ CASE WHEN e.client_ip IS NULL THEN NULL ELSE host( e.client_ip) END,
421451 COALESCE(e.request_path, ''),
422452 e.stream,
423453 COALESCE(e.inbound_endpoint, ''),
0 commit comments