watch-tool/local_storage.go

180 lines
3.7 KiB
Go

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
}