Hub v0.6.1: delete issues from UI + fingerprint hardening
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,9 +3,17 @@ package store
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
reANSI = regexp.MustCompile(`\x1b\[[0-9;]*m`)
|
||||
reTimestamp = regexp.MustCompile(`\d{4}[-/]\d{2}[-/]\d{2}[T ]\d{2}:\d{2}:\d{2}[.\d]*([+-]\d{2}:?\d{2})?[Z ]?:? ?`)
|
||||
reSyslog = regexp.MustCompile(`[A-Z][a-z]{2}\s+\d{1,2} \d{2}:\d{2}:\d{2} `)
|
||||
)
|
||||
|
||||
// AppTelemetryRecord holds per-app telemetry received from a controller report.
|
||||
type AppTelemetryRecord struct {
|
||||
AppName string `json:"app_name"`
|
||||
@@ -180,10 +188,15 @@ func upsertAppIssue(tx *sql.Tx, appName, fingerprint, severity, message, custome
|
||||
|
||||
// fingerprintIssue creates a short fingerprint key from a message string.
|
||||
func fingerprintIssue(msg string) string {
|
||||
if len(msg) > 100 {
|
||||
msg = msg[:100]
|
||||
s := reANSI.ReplaceAllString(msg, "")
|
||||
s = reTimestamp.ReplaceAllString(s, "")
|
||||
s = reSyslog.ReplaceAllString(s, "")
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.ToLower(s)
|
||||
if len(s) > 100 {
|
||||
s = s[:100]
|
||||
}
|
||||
return msg
|
||||
return s
|
||||
}
|
||||
|
||||
// min returns the smaller of two ints.
|
||||
@@ -464,3 +477,22 @@ func (s *Store) DeleteAppIssues(appName string) (int64, error) {
|
||||
}
|
||||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
// DeleteAppIssuesByIDs removes specific issue records by their IDs.
|
||||
func (s *Store) DeleteAppIssuesByIDs(ids []int) (int64, error) {
|
||||
if len(ids) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
placeholders := make([]string, len(ids))
|
||||
args := make([]interface{}, len(ids))
|
||||
for i, id := range ids {
|
||||
placeholders[i] = "?"
|
||||
args[i] = id
|
||||
}
|
||||
query := "DELETE FROM app_log_issues WHERE id IN (" + strings.Join(placeholders, ",") + ")"
|
||||
res, err := s.db.Exec(query, args...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user