我正在尝试使用Golang写入日志文件.
我尝试了几种方法,但都失败了.这是我尝试过的:
func TestLogging(t *testing.T) {
if !FileExists("logfile") {
CreateFile("logfile")
}
f, err := os.Open("logfile")
if err != nil {
t.Fatalf("error: %v", err)
}
// attempt #1
log.SetOutput(io.MultiWriter(os.Stderr, f))
log.Println("hello, logfile")
// attempt #2
log.SetOutput(io.Writer(f))
log.Println("hello, logfile")
// attempt #3
log.SetOutput(f)
log.Println("hello, logfile")
}
func FileExists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
func CreateFile(name string) error {
fo, err := os.Create(name)
if err != nil {
return err
}
defer func() {
fo.Close()
}()
return nil
}
Run Code Online (Sandbox Code Playgroud)
创建了日志文件,但没有任何内容被打印或附加到它.为什么?
All*_*n A 148
os.Open() 过去必须有不同的工作方式,但这对我有用:
f, err := os.OpenFile("testlogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
}
defer f.Close()
log.SetOutput(f)
log.Println("This is a test log entry")
Run Code Online (Sandbox Code Playgroud)
基于Go文档,os.Open()无法工作log.SetOutput,因为它打开文件"for reading:"
func Open
func Open(name string) (file *File, err error)Open打开指定的文件进行阅读.如果成功,返回文件上的方法可用于读取; 关联的文件描述符具有模式O_RDONLY.如果有错误,它将是类型*PathError.
编辑
移动defer f.Close()到if err != nil检查后
小智 30
我更喜欢12因素app推荐的简单性和灵活性.要附加到日志文件,您可以使用shell重定向.Go中的默认记录器写入stderr(2).
./app 2>> logfile
Run Code Online (Sandbox Code Playgroud)
dee*_*ssn 16
通常,我会在屏幕上打印日志并写入文件。希望这对某人有帮助。
f, err := os.OpenFile("/tmp/orders.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
}
defer f.Close()
wrt := io.MultiWriter(os.Stdout, f)
log.SetOutput(wrt)
log.Println(" Orders API Called")
Run Code Online (Sandbox Code Playgroud)
小智 6
这适合我
创建了一个名为logger.go的包
package logger
import (
"flag"
"os"
"log"
"go/build"
)
var (
Log *log.Logger
)
func init() {
// set location of log file
var logpath = build.Default.GOPATH + "/src/chat/logger/info.log"
flag.Parse()
var file, err1 = os.Create(logpath)
if err1 != nil {
panic(err1)
}
Log = log.New(file, "", log.LstdFlags|log.Lshortfile)
Log.Println("LogFile : " + logpath)
}
Run Code Online (Sandbox Code Playgroud)
将包导入到您想要记录的位置,例如main.go
package main
import (
"logger"
)
const (
VERSION = "0.13"
)
func main() {
// time to use our logger, print version, processID and number of running process
logger.Log.Printf("Server v%s pid=%d started with processes: %d", VERSION, os.Getpid(),runtime.GOMAXPROCS(runtime.NumCPU()))
}
Run Code Online (Sandbox Code Playgroud)如果您在 linux 机器上运行二进制文件,则可以使用 shell 脚本。
覆盖到文件中
./binaryapp > binaryapp.log
Run Code Online (Sandbox Code Playgroud)
追加到文件中
./binaryapp >> binaryapp.log
Run Code Online (Sandbox Code Playgroud)
将 stderr 覆盖到文件中
./binaryapp &> binaryapp.error.log
Run Code Online (Sandbox Code Playgroud)
将 stderr 附加到文件中
./binaryapp &>> binalyapp.error.log
Run Code Online (Sandbox Code Playgroud)
使用 shell 脚本文件可以更动态。
小智 5
Go 中的默认记录器写入 stderr (2)。重定向到文件
import (
"syscall"
"os"
)
func main(){
fErr, err = os.OpenFile("Errfile", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
syscall.Dup2(int(fErr.Fd()), 1) /* -- stdout */
syscall.Dup2(int(fErr.Fd()), 2) /* -- stderr */
}
Run Code Online (Sandbox Code Playgroud)
在您的全局声明顶部,var以便您的所有流程可以在需要时访问。
package main
import (
"log"
"os"
)
var (
outfile, _ = os.Create("path/to/my.log") // update path for your needs
l = log.New(outfile, "", 0)
)
func main() {
l.Println("hello, log!!!")
}
Run Code Online (Sandbox Code Playgroud)
小智 5
基于 Allison 和 Deepak 的回答,我开始使用 logrus 并且非常喜欢它:
var log = logrus.New()
func init() {
// log to console and file
f, err := os.OpenFile("crawler.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
}
wrt := io.MultiWriter(os.Stdout, f)
log.SetOutput(wrt)
}
Run Code Online (Sandbox Code Playgroud)
我在主函数中有一个 defer f.Close()