package logger import ( "encoding/json" "fmt" "io" "io/ioutil" "os" "sync" "time" "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) GetHumidities(fromDate *time.Time, tillDate *time.Time, sensorNameOrUUID *[]string) ([]*types.Humidity, error) { return nil, nil } func (fl *FileLogger) GetTemperatures(from *time.Time, till *time.Time, sensorIDs []string) ([]*types.Temperature, error) { cachedTemperatures := []*types.Temperature{} // iterate over all configured temperature logfiles for _, logfile := range fl.LogFiles[LogTemperature] { // skip logfile if not exists if _, err := os.Stat(logfile); os.IsNotExist(err) { return nil, fmt.Errorf("Logfile %v not exists", logfile) } loggedTemperatures := []*types.Temperature{} f, err := os.Open(logfile) if err != nil { return nil, fmt.Errorf("Can not open %v: %v", logfile, err) } defer f.Close() decoder := json.NewDecoder(f) err = decoder.Decode(&loggedTemperatures) if err != nil { return nil, fmt.Errorf("Can not decode temperatures from logfile %v: %v", logfile, err) } // sort all redundant values out for _, loggedTemperature := range loggedTemperatures { found := false for _, cachedTemperature := range cachedTemperatures { if cachedTemperature.TemperatureID == loggedTemperature.TemperatureID { found = true break } } if !found { cachedTemperatures = append(cachedTemperatures, loggedTemperature) } } } // // sort out all temperatures which are not mesured by sensor id // for i, cachedTemperature := range cachedTemperatures { // found := false // for _, sensorID := range sensorIDs { // if cachedTemperature.SensorID == sensorID { // found = true // break // } // } // if !found { // cachedTemperatures = append(cachedTemperatures[:i], cachedTemperatures[i+1:]...) // } // } // // sort out all temperatures which are before from date // if from != nil { // for i, cachedTemperature := range cachedTemperatures { // if cachedTemperature.TemperatureDate.Before(*from) { // cachedTemperatures = append(cachedTemperatures[:i], cachedTemperatures[i+1:]...) // } // } // } // // sort out all temperatures which are after till date // if till != nil { // for i, cachedTemperature := range cachedTemperatures { // if cachedTemperature.TemperatureDate.After(*till) { // cachedTemperatures = append(cachedTemperatures[:i], cachedTemperatures[i+1:]...) // } // } // } return cachedTemperatures, nil } 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 { for _, logfile := range fl.LogFiles[LogTemperature] { logTemperatures := []*types.Temperature{} // open logfile f, err := os.OpenFile(logfile, os.O_RDWR, os.ModePerm) if err != nil { return fmt.Errorf("Can not open file %v: %v", logfile, err) } defer f.Close() // if logfile already exists, read temperatures from logfile if _, err := os.Stat(logfile); os.IsExist(err) { decoder := json.NewDecoder(f) err = decoder.Decode(&logTemperatures) if err != nil { return fmt.Errorf("Can not decode temperatures from reader") } } // append new temperatures with exsisting humidities from logfile logTemperatures = append(logTemperatures, temperatures...) // encode temperatures encoder := json.NewEncoder(f) encoder.SetIndent("", " ") err = encoder.Encode(logTemperatures) if err != nil { return fmt.Errorf("Can not encode temperatures for the writer") } } return nil } func NewFileLogger(w io.Writer) *FileLogger { return &FileLogger{ writer: w, } }