package main import ( "context" "database/sql" "encoding/json" _ "modernc.org/sqlite" ) type StorageService struct { db *sql.DB } func NewStorageService(dbPath string) (*StorageService, error) { db, err := sql.Open("sqlite", dbPath) if err != nil { return nil, err } createTableStmt := ` CREATE TABLE IF NOT EXISTS log_entries ( id INTEGER PRIMARY KEY AUTOINCREMENT, service TEXT, timestamp DATETIME, type TEXT, host TEXT, tool TEXT, log_level TEXT, log_message TEXT, raw TEXT, priority TEXT, priority_name TEXT, unit TEXT, pid INTEGER, boot_id TEXT, machine_id TEXT, fields TEXT, service_information TEXT, system_metrics TEXT, tool_information TEXT ); ` _, err = db.ExecContext(context.Background(), createTableStmt) if err != nil { return nil, err } return &StorageService{db: db}, nil } func (s *StorageService) Close() error { return s.db.Close() } func (s *StorageService) SaveLogEntry(ctx context.Context, entry *LogEntry) error { fieldsJSON := "" if entry.Fields != nil { b, err := json.Marshal(entry.Fields) if err != nil { return err } fieldsJSON = string(b) } serviceInfoJSON := "" if entry.ServiceInformation != nil { b, err := json.Marshal(entry.ServiceInformation) if err != nil { return err } serviceInfoJSON = string(b) } systemMetricsJSON := "" if entry.SystemMetrics != nil { b, err := json.Marshal(entry.SystemMetrics) if err != nil { return err } systemMetricsJSON = string(b) } toolInfoJSON := "" if entry.ToolInformation != nil { b, err := json.Marshal(entry.ToolInformation) if err != nil { return err } toolInfoJSON = string(b) } stmt := ` INSERT INTO log_entries (service, timestamp, type, host, tool, log_level, log_message, raw, priority, priority_name, unit, pid, boot_id, machine_id, fields, service_information, system_metrics, tool_information) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ` _, err := s.db.ExecContext(ctx, stmt, entry.Service, entry.Timestamp, entry.Type, entry.Host, entry.Tool, entry.LogLevel, entry.LogMessage, entry.Raw, entry.Priority, entry.PriorityName, entry.Unit, entry.PID, entry.BootID, entry.MachineID, fieldsJSON, serviceInfoJSON, systemMetricsJSON, toolInfoJSON, ) return err } func (s *StorageService) LoadLogEntry(ctx context.Context, id int64) (*LogEntry, error) { row := s.db.QueryRowContext(ctx, "SELECT service, timestamp, type, host, tool, log_level, log_message, raw, priority, priority_name, unit, pid, boot_id, machine_id, fields, service_information, system_metrics, tool_information FROM log_entries WHERE id = ?", id) var entry LogEntry var fieldsJSON, serviceInfoJSON, systemMetricsJSON, toolInfoJSON string err := row.Scan( &entry.Service, &entry.Timestamp, &entry.Type, &entry.Host, &entry.Tool, &entry.LogLevel, &entry.LogMessage, &entry.Raw, &entry.Priority, &entry.PriorityName, &entry.Unit, &entry.PID, &entry.BootID, &entry.MachineID, &fieldsJSON, &serviceInfoJSON, &systemMetricsJSON, &toolInfoJSON, ) if err != nil { return nil, err } if fieldsJSON != "" { var fields map[string]any if err = json.Unmarshal([]byte(fieldsJSON), &fields); err == nil { entry.Fields = fields } } if serviceInfoJSON != "" { var si any if err = json.Unmarshal([]byte(serviceInfoJSON), &si); err == nil { entry.ServiceInformation = si } } if systemMetricsJSON != "" { var sm any if err = json.Unmarshal([]byte(systemMetricsJSON), &sm); err == nil { entry.SystemMetrics = sm } } if toolInfoJSON != "" { var ti any if err = json.Unmarshal([]byte(toolInfoJSON), &ti); err == nil { entry.ToolInformation = ti } } return &entry, nil }