Skip to content

Commit a2418c6

Browse files
committed
feat(ops): adapt repository INSERT/SELECT + add setOpsEndpointContext in error logger middleware
1 parent 8c4a217 commit a2418c6

2 files changed

Lines changed: 112 additions & 4 deletions

File tree

backend/internal/handler/ops_error_logger.go

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ const (
2727
opsRequestBodyKey = "ops_request_body"
2828
opsAccountIDKey = "ops_account_id"
2929

30+
opsUpstreamModelKey = "ops_upstream_model"
31+
opsRequestTypeKey = "ops_request_type"
32+
3033
// 错误过滤匹配常量 — shouldSkipOpsErrorLog 和错误分类共用
3134
opsErrContextCanceled = "context canceled"
3235
opsErrNoAvailableAccounts = "no available accounts"
@@ -345,6 +348,18 @@ func setOpsRequestContext(c *gin.Context, model string, stream bool, requestBody
345348
}
346349
}
347350

351+
// setOpsEndpointContext stores upstream model and request type for ops error logging.
352+
// Called by handlers after model mapping and request type determination.
353+
func setOpsEndpointContext(c *gin.Context, upstreamModel string, requestType int16) {
354+
if c == nil {
355+
return
356+
}
357+
if upstreamModel = strings.TrimSpace(upstreamModel); upstreamModel != "" {
358+
c.Set(opsUpstreamModelKey, upstreamModel)
359+
}
360+
c.Set(opsRequestTypeKey, requestType)
361+
}
362+
348363
func attachOpsRequestBodyToEntry(c *gin.Context, entry *service.OpsInsertErrorLogInput) {
349364
if c == nil || entry == nil {
350365
return
@@ -628,7 +643,30 @@ func OpsErrorLoggerMiddleware(ops *service.OpsService) gin.HandlerFunc {
628643
}
629644
return ""
630645
}(),
631-
Stream: stream,
646+
Stream: stream,
647+
InboundEndpoint: GetInboundEndpoint(c),
648+
UpstreamEndpoint: GetUpstreamEndpoint(c, platform),
649+
RequestedModel: modelName,
650+
UpstreamModel: func() string {
651+
if v, ok := c.Get(opsUpstreamModelKey); ok {
652+
if s, ok := v.(string); ok {
653+
return strings.TrimSpace(s)
654+
}
655+
}
656+
return ""
657+
}(),
658+
RequestType: func() *int16 {
659+
if v, ok := c.Get(opsRequestTypeKey); ok {
660+
switch t := v.(type) {
661+
case int16:
662+
return &t
663+
case int:
664+
v16 := int16(t)
665+
return &v16
666+
}
667+
}
668+
return nil
669+
}(),
632670
UserAgent: c.GetHeader("User-Agent"),
633671

634672
ErrorPhase: "upstream",
@@ -756,7 +794,30 @@ func OpsErrorLoggerMiddleware(ops *service.OpsService) gin.HandlerFunc {
756794
}
757795
return ""
758796
}(),
759-
Stream: stream,
797+
Stream: stream,
798+
InboundEndpoint: GetInboundEndpoint(c),
799+
UpstreamEndpoint: GetUpstreamEndpoint(c, platform),
800+
RequestedModel: modelName,
801+
UpstreamModel: func() string {
802+
if v, ok := c.Get(opsUpstreamModelKey); ok {
803+
if s, ok := v.(string); ok {
804+
return strings.TrimSpace(s)
805+
}
806+
}
807+
return ""
808+
}(),
809+
RequestType: func() *int16 {
810+
if v, ok := c.Get(opsRequestTypeKey); ok {
811+
switch t := v.(type) {
812+
case int16:
813+
return &t
814+
case int:
815+
v16 := int16(t)
816+
return &v16
817+
}
818+
}
819+
return nil
820+
}(),
760821
UserAgent: c.GetHeader("User-Agent"),
761822

762823
ErrorPhase: phase,

backend/internal/repository/ops_repo.go

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ INSERT INTO ops_error_logs (
2929
model,
3030
request_path,
3131
stream,
32+
inbound_endpoint,
33+
upstream_endpoint,
34+
requested_model,
35+
upstream_model,
36+
request_type,
3237
user_agent,
3338
error_phase,
3439
error_type,
@@ -57,7 +62,7 @@ INSERT INTO ops_error_logs (
5762
retry_count,
5863
created_at
5964
) VALUES (
60-
$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38
65+
$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$40,$41,$42,$43
6166
)`
6267

6368
func NewOpsRepository(db *sql.DB) service.OpsRepository {
@@ -140,6 +145,11 @@ func opsInsertErrorLogArgs(input *service.OpsInsertErrorLogInput) []any {
140145
opsNullString(input.Model),
141146
opsNullString(input.RequestPath),
142147
input.Stream,
148+
opsNullString(input.InboundEndpoint),
149+
opsNullString(input.UpstreamEndpoint),
150+
opsNullString(input.RequestedModel),
151+
opsNullString(input.UpstreamModel),
152+
opsNullInt16(input.RequestType),
143153
opsNullString(input.UserAgent),
144154
input.ErrorPhase,
145155
input.ErrorType,
@@ -231,7 +241,12 @@ SELECT
231241
COALESCE(g.name, ''),
232242
CASE WHEN e.client_ip IS NULL THEN NULL ELSE e.client_ip::text END,
233243
COALESCE(e.request_path, ''),
234-
e.stream
244+
e.stream,
245+
COALESCE(e.inbound_endpoint, ''),
246+
COALESCE(e.upstream_endpoint, ''),
247+
COALESCE(e.requested_model, ''),
248+
COALESCE(e.upstream_model, ''),
249+
e.request_type
235250
FROM ops_error_logs e
236251
LEFT JOIN accounts a ON e.account_id = a.id
237252
LEFT JOIN groups g ON e.group_id = g.id
@@ -263,6 +278,7 @@ LIMIT $` + itoa(len(args)+1) + ` OFFSET $` + itoa(len(args)+2)
263278
var resolvedBy sql.NullInt64
264279
var resolvedByName string
265280
var resolvedRetryID sql.NullInt64
281+
var requestType sql.NullInt64
266282
if err := rows.Scan(
267283
&item.ID,
268284
&item.CreatedAt,
@@ -294,6 +310,11 @@ LIMIT $` + itoa(len(args)+1) + ` OFFSET $` + itoa(len(args)+2)
294310
&clientIP,
295311
&item.RequestPath,
296312
&item.Stream,
313+
&item.InboundEndpoint,
314+
&item.UpstreamEndpoint,
315+
&item.RequestedModel,
316+
&item.UpstreamModel,
317+
&requestType,
297318
); err != nil {
298319
return nil, err
299320
}
@@ -334,6 +355,10 @@ LIMIT $` + itoa(len(args)+1) + ` OFFSET $` + itoa(len(args)+2)
334355
item.GroupID = &v
335356
}
336357
item.GroupName = groupName
358+
if requestType.Valid {
359+
v := int16(requestType.Int64)
360+
item.RequestType = &v
361+
}
337362
out = append(out, &item)
338363
}
339364
if err := rows.Err(); err != nil {
@@ -393,6 +418,11 @@ SELECT
393418
CASE WHEN e.client_ip IS NULL THEN NULL ELSE e.client_ip::text END,
394419
COALESCE(e.request_path, ''),
395420
e.stream,
421+
COALESCE(e.inbound_endpoint, ''),
422+
COALESCE(e.upstream_endpoint, ''),
423+
COALESCE(e.requested_model, ''),
424+
COALESCE(e.upstream_model, ''),
425+
e.request_type,
396426
COALESCE(e.user_agent, ''),
397427
e.auth_latency_ms,
398428
e.routing_latency_ms,
@@ -427,6 +457,7 @@ LIMIT 1`
427457
var responseLatency sql.NullInt64
428458
var ttft sql.NullInt64
429459
var requestBodyBytes sql.NullInt64
460+
var requestType sql.NullInt64
430461

431462
err := r.db.QueryRowContext(ctx, q, id).Scan(
432463
&out.ID,
@@ -464,6 +495,11 @@ LIMIT 1`
464495
&clientIP,
465496
&out.RequestPath,
466497
&out.Stream,
498+
&out.InboundEndpoint,
499+
&out.UpstreamEndpoint,
500+
&out.RequestedModel,
501+
&out.UpstreamModel,
502+
&requestType,
467503
&out.UserAgent,
468504
&authLatency,
469505
&routingLatency,
@@ -540,6 +576,10 @@ LIMIT 1`
540576
v := int(requestBodyBytes.Int64)
541577
out.RequestBodyBytes = &v
542578
}
579+
if requestType.Valid {
580+
v := int16(requestType.Int64)
581+
out.RequestType = &v
582+
}
543583

544584
// Normalize request_body to empty string when stored as JSON null.
545585
out.RequestBody = strings.TrimSpace(out.RequestBody)
@@ -1479,3 +1519,10 @@ func opsNullInt(v any) any {
14791519
return sql.NullInt64{}
14801520
}
14811521
}
1522+
1523+
func opsNullInt16(v *int16) any {
1524+
if v == nil {
1525+
return sql.NullInt64{}
1526+
}
1527+
return sql.NullInt64{Int64: int64(*v), Valid: true}
1528+
}

0 commit comments

Comments
 (0)