package logger import ( "encoding/json" "fmt" "io" "io/ioutil" "os" "path/filepath" "sync" "git.cryptic.systems/fh-trier/go-flucky/pkg/internal/errutils" "git.cryptic.systems/fh-trier/go-flucky/pkg/types" ) type FileLogger struct { LogFiles map[LogValue][]string `json:"logfiles"` writer io.Writer } func (fl *FileLogger) AddLogFile(logfile string, logValue LogValue) { fl.LogFiles[logValue] = append(fl.LogFiles[logValue], logfile) } func (fl *FileLogger) LogHumidities(humidities []*types.Humidity) error { countLogfiles := len(fl.LogFiles[LogHumidity]) wg := sync.WaitGroup{} wg.Add(countLogfiles) errChan := make(chan error) for _, logfile := range fl.LogFiles[LogHumidity] { go func(humidities []*types.Humidity, logfile string) { defer wg.Done() // read existing humidities as bytes bytes, err := ioutil.ReadFile(logfile) if err != nil { errChan <- err return } // convert bytes into humidities logHumidities := []*types.Humidity{} err = json.Unmarshal(bytes, &logHumidities) if err != nil { errChan <- err return } // append new humidities with exsisting humidities from logfile logHumidities = append(logHumidities, humidities...) // convert humidities into json file bytes, err = json.MarshalIndent(logHumidities, "", " ") err = json.Unmarshal(bytes, &logHumidities) if err != nil { errChan <- err return } ioutil.WriteFile(logfile, bytes, os.ModePerm) }(humidities, logfile) } wg.Wait() errList := errutils.CollectErrors(errChan) err := errutils.FormatErrors(errList) if err != nil { return err } return nil } func (fl *FileLogger) LogTemperatures(temperatures []*types.Temperature) error { countLogfiles := len(fl.LogFiles[LogTemperature]) wg := sync.WaitGroup{} wg.Add(countLogfiles) errChan := make(chan error) for _, logfile := range fl.LogFiles[LogTemperature] { go func(temps []*types.Temperature, lf string) { defer wg.Done() if _, err := os.Stat(lf); os.IsNotExist(err) { err := os.MkdirAll(filepath.Dir(lf), os.ModeDir) if err != nil { errChan <- fmt.Errorf("Can not create directory: %v", err) return } f, err := os.Create(lf) if err != nil { errChan <- fmt.Errorf("Can not create log file: %v", err) return } f.Close() } // open logfile f, err := os.Open(lf) if err != nil { errChan <- err return } // decode file content into temperatures logTemperatures := []*types.Temperature{} decoder := json.NewDecoder(f) err = decoder.Decode(&logTemperatures) if err != nil { errChan <- err return } // close file f.Close() // append new humidities with exsisting humidities from logfile logTemperatures = append(logTemperatures, temps...) // create new logfile f, err = os.Create(lf) if err != nil { errChan <- err return } // convert humidities into json file encoder := json.NewEncoder(f) encoder.SetIndent("", " ") err = encoder.Encode(logTemperatures) if err != nil { errChan <- err return } f.Close() }(temperatures, logfile) } wg.Wait() errList := errutils.CollectErrors(errChan) err := errutils.FormatErrors(errList) if err != nil { return err } return nil } func NewFileLogger(w io.Writer) *FileLogger { return &FileLogger{ writer: w, } }