177 lines
6.8 KiB
Plaintext
177 lines
6.8 KiB
Plaintext
---
|
|
title: "Log Store"
|
|
description: "A robust and queryable system for persisting API request and response logs, with support for multiple database backends."
|
|
icon: "clipboard-list"
|
|
---
|
|
|
|
The LogStore is a core component of the Bifrost framework responsible for capturing, storing, and retrieving detailed logs of API requests and responses. It provides a persistent, queryable audit trail of all activity passing through the gateway, which is essential for debugging, monitoring, analytics, and compliance.
|
|
|
|
## Core Features
|
|
|
|
- **Persistent Logging**: Automatically saves detailed information about each API request, including input, output, status, latency, and cost.
|
|
- **Multiple Backend Support**: Comes with built-in support for SQLite and PostgreSQL, allowing you to choose the best storage solution for your deployment needs.
|
|
- **Rich Querying and Filtering**: A powerful search API allows you to filter and sort logs based on a wide range of criteria such as provider, model, status, latency, cost, and content.
|
|
- **Performance Analytics**: The search functionality also provides aggregated statistics, including total requests, success rate, average latency, total tokens, and total cost for the queried data.
|
|
- **Structured Data Model**: Logs are stored in a structured format, with complex objects like message history and tool calls serialized as JSON for efficient storage and retrieval.
|
|
- **Automatic Data Management**: Includes GORM hooks to automatically handle JSON serialization/deserialization and to build a searchable content summary.
|
|
|
|
## Architecture
|
|
|
|
The LogStore is built around the `LogStore` interface, which defines the standard methods for interacting with the log database. The primary implementation, `RDBLogStore`, uses GORM to provide an abstraction over relational databases.
|
|
|
|
### Supported Backends
|
|
|
|
- **SQLite**: The default, file-based database, ideal for local development and smaller, single-node deployments.
|
|
- **PostgreSQL**: A production-ready database for scalable and high-availability deployments.
|
|
|
|
The backend is configured in Bifrost's main configuration file.
|
|
|
|
### Initialization
|
|
|
|
The LogStore is initialized at startup based on the provided configuration.
|
|
|
|
```go
|
|
import (
|
|
"github.com/maximhq/bifrost/framework/logstore"
|
|
"github.com/maximhq/bifrost/core/schemas"
|
|
)
|
|
|
|
// Example: Initialize a SQLite-based LogStore
|
|
config := &logstore.Config{
|
|
Enabled: true,
|
|
Type: logstore.LogStoreTypeSQLite,
|
|
Config: &logstore.SQLiteConfig{
|
|
File: "/path/to/logs.db",
|
|
},
|
|
}
|
|
|
|
var logger schemas.Logger // Assume logger is initialized
|
|
store, err := logstore.NewLogStore(context.Background(), config, logger)
|
|
if err != nil {
|
|
// Handle error
|
|
}
|
|
```
|
|
|
|
Here is an example for initializing a PostgreSQL-based `LogStore`:
|
|
```go
|
|
// Example: Initialize a PostgreSQL-based LogStore
|
|
pgConfig := &logstore.Config{
|
|
Enabled: true,
|
|
Type: logstore.LogStoreTypePostgres,
|
|
Config: &logstore.PostgresConfig{
|
|
Host: "localhost",
|
|
Port: "5432",
|
|
User: "postgres",
|
|
Password: "secret",
|
|
DBName: "bifrost_logs",
|
|
SSLMode: "disable",
|
|
MaxIdleConns: 5, // Optional: Maximum idle connections (default: 5)
|
|
MaxOpenConns: 50, // Optional: Maximum open connections (default: 50)
|
|
},
|
|
}
|
|
|
|
store, err = logstore.NewLogStore(context.Background(), pgConfig, logger)
|
|
if err != nil {
|
|
// Handle error
|
|
}
|
|
```
|
|
|
|
<Note>
|
|
PostgreSQL databases used by Bifrost stores must be UTF8 encoded. See [PostgreSQL UTF8 Requirement](../../quickstart/gateway/setting-up#postgresql-utf8-requirement).
|
|
</Note>
|
|
|
|
### Connection Pool Configuration
|
|
|
|
For PostgreSQL backends, you can configure the database connection pool to optimize performance based on your workload:
|
|
|
|
- **MaxIdleConns**: Maximum number of idle connections in the pool (default: 5)
|
|
- **MaxOpenConns**: Maximum number of open connections to the database (default: 50)
|
|
|
|
These parameters help manage database connection resources effectively. Increase them for high-traffic deployments or decrease them for resource-constrained environments.
|
|
|
|
## Data Model
|
|
|
|
The core of the LogStore is the `Log` struct, which represents a single log entry in the `logs` table.
|
|
|
|
```go
|
|
// Log represents a complete log entry for a request/response cycle
|
|
type Log struct {
|
|
ID string `gorm:"primaryKey;type:varchar(255)"`
|
|
Timestamp time.Time `gorm:"index;not null"`
|
|
Object string `gorm:"type:varchar(255);index;not null;column:object_type"`
|
|
Provider string `gorm:"type:varchar(255);index;not null"`
|
|
Model string `gorm:"type:varchar(255);index;not null"`
|
|
Latency *float64
|
|
Cost *float64 `gorm:"index"`
|
|
Status string `gorm:"type:varchar(50);index;not null"` // "processing", "success", or "error"
|
|
Stream bool `gorm:"default:false"`
|
|
|
|
// Denormalized token fields for easier querying
|
|
PromptTokens int `gorm:"default:0"`
|
|
CompletionTokens int `gorm:"default:0"`
|
|
TotalTokens int `gorm:"default:0"`
|
|
|
|
// JSON serialized fields
|
|
InputHistory string `gorm:"type:text"`
|
|
OutputMessage string `gorm:"type:text"`
|
|
TokenUsage string `gorm:"type:text"`
|
|
ErrorDetails string `gorm:"type:text"`
|
|
// ... and many more for different data types
|
|
}
|
|
```
|
|
Complex data like message arrays and tool calls are serialized into JSON strings for storage and are automatically deserialized back into their struct forms when retrieved.
|
|
|
|
## Usage
|
|
|
|
### Creating Log Entries
|
|
|
|
A log entry is created by populating a `Log` struct and passing it to the `Create` method. This is typically handled internally by Bifrost's logging plugins.
|
|
|
|
```go
|
|
logEntry := &logstore.Log{
|
|
ID: "req-xyz123",
|
|
Timestamp: time.Now(),
|
|
Provider: "openai",
|
|
Model: "gpt-4",
|
|
Status: "success",
|
|
// ... other fields
|
|
}
|
|
err := store.Create(ctx, logEntry)
|
|
```
|
|
|
|
### Searching and Filtering Logs
|
|
|
|
The `SearchLogs` method provides a powerful way to query logs with fine-grained filters and pagination.
|
|
|
|
```go
|
|
// Define search criteria
|
|
filters := logstore.SearchFilters{
|
|
Providers: []string{"openai", "anthropic"},
|
|
Status: []string{"error"},
|
|
StartTime: &startTime, // time.Time pointer
|
|
}
|
|
|
|
pagination := logstore.PaginationOptions{
|
|
Limit: 50,
|
|
Offset: 0,
|
|
SortBy: "timestamp",
|
|
Order: "desc",
|
|
}
|
|
|
|
// Execute the search
|
|
results, err := store.SearchLogs(ctx, filters, pagination)
|
|
if err != nil {
|
|
// Handle error
|
|
}
|
|
|
|
// Process the results
|
|
for _, log := range results.Logs {
|
|
fmt.Printf("Found log: %s\n", log.ID)
|
|
}
|
|
|
|
// Access aggregated stats
|
|
fmt.Printf("Total errors: %d\n", results.Stats.TotalRequests)
|
|
```
|
|
|
|
The LogStore is an indispensable tool for observability in Bifrost, providing the detailed audit trail needed to monitor, debug, and analyze AI application performance and behavior effectively.
|