func toValue(p interface{}) reflect.Value {
	v := reflect.ValueOf(p)
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}
	return v
}
toValue converts any value to reflect.Value
package logrus_fluent
import (
	"fmt"
	"reflect"
	"strings"
)
func ConvertToValue(p interface{}, tagName string) interface{} {
	rv := toValue(p)
	switch rv.Kind() {
	case reflect.Struct:
		if err, ok := p.(error); ok {
			return err.Error()
		}
		return convertFromStruct(rv.Interface(), tagName)
	case reflect.Map:
		return convertFromMap(rv, tagName)
	case reflect.Slice:
		return convertFromSlice(rv, tagName)
	case reflect.Chan:
		return nil
	case reflect.Invalid:
		return nil
	default:
		return rv.Interface()
	}
}
func convertFromMap(rv reflect.Value, tagName string) interface{} {
	result := make(map[string]interface{})
	for _, key := range rv.MapKeys() {
		kv := rv.MapIndex(key)
		result[fmt.Sprint(key.Interface())] = ConvertToValue(kv.Interface(), tagName)
	}
	return result
}
func convertFromSlice(rv reflect.Value, tagName string) interface{} {
	var result []interface{}
	for i, max := 0, rv.Len(); i < max; i++ {
		result = append(result, ConvertToValue(rv.Index(i).Interface(), tagName))
	}
	return result
}
func convertFromStruct(p interface{}, tagName string) interface{} {
	result := make(map[string]interface{})
	return convertFromStructDeep(result, tagName, toType(p), toValue(p))
}
func convertFromStructDeep(result map[string]interface{}, tagName string, t reflect.Type, values reflect.Value) interface{} {
	for i, max := 0, t.NumField(); i < max; i++ {
		f := t.Field(i)
		if f.PkgPath != "" && !f.Anonymous {
			continue
		}
		if f.Anonymous {
			tt := f.Type
			if tt.Kind() == reflect.Ptr {
				tt = tt.Elem()
			}
			vv := values.Field(i)
			if !vv.IsValid() {
				continue
			}
			if vv.Kind() == reflect.Ptr {
				vv = vv.Elem()
			}
			if vv.Kind() == reflect.Struct {
				convertFromStructDeep(result, tagName, tt, vv)
			}
			continue
		}
		tag, opts := parseTag(f, tagName)
		if tag == "-" {
			continue  
		}
		if !values.IsValid() {
			continue
		}
		v := values.Field(i)
		if opts.Has("omitempty") && isZero(v) {
			continue  
		}
		name := getNameFromTag(f, tagName)
		result[name] = ConvertToValue(v.Interface(), TagName)
	}
	return result
}