func Errorf(format string, v ...interface{}) {
	if LogLevel >= 1 {
		DoLog(3, ERROR, fmt.Sprintf(format, v...))
	}
}
Error log formatted
package gou
import (
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
	"sync"
	"time"
	"github.com/lytics/logrus"
)
const (
	NOLOGGING = -1
	FATAL     = 0
	ERROR     = 1
	WARN      = 2
	INFO      = 3
	DEBUG     = 4
)
var (
	LogLevel    int = ERROR
	EMPTY       struct{}
	ErrLogLevel int = ERROR
	logger      *log.Logger
	rus         *logrus.Logger
	loggerErr   *log.Logger
	LogColor    = map[int]string{FATAL: "\033[0m\033[37m",
		ERROR: "\033[0m\033[31m",
		WARN:  "\033[0m\033[33m",
		INFO:  "\033[0m\033[35m",
		DEBUG: "\033[0m\033[34m"}
	LogPrefix = map[int]string{
		FATAL: "[FATAL] ",
		ERROR: "[ERROR] ",
		WARN:  "[WARN] ",
		INFO:  "[INFO] ",
		DEBUG: "[DEBUG] ",
	}
	escapeNewlines bool           = false
	postFix                       = ""  
	LogLevelWords  map[string]int = map[string]int{"fatal": 0, "error": 1, "warn": 2, "info": 3, "debug": 4, "none": -1}
	logThrottles                  = make(map[string]*Throttler)
	throttleMu     sync.Mutex
)
func SetupLogging(lvl string) {
	SetLogger(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), strings.ToLower(lvl))
}
func SetupLoggingLong(lvl string) {
	SetLogger(log.New(os.Stderr, "", log.LstdFlags|log.Llongfile|log.Lmicroseconds), strings.ToLower(lvl))
}
func SetupLoggingFile(f *os.File, lvl string) {
	SetLogger(log.New(f, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), strings.ToLower(lvl))
}
func SetupLogrus(lvl string) {
	loglvl, err := logrus.ParseLevel(lvl)
	if err != nil {
		fmt.Printf("error parsing log level: %v", err)
	}
	rus = &logrus.Logger{
		Out:       os.Stdout,
		Formatter: new(logrus.SeverityFormatter),  
		Hooks:     make(logrus.LevelHooks),
		Level:     loglvl,
	}
}
func GetRus() *logrus.Logger {
	return rus
}
func SetColorIfTerminal() {
	if IsTerminal() {
		SetColorOutput()
	}
}
func SetColorOutput() {
	for lvl, color := range LogColor {
		LogPrefix[lvl] = color
	}
	postFix = "\033[0m"
}
func SetEscapeNewlines(en bool) {
	escapeNewlines = en
}
func DiscardStandardLogger() {
	log.SetOutput(new(DevNull))
}
func SetLogger(l *log.Logger, logLevel string) {
	logger = l
	LogLevelSet(logLevel)
}
func GetLogger() *log.Logger {
	return logger
}
func SetErrLogger(l *log.Logger, logLevel string) {
	loggerErr = l
	if lvl, ok := LogLevelWords[logLevel]; ok {
		ErrLogLevel = lvl
	}
}
func GetErrLogger() *log.Logger {
	return logger
}
func LogLevelSet(levelWord string) {
	if lvl, ok := LogLevelWords[levelWord]; ok {
		LogLevel = lvl
	}
}
func Debug(v ...interface{}) {
	if LogLevel >= 4 {
		DoLog(3, DEBUG, fmt.Sprint(v...))
	}
}
func Debugf(format string, v ...interface{}) {
	if LogLevel >= 4 {
		DoLog(3, DEBUG, fmt.Sprintf(format, v...))
	}
}
func DebugT(lineCt int) {
	if LogLevel >= 4 {
		DoLog(3, DEBUG, fmt.Sprint("\n", PrettyStack(lineCt)))
	}
}
func Info(v ...interface{}) {
	if LogLevel >= 3 {
		DoLog(3, INFO, fmt.Sprint(v...))
	}
}
func Infof(format string, v ...interface{}) {
	if LogLevel >= 3 {
		DoLog(3, INFO, fmt.Sprintf(format, v...))
	}
}
func InfoT(lineCt int) {
	if LogLevel >= 3 {
		DoLog(3, INFO, fmt.Sprint("\n", PrettyStack(lineCt)))
	}
}
func Warn(v ...interface{}) {
	if LogLevel >= 2 {
		DoLog(3, WARN, fmt.Sprint(v...))
	}
}
func Warnf(format string, v ...interface{}) {
	if LogLevel >= 2 {
		DoLog(3, WARN, fmt.Sprintf(format, v...))
	}
}
func WarnT(lineCt int) {
	if LogLevel >= 2 {
		DoLog(3, WARN, fmt.Sprint("\n", PrettyStack(lineCt)))
	}
}
func Error(v ...interface{}) {
	if LogLevel >= 1 {
		DoLog(3, ERROR, fmt.Sprint(v...))
	}
}