英文:
Logging to a file in golang
问题
我正在使用golang开始编写代码,并且在构建应用程序时,我想从一开始就添加日志记录,但是我遇到了问题。
如果我打开一个文件并使用标准的日志记录库,我可以将日志写入文件中。代码如下:
package main
import (
"os"
"fmt"
"log"
)
func main() {
// 打开一个文件
f, err := os.OpenFile("test.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
fmt.Printf("error opening file: %v", err)
}
// 不要忘记关闭文件
defer f.Close()
// 将日志输出到文件
log.SetOutput(f)
log.Output(1, "this is an event")
}
这样我就可以在test.log文件中看到日志行。然而,如果我尝试将其改为支持logrus(https://github.com/Sirupsen/logrus),代码如下:
package main
import (
"os"
"fmt"
log "github.com/Sirupsen/logrus"
)
func init() {
// 打开一个文件
f, err := os.OpenFile("testlogrus.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
fmt.Printf("error opening file: %v", err)
}
// 不要忘记关闭文件
defer f.Close()
// 将日志格式设置为JSON格式
log.SetFormatter(&log.JSONFormatter{})
// 将日志输出到stderr,也可以是一个文件
log.SetOutput(f)
// 只记录警告级别及以上的日志
log.SetLevel(log.DebugLevel)
}
func main() {
log.WithFields(log.Fields{
"Animal": "Logrus",
}).Info("A logrus appears")
}
我只会看到错误信息:
Failed to write to log, write testlogrus.log: bad file descriptor
我只会得到"bad file descriptor"的错误。你有什么想法我做错了什么吗?
谢谢
Craig
英文:
I am starting out with golang, and as I am starting to build out my applciation I want to add logging from the start, and that is where I am running into issues.
If I open a file and use the standard logging library, I am able to write to a file. Like so.
package main
import (
"os"
"fmt"
"log"
)
func main() {
// open a file
f, err := os.OpenFile("test.log", os.O_APPEND | os.O_CREATE | os.O_RDWR, 0666)
if err != nil {
fmt.Printf("error opening file: %v", err)
}
// don't forget to close it
defer f.Close()
// assign it to the standard logger
log.SetOutput(f)
log.Output(1, "this is an event")
}
I will get my test.log with the log line in it. However if I try to adapt this to support logrus https://github.com/Sirupsen/logrus like this
package main
import (
"os"
"fmt"
log "github.com/Sirupsen/logrus"
)
func init() {
// open a file
f, err := os.OpenFile("testlogrus.log", os.O_APPEND | os.O_CREATE | os.O_RDWR, 0666)
if err != nil {
fmt.Printf("error opening file: %v", err)
}
// don't forget to close it
defer f.Close()
// Log as JSON instead of the default ASCII formatter.
log.SetFormatter(&log.JSONFormatter{})
// Output to stderr instead of stdout, could also be a file.
log.SetOutput(f)
// Only log the warning severity or above.
log.SetLevel(log.DebugLevel)
}
func main() {
log.WithFields(log.Fields{
"Animal": "Logrus",
}).Info("A logrus appears")
}
All I will ever see are errors.
Failed to write to log, write testlogrus.log: bad file descriptor
All I ever get is the bad file descriptor error. Any ideas what I am doing wrong?
Thanks
Craig
答案1
得分: 13
由于您在init函数中设置了文件,并且使用了defer f.Close(),文件会在init函数返回后关闭。
您可以选择保持文件打开状态,或将整个操作移到main函数中。
英文:
Since you setup the file in the init function and you have defer f.Close(), the file gets closed after init returns.
you either have to keep the file open or move the whole thing into main.
答案2
得分: 2
在Linux上,在开发过程中,你可以将输出写入标准输出(stdout)并将其导入到文件中。在生产环境中,可以将输出写入系统日志(syslog)。无论哪种方式,你都不需要自己处理文件。
英文:
On Linux
In development you can write to stdout and pipe to a file.
In production write to syslog.
Both ways you dont need to handle the file yourself.
答案3
得分: 1
如果你使用logrus,最好使用文档推荐的hooks。
参考:https://github.com/rifflock/lfshook 上的示例。
在我看来,将整个代码移到主函数中通常不是一个好主意,相反,我们希望有良好分段的代码。
英文:
If you use logrus you should better use hooks which is recommended by documentation.
See : https://github.com/rifflock/lfshook for examples.
In my opinon moving the whole thing to the main is generally not a good idea, instead we want well-segmented code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论