func (l *alog) Errorln(err error, v ...interface{}) {
	go l.sendMultiLine(ERROR, err, v...)
}
Errorln creates error logs using the error and other values passed in.
Each error and value is printed on a different line
package alog
import (
	"context"
	"encoding/json"
	"fmt"
	"sync"
	"time"
	"go.devnw.com/validator"
)
const streamlog = "stream log"
type alog struct {
	ctx          context.Context
	cancel       context.CancelFunc
	destinations []Destination
	location *time.Location
	dateformat string
	prefix     string
	buffer     int
	mutty sync.RWMutex
	out map[LogLevel][]chan<- *log
	cleaned chan bool
}
func (l *alog) cleanup() {
	<-l.ctx.Done()
	l.mutty.Lock()
	defer l.mutty.Unlock()
	defer close(l.cleaned)
	for _, destinations := range l.out {
		for _, out := range destinations {
			ctx, cancel := context.WithTimeout(
				l.ctx,
				time.Millisecond,
			)
			go func(
				ctx context.Context,
				cancel context.CancelFunc,
				out chan<- *log,
			) {
				defer close(out)
				defer cancel()
				for len(out) > 0 {
					select {
					case <-ctx.Done():
					default:
					}
				}
			}(ctx, cancel, out)
		}
	}
}
func (l *alog) init() {
	go l.cleanup()
	for _, dest := range l.destinations {
		for level := range l.out {
			if dest.Types&level <= 0 {
				continue
			}
			l.out[level] = append(
				l.out[level],
				l.listen(l.ctx, dest),
			)
		}
	}
}
func (l *alog) listen(
	ctx context.Context,
	destination Destination,
) chan<- *log {
	logs := make(chan *log)
	go func(ctx context.Context, logs <-chan *log, destination Destination) {
		for {
			select {
			case <-ctx.Done():
				return
			case l, ok := <-logs:
				if !ok {
					return
				}
				if !validator.Valid(l) {
					continue
				}
				message := l.String()
				if destination.Format == JSON {
					msg, err := json.Marshal(l)
					if err != nil {
						panic("error marshaling JSON")
					}
					message = string(msg) + "\n"
				}
				_, err := destination.Writer.Write([]byte(message))
				if err != nil {
					panic("error writing to destination")
				}
			}
		}
	}(ctx, logs, destination)
	return logs
}
func (l *alog) send(ctx context.Context, value *log) {
	if value == nil {
		return
	}
	select {
	case <-ctx.Done():
	default:
		l.mutty.RLock()
		defer l.mutty.RUnlock()
		for _, destination := range l.out[value.logtype] {
			select {
			case <-ctx.Done():
				return
			case destination <- value:
			}
		}
	}
}
func (l *alog) buildlog(
	logtype LogLevel,
	custom string,
	err error,
	format *string,
	t time.Time,
	v ...interface{},
) (newlog *log) {
	values := v
	if format != nil {
		values = []interface{}{fmt.Sprintf(*format, v...)}
	}
	newlog = &log{
		logger:     l,
		logtype:    logtype,
		customtype: custom,
		timestamp:  t,
		err:        err,
		values:     values,
	}
	return newlog
}
func (l *alog) clog(
	ctx context.Context,
	v <-chan interface{},
	level LogLevel,
	custom string,
) {
	go func(
		ctx context.Context,
		v <-chan interface{},
		level LogLevel,
		custom string,
	) {
		for {
			select {
			case <-ctx.Done():
				return
			case value, ok := <-v:
				if !ok {
					return
				}
				switch t := value.(type) {
				case nil:
				case error:
					l.send(
						ctx,
						l.buildlog(
							level,
							custom,
							t,
							nil,
							time.Now(),
							streamlog,
						),
					)
				default:
					l.send(
						ctx,
						l.buildlog(
							level,
							custom,
							nil,
							nil,
							time.Now(),
							t,
						),
					)
				}
			}
		}
	}(ctx, v, level, custom)
}
func (l *alog) sendMultiLine(
	level LogLevel,
	err error,
	values ...interface{},
) {
	t := time.Now()
	for _, value := range values {
		l.send(
			l.ctx,
			l.buildlog(level, "", err, nil, t, value),
		)
	}
}
func (l *alog) Printc(ctx context.Context, v <-chan interface{}) {
	l.clog(ctx, v, INFO, "")
}
func (l *alog) Print(v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(INFO, "", nil, nil, t, v...))
}
func (l *alog) Println(v ...interface{}) {
	go l.sendMultiLine(INFO, nil, v...)
}
func (l *alog) Printf(format string, v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(INFO, "", nil, &format, t, v...))
}
func (l *alog) Debugc(ctx context.Context, v <-chan interface{}) {
	l.clog(ctx, v, DEBUG, "")
}
func (l *alog) Debug(err error, v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(DEBUG, "", err, nil, t, v...))
}
func (l *alog) Debugln(err error, v ...interface{}) {
	go l.sendMultiLine(DEBUG, err, v...)
}
func (l *alog) Debugf(err error, format string, v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(DEBUG, "", err, &format, t, v...))
}
func (l *alog) Tracec(ctx context.Context, v <-chan interface{}) {
	l.clog(ctx, v, TRACE, "")
}
func (l *alog) Trace(err error, v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(TRACE, "", err, nil, t, v...))
}
func (l *alog) Traceln(err error, v ...interface{}) {
	go l.sendMultiLine(TRACE, err, v...)
}
func (l *alog) Tracef(err error, format string, v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(TRACE, "", err, &format, t, v...))
}
func (l *alog) Warnc(ctx context.Context, v <-chan interface{}) {
	l.clog(ctx, v, WARN, "")
}
func (l *alog) Warn(err error, v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(WARN, "", err, nil, t, v...))
}
func (l *alog) Warnln(err error, v ...interface{}) {
	go l.sendMultiLine(WARN, err, v...)
}
func (l *alog) Warnf(err error, format string, v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(WARN, "", err, &format, t, v...))
}
func (l *alog) Errorc(ctx context.Context, v <-chan interface{}) {
	l.clog(ctx, v, ERROR, "")
}
func (l *alog) Error(err error, v ...interface{}) {
	t := time.Now()
	go l.send(l.ctx, l.buildlog(ERROR, "", err, nil, t, v...))
}