When using the wrapped logrus function/logger, the logger prefixes all log lines with the file name and line number of the logger function call, for example:
INFO[0000]logging.go:39 myfolder/logging.Info()
If I wrap the log function like this, for instance: package logging
import (
"fmt"
"github.com/sirupsen/logrus"
"os"
"path"
"runtime"
)
var (
log *logrus.Logger
)
func init() {
log = logrus.New()
log.SetReportCaller(true)
log.Formatter = &logrus.TextFormatter{
CallerPrettyfier: func(f *runtime.Frame) (string, string) {
filename := path.Base(f.File)
return fmt.Sprintf("%s()", f.Function), fmt.Sprintf("%s:%d", filename, f.Line)
},
}
}
func Info(args ...interface{}) {
log.Info(args...)
}
Every line emitted by this function is going to be prefixed with the line number of the logging function
call. That is as expected, but the desired behavior is for each line to be prefixed with the line number of the line where Info
is called.
The Desired output should be :
INFO[0000]myfile.go:39 myfolder/myfile.myfunction()
Is there any way around it?
It is not possible to do it in the logrus. I had a similar requirement and ended up doing the following which worked for us.
package mylog
import (
"fmt"
"github.com/Sirupsen/logrus"
"runtime"
"strings"
)
var logger = logrus.New()
func SetLogFormatter(formatter logrus.Formatter) {
logger.Formatter = formatter
}
// Info logs a message at level Info on the standard logger.
func Info(args ...interface{}) {
if logger.Level >= logrus.InfoLevel {
entry := logger.WithFields(logrus.Fields{})
entry.Data["file"] = fileInfo(2)
entry.Info(args...)
}
}
func fileInfo(skip int) string {
_, file, line, ok := runtime.Caller(skip)
if !ok {
file = "<???>"
line = 1
} else {
slash := strings.LastIndex(file, "/")
if slash >= 0 {
file = file[slash+1:]
}
}
return fmt.Sprintf("%s:%d", file, line)
}
See if this or some variation of this works for your use case. I have removed the application-specific code from the code snippet above.