feat: file logger
This commit is contained in:
		| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"git.cryptic.systems/fh-trier/go-flucky/cmd/remote" | 	"git.cryptic.systems/fh-trier/go-flucky/cmd/remote" | ||||||
| 	"git.cryptic.systems/fh-trier/go-flucky/cmd/sensor" | 	"git.cryptic.systems/fh-trier/go-flucky/cmd/sensor" | ||||||
| 	"git.cryptic.systems/fh-trier/go-flucky/cmd/temperature" | 	"git.cryptic.systems/fh-trier/go-flucky/cmd/temperature" | ||||||
|  | 	"git.cryptic.systems/fh-trier/go-flucky/pkg/logger" | ||||||
| 	"git.cryptic.systems/fh-trier/go-flucky/pkg/types" | 	"git.cryptic.systems/fh-trier/go-flucky/pkg/types" | ||||||
|  |  | ||||||
| 	"git.cryptic.systems/fh-trier/go-flucky/pkg/config" | 	"git.cryptic.systems/fh-trier/go-flucky/pkg/config" | ||||||
| @@ -29,12 +30,19 @@ var rootCmd = &cobra.Command{ | |||||||
| 				return fmt.Errorf("Can not locate the hostname: %v", err) | 				return fmt.Errorf("Can not locate the hostname: %v", err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			logfiles := make(map[logger.LogValue][]string) | ||||||
|  | 			logfiles[logger.LogHumidity] = []string{"/var/log/flucky/humidity.log"} | ||||||
|  | 			logfiles[logger.LogTemperature] = []string{"/var/log/flucky/temperature.log"} | ||||||
|  |  | ||||||
| 			fc := config.FluckyConfig{ | 			fc := config.FluckyConfig{ | ||||||
| 				Device: &types.Device{ | 				Device: &types.Device{ | ||||||
| 					DeviceID:     uuid.NewV4().String(), | 					DeviceID:     uuid.NewV4().String(), | ||||||
| 					DeviceName:   hostname, | 					DeviceName:   hostname, | ||||||
| 					CreationDate: time.Now(), | 					CreationDate: time.Now(), | ||||||
| 				}, | 				}, | ||||||
|  | 				FileLogger: &logger.FileLogger{ | ||||||
|  | 					LogFiles: logfiles, | ||||||
|  | 				}, | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			err = config.Write(&fc, cfg) | 			err = config.Write(&fc, cfg) | ||||||
|   | |||||||
| @@ -8,6 +8,8 @@ import ( | |||||||
| 	"text/tabwriter" | 	"text/tabwriter" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"git.cryptic.systems/fh-trier/go-flucky/pkg/logger" | ||||||
|  |  | ||||||
| 	"git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" | 	"git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" | ||||||
|  |  | ||||||
| 	"git.cryptic.systems/fh-trier/go-flucky/pkg/types" | 	"git.cryptic.systems/fh-trier/go-flucky/pkg/types" | ||||||
| @@ -16,9 +18,10 @@ import ( | |||||||
|  |  | ||||||
| // FluckyConfig dasd | // FluckyConfig dasd | ||||||
| type FluckyConfig struct { | type FluckyConfig struct { | ||||||
| 	Device  *types.Device   `json:"device"` | 	Device *types.Device `json:"device"` | ||||||
| 	Sensors []*types.Sensor `json:"sensors"` | 	*logger.FileLogger | ||||||
| 	Remotes []*Remote       `json:"remotes"` | 	Remotes []*Remote       `json:"remotes"` | ||||||
|  | 	Sensors []*types.Sensor `json:"sensors"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddSensor add a new sensor | // AddSensor add a new sensor | ||||||
|   | |||||||
							
								
								
									
										161
									
								
								pkg/logger/file_logger.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								pkg/logger/file_logger.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,161 @@ | |||||||
|  | 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, | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								pkg/logger/logger.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								pkg/logger/logger.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | package logger | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"git.cryptic.systems/fh-trier/go-flucky/pkg/types" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type Logger interface { | ||||||
|  | 	LogHumidities(humidities []*types.Humidity) error | ||||||
|  | 	LogTemperatures(temperatures []*types.Temperature) error | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type LoggerType string | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	LogFile   LoggerType = "file" | ||||||
|  | 	LogRemote            = "remote" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type LogValue string | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	LogHumidity    LogValue = "humidity" | ||||||
|  | 	LogTemperature          = "temperature" | ||||||
|  | ) | ||||||
		Reference in New Issue
	
	Block a user