diff options
Diffstat (limited to 'datalogger/logger.go')
| -rw-r--r-- | datalogger/logger.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/datalogger/logger.go b/datalogger/logger.go new file mode 100644 index 0000000..26717fb --- /dev/null +++ b/datalogger/logger.go @@ -0,0 +1,83 @@ +package datalogger + +import ( + "fmt" + "io" + "os" + "reflect" + "sync" +) + +type DataLogger[T any] interface { + LogRecord(record T) + Export() bool + Close() bool +} + +type CSVDataLogger[T any] struct { + mut *sync.Mutex + recordCount int + data []T + isOpen bool + destination io.WriteCloser +} + +func CreateCSVDataLogger[T any](filename string) (DataLogger[T], error) { + fmt.Printf("Creating a CSV data logger: %v!\n", filename) + data := make([]T, 0) + destination, err := os.Create(filename) + if err != nil { + return &CSVDataLogger[T]{&sync.Mutex{}, 0, data, true, destination}, err + } + + result := CSVDataLogger[T]{&sync.Mutex{}, 0, data, true, destination} + return &result, nil +} + +func (logger *CSVDataLogger[T]) LogRecord(record T) { + logger.mut.Lock() + defer logger.mut.Unlock() + logger.recordCount += 1 + logger.data = append(logger.data, record) +} + +func (logger *CSVDataLogger[T]) Export() bool { + logger.mut.Lock() + defer logger.mut.Unlock() + if !logger.isOpen { + return false + } + + t := new(T) + visibleFields := reflect.VisibleFields(reflect.TypeOf(t).Elem()) + for _, v := range visibleFields { + description, success := v.Tag.Lookup("Description") + columnName := fmt.Sprintf("%s", v.Name) + if success { + columnName = fmt.Sprintf("%s", description) + } + logger.destination.Write([]byte(fmt.Sprintf("%s, ", columnName))) + } + logger.destination.Write([]byte("\n")) + + for _, d := range logger.data { + for _, v := range visibleFields { + data := reflect.ValueOf(d) + toWrite := data.FieldByIndex(v.Index) + logger.destination.Write([]byte(fmt.Sprintf("%v, ", toWrite))) + } + logger.destination.Write([]byte("\n")) + } + return true +} + +func (logger *CSVDataLogger[T]) Close() bool { + logger.mut.Lock() + defer logger.mut.Unlock() + if !logger.isOpen { + return false + } + logger.destination.Close() + logger.isOpen = false + return true +} |
