From f657f9d6d823b0bccc49eff84dbfeef06e14781e Mon Sep 17 00:00:00 2001 From: Pratham Mishra <99235987+Pratham-Mishra04@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:42:32 +0530 Subject: [PATCH] enhancement: transports logging, ui, and docker --- transports/Dockerfile | 11 +- transports/bifrost-http/main.go | 2 +- .../bifrost-http/plugins/logging/main.go | 14 - .../bifrost-http/plugins/logging/utils.go | 35 +-- transports/bifrost-http/ui/404.html | 4 +- transports/bifrost-http/ui/404/index.html | 4 +- .../_next/static/chunks/0-92aa8a29adf5b5bf.js | 1 + .../_next/static/chunks/0-c8687fc5d2be8f26.js | 1 - .../static/chunks/393-ea6cc19b80a7c19c.js | 1 - .../static/chunks/452-52b7b5dcb4902a2c.js | 1 + .../static/chunks/452-ba1c85b70e91fcc3.js | 1 - .../static/chunks/978-ce74b487c7fe1ab8.js | 1 + ...7a7c8bd8d1a.js => 983-ee41b772651f7909.js} | 4 +- .../app/config/page-48faa8da2b43fe44.js | 1 + .../app/config/page-e81b135af619a46a.js | 1 - ...03d062da.js => layout-c2b2a9913cc00c9e.js} | 2 +- .../chunks/app/page-6e8e689326a7a90d.js | 1 + .../chunks/app/page-c5d93cc14cf22918.js | 1 - .../app/plugins/page-ad4b7f09b3bb7f4c.js | 1 + .../app/plugins/page-c7cc9c96cbdec10a.js | 1 - .../ui/_next/static/css/1c39a7604f11b7f7.css | 1 + .../ui/_next/static/css/1e10a4984e26ab69.css | 1 - transports/bifrost-http/ui/config/index.html | 4 +- transports/bifrost-http/ui/config/index.txt | 18 +- transports/bifrost-http/ui/docs/index.html | 4 +- transports/bifrost-http/ui/docs/index.txt | 16 +- transports/bifrost-http/ui/index.html | 4 +- transports/bifrost-http/ui/index.txt | 18 +- transports/bifrost-http/ui/plugins/index.html | 4 +- transports/bifrost-http/ui/plugins/index.txt | 18 +- ui/app/page.tsx | 11 +- ui/app/plugins/page.tsx | 25 +- ui/components/config/provider-form.tsx | 4 +- ui/components/logs/empty-state.tsx | 259 +++++++++++------- ui/hooks/useWebSocket.tsx | 12 +- ui/lib/api.ts | 14 +- ui/lib/types/logs.ts | 1 - ui/lib/utils/port.ts | 127 +++++++++ 38 files changed, 379 insertions(+), 250 deletions(-) create mode 100644 transports/bifrost-http/ui/_next/static/chunks/0-92aa8a29adf5b5bf.js delete mode 100644 transports/bifrost-http/ui/_next/static/chunks/0-c8687fc5d2be8f26.js delete mode 100644 transports/bifrost-http/ui/_next/static/chunks/393-ea6cc19b80a7c19c.js create mode 100644 transports/bifrost-http/ui/_next/static/chunks/452-52b7b5dcb4902a2c.js delete mode 100644 transports/bifrost-http/ui/_next/static/chunks/452-ba1c85b70e91fcc3.js create mode 100644 transports/bifrost-http/ui/_next/static/chunks/978-ce74b487c7fe1ab8.js rename transports/bifrost-http/ui/_next/static/chunks/{990-b08497a7c8bd8d1a.js => 983-ee41b772651f7909.js} (60%) create mode 100644 transports/bifrost-http/ui/_next/static/chunks/app/config/page-48faa8da2b43fe44.js delete mode 100644 transports/bifrost-http/ui/_next/static/chunks/app/config/page-e81b135af619a46a.js rename transports/bifrost-http/ui/_next/static/chunks/app/{layout-739652a903d062da.js => layout-c2b2a9913cc00c9e.js} (58%) create mode 100644 transports/bifrost-http/ui/_next/static/chunks/app/page-6e8e689326a7a90d.js delete mode 100644 transports/bifrost-http/ui/_next/static/chunks/app/page-c5d93cc14cf22918.js create mode 100644 transports/bifrost-http/ui/_next/static/chunks/app/plugins/page-ad4b7f09b3bb7f4c.js delete mode 100644 transports/bifrost-http/ui/_next/static/chunks/app/plugins/page-c7cc9c96cbdec10a.js create mode 100644 transports/bifrost-http/ui/_next/static/css/1c39a7604f11b7f7.css delete mode 100644 transports/bifrost-http/ui/_next/static/css/1e10a4984e26ab69.css create mode 100644 ui/lib/utils/port.ts diff --git a/transports/Dockerfile b/transports/Dockerfile index 96b0dccea6..a56d274d47 100644 --- a/transports/Dockerfile +++ b/transports/Dockerfile @@ -2,11 +2,11 @@ FROM golang:1.24-alpine AS builder WORKDIR /app -# Install dependencies in a single layer -RUN apk add --no-cache upx +# Install dependencies including gcc for CGO and sqlite +RUN apk add --no-cache upx gcc musl-dev sqlite-dev -# Set environment for static build -ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 +# Set environment for CGO-enabled build (required for go-sqlite3) +ENV CGO_ENABLED=1 GOOS=linux # Define build-time variables ARG TRANSPORT_TYPE=http @@ -16,10 +16,11 @@ ARG TAG_VERSION=latest RUN go mod init bifrost-build && \ go get github.com/maximhq/bifrost/transports/bifrost-${TRANSPORT_TYPE}@${TAG_VERSION} -# Build the binary locally +# Build the binary with CGO enabled and static SQLite linking RUN go build \ -ldflags="-w -s -extldflags '-static'" \ -a -trimpath \ + -tags "sqlite_static" \ -o /app/main \ github.com/maximhq/bifrost/transports/bifrost-${TRANSPORT_TYPE} diff --git a/transports/bifrost-http/main.go b/transports/bifrost-http/main.go index d2703b55e6..73c2ba7bc2 100644 --- a/transports/bifrost-http/main.go +++ b/transports/bifrost-http/main.go @@ -373,7 +373,7 @@ func main() { // Apply CORS middleware to all routes corsHandler := corsMiddleware(r.Handler) - log.Printf("Starting server on port %s", port) + log.Printf("Successfully started bifrost. Serving UI on http://localhost:%s", port) if err := fasthttp.ListenAndServe(":"+port, corsHandler); err != nil { log.Fatalf("Error starting server: %v", err) } diff --git a/transports/bifrost-http/plugins/logging/main.go b/transports/bifrost-http/plugins/logging/main.go index 58cfc3fc70..1587a9e313 100644 --- a/transports/bifrost-http/plugins/logging/main.go +++ b/transports/bifrost-http/plugins/logging/main.go @@ -64,7 +64,6 @@ type UpdateLogData struct { OutputMessage *schemas.BifrostMessage ToolCalls *[]schemas.ToolCall ErrorDetails *schemas.BifrostError - ExtraFields map[string]interface{} Model string // May be different from request Object string // May be different from request } @@ -85,7 +84,6 @@ type LogEntry struct { TokenUsage *schemas.LLMUsage `json:"token_usage,omitempty"` Status string `json:"status"` // "processing", "success", or "error" ErrorDetails *schemas.BifrostError `json:"error_details,omitempty"` - ExtraFields map[string]interface{} `json:"extra_fields,omitempty"` CreatedAt time.Time `json:"created_at"` } @@ -233,7 +231,6 @@ func (p *LoggerPlugin) createTables() error { tool_calls TEXT, params TEXT, error_details TEXT, - extra_fields TEXT, -- For content search content_summary TEXT, @@ -499,17 +496,6 @@ func (p *LoggerPlugin) PostHook(ctx *context.Context, result *schemas.BifrostRes updateData.ToolCalls = result.Choices[0].Message.AssistantMessage.ToolCalls } } - - // Extra fields if available - if result.ExtraFields.Provider != "" || result.ExtraFields.Params.MaxTokens != nil { - updateData.ExtraFields = map[string]interface{}{ - "provider": result.ExtraFields.Provider, - "params": result.ExtraFields.Params, - "latency": result.ExtraFields.Latency, - "billed_usage": result.ExtraFields.BilledUsage, - "raw_response": result.ExtraFields.RawResponse, - } - } } logMsg.UpdateData = updateData diff --git a/transports/bifrost-http/plugins/logging/utils.go b/transports/bifrost-http/plugins/logging/utils.go index f90207a4a6..725063f976 100644 --- a/transports/bifrost-http/plugins/logging/utils.go +++ b/transports/bifrost-http/plugins/logging/utils.go @@ -110,13 +110,6 @@ func (p *LoggerPlugin) updateLogEntry(requestID string, timestamp time.Time, dat args = append(args, string(errorDetailsJSON)) } - // Update extra fields - if data.ExtraFields != nil { - extraFieldsJSON, _ := json.Marshal(data.ExtraFields) - setParts = append(setParts, "extra_fields = ?") - args = append(args, string(extraFieldsJSON)) - } - // Add the WHERE clause parameter args = append(args, requestID) @@ -161,13 +154,13 @@ func (p *LoggerPlugin) getLogEntry(requestID string) (*LogEntry, error) { SELECT id, timestamp, provider, model, object_type, status, latency, prompt_tokens, completion_tokens, total_tokens, input_history, output_message, tools, tool_calls, - params, error_details, extra_fields, created_at + params, error_details, created_at FROM logs WHERE id = ?` var entry LogEntry var timestampUnix, createdAtUnix int64 var inputHistoryJSON, outputMessageJSON, toolsJSON, toolCallsJSON sql.NullString - var paramsJSON, errorDetailsJSON, extraFieldsJSON sql.NullString + var paramsJSON, errorDetailsJSON sql.NullString var promptTokens, completionTokens, totalTokensRow sql.NullInt64 var latency sql.NullFloat64 @@ -176,7 +169,7 @@ func (p *LoggerPlugin) getLogEntry(requestID string) (*LogEntry, error) { &entry.Object, &entry.Status, &latency, &promptTokens, &completionTokens, &totalTokensRow, &inputHistoryJSON, &outputMessageJSON, &toolsJSON, &toolCallsJSON, - ¶msJSON, &errorDetailsJSON, &extraFieldsJSON, + ¶msJSON, &errorDetailsJSON, &createdAtUnix, ) if err != nil { @@ -226,9 +219,6 @@ func (p *LoggerPlugin) getLogEntry(requestID string) (*LogEntry, error) { if errorDetailsJSON.Valid { json.Unmarshal([]byte(errorDetailsJSON.String), &entry.ErrorDetails) } - if extraFieldsJSON.Valid { - json.Unmarshal([]byte(extraFieldsJSON.String), &entry.ExtraFields) - } return &entry, nil } @@ -335,9 +325,9 @@ func (p *LoggerPlugin) SearchLogs(filters *SearchFilters, pagination *Pagination for rows.Next() { var entry LogEntry - var timestampUnix int64 + var timestampUnix sql.NullInt64 var inputHistoryJSON, outputMessageJSON, toolsJSON, toolCallsJSON sql.NullString - var paramsJSON, errorDetailsJSON, extraFieldsJSON sql.NullString + var paramsJSON, errorDetailsJSON sql.NullString var promptTokens, completionTokens, totalTokensRow sql.NullInt64 var latency sql.NullFloat64 @@ -346,14 +336,18 @@ func (p *LoggerPlugin) SearchLogs(filters *SearchFilters, pagination *Pagination &entry.Object, &entry.Status, &latency, &promptTokens, &completionTokens, &totalTokensRow, &inputHistoryJSON, &outputMessageJSON, &toolsJSON, &toolCallsJSON, - ¶msJSON, &errorDetailsJSON, &extraFieldsJSON, + ¶msJSON, &errorDetailsJSON, ) if err != nil { return nil, fmt.Errorf("failed to scan row: %w", err) } - // Convert timestamp - entry.Timestamp = time.Unix(timestampUnix/1e9, timestampUnix%1e9) // Convert from nanoseconds + // Convert timestamp (handle NULL values) + if timestampUnix.Valid { + entry.Timestamp = time.Unix(timestampUnix.Int64/1e9, timestampUnix.Int64%1e9) // Convert from nanoseconds + } else { + entry.Timestamp = time.Time{} // Set to zero time if NULL + } // Handle latency if latency.Valid { @@ -394,9 +388,6 @@ func (p *LoggerPlugin) SearchLogs(filters *SearchFilters, pagination *Pagination if errorDetailsJSON.Valid { json.Unmarshal([]byte(errorDetailsJSON.String), &entry.ErrorDetails) } - if extraFieldsJSON.Valid { - json.Unmarshal([]byte(extraFieldsJSON.String), &entry.ExtraFields) - } logs = append(logs, entry) } @@ -433,7 +424,7 @@ func (p *LoggerPlugin) buildSearchQuery(filters *SearchFilters, pagination *Pagi SELECT id, timestamp, provider, model, object_type, status, latency, prompt_tokens, completion_tokens, total_tokens, input_history, output_message, tools, tool_calls, - params, error_details, extra_fields + params, error_details FROM logs` countQuery := "SELECT COUNT(*) FROM logs" diff --git a/transports/bifrost-http/ui/404.html b/transports/bifrost-http/ui/404.html index fb4e4626b4..1d921e5b46 100644 --- a/transports/bifrost-http/ui/404.html +++ b/transports/bifrost-http/ui/404.html @@ -1,4 +1,4 @@ -