英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论