boilerplate-go/core/log/log.go

261 lines
5.7 KiB
Go

package log
import (
"encoding/json"
"fmt"
"gitlab.com/arkadooti.sarkar/go-boilerplate/core/appcontext"
"io"
"log"
"os"
"strings"
)
const (
//INFO level 1
INFO = iota
//HTTP level 2
HTTP
//ERROR level 3
ERROR
//TRACE level 4
TRACE
//WARNING level 5
WARNING
)
var (
setLevel = WARNING
trace *log.Logger
info *log.Logger
warning *log.Logger
httplog *log.Logger
errorlog *log.Logger
)
const (
clusterType = "CLUSTER_TYPE"
clusterTypeLocal = "local"
clusterTypeDev = "dev1"
)
// FieldsMap map of key value pair to log
type FieldsMap map[string]interface{}
func init() {
logInit(os.Stdout,
os.Stdout,
os.Stdout,
os.Stdout,
os.Stderr)
}
func logInit(traceHandle, infoHandle, warningHandle, httpHandle, errorHandle io.Writer) {
flagWithClusterType := log.LUTC | log.LstdFlags | log.Lshortfile
flagWithoutClusterType := log.LUTC | log.LstdFlags
var flag int
if os.Getenv(clusterType) == clusterTypeLocal || os.Getenv(clusterType) == clusterTypeDev {
flag = flagWithClusterType
} else {
flag = flagWithoutClusterType
}
trace = log.New(traceHandle, "TRACE|", flag)
info = log.New(infoHandle, "INFO|", flag)
warning = log.New(warningHandle, "WARNING|", flag)
httplog = log.New(httpHandle, "HTTP|", flag)
errorlog = log.New(errorHandle, "ERROR|", flagWithClusterType)
}
func doLog(cLog *log.Logger, level, callDepth int, v ...interface{}) {
if level <= setLevel {
if level == ERROR {
cLog.SetOutput(os.Stderr)
cLog.SetFlags(log.Llongfile)
}
cLog.Output(callDepth, fmt.Sprintln(v...))
}
}
func generatePrefix(ctx appcontext.AppContext) string {
// TODO: Add departmentName once that is implemented fully
return strings.Join([]string{ctx.UserEmail}, ":")
}
func generateTrackingIDs(ctx appcontext.AppContext) (retString string) {
requestID := ctx.RequestID
if requestID != "" {
retString = "requestId=" + requestID
}
return
}
// Trace system gives facility to helps you isolate your system problems by monitoring selected events Ex. entry and exit
func traceLog(v ...interface{}) {
doLog(trace, TRACE, 4, v...)
}
// Info dedicated for logging valuable information
func infoLog(v ...interface{}) {
doLog(info, INFO, 4, v...)
}
// Warning for critical error
func warningLog(v ...interface{}) {
doLog(warning, WARNING, 4, v...)
}
// Error logging error
func errorLog(v ...interface{}) {
doLog(errorlog, ERROR, 4, v...)
}
func fatalLog(v ...interface{}) {
doLog(errorlog, ERROR, 4, v...)
os.Exit(1)
}
func HTTPLog(logMessage string) {
doLog(httplog, HTTP, 6, logMessage)
}
func GenericTrace(ctx appcontext.AppContext, traceMessage string, data ...FieldsMap) {
var fields FieldsMap
if len(data) > 0 {
fields = data[0]
}
if os.Getenv("SERVICE_TRACE") == "true" {
prefix := generatePrefix(ctx)
trackingIDs := generateTrackingIDs(ctx)
msg := fmt.Sprintf("|%s|%s|",
prefix,
trackingIDs)
if fields != nil && len(fields) > 0 {
fieldsBytes, _ := json.Marshal(fields)
fieldsString := string(fieldsBytes)
traceLog(msg, traceMessage, "|", fieldsString)
} else {
traceLog(msg, traceMessage)
}
}
}
func GenericInfo(ctx appcontext.AppContext, infoMessage string, data ...FieldsMap) {
var fields FieldsMap
if len(data) > 0 {
fields = data[0]
}
prefix := generatePrefix(ctx)
trackingIDs := generateTrackingIDs(ctx)
fieldsBytes, _ := json.Marshal(fields)
fieldsString := string(fieldsBytes)
msg := fmt.Sprintf("|%s|%s|",
prefix,
trackingIDs)
if fields != nil && len(fields) > 0 {
infoLog(msg, infoMessage, "|", fieldsString)
} else {
infoLog(msg, infoMessage)
}
}
func GenericWarning(ctx appcontext.AppContext, warnMessage string, data ...FieldsMap) {
var fields FieldsMap
if len(data) > 0 {
fields = data[0]
}
if os.Getenv("SERVICE_WARN") == "true" {
prefix := generatePrefix(ctx)
trackingIDs := generateTrackingIDs(ctx)
msg := fmt.Sprintf("|%s|%s|",
prefix,
trackingIDs)
if fields != nil && len(fields) > 0 {
fieldsBytes, _ := json.Marshal(fields)
fieldsString := string(fieldsBytes)
warningLog(msg, warnMessage, "|", fieldsString)
} else {
warningLog(msg, warnMessage)
}
}
}
func GenericError(ctx appcontext.AppContext, e error, data ...FieldsMap) {
var fields FieldsMap
if len(data) > 0 {
fields = data[0]
}
prefix := generatePrefix(ctx)
trackingIDs := generateTrackingIDs(ctx)
msg := ""
if e != nil {
msg = fmt.Sprintf("|%s|%s|%s", prefix, trackingIDs, e.Error())
} else {
msg = fmt.Sprintf("|%s|%s", prefix, trackingIDs)
}
if fields != nil && len(fields) > 0 {
fieldsBytes, _ := json.Marshal(fields)
fieldsString := string(fieldsBytes)
errorLog(msg, "|", fieldsString)
} else {
errorLog(msg)
}
}
func CriticalError(ctx appcontext.AppContext, e error, data ...FieldsMap) {
var fields FieldsMap
if len(data) > 0 {
fields = data[0]
}
prefix := generatePrefix(ctx)
trackingIDs := generateTrackingIDs(ctx)
msg := ""
if e != nil {
msg = fmt.Sprintf("|%s|%s|%s", prefix, trackingIDs, e.Error())
} else {
msg = fmt.Sprintf("|%s|%s", prefix, trackingIDs)
}
if fields != nil && len(fields) > 0 {
fieldsBytes, _ := json.Marshal(fields)
fieldsString := string(fieldsBytes)
errorLog(msg, "|", fieldsString)
} else {
errorLog(msg)
}
}
func FatalLog(ctx appcontext.AppContext, e error, data ...FieldsMap) {
var fields FieldsMap
if len(data) > 0 {
fields = data[0]
}
prefix := generatePrefix(ctx)
trackingIDs := generateTrackingIDs(ctx)
msg := ""
if e != nil {
msg = fmt.Sprintf("|%s|%s|%s", prefix, trackingIDs, e.Error())
} else {
msg = fmt.Sprintf("|%s|%s", prefix, trackingIDs)
}
if fields != nil && len(fields) > 0 {
fieldsBytes, _ := json.Marshal(fields)
fieldsString := string(fieldsBytes)
fatalLog(msg, "|", fieldsString)
} else {
fatalLog(msg)
}
}