drive-health/lib/svc/service.go

132 lines
3.2 KiB
Go

package svc
import (
"encoding/gob"
"fmt"
"io"
"os"
"time"
"tea.chunkbyte.com/kato/drive-health/lib/config"
"tea.chunkbyte.com/kato/drive-health/lib/hardware"
)
// The path to where the snapshot database is located
const SNAPSHOT_LIST_PATH = "./snapshots.dat"
// A simple in-memory buffer for the history of snapshots
var snapShotBuffer []*HardwareSnapshot
// A snapshot in time of the current state of the harddrives
type HardwareSnapshot struct {
TimeStamp time.Time
HDD []*hardware.HardDrive
}
type Snapshots struct {
List []*HardwareSnapshot
}
// The function itterates through all hard disks and takes a snapshot of their state,
// returns a struct which contains metadata as well as the harddrives themselves.
func TakeHardwareSnapshot() (*HardwareSnapshot, error) {
drives, err := hardware.GetSystemHardDrives()
if err != nil {
return nil, err
}
snapShot := &HardwareSnapshot{
TimeStamp: time.Now(),
HDD: []*hardware.HardDrive{},
}
for _, hdd := range drives {
hdd.GetTemperature(true)
snapShot.HDD = append(snapShot.HDD, hdd)
}
// Append to the in-memory listing
snapShotBuffer = append(snapShotBuffer, snapShot)
// Return the snapshot just in case there is any need to modify it,
// any modification to it will also affect the current buffer from memory.
return snapShot, nil
}
// The function wil check if the `.dat` file is present, if it is then it will load it into memory
func UpdateHardwareSnapshotsFromFile() {
file, err := os.Open(SNAPSHOT_LIST_PATH)
if err != nil {
if os.IsNotExist(err) {
return // File does not exist, no snapshots to load
}
panic(err) // Handle error according to your error handling policy
}
defer file.Close()
decoder := gob.NewDecoder(file)
var snapshots Snapshots
if err := decoder.Decode(&snapshots); err != nil {
if err == io.EOF {
return // End of file reached
}
panic(err) // Handle error according to your error handling policy
}
snapShotBuffer = snapshots.List
fmt.Printf("Loaded %v snapshots from .dat", len(snapShotBuffer))
}
// Get the list of snapshots that have been buffered in memory
func GetHardwareSnapshot() []*HardwareSnapshot {
return snapShotBuffer
}
// Dump the current snapshot history from memory to file
func SaveSnapshotsToFile() error {
file, err := os.Create(SNAPSHOT_LIST_PATH)
if err != nil {
return err
}
defer file.Close()
encoder := gob.NewEncoder(file)
snapshots := Snapshots{List: snapShotBuffer}
if err := encoder.Encode(snapshots); err != nil {
return err
}
return nil
}
func RunService() {
// Snapshot taking routine
go func() {
for {
time.Sleep(time.Duration(config.GetConfiguration().DiskFetchFrequency) * time.Second)
data, err := TakeHardwareSnapshot()
if err != nil {
fmt.Printf("Hardware Fetch Error: %s", err)
} else {
fmt.Println("Got Snapshot for " + data.TimeStamp.Format("02/01/2006"))
for _, hdd := range data.HDD {
fmt.Printf("%s[%s]: %v\n", hdd.Model, hdd.Size, hdd.Temperature)
}
}
}
}()
// Periodic saving routine
go func() {
for {
time.Sleep(time.Duration(config.GetConfiguration().MemoryDumpFrequency) * time.Second)
err := SaveSnapshotsToFile()
if err != nil {
fmt.Printf("Memory Dump Error: %s", err)
}
}
}()
}