Skip to content

Commit cb0b2dd

Browse files
committed
Merge branch 'moonshot-xxii-debugger' of github.com:launchdarkly/ldcli into moonshot-xxii-debugger
2 parents 5caa3b5 + 2260ca4 commit cb0b2dd

File tree

7 files changed

+401
-0
lines changed

7 files changed

+401
-0
lines changed

internal/dev_server/api/api.yaml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,34 @@ paths:
188188
$ref: "#/components/responses/ErrorResponse"
189189
400:
190190
$ref: "#/components/responses/ErrorResponse"
191+
/dev/debug-sessions:
192+
get:
193+
operationId: getDebugSessions
194+
summary: list all debug sessions with event counts
195+
parameters:
196+
- name: limit
197+
in: query
198+
description: limit the number of debug sessions returned
199+
required: false
200+
schema:
201+
type: integer
202+
default: 50
203+
- name: offset
204+
in: query
205+
description: offset for pagination
206+
required: false
207+
schema:
208+
type: integer
209+
default: 0
210+
responses:
211+
200:
212+
description: OK. List of debug sessions
213+
content:
214+
application/json:
215+
schema:
216+
$ref: "#/components/schemas/DebugSessionsPage"
217+
400:
218+
$ref: "#/components/responses/ErrorResponse"
191219
components:
192220
parameters:
193221
flagKey:
@@ -294,6 +322,45 @@ components:
294322
type: string
295323
name:
296324
type: string
325+
DebugSession:
326+
description: Debug session with event count
327+
type: object
328+
required:
329+
- key
330+
- written_at
331+
- event_count
332+
properties:
333+
key:
334+
type: string
335+
description: unique identifier for the debug session
336+
written_at:
337+
type: string
338+
format: date-time
339+
description: timestamp when the debug session was created
340+
event_count:
341+
type: integer
342+
format: int64
343+
description: number of events associated with this debug session
344+
DebugSessionsPage:
345+
description: Paginated response of debug sessions
346+
type: object
347+
required:
348+
- sessions
349+
- total_count
350+
- has_more
351+
properties:
352+
sessions:
353+
type: array
354+
items:
355+
$ref: "#/components/schemas/DebugSession"
356+
description: list of debug sessions
357+
total_count:
358+
type: integer
359+
format: int64
360+
description: total number of debug sessions available
361+
has_more:
362+
type: boolean
363+
description: whether there are more results available
297364
responses:
298365
FlagOverride:
299366
description: Flag override
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package api
2+
3+
import (
4+
"context"
5+
6+
"github.com/launchdarkly/ldcli/internal/dev_server/model"
7+
)
8+
9+
func (s server) GetDebugSessions(ctx context.Context, request GetDebugSessionsRequestObject) (GetDebugSessionsResponseObject, error) {
10+
eventStore := model.EventStoreFromContext(ctx)
11+
12+
// Set default values for pagination
13+
limit := 50
14+
offset := 0
15+
16+
if request.Params.Limit != nil {
17+
limit = *request.Params.Limit
18+
}
19+
if request.Params.Offset != nil {
20+
offset = *request.Params.Offset
21+
}
22+
23+
// Validate parameters
24+
if limit < 1 || limit > 1000 {
25+
return GetDebugSessions400JSONResponse{ErrorResponseJSONResponse{
26+
Code: "invalid_parameter",
27+
Message: "limit must be between 1 and 1000",
28+
}}, nil
29+
}
30+
31+
if offset < 0 {
32+
return GetDebugSessions400JSONResponse{ErrorResponseJSONResponse{
33+
Code: "invalid_parameter",
34+
Message: "offset must be non-negative",
35+
}}, nil
36+
}
37+
38+
// Query debug sessions from the event store
39+
page, err := eventStore.QueryDebugSessions(ctx, limit, offset)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
// Convert model.DebugSession to API DebugSession
45+
var apiSessions []DebugSession
46+
for _, session := range page.Sessions {
47+
apiSessions = append(apiSessions, DebugSession{
48+
Key: session.Key,
49+
WrittenAt: session.WrittenAt,
50+
EventCount: session.EventCount,
51+
})
52+
}
53+
54+
response := DebugSessionsPage{
55+
Sessions: apiSessions,
56+
TotalCount: page.TotalCount,
57+
HasMore: page.HasMore,
58+
}
59+
60+
return GetDebugSessions200JSONResponse(response), nil
61+
}

internal/dev_server/api/server.gen.go

Lines changed: 129 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/dev_server/events_db/sqlite.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,63 @@ func (s *Sqlite) QueryEvents(ctx context.Context, debugSessionKey string, kind *
112112
}, nil
113113
}
114114

115+
func (s *Sqlite) QueryDebugSessions(ctx context.Context, limit int, offset int) (*model.DebugSessionsPage, error) {
116+
// Execute the main query based on the provided SQL
117+
query := `
118+
SELECT debug_session.key, debug_session.written_at, COUNT(debug_events.id) as event_count
119+
FROM debug_session
120+
LEFT JOIN debug_events ON debug_session.key = debug_events.debug_session_key
121+
GROUP BY debug_session.key, debug_session.written_at
122+
ORDER BY debug_session.written_at DESC
123+
LIMIT ? OFFSET ?`
124+
125+
rows, err := s.database.QueryContext(ctx, query, limit, offset)
126+
if err != nil {
127+
return nil, err
128+
}
129+
defer rows.Close()
130+
131+
var sessions []model.DebugSession
132+
for rows.Next() {
133+
var session model.DebugSession
134+
var writtenAtStr string
135+
136+
err := rows.Scan(&session.Key, &writtenAtStr, &session.EventCount)
137+
if err != nil {
138+
return nil, err
139+
}
140+
141+
// Parse the timestamp - SQLite returns ISO 8601 format
142+
session.WrittenAt, err = time.Parse(time.RFC3339, writtenAtStr)
143+
if err != nil {
144+
return nil, err
145+
}
146+
147+
sessions = append(sessions, session)
148+
}
149+
150+
if err = rows.Err(); err != nil {
151+
return nil, err
152+
}
153+
154+
// Get total count for pagination info
155+
var totalCount int64
156+
countQuery := `SELECT COUNT(*) FROM debug_session`
157+
err = s.database.QueryRowContext(ctx, countQuery).Scan(&totalCount)
158+
if err != nil {
159+
return nil, err
160+
}
161+
162+
// Determine if there are more results
163+
hasMore := int64(offset+len(sessions)) < totalCount
164+
165+
return &model.DebugSessionsPage{
166+
Sessions: sessions,
167+
TotalCount: totalCount,
168+
HasMore: hasMore,
169+
}, nil
170+
}
171+
115172
var _ model.EventStore = &Sqlite{}
116173

117174
func NewSqlite(ctx context.Context, dbPath string) (*Sqlite, error) {

0 commit comments

Comments
 (0)