Select Git revision
logger.go 5.58 KiB
package logger
import (
"encoding/json"
"fmt"
"io"
"strings"
"time"
"gitlab.com/uafrica/go-utils/errors"
)
type ILogger interface {
Fatalf(format string, args ...interface{})
Fatal(args ...interface{})
Errorf(format string, args ...interface{})
Error(args ...interface{})
Warnf(format string, args ...interface{})
Warn(args ...interface{})
Infof(format string, args ...interface{})
Info(args ...interface{})
Debugf(format string, args ...interface{})
Debug(args ...interface{})
}
type Logger struct {
//apiRequest *events.APIGatewayProxyRequest
//currentRequestID *string
level Level
writer io.Writer
data map[string]interface{}
}
func (l Logger) WithFields(data map[string]interface{}) Logger {
newLogger := Logger{
level: l.level,
writer: l.writer,
data: map[string]interface{}{},
}
for n, v := range l.data {
newLogger.data[n] = v
}
for n, v := range data {
newLogger.data[n] = v
}
return newLogger
}
func (l Logger) Fatalf(format string, args ...interface{}) {
l.WithFields(map[string]interface{}{"call_stack": errors.Stack(3)}).log(LevelFatal, 1, fmt.Sprintf(format, args...))
}
func (l Logger) Fatal(args ...interface{}) {
l.WithFields(map[string]interface{}{"call_stack": errors.Stack(3)}).log(LevelFatal, 1, fmt.Sprint(args...))
}
func (l Logger) Errorf(format string, args ...interface{}) {
l.WithFields(map[string]interface{}{"call_stack": errors.Stack(3)}).log(LevelError, 1, fmt.Sprintf(format, args...))
}
func (l Logger) Error(args ...interface{}) {
l.WithFields(map[string]interface{}{"call_stack": errors.Stack(3)}).log(LevelError, 1, fmt.Sprint(args...))
}
func (l Logger) Warnf(format string, args ...interface{}) {
l.log(LevelWarn, 1, fmt.Sprintf(format, args...))
}
func (l Logger) Warn(args ...interface{}) {
l.log(LevelWarn, 1, fmt.Sprint(args...))
}
func (l Logger) Infof(format string, args ...interface{}) {
l.log(LevelInfo, 1, fmt.Sprintf(format, args...))
}
func (l Logger) Info(args ...interface{}) {
l.log(LevelInfo, 1, fmt.Sprint(args...))
}
func (l Logger) Debugf(format string, args ...interface{}) {
l.log(LevelDebug, 1, fmt.Sprintf(format, args...))
}
func (l Logger) Debug(args ...interface{}) {
l.log(LevelDebug, 1, fmt.Sprint(args...))
}
func (l Logger) log(level Level, skip int, msg string) {
if level <= l.level && l.writer != nil {
entry := Entry{
Timestamp: time.Now(),
Level: level,
Caller: errors.GetCaller(skip + 2).Info(),
Data: l.data,
Message: strings.ReplaceAll(msg, "\n", ";"),
}
// jsonEntry, err := json.Marshal(entry)
// if err != nil {
// l.writer.Write([]byte(fmt.Sprintf("failed to marshal entry: %v: %+v\n", err, entry)))
// }
// l.writer.Write(append(jsonEntry, []byte("\n")...))
source := fmt.Sprintf("%s(%d)", entry.Caller.File, entry.Caller.Line)
if len(source) > 25 {
source = source[len(source)-25:]
}
textEntry := fmt.Sprintf("%s %5.5s %-25.25s %s",
entry.Timestamp.Format("2006-01-02 15:04:05"),
entry.Level,
source,
entry.Message)
if len(entry.Data) > 0 {
jsonData, _ := json.Marshal(entry.Data)
textEntry += " " + string(jsonData)
}
l.writer.Write(append([]byte(textEntry), []byte("\n")...))
}
}
type Entry struct {
Timestamp time.Time `json:"time"`
Level Level `json:"level"`
Caller errors.CallerInfo `json:"caller"`
Data map[string]interface{} `json:"data"`
Message string `json:"message"`
}
// func sendRaygunError(fields map[string]interface{}, errToSend error) {
// if os.Getenv("DEBUGGING") == "true" {
// // Don't log raygun errors on debug
// return
// }
// raygun, err := RaygunReporter()
// if err != nil || raygun == nil {
// logger.Errorf("Unable to create Raygun client: " + err.Error())
// return
// }
// env := getEnvironment()
// tags := []string{env}
// //todo: raygun.Version(globals.BuildVersion)
// //todo: tags = append(tags, globals.BuildVersion)
// if logger.apiRequest != nil {
// methodAndPath := logger.apiRequest.HTTPMethod + ": " + logger.apiRequest.Path
// tags = append(tags, methodAndPath)
// fields["body"] = logger.apiRequest.Body
// fields["query"] = logger.apiRequest.QueryStringParameters
// fields["identity"] = logger.apiRequest.RequestContext.Identity
// }
// raygun.Tags(tags)
// if logger.currentRequestID != nil {
// fields["request_id"] = logger.currentRequestID
// }
// fields["env"] = env
// raygun.CustomData(fields)
// raygun.Request(fakeHttpRequest())
// if errToSend == nil {
// errToSend = errors.New("")
// }
// err = raygun.SendError(errToSend)
// if err != nil {
// logger.Errorf("Failed to send raygun error: " + err.Error())
// }
// }
// func fakeHttpRequest() *http.Request {
// if logger.apiRequest == nil {
// return nil
// }
// requestURL := url.URL{
// Path: logger.apiRequest.Path,
// Host: logger.apiRequest.Headers["Host"],
// }
// request := http.Request{
// Method: logger.apiRequest.HTTPMethod,
// URL: &requestURL,
// Header: logger.apiRequest.MultiValueHeaders,
// }
// return &request
// }
// func RaygunReporter() (*raygun4go.Client, error) {
// key := "AwdpHhwOF1lTT6AppyEHA"
// // TODO Raygun per environment
// //env := getEnvironment()
// //if env == "dev" {
// // key = "q98iTyE5CcF7raZsIiLA"
// //} else if env == "stage" {
// // key = "TA54mzcv9cBWBLmfwIQMDg"
// //} else if env == "prod" {
// // key = "BXdraqiPKBXImqP4siK1w"
// //}
// raygun, err := raygun4go.New("uAfrica V3", key)
// if err != nil || raygun == nil {
// logger.Errorf("Unable to create Raygun client:" + err.Error())
// return nil, err
// }
// return raygun, nil
// }