chore: publish pxmon v0.2.0
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ChangeRecord struct {
|
||||
At time.Time `json:"at"`
|
||||
Action string `json:"action"`
|
||||
Target string `json:"target"`
|
||||
Details string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
func (s *Service) changeHistoryPath() string {
|
||||
return filepath.Join(s.DataDir(), "history", "changes.log")
|
||||
}
|
||||
|
||||
func (s *Service) AppendChange(action, target, details string) error {
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
rec := ChangeRecord{
|
||||
At: s.now().UTC(),
|
||||
Action: strings.TrimSpace(action),
|
||||
Target: strings.TrimSpace(target),
|
||||
Details: strings.TrimSpace(details),
|
||||
}
|
||||
if rec.Action == "" {
|
||||
return nil
|
||||
}
|
||||
path := s.changeHistoryPath()
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
b, err := json.Marshal(rec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write(append(b, '\n'))
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Service) ListChanges(limit int) ([]ChangeRecord, error) {
|
||||
path := s.changeHistoryPath()
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
capHint := 32
|
||||
if limit > capHint {
|
||||
capHint = limit
|
||||
}
|
||||
items := make([]ChangeRecord, 0, capHint)
|
||||
sc := bufio.NewScanner(f)
|
||||
sc.Buffer(make([]byte, 0, 64*1024), 2*1024*1024)
|
||||
for sc.Scan() {
|
||||
line := strings.TrimSpace(sc.Text())
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
var rec ChangeRecord
|
||||
if err := json.Unmarshal([]byte(line), &rec); err != nil {
|
||||
continue
|
||||
}
|
||||
items = append(items, rec)
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
return nil, fmt.Errorf("scan change history: %w", err)
|
||||
}
|
||||
if limit > 0 && len(items) > limit {
|
||||
items = items[len(items)-limit:]
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
Reference in New Issue
Block a user