func (log *Logger) Panicf(fmtstr string, args ...interface{}) {
	msg := fmt.Sprintf(fmtstr, args...)
	logLevel, panicLevel := log.panicLevel()
	if logLevel <= panicLevel {
		log.write(0, panicLevel, msg)
	}
	panic(msg)
}
Panicf does the same with Panic except it calls fmt.Sprintf to format a log.

ATTENTION: the log may NOT be output when a Writer is in asynchronous mode and
there is NO recovery after panicking.
Panicf never outputs the stack with the log or calls os.Exit.
package logger
import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"runtime/debug"
	"strings"
	"sync"
	"time"
	"github.com/gxlog/gxlog/iface"
)
const callDepthOffset = 3
type Logger struct {
	config *Config
	slots  []slotLink
	equivalents [][]int
	countMap    map[locator]int64
	timeMap     map[locator]*timeQueue
	attr        copyOnWrite
	lock        *sync.Mutex
}
func New(config Config) *Logger {
	config.setDefaults()
	logger := &Logger{
		config:      &config,
		equivalents: make([][]int, MaxSlot),
		countMap:    make(map[locator]int64, mapInitCap),
		timeMap:     make(map[locator]*timeQueue, mapInitCap),
		lock:        new(sync.Mutex),
	}
	logger.initSlots()
	return logger
}
func (log *Logger) Trace(args ...interface{}) {
	log.Log(1, iface.Trace, args...)
}
func (log *Logger) Tracef(fmtstr string, args ...interface{}) {
	log.Logf(1, iface.Trace, fmtstr, args...)
}
func (log *Logger) Debug(args ...interface{}) {
	log.Log(1, iface.Debug, args...)
}
func (log *Logger) Debugf(fmtstr string, args ...interface{}) {
	log.Logf(1, iface.Debug, fmtstr, args...)
}
func (log *Logger) Info(args ...interface{}) {
	log.Log(1, iface.Info, args...)
}
func (log *Logger) Infof(fmtstr string, args ...interface{}) {
	log.Logf(1, iface.Info, fmtstr, args...)
}
func (log *Logger) Warn(args ...interface{}) {
	log.Log(1, iface.Warn, args...)
}
func (log *Logger) Warnf(fmtstr string, args ...interface{}) {
	log.Logf(1, iface.Warn, fmtstr, args...)
}
func (log *Logger) Error(args ...interface{}) {
	log.Log(1, iface.Error, args...)
}
func (log *Logger) Errorf(fmtstr string, args ...interface{}) {
	log.Logf(1, iface.Error, fmtstr, args...)
}
func (log *Logger) Fatal(args ...interface{}) {
	log.Log(1, iface.Fatal, args...)
}
func (log *Logger) Fatalf(fmtstr string, args ...interface{}) {
	log.Logf(1, iface.Fatal, fmtstr, args...)
}
func (log *Logger) LogError(level iface.Level, text string) error {
	log.Log(1, level, text)
	return errors.New(text)
}
func (log *Logger) LogErrorf(level iface.Level, fmtstr string, args ...interface{}) error {
	err := fmt.Errorf(fmtstr, args...)
	log.Log(1, level, err.Error())
	return err
}
func (log *Logger) Log(callDepth int, level iface.Level, args ...interface{}) {
	logLevel, trackLevel, exitLevel := log.levels()
	if logLevel <= level {
		if trackLevel <= level {
			stack := debug.Stack()
			args = append(args, "\n", string(stack[:len(stack)-1]))
		}
		log.write(callDepth, level, fmt.Sprint(args...))
		if exitLevel <= level {
			os.Exit(1)
		}
	}
}
func (log *Logger) Logf(callDepth int, level iface.Level, fmtstr string, args ...interface{}) {
	logLevel, trackLevel, exitLevel := log.levels()
	if logLevel <= level {
		if trackLevel <= level {
			fmtstr += "\n%s"
			stack := debug.Stack()
			args = append(args, stack[:len(stack)-1])
		}
		log.write(callDepth, level, fmt.Sprintf(fmtstr, args...))
		if exitLevel <= level {
			os.Exit(1)
		}
	}
}
func (log *Logger) Panic(args ...interface{}) {
	msg := fmt.Sprint(args...)
	logLevel, panicLevel := log.panicLevel()
	if logLevel <= panicLevel {
		log.write(0, panicLevel, msg)
	}
	panic(msg)
}