func newCustomReceiverDispatcherByValue(formatter *formatter, customReceiver CustomReceiver, name string, cArgs CustomReceiverInitArgs) (*customReceiverDispatcher, error) {
	if formatter == nil {
		return nil, errors.New("formatter cannot be nil")
	}
	if customReceiver == nil {
		return nil, errors.New("customReceiver cannot be nil")
	}
	disp := &customReceiverDispatcher{formatter, customReceiver, name, cArgs}
	return disp, nil
}
newCustomReceiverDispatcherByValue is basically the same as newCustomReceiverDispatcher, but using
a specific CustomReceiver value instead of instantiating a new one by type.
package seelog
import (
	"errors"
	"fmt"
	"reflect"
	"sort"
)
var registeredReceivers = make(map[string]reflect.Type)
func RegisterReceiver(name string, receiver CustomReceiver) {
	newType := reflect.TypeOf(reflect.ValueOf(receiver).Elem().Interface())
	if t, ok := registeredReceivers[name]; ok && t != newType {
		panic(fmt.Sprintf("duplicate types for %s: %s != %s", name, t, newType))
	}
	registeredReceivers[name] = newType
}
func customReceiverByName(name string) (creceiver CustomReceiver, err error) {
	rt, ok := registeredReceivers[name]
	if !ok {
		return nil, fmt.Errorf("Custom receiver name not registered: '%s'", name)
	}
	v, ok := reflect.New(rt).Interface().(CustomReceiver)
	if !ok {
		return nil, fmt.Errorf("Cannot instantiate receiver with name='%s'", name)
	}
	return v, nil
}
type CustomReceiverInitArgs struct {
	XmlCustomAttrs map[string]string
}
type CustomReceiver interface {
	ReceiveMessage(message string, level LogLevel, context LogContextInterface) error
	AfterParse(initArgs CustomReceiverInitArgs) error
	Flush()
	Close() error
}
type customReceiverDispatcher struct {
	formatter          *formatter
	innerReceiver      CustomReceiver
	customReceiverName string
	usedArgs           CustomReceiverInitArgs
}
func newCustomReceiverDispatcher(formatter *formatter, customReceiverName string, cArgs CustomReceiverInitArgs) (*customReceiverDispatcher, error) {
	if formatter == nil {
		return nil, errors.New("formatter cannot be nil")
	}
	if len(customReceiverName) == 0 {
		return nil, errors.New("custom receiver name cannot be empty")
	}
	creceiver, err := customReceiverByName(customReceiverName)
	if err != nil {
		return nil, err
	}
	err = creceiver.AfterParse(cArgs)
	if err != nil {
		return nil, err
	}
	disp := &customReceiverDispatcher{formatter, creceiver, customReceiverName, cArgs}
	return disp, nil
}