368 lines
8.7 KiB
Go
368 lines
8.7 KiB
Go
/*
|
|
* Copyright 2020 The Dragonfly Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package logger
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"strconv"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
"golang.org/x/sys/unix"
|
|
"google.golang.org/grpc/grpclog"
|
|
)
|
|
|
|
var (
|
|
CoreLogger *zap.SugaredLogger
|
|
GrpcLogger *zap.SugaredLogger
|
|
GinLogger *zap.SugaredLogger
|
|
GCLogger *zap.SugaredLogger
|
|
StorageGCLogger *zap.SugaredLogger
|
|
JobLogger *zap.SugaredLogger
|
|
KeepAliveLogger *zap.SugaredLogger
|
|
StatSeedLogger *zap.Logger
|
|
DownloaderLogger *zap.Logger
|
|
|
|
coreLogLevelEnabler zapcore.LevelEnabler
|
|
)
|
|
|
|
func init() {
|
|
config := zap.NewDevelopmentConfig()
|
|
config.Level = zap.NewAtomicLevelAt(zap.InfoLevel)
|
|
log, err := config.Build(zap.AddCaller(), zap.AddStacktrace(zap.WarnLevel), zap.AddCallerSkip(1))
|
|
if err == nil {
|
|
sugar := log.Sugar()
|
|
SetCoreLogger(sugar)
|
|
SetGrpcLogger(sugar)
|
|
SetGinLogger(sugar)
|
|
SetGCLogger(sugar)
|
|
SetStorageGCLogger(sugar)
|
|
SetKeepAliveLogger(sugar)
|
|
SetStatSeedLogger(log)
|
|
SetDownloadLogger(log)
|
|
SetJobLogger(sugar)
|
|
}
|
|
levels = append(levels, config.Level)
|
|
}
|
|
|
|
// SetLevel updates all log level
|
|
func SetLevel(level zapcore.Level) {
|
|
Infof("change log level to %s", level.String())
|
|
for _, l := range levels {
|
|
l.SetLevel(level)
|
|
}
|
|
}
|
|
|
|
func SetCoreLogger(log *zap.SugaredLogger) {
|
|
CoreLogger = log
|
|
coreLogLevelEnabler = log.Desugar().Core()
|
|
}
|
|
|
|
func SetGCLogger(log *zap.SugaredLogger) {
|
|
GCLogger = log
|
|
}
|
|
|
|
func SetStorageGCLogger(log *zap.SugaredLogger) {
|
|
StorageGCLogger = log
|
|
}
|
|
|
|
func SetKeepAliveLogger(log *zap.SugaredLogger) {
|
|
KeepAliveLogger = log
|
|
}
|
|
|
|
func SetStatSeedLogger(log *zap.Logger) {
|
|
StatSeedLogger = log
|
|
}
|
|
|
|
func SetDownloadLogger(log *zap.Logger) {
|
|
DownloaderLogger = log
|
|
}
|
|
|
|
func SetGrpcLogger(log *zap.SugaredLogger) {
|
|
GrpcLogger = log
|
|
var v int
|
|
vLevel := os.Getenv("GRPC_GO_LOG_VERBOSITY_LEVEL")
|
|
if vl, err := strconv.Atoi(vLevel); err == nil {
|
|
v = vl
|
|
}
|
|
grpclog.SetLoggerV2(&zapGrpc{GrpcLogger, v})
|
|
}
|
|
|
|
func SetGinLogger(log *zap.SugaredLogger) {
|
|
GinLogger = log
|
|
}
|
|
|
|
func SetJobLogger(log *zap.SugaredLogger) {
|
|
JobLogger = log
|
|
}
|
|
|
|
type SugaredLoggerOnWith struct {
|
|
withArgs []any
|
|
}
|
|
|
|
func With(args ...any) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: args,
|
|
}
|
|
}
|
|
|
|
func WithScheduler(hostname, ip string, clusterID uint64) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"hostname", hostname, "ip", ip, "clusterID", clusterID},
|
|
}
|
|
}
|
|
|
|
func WithPeer(hostID, taskID, peerID string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"hostID", hostID, "taskID", taskID, "peerID", peerID},
|
|
}
|
|
}
|
|
|
|
func WithTask(taskID, url string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"taskID", taskID, "url", url},
|
|
}
|
|
}
|
|
|
|
func WithHost(hostID, hostname, ip string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"hostID", hostID, "hostname", hostname, "ip", ip},
|
|
}
|
|
}
|
|
|
|
func WithTaskID(taskID string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"taskID", taskID},
|
|
}
|
|
}
|
|
|
|
func WithHostID(hostID string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"hostID", hostID},
|
|
}
|
|
}
|
|
|
|
func WithKeepAlive(hostname, ip, sourceType string, clusterID uint64) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"hostname", hostname, "ip", ip, "sourceType", sourceType, "clusterID", clusterID},
|
|
}
|
|
}
|
|
|
|
func WithTaskAndPeerID(taskID, peerID string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"taskID", taskID, "peerID", peerID},
|
|
}
|
|
}
|
|
|
|
func WithHostnameAndIP(hostname, ip string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"hostname", hostname, "ip", ip},
|
|
}
|
|
}
|
|
|
|
func WithGroupAndJobID(taskID, jobID string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"groupID", taskID, "jobID", jobID},
|
|
}
|
|
}
|
|
|
|
func WithGroupAndTaskID(groupID, taskID string) *SugaredLoggerOnWith {
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: []any{"groupID", groupID, "taskID", taskID},
|
|
}
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) With(args ...any) *SugaredLoggerOnWith {
|
|
args = append(args, log.withArgs...)
|
|
return &SugaredLoggerOnWith{
|
|
withArgs: args,
|
|
}
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) Infof(template string, args ...any) {
|
|
if !coreLogLevelEnabler.Enabled(zap.InfoLevel) {
|
|
return
|
|
}
|
|
CoreLogger.Infow(fmt.Sprintf(template, args...), log.withArgs...)
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) Info(args ...any) {
|
|
if !coreLogLevelEnabler.Enabled(zap.InfoLevel) {
|
|
return
|
|
}
|
|
CoreLogger.Infow(fmt.Sprint(args...), log.withArgs...)
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) Warnf(template string, args ...any) {
|
|
if !coreLogLevelEnabler.Enabled(zap.WarnLevel) {
|
|
return
|
|
}
|
|
CoreLogger.Warnw(fmt.Sprintf(template, args...), log.withArgs...)
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) Warn(args ...any) {
|
|
if !coreLogLevelEnabler.Enabled(zap.WarnLevel) {
|
|
return
|
|
}
|
|
CoreLogger.Warnw(fmt.Sprint(args...), log.withArgs...)
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) Errorf(template string, args ...any) {
|
|
if !coreLogLevelEnabler.Enabled(zap.ErrorLevel) {
|
|
return
|
|
}
|
|
CoreLogger.Errorw(fmt.Sprintf(template, args...), log.withArgs...)
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) Error(args ...any) {
|
|
if !coreLogLevelEnabler.Enabled(zap.ErrorLevel) {
|
|
return
|
|
}
|
|
CoreLogger.Errorw(fmt.Sprint(args...), log.withArgs...)
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) Debugf(template string, args ...any) {
|
|
if !coreLogLevelEnabler.Enabled(zap.DebugLevel) {
|
|
return
|
|
}
|
|
CoreLogger.Debugw(fmt.Sprintf(template, args...), log.withArgs...)
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) Debug(args ...any) {
|
|
if !coreLogLevelEnabler.Enabled(zap.DebugLevel) {
|
|
return
|
|
}
|
|
CoreLogger.Debugw(fmt.Sprint(args...), log.withArgs...)
|
|
}
|
|
|
|
func (log *SugaredLoggerOnWith) IsDebug() bool {
|
|
return coreLogLevelEnabler.Enabled(zap.DebugLevel)
|
|
}
|
|
|
|
func Infof(template string, args ...any) {
|
|
CoreLogger.Infof(template, args...)
|
|
}
|
|
|
|
func Info(args ...any) {
|
|
CoreLogger.Info(args...)
|
|
}
|
|
|
|
func Warnf(template string, args ...any) {
|
|
CoreLogger.Warnf(template, args...)
|
|
}
|
|
|
|
func Warn(args ...any) {
|
|
CoreLogger.Warn(args...)
|
|
}
|
|
|
|
func Errorf(template string, args ...any) {
|
|
CoreLogger.Errorf(template, args...)
|
|
}
|
|
|
|
func Error(args ...any) {
|
|
CoreLogger.Error(args...)
|
|
}
|
|
|
|
func Debugf(template string, args ...any) {
|
|
CoreLogger.Debugf(template, args...)
|
|
}
|
|
|
|
func Debug(args ...any) {
|
|
CoreLogger.Debug(args...)
|
|
}
|
|
|
|
func IsDebug() bool {
|
|
return coreLogLevelEnabler.Enabled(zap.DebugLevel)
|
|
}
|
|
|
|
func Fatalf(template string, args ...any) {
|
|
CoreLogger.Fatalf(template, args...)
|
|
}
|
|
|
|
func Fatal(args ...any) {
|
|
CoreLogger.Fatal(args...)
|
|
}
|
|
|
|
type zapGrpc struct {
|
|
*zap.SugaredLogger
|
|
verbose int
|
|
}
|
|
|
|
func (z *zapGrpc) Infoln(args ...any) {
|
|
z.SugaredLogger.Info(args...)
|
|
}
|
|
|
|
func (z *zapGrpc) Warning(args ...any) {
|
|
z.SugaredLogger.Warn(args...)
|
|
}
|
|
|
|
func (z *zapGrpc) Warningln(args ...any) {
|
|
z.SugaredLogger.Warn(args...)
|
|
}
|
|
|
|
func (z *zapGrpc) Warningf(format string, args ...any) {
|
|
z.SugaredLogger.Warnf(format, args...)
|
|
}
|
|
|
|
func (z *zapGrpc) Errorln(args ...any) {
|
|
z.SugaredLogger.Error(args...)
|
|
}
|
|
|
|
func (z *zapGrpc) Fatalln(args ...any) {
|
|
z.SugaredLogger.Fatal(args...)
|
|
}
|
|
|
|
func (z *zapGrpc) V(level int) bool {
|
|
return level <= z.verbose
|
|
}
|
|
|
|
// Redirect stdout and stderr to file for debugging.
|
|
func RedirectStdoutAndStderr(console bool, logDir string) {
|
|
// When console log is enabled, skip redirect.
|
|
if console {
|
|
return
|
|
}
|
|
|
|
// Redirect stdout to stdout.log file.
|
|
stdoutPath := path.Join(logDir, "stdout.log")
|
|
if stdout, err := os.OpenFile(stdoutPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND|os.O_SYNC, 0644); err != nil {
|
|
Warnf("open %s error: %s", stdoutPath, err)
|
|
} else {
|
|
err := unix.Dup2(int(stdout.Fd()), int(os.Stdout.Fd()))
|
|
if err != nil {
|
|
Warnf("redirect stdout error: %s", err)
|
|
} else {
|
|
fmt.Fprintf(os.Stdout, "stdout redirect at %v\n", time.Now())
|
|
}
|
|
}
|
|
|
|
// Redirect stderr to stderr.log file.
|
|
stderrPath := path.Join(logDir, "stderr.log")
|
|
if stderr, err := os.OpenFile(stderrPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND|os.O_SYNC, 0644); err != nil {
|
|
Warnf("open %s error: %s", stderrPath, err)
|
|
} else {
|
|
if err := unix.Dup2(int(stderr.Fd()), int(os.Stderr.Fd())); err != nil {
|
|
Warnf("redirect stderr error: %s", err)
|
|
} else {
|
|
fmt.Fprintf(os.Stderr, "stderr redirect at %v\n", time.Now())
|
|
}
|
|
}
|
|
}
|