我正在尝试使用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
}
创建了日志文件,但没有任何内容被打印或附加到它。为什么呢?
答案 0 :(得分:137)
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")
根据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
检查
答案 1 :(得分:23)
我更喜欢12因素应用推荐的简单性和灵活性。要附加到日志文件,您可以使用shell重定向。 Go中的默认记录器写入stderr(2)。
./app 2>> logfile
答案 2 :(得分: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)
}
将包导入到您想要记录的位置,例如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()))
}
答案 3 :(得分:5)
我通常在屏幕上打印日志,并将其写入文件。希望这对某人有帮助。
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")
答案 4 :(得分:4)
Go中的默认记录器写入stderr(2)。 重定向到文件
import pyfits
from nifty import *
hdulist = pyfits.open('PolCat_withRRM.fits')
tbdata = hdulist[1].data
G_lon = np.array(tbdata.field('G_lon'))
G_lat = np.array(tbdata.field('G_lat'))
np.save('glon', G_lon)
np.save('glat', G_lat)
matrix=[G_lon,G_lat]
matrice=np.array(matrix)
#loading information about the sources and the (simulated) data
lon = np.load('lon.npy')
lat = np.load('lat.npy')
#Now I want know where the values in colujmns G_lon e G_lat are in lon e lat columns
delta=(0.003,0.003)
for item1 in zip(G_lon, G_lat):
for item2 in zip(lon, lat):
if (item2 >= tuple(np.subtract(item1,delta))) and (item2 <= tuple(np.sum(item1,delta))):
item2_index=np.where(lon)
item = lon[item2_index]
print item2
答案 5 :(得分:4)
基于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)
}
我在主函数中延迟了f.Close()
答案 6 :(得分:2)
在您的全局 <Switch {...switchProps}>
{
routes.map((route, i) => (
<Route
key={route.key || i}
path={route.path}
exact={route.exact}
strict={route.strict}
render={(props) => {
const location = route.check && route.check(props);
if (location) {
props.history.push(location);
return null;
}
return (
<route.component
{...props}
{...extraProps}
route={route}
/>
);
}}
/>
))
}
</Switch>
中声明最高位置,以便您的所有流程都可以根据需要进行访问。
var
答案 7 :(得分:1)
如果您在Linux计算机上运行二进制文件,则可以使用Shell脚本。
覆盖到文件
./binaryapp > binaryapp.log
附加到文件
./binaryapp >> binaryapp.log
将stderr覆盖到文件中
./binaryapp &> binaryapp.error.log
将stderr附加到文件中
./binaryapp &>> binalyapp.error.log
使用shell脚本文件可以更加动态。
答案 8 :(得分:0)
我正在将日志写入文件,这些日志每天生成一次(每天生成一个日志文件)。这种方法对我来说很好:
var (
serverLogger *log.Logger
)
func init() {
// set location of log file
date := time.Now().Format("2006-01-02")
var logpath = os.Getenv(constant.XDirectoryPath) + constant.LogFilePath + date + constant.LogFileExtension
os.MkdirAll(os.Getenv(constant.XDirectoryPath)+constant.LogFilePath, os.ModePerm)
flag.Parse()
var file, err1 = os.OpenFile(logpath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err1 != nil {
panic(err1)
}
mw := io.MultiWriter(os.Stdout, file)
serverLogger = log.New(mw, constant.Empty, log.LstdFlags)
serverLogger.Println("LogFile : " + logpath)
}
// LogServer logs to server's log file
func LogServer(logLevel enum.LogLevel, message string) {
_, file, no, ok := runtime.Caller(1)
logLineData := "logger_server.go"
if ok {
file = shortenFilePath(file)
logLineData = fmt.Sprintf(file + constant.ColonWithSpace + strconv.Itoa(no) + constant.HyphenWithSpace)
}
serverLogger.Println(logLineData + logLevel.String() + constant.HyphenWithSpace + message)
}
// ShortenFilePath Shortens file path to a/b/c/d.go tp d.go
func shortenFilePath(file string) string {
short := file
for i := len(file) - 1; i > 0; i-- {
if file[i] == constant.ForwardSlash {
short = file[i+1:]
break
}
}
file = short
return file
}
“ shortenFilePath()”方法,用于从文件的完整路径获取文件名。和“ LogServer()”方法用于创建格式化的日志语句(包含:文件名,行号,日志级别,错误语句等)
答案 9 :(得分:0)
为了帮助其他人,我创建了一个基本的日志功能来处理两种情况下的日志记录,如果您希望将输出输出到stdout,然后打开debug,它会直接执行switch标记,以便您选择输出。 / p>
func myLog(msg ...interface{}) {
defer func() { r := recover(); if r != nil { fmt.Print("Error detected logging:", r) } }()
if conf.DEBUG {
fmt.Println(msg)
} else {
logfile, err := os.OpenFile(conf.LOGDIR+"/"+conf.AppName+".log", os.O_RDWR | os.O_CREATE | os.O_APPEND,0666)
if !checkErr(err) {
log.SetOutput(logfile)
log.Println(msg)
}
defer logfile.Close()
}
}
答案 10 :(得分:0)
这可能会对您有所帮助(如果存在日志文件,请使用它;如果不存在,请创建它):
package main
import (
"flag"
"log"
"os"
)
//Se declara la variable Log. Esta será usada para registrar los eventos.
var (
Log *log.Logger = Loggerx()
)
func Loggerx() *log.Logger {
LOG_FILE_LOCATION := os.Getenv("LOG_FILE_LOCATION")
//En el caso que la variable de entorno exista, el sistema usa la configuración del docker.
if LOG_FILE_LOCATION == "" {
LOG_FILE_LOCATION = "../logs/" + APP_NAME + ".log"
} else {
LOG_FILE_LOCATION = LOG_FILE_LOCATION + APP_NAME + ".log"
}
flag.Parse()
//Si el archivo existe se rehusa, es decir, no elimina el archivo log y crea uno nuevo.
if _, err := os.Stat(LOG_FILE_LOCATION); os.IsNotExist(err) {
file, err1 := os.Create(LOG_FILE_LOCATION)
if err1 != nil {
panic(err1)
}
//si no existe,se crea uno nuevo.
return log.New(file, "", log.Ldate|log.Ltime|log.Lshortfile)
} else {
//si existe se rehusa.
file, err := os.OpenFile(LOG_FILE_LOCATION, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
panic(err)
}
return log.New(file, "", log.Ldate|log.Ltime|log.Lshortfile)
}
}
有关更多详细信息:https://su9.co/9BAE74B