259 lines
5.2 KiB
Go
259 lines
5.2 KiB
Go
package logx
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/appleboy/gorush/core"
|
|
|
|
"github.com/mattn/go-isatty"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var (
|
|
green = string([]byte{27, 91, 57, 55, 59, 52, 50, 109})
|
|
yellow = string([]byte{27, 91, 57, 55, 59, 52, 51, 109})
|
|
red = string([]byte{27, 91, 57, 55, 59, 52, 49, 109})
|
|
blue = string([]byte{27, 91, 57, 55, 59, 52, 52, 109})
|
|
reset = string([]byte{27, 91, 48, 109})
|
|
)
|
|
|
|
// LogPushEntry is push response log
|
|
type LogPushEntry struct {
|
|
ID string `json:"notif_id,omitempty"`
|
|
Type string `json:"type"`
|
|
Platform string `json:"platform"`
|
|
Token string `json:"token"`
|
|
Message string `json:"message"`
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
var isTerm bool
|
|
|
|
//nolint
|
|
func init() {
|
|
isTerm = isatty.IsTerminal(os.Stdout.Fd())
|
|
}
|
|
|
|
var (
|
|
// LogAccess is log server request log
|
|
LogAccess = logrus.New()
|
|
// LogError is log server error log
|
|
LogError = logrus.New()
|
|
)
|
|
|
|
// InitLog use for initial log module
|
|
func InitLog(accessLevel, accessLog, errorLevel, errorLog string) error {
|
|
var err error
|
|
|
|
if !isTerm {
|
|
LogAccess.SetFormatter(&logrus.JSONFormatter{})
|
|
LogError.SetFormatter(&logrus.JSONFormatter{})
|
|
} else {
|
|
LogAccess.Formatter = &logrus.TextFormatter{
|
|
TimestampFormat: "2006/01/02 - 15:04:05",
|
|
FullTimestamp: true,
|
|
}
|
|
|
|
LogError.Formatter = &logrus.TextFormatter{
|
|
TimestampFormat: "2006/01/02 - 15:04:05",
|
|
FullTimestamp: true,
|
|
}
|
|
}
|
|
|
|
// set logger
|
|
if err = SetLogLevel(LogAccess, accessLevel); err != nil {
|
|
return errors.New("Set access log level error: " + err.Error())
|
|
}
|
|
|
|
if err = SetLogLevel(LogError, errorLevel); err != nil {
|
|
return errors.New("Set error log level error: " + err.Error())
|
|
}
|
|
|
|
if err = SetLogOut(LogAccess, accessLog); err != nil {
|
|
return errors.New("Set access log path error: " + err.Error())
|
|
}
|
|
|
|
if err = SetLogOut(LogError, errorLog); err != nil {
|
|
return errors.New("Set error log path error: " + err.Error())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SetLogOut provide log stdout and stderr output
|
|
func SetLogOut(log *logrus.Logger, outString string) error {
|
|
switch outString {
|
|
case "stdout":
|
|
log.Out = os.Stdout
|
|
case "stderr":
|
|
log.Out = os.Stderr
|
|
default:
|
|
f, err := os.OpenFile(outString, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Out = f
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SetLogLevel is define log level what you want
|
|
// log level: panic, fatal, error, warn, info and debug
|
|
func SetLogLevel(log *logrus.Logger, levelString string) error {
|
|
level, err := logrus.ParseLevel(levelString)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Level = level
|
|
|
|
return nil
|
|
}
|
|
|
|
func colorForPlatForm(platform int) string {
|
|
switch platform {
|
|
case core.PlatFormIos:
|
|
return blue
|
|
case core.PlatFormAndroid:
|
|
return yellow
|
|
case core.PlatFormHuawei:
|
|
return green
|
|
default:
|
|
return reset
|
|
}
|
|
}
|
|
|
|
func typeForPlatForm(platform int) string {
|
|
switch platform {
|
|
case core.PlatFormIos:
|
|
return "ios"
|
|
case core.PlatFormAndroid:
|
|
return "android"
|
|
case core.PlatFormHuawei:
|
|
return "huawei"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func hideToken(token string, markLen int) string {
|
|
if token == "" {
|
|
return ""
|
|
}
|
|
|
|
if len(token) < markLen*2 {
|
|
return strings.Repeat("*", len(token))
|
|
}
|
|
|
|
start := token[len(token)-markLen:]
|
|
end := token[0:markLen]
|
|
|
|
result := strings.ReplaceAll(token, start, strings.Repeat("*", markLen))
|
|
result = strings.ReplaceAll(result, end, strings.Repeat("*", markLen))
|
|
|
|
return result
|
|
}
|
|
|
|
// GetLogPushEntry get push data into log structure
|
|
func GetLogPushEntry(input *InputLog) LogPushEntry {
|
|
var errMsg string
|
|
|
|
plat := typeForPlatForm(input.Platform)
|
|
|
|
if input.Error != nil {
|
|
errMsg = input.Error.Error()
|
|
}
|
|
|
|
token := input.Token
|
|
if input.HideToken {
|
|
token = hideToken(input.Token, 10)
|
|
}
|
|
|
|
message := input.Message
|
|
if input.HideMessage {
|
|
message = "(message redacted)"
|
|
}
|
|
|
|
return LogPushEntry{
|
|
ID: input.ID,
|
|
Type: input.Status,
|
|
Platform: plat,
|
|
Token: token,
|
|
Message: message,
|
|
Error: errMsg,
|
|
}
|
|
}
|
|
|
|
// InputLog log request
|
|
type InputLog struct {
|
|
ID string
|
|
Status string
|
|
Token string
|
|
Message string
|
|
Platform int
|
|
Error error
|
|
HideToken bool
|
|
HideMessage bool
|
|
Format string
|
|
}
|
|
|
|
// LogPush record user push request and server response.
|
|
func LogPush(input *InputLog) LogPushEntry {
|
|
var platColor, resetColor, output string
|
|
|
|
if isTerm {
|
|
platColor = colorForPlatForm(input.Platform)
|
|
resetColor = reset
|
|
}
|
|
|
|
log := GetLogPushEntry(input)
|
|
|
|
if input.Format == "json" {
|
|
logJSON, _ := json.Marshal(log)
|
|
|
|
output = string(logJSON)
|
|
} else {
|
|
var typeColor string
|
|
switch input.Status {
|
|
case core.SucceededPush:
|
|
if isTerm {
|
|
typeColor = green
|
|
}
|
|
|
|
output = fmt.Sprintf("|%s %s %s| %s%s%s [%s] %s",
|
|
typeColor, log.Type, resetColor,
|
|
platColor, log.Platform, resetColor,
|
|
log.Token,
|
|
log.Message,
|
|
)
|
|
case core.FailedPush:
|
|
if isTerm {
|
|
typeColor = red
|
|
}
|
|
|
|
output = fmt.Sprintf("|%s %s %s| %s%s%s [%s] | %s | Error Message: %s",
|
|
typeColor, log.Type, resetColor,
|
|
platColor, log.Platform, resetColor,
|
|
log.Token,
|
|
log.Message,
|
|
log.Error,
|
|
)
|
|
}
|
|
}
|
|
|
|
switch input.Status {
|
|
case core.SucceededPush:
|
|
LogAccess.Info(output)
|
|
case core.FailedPush:
|
|
LogError.Error(output)
|
|
}
|
|
|
|
return log
|
|
}
|