Documentation
¶
Overview ¶
Package logging provides Gin middleware for HTTP request logging and panic recovery. It integrates Gin web framework with logrus for structured logging of HTTP requests, responses, and error handling with panic recovery capabilities.
Package logging provides request logging functionality for the CLI Proxy API server. It handles capturing and storing detailed HTTP request and response data when enabled through configuration, supporting both regular and streaming responses.
Index ¶
- func ConfigureLogOutput(cfg *config.Config) error
- func GetGinRequestID(c *gin.Context) string
- func GetRequestID(ctx context.Context) string
- func GinLogrusLogger() gin.HandlerFunc
- func GinLogrusRecovery() gin.HandlerFunc
- func ResolveLogDirectory(cfg *config.Config) string
- func SetupBaseLogger()
- func SkipGinRequestLogging(c *gin.Context)
- func WithRequestID(ctx context.Context, requestID string) context.Context
- type FileRequestLogger
- func (l *FileRequestLogger) IsEnabled() bool
- func (l *FileRequestLogger) LogRequest(url, method string, requestHeaders map[string][]string, body []byte, ...) error
- func (l *FileRequestLogger) LogRequestWithOptions(url, method string, requestHeaders map[string][]string, body []byte, ...) error
- func (l *FileRequestLogger) LogStreamingRequest(url, method string, headers map[string][]string, body []byte, requestID string) (StreamingLogWriter, error)
- func (l *FileRequestLogger) SetEnabled(enabled bool)
- func (l *FileRequestLogger) SetErrorLogsMaxFiles(maxFiles int)
- type LogFormatter
- type RequestLogger
- type StreamingLogWriter
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ConfigureLogOutput ¶
ConfigureLogOutput switches the global log destination between rotating files and stdout. When logsMaxTotalSizeMB > 0, a background cleaner removes the oldest log files in the logs directory until the total size is within the limit.
func GetGinRequestID ¶
GetGinRequestID retrieves the request ID from the Gin context.
func GetRequestID ¶
GetRequestID retrieves the request ID from the context. Returns empty string if not found.
func GinLogrusLogger ¶
func GinLogrusLogger() gin.HandlerFunc
GinLogrusLogger returns a Gin middleware handler that logs HTTP requests and responses using logrus. It captures request details including method, path, status code, latency, client IP, and any error messages. Request ID is only added for AI API requests.
Output format (AI API): [2025-12-23 20:14:10] [info ] | a1b2c3d4 | 200 | 23.559s | ... Output format (others): [2025-12-23 20:14:10] [info ] | -------- | 200 | 23.559s | ...
Returns:
- gin.HandlerFunc: A middleware handler for request logging
func GinLogrusRecovery ¶
func GinLogrusRecovery() gin.HandlerFunc
GinLogrusRecovery returns a Gin middleware handler that recovers from panics and logs them using logrus. When a panic occurs, it captures the panic value, stack trace, and request path, then returns a 500 Internal Server Error response to the client.
Returns:
- gin.HandlerFunc: A middleware handler for panic recovery
func ResolveLogDirectory ¶
ResolveLogDirectory determines the directory used for application logs.
func SetupBaseLogger ¶
func SetupBaseLogger()
SetupBaseLogger configures the shared logrus instance and Gin writers. It is safe to call multiple times; initialization happens only once.
func SkipGinRequestLogging ¶
SkipGinRequestLogging marks the provided Gin context so that GinLogrusLogger will skip emitting a log line for the associated request.
Types ¶
type FileRequestLogger ¶
type FileRequestLogger struct {
// contains filtered or unexported fields
}
FileRequestLogger implements RequestLogger using file-based storage. It provides file-based logging functionality for HTTP requests and responses.
func NewFileRequestLogger ¶
func NewFileRequestLogger(enabled bool, logsDir string, configDir string, errorLogsMaxFiles int) *FileRequestLogger
NewFileRequestLogger creates a new file-based request logger.
Parameters:
- enabled: Whether request logging should be enabled
- logsDir: The directory where log files should be stored (can be relative)
- configDir: The directory of the configuration file; when logsDir is relative, it will be resolved relative to this directory
- errorLogsMaxFiles: Maximum number of error log files to retain (0 = no cleanup)
Returns:
- *FileRequestLogger: A new file-based request logger instance
func (*FileRequestLogger) IsEnabled ¶
func (l *FileRequestLogger) IsEnabled() bool
IsEnabled returns whether request logging is currently enabled.
Returns:
- bool: True if logging is enabled, false otherwise
func (*FileRequestLogger) LogRequest ¶
func (l *FileRequestLogger) LogRequest( url, method string, requestHeaders map[string][]string, body []byte, statusCode int, responseHeaders map[string][]string, response, websocketTimeline, apiRequest, apiResponse, apiWebsocketTimeline []byte, apiResponseErrors []*interfaces.ErrorMessage, requestID string, requestTimestamp, apiResponseTimestamp time.Time, ) error
LogRequest logs a complete non-streaming request/response cycle to a file.
Parameters:
- url: The request URL
- method: The HTTP method
- requestHeaders: The request headers
- body: The request body
- statusCode: The response status code
- responseHeaders: The response headers
- response: The raw response data
- websocketTimeline: Optional downstream websocket event timeline
- apiRequest: The API request data
- apiResponse: The API response data
- apiWebsocketTimeline: Optional upstream websocket event timeline
- requestID: Optional request ID for log file naming
- requestTimestamp: When the request was received
- apiResponseTimestamp: When the API response was received
Returns:
- error: An error if logging fails, nil otherwise
func (*FileRequestLogger) LogRequestWithOptions ¶
func (l *FileRequestLogger) LogRequestWithOptions( url, method string, requestHeaders map[string][]string, body []byte, statusCode int, responseHeaders map[string][]string, response, websocketTimeline, apiRequest, apiResponse, apiWebsocketTimeline []byte, apiResponseErrors []*interfaces.ErrorMessage, force bool, requestID string, requestTimestamp, apiResponseTimestamp time.Time, ) error
LogRequestWithOptions logs a request with optional forced logging behavior. The force flag allows writing error logs even when regular request logging is disabled.
func (*FileRequestLogger) LogStreamingRequest ¶
func (l *FileRequestLogger) LogStreamingRequest( url, method string, headers map[string][]string, body []byte, requestID string, ) (StreamingLogWriter, error)
LogStreamingRequest initiates logging for a streaming request.
Parameters:
- url: The request URL
- method: The HTTP method
- headers: The request headers
- body: The request body
- requestID: Optional request ID for log file naming
Returns:
- StreamingLogWriter: A writer for streaming response chunks
- error: An error if logging initialization fails, nil otherwise
func (*FileRequestLogger) SetEnabled ¶
func (l *FileRequestLogger) SetEnabled(enabled bool)
SetEnabled updates the request logging enabled state. This method allows dynamic enabling/disabling of request logging.
Parameters:
- enabled: Whether request logging should be enabled
func (*FileRequestLogger) SetErrorLogsMaxFiles ¶
func (l *FileRequestLogger) SetErrorLogsMaxFiles(maxFiles int)
SetErrorLogsMaxFiles updates the maximum number of error log files to retain.
type LogFormatter ¶
type LogFormatter struct{}
LogFormatter defines a custom log format for logrus. This formatter adds timestamp, level, request ID, and source location to each log entry. Format: [2025-12-23 20:14:04] debug [manager.go:524] | a1b2c3d4 | Use API key sk-9...0RHO for model gpt-5.2
type RequestLogger ¶
type RequestLogger interface {
// LogRequest logs a complete non-streaming request/response cycle.
//
// Parameters:
// - url: The request URL
// - method: The HTTP method
// - requestHeaders: The request headers
// - body: The request body
// - statusCode: The response status code
// - responseHeaders: The response headers
// - response: The raw response data
// - apiRequest: The API request data
// - apiResponse: The API response data
// - requestID: Optional request ID for log file naming
// - requestTimestamp: When the request was received
// - apiResponseTimestamp: When the API response was received
//
// Returns:
// - error: An error if logging fails, nil otherwise
LogRequest(
url, method string,
requestHeaders map[string][]string,
body []byte,
statusCode int,
responseHeaders map[string][]string,
response, websocketTimeline, apiRequest, apiResponse, apiWebsocketTimeline []byte,
apiResponseErrors []*interfaces.ErrorMessage,
requestID string,
requestTimestamp, apiResponseTimestamp time.Time,
) error
// LogStreamingRequest initiates logging for a streaming request and returns a writer for chunks.
//
// Parameters:
// - url: The request URL
// - method: The HTTP method
// - headers: The request headers
// - body: The request body
// - requestID: Optional request ID for log file naming
//
// Returns:
// - StreamingLogWriter: A writer for streaming response chunks
// - error: An error if logging initialization fails, nil otherwise
LogStreamingRequest(
url, method string,
headers map[string][]string,
body []byte,
requestID string,
) (StreamingLogWriter, error)
// IsEnabled returns whether request logging is currently enabled.
//
// Returns:
// - bool: True if logging is enabled, false otherwise
IsEnabled() bool
}
RequestLogger defines the interface for logging HTTP requests and responses. It provides methods for logging both regular and streaming HTTP request/response cycles.
type StreamingLogWriter ¶
type StreamingLogWriter interface {
// WriteChunkAsync writes a response chunk asynchronously (non-blocking).
//
// Parameters:
// - chunk: The response chunk to write
WriteChunkAsync(chunk []byte)
// WriteStatus writes the response status and headers to the log.
//
// Parameters:
// - status: The response status code
// - headers: The response headers
//
// Returns:
// - error: An error if writing fails, nil otherwise
WriteStatus(status int, headers map[string][]string) error
// WriteAPIRequest writes the upstream API request details to the log.
// This should be called before WriteStatus to maintain proper log ordering.
//
// Parameters:
// - apiRequest: The API request data (typically includes URL, headers, body sent upstream)
//
// Returns:
// - error: An error if writing fails, nil otherwise
WriteAPIRequest(apiRequest []byte) error
// WriteAPIResponse writes the upstream API response details to the log.
// This should be called after the streaming response is complete.
//
// Parameters:
// - apiResponse: The API response data
//
// Returns:
// - error: An error if writing fails, nil otherwise
WriteAPIResponse(apiResponse []byte) error
// WriteAPIWebsocketTimeline writes the upstream websocket timeline to the log.
// This should be called when upstream communication happened over websocket.
//
// Parameters:
// - apiWebsocketTimeline: The upstream websocket event timeline
//
// Returns:
// - error: An error if writing fails, nil otherwise
WriteAPIWebsocketTimeline(apiWebsocketTimeline []byte) error
// SetFirstChunkTimestamp sets the TTFB timestamp captured when first chunk was received.
//
// Parameters:
// - timestamp: The time when first response chunk was received
SetFirstChunkTimestamp(timestamp time.Time)
// Close finalizes the log file and cleans up resources.
//
// Returns:
// - error: An error if closing fails, nil otherwise
Close() error
}
StreamingLogWriter handles real-time logging of streaming response chunks. It provides methods for writing streaming response data asynchronously.