log.go
func (l *templateLogger) Print(start time.Time, query string, args ...interface{}) error {
	if len(args) > 0 {
		values := make([]string, len(args))
		for i, arg := range args {
			values[i] = fmt.Sprintf("%#v", arg)
		}
		query = fmt.Sprintf("%v; [%v]", query, strings.Join(values, ", "))
	} else {
		query = fmt.Sprintf("%s;", query)
	}
	data := map[string]interface{}{
		"time":     start,
		"duration": fmt.Sprintf("%.2fms", now().Sub(start).Seconds()*float64(time.Microsecond)),
		"query":    query,
	}
	var buf bytes.Buffer
	if err := l.t.Execute(&buf, data); err != nil {
		return err
	}
	l.m.Lock()
	defer l.m.Unlock()
	if _, err := fmt.Fprintln(l.w, strings.TrimSuffix(buf.String(), "\n")); err != nil {
		return err
	}
	return nil
}
func (l *templateLogger) Print(start time.Time, query string, args ...interface{}) error {
	if len(args) > 0 {
		values := make([]string, len(args))
		for i, arg := range args {
			values[i] = fmt.Sprintf("%#v", arg)
		}
		query = fmt.Sprintf("%v; [%v]", query, strings.Join(values, ", "))
	} else {
		query = fmt.Sprintf("%s;", query)
	}
	data := map[string]interface{}{
		"time":     start,
		"duration": fmt.Sprintf("%.2fms", now().Sub(start).Seconds()*float64(time.Microsecond)),
		"query":    query,
	}
	var buf bytes.Buffer
	if err := l.t.Execute(&buf, data); err != nil {
		return err
	}
	l.m.Lock()
	defer l.m.Unlock()
	if _, err := fmt.Fprintln(l.w, strings.TrimSuffix(buf.String(), "\n")); err != nil {
		return err
	}
	return nil
}
// Print outputs query log using format template.
// All arguments will be used to formatting.