diff options
Diffstat (limited to 'datalogger/logger.go')
| -rw-r--r-- | datalogger/logger.go | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/datalogger/logger.go b/datalogger/logger.go index dd071a1..1a4cd20 100644 --- a/datalogger/logger.go +++ b/datalogger/logger.go @@ -11,7 +11,6 @@ * You should have received a copy of the GNU General Public License along * with Go Responsiveness. If not, see <https://www.gnu.org/licenses/>. */ - package datalogger import ( @@ -20,6 +19,8 @@ import ( "os" "reflect" "sync" + + "github.com/network-quality/goresponsiveness/utilities" ) type DataLogger[T any] interface { @@ -55,6 +56,33 @@ func (logger *CSVDataLogger[T]) LogRecord(record T) { logger.data = append(logger.data, record) } +func doCustomFormatting(value reflect.Value, tag reflect.StructTag) (string, error) { + if utilities.IsInterfaceNil(value) { + return "", fmt.Errorf("Cannot format an empty interface value") + } + formatMethodName, success := tag.Lookup("Formatter") + if !success { + return "", fmt.Errorf("Could not find the formatter name") + } + formatMethodArgument, success := tag.Lookup("FormatterArgument") + if !success { + return "", fmt.Errorf("Could not find the formatter name") + } + + formatMethod := value.MethodByName(formatMethodName) + if formatMethod == reflect.ValueOf(0) { + return "", fmt.Errorf("Type %v does not support a method named %v", value.Type(), formatMethodName) + } + + formatMethodArgumentUsable := make([]reflect.Value, 1) + formatMethodArgumentUsable[0] = reflect.ValueOf(formatMethodArgument) + result := formatMethod.Call(formatMethodArgumentUsable) + if len(result) == 1 { + return result[0].String(), nil + } + return "", fmt.Errorf("Too many results returned by the format method's invocation.") +} + func (logger *CSVDataLogger[T]) Export() bool { logger.mut.Lock() defer logger.mut.Unlock() @@ -62,8 +90,7 @@ func (logger *CSVDataLogger[T]) Export() bool { return false } - t := new(T) - visibleFields := reflect.VisibleFields(reflect.TypeOf(t).Elem()) + visibleFields := reflect.VisibleFields(reflect.TypeOf((*T)(nil)).Elem()) for _, v := range visibleFields { description, success := v.Tag.Lookup("Description") columnName := fmt.Sprintf("%s", v.Name) @@ -78,7 +105,11 @@ func (logger *CSVDataLogger[T]) Export() bool { for _, v := range visibleFields { data := reflect.ValueOf(d) toWrite := data.FieldByIndex(v.Index) - logger.destination.Write([]byte(fmt.Sprintf("%v, ", toWrite))) + if formattedToWrite, err := doCustomFormatting(toWrite, v.Tag); err == nil { + logger.destination.Write([]byte(fmt.Sprintf("%s,", formattedToWrite))) + } else { + logger.destination.Write([]byte(fmt.Sprintf("%v, ", toWrite))) + } } logger.destination.Write([]byte("\n")) } |
