Excuse the newb question but I truly enjoy using logrus and we are about to ship our product to production but I have not yet figured out how to write to file. for example how do i write to /var/log/$app using logrus.
thanks in advance
Use log.SetOutput() with a file handler, anything that implements io.Writer is good.
f, err := os.OpenFile(filename, os.O_WRONLY | os.O_CREATE, 0755)
if err != nil {
# handle
}
logrus.SetOutput(f)
Thanks much appreciated!
On Mar 20, 2015 3:04 PM, "Simon Eskildsen" [email protected] wrote:
Closed #156 https://github.com/Sirupsen/logrus/issues/156.
—
Reply to this email directly or view it on GitHub
https://github.com/Sirupsen/logrus/issues/156#event-260848051.
If you're using the text formatter you may have to pass DisableColors (see the docs) if you're running from a TTY.
Sorry that this is a little confusing, it could probably be documented better. It's much more common to log to stdout/stderr in my experience, and have something pick it up.
I agree but where I currently am we log to both /var/log/app.log & then
logstash picks it up from there. But I agree ;).
On Mar 20, 2015 5:48 PM, "Simon Eskildsen" [email protected] wrote:
Sorry that this is a little confusing, it could probably be documented
better. It's much more common to log to stdout/stderr in my experience, and
have something pick it up.—
Reply to this email directly or view it on GitHub
https://github.com/Sirupsen/logrus/issues/156#issuecomment-84209524.
:) enjoy logrus

Hi @Sirupsen , how to make logs both print on screen and save to local file?
@wangkirin take a look at the LFS hook: https://github.com/rifflock/lfshook
@sirupsen When I'm trying to discard the logs (for testing purpose) using
logrus.SetOutput(ioutil.Discard)
It does not work and I still see the error on STDOUT.
Any idea ?
This is works for me:
package main
import (
"os"
"github.com/Sirupsen/logrus"
)
const LOG_FILE = "/tmp/logrus.log"
func main() {
// create the logger
logger := logrus.New()
// with Json Formatter
logger.Formatter = &logrus.JSONFormatter{}
logger.SetOutput(os.Stdout)
file, err := os.OpenFile(LOG_FILE, os.O_WRONLY | os.O_CREATE | os.O_APPEND, 0755)
if err != nil {
logger.Fatal(err)
}
defer file.Close()
logger.SetOutput(file)
}
All log saved into LOG_FILE
Do we not have to register an exit handler to make sure the file is closed, as well as explicitly call logrus.Exit(0) to make sure it is called at the end of main()?
var logFile *os.File
func main() {
logFile, _ = os.OpenFile("app_<timestamp_here>.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
logrus.SetOutput(io.MultiWriter(os.Stderr, logFile))
logrus.RegisterExitHandler(closeLogFile)
// ...
logrus.Exit(0)
}
func closeLogFile() {
if logFile != nil {
logFile.Close()
}
}
To simplify @MMulthaupt 's usage, I did the following (which includes generating a new timestamp per run):
package main
import (
"time"
"os"
"path/filepath"
log "github.com/sirupsen/logrus"
)
cwd, err := os.Getwd()
if err != nil {
log.Fatalf("Failed to determine working directory: %s", err)
}
runID := time.Now().Format("run-2006-01-02-15-04-05")
logLocation := filepath.Join(cwd, runID + ".log")
logFile, err := os.OpenFile(logLocation, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("Failed to open log file %s for output: %s", logLocation, err)
}
log.SetOutput(io.MultiWriter(os.Stderr, logFile))
log.RegisterExitHandler(func() {
if logFile == nil {
return
}
logFile.Close()
})
log.WithFields(log.Fields{"at": "start", "log-location": logLocation}).Info()
// perform actions
log.Exit(0)
Did someone faced with a problem caused by dangling file descriptor while using logrotate? logrus doesn't frees up file descriptor and thereby continues write logs to an archive file maded by logrotate.
@Farit-Biktimirov You would have to have logrotate HUP the process and register a signal handler to respond to that signal open a new file, call SetOutput to start using the new file, and then close the old file.
Most helpful comment
Use
log.SetOutput()with a file handler, anything that implementsio.Writeris good.