179 lines
4.0 KiB
Go
179 lines
4.0 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/backend/internal/storage"
|
|
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
|
|
)
|
|
|
|
type LogRepository struct {
|
|
Conn driver.Conn
|
|
}
|
|
|
|
func NewLogRepository(conn driver.Conn) *LogRepository {
|
|
return &LogRepository{Conn: conn}
|
|
}
|
|
|
|
func (r *LogRepository) Init(ctx context.Context) error {
|
|
return r.Conn.Exec(ctx, storage.CreateLogsTable)
|
|
}
|
|
|
|
func (r *LogRepository) Insert(ctx context.Context, log storage.LogEntry) error {
|
|
return r.Conn.Exec(ctx, `
|
|
INSERT INTO logs (timestamp, level, service, agent, message)
|
|
VALUES ($1, $2, $3, $4, $5)
|
|
`, log.Timestamp, log.Level, log.Service, log.Agent, log.Message)
|
|
}
|
|
|
|
func (r *LogRepository) InsertBatch(ctx context.Context, logs []storage.LogEntry) error {
|
|
batch, err := r.Conn.PrepareBatch(ctx, "INSERT INTO logs (timestamp, level, service, agent, message)")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, log := range logs {
|
|
if err := batch.Append(log.Timestamp, log.Level, log.Service, log.Agent, log.Message); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return batch.Send()
|
|
}
|
|
|
|
type LogFilter struct {
|
|
Level string
|
|
Service string
|
|
Agent string
|
|
DateFrom time.Time
|
|
DateTo time.Time
|
|
Limit int
|
|
Offset int
|
|
}
|
|
|
|
func (r *LogRepository) Search(ctx context.Context, filter LogFilter) ([]storage.LogEntry, error) {
|
|
query := "SELECT timestamp, level, service, agent, message FROM logs WHERE 1=1"
|
|
args := make([]interface{}, 0)
|
|
argIdx := 1
|
|
|
|
if filter.Level != "" {
|
|
query += " AND level = $" + string(rune('0'+argIdx))
|
|
args = append(args, filter.Level)
|
|
argIdx++
|
|
}
|
|
|
|
if filter.Service != "" {
|
|
query += " AND service = $" + string(rune('0'+argIdx))
|
|
args = append(args, filter.Service)
|
|
argIdx++
|
|
}
|
|
|
|
if filter.Agent != "" {
|
|
query += " AND agent = $" + string(rune('0'+argIdx))
|
|
args = append(args, filter.Agent)
|
|
argIdx++
|
|
}
|
|
|
|
if !filter.DateFrom.IsZero() {
|
|
query += " AND timestamp >= $" + string(rune('0'+argIdx))
|
|
args = append(args, filter.DateFrom)
|
|
argIdx++
|
|
}
|
|
|
|
if !filter.DateTo.IsZero() {
|
|
query += " AND timestamp <= $" + string(rune('0'+argIdx))
|
|
args = append(args, filter.DateTo)
|
|
argIdx++
|
|
}
|
|
|
|
query += " ORDER BY timestamp DESC"
|
|
|
|
if filter.Limit > 0 {
|
|
query += " LIMIT $" + string(rune('0'+argIdx))
|
|
args = append(args, filter.Limit)
|
|
argIdx++
|
|
} else {
|
|
query += " LIMIT 100"
|
|
}
|
|
|
|
if filter.Offset > 0 {
|
|
query += " OFFSET $" + string(rune('0'+argIdx))
|
|
args = append(args, filter.Offset)
|
|
}
|
|
|
|
rows, err := r.Conn.Query(ctx, query, args...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var logs []storage.LogEntry
|
|
for rows.Next() {
|
|
var log storage.LogEntry
|
|
if err := rows.Scan(&log.Timestamp, &log.Level, &log.Service, &log.Agent, &log.Message); err != nil {
|
|
return nil, err
|
|
}
|
|
logs = append(logs, log)
|
|
}
|
|
|
|
return logs, rows.Err()
|
|
}
|
|
|
|
func (r *LogRepository) GetDistinctServices(ctx context.Context) ([]string, error) {
|
|
rows, err := r.Conn.Query(ctx, "SELECT DISTINCT service FROM logs ORDER BY service")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var services []string
|
|
for rows.Next() {
|
|
var service string
|
|
if err := rows.Scan(&service); err != nil {
|
|
return nil, err
|
|
}
|
|
services = append(services, service)
|
|
}
|
|
|
|
return services, rows.Err()
|
|
}
|
|
|
|
func (r *LogRepository) GetDistinctAgents(ctx context.Context) ([]string, error) {
|
|
rows, err := r.Conn.Query(ctx, "SELECT DISTINCT agent FROM logs ORDER BY agent")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var agents []string
|
|
for rows.Next() {
|
|
var agent string
|
|
if err := rows.Scan(&agent); err != nil {
|
|
return nil, err
|
|
}
|
|
agents = append(agents, agent)
|
|
}
|
|
|
|
return agents, rows.Err()
|
|
}
|
|
|
|
func (r *LogRepository) GetDistinctLevels(ctx context.Context) ([]string, error) {
|
|
rows, err := r.Conn.Query(ctx, "SELECT DISTINCT level FROM logs ORDER BY level")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var levels []string
|
|
for rows.Next() {
|
|
var level string
|
|
if err := rows.Scan(&level); err != nil {
|
|
return nil, err
|
|
}
|
|
levels = append(levels, level)
|
|
}
|
|
|
|
return levels, rows.Err()
|
|
}
|