Golang自定义日志包在其他文件中无法使用的问题

Golang自定义日志包在其他文件中无法使用的问题 大家好,我遇到了一个问题:无法在项目的其他文件中使用我自定义的 Logger 包中的不同日志记录器。以下是我的 Logger 包及其 InitLogs() 方法。 我的应用程序中只有一个模块 ConsulGitOpsOperator/packages,所有其他自定义包都位于此。我可以在主函数中使用其他包的方法,但不知为何 Logger 包在其他文件中不起作用。能否请您帮我找到一个解决方案?

非常感谢任何帮助!!

package Logger

import (
	"ConsulGitOpsOperator/packages/Config"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
)

var (
	Info    *log.Logger
	Warning *log.Logger
	Error   *log.Logger
)

func InitLogs() {
	logPath := fmt.Sprintf("%s%s", Config.WorkingDir(), "\\appLogs.txt")
	flag.Parse()
	logFile, err := os.OpenFile(logPath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Printf("Error creating log file: %v\n", err)
		os.Exit(1)
	}
	defer logFile.Close()
	writer := io.Writer(logFile)
	flags := log.Ldate | log.Ltime | log.Lshortfile
	Info = log.New(writer, "INFO: ", flags)
	Warning = log.New(writer, "WARNING: ", flags)
	Error = log.New(writer, "ERROR: ", flags)
	writeLog := io.MultiWriter(os.Stdout, writer)
	log.SetOutput(writeLog)
	Warning.Println("LogFile : " + logPath)	// the output is saved in the logFile
}

以下是我在主函数中导入和使用它的方式

package main

import (
	"ConsulGitOpsOperator/packages/GenerateACLTokens"
	Logger "ConsulGitOpsOperator/packages/Logger"
)

func main() {

	Logger.InitLogs()
	Logger.Info.Println("This is an Info")  // the output is NOT saved in the logFile
	err := GenerateACLTokens.StartGeneratingToken()
	if err != nil {
		Logger.Error.Println("Error", err)  // the output is NOT saved in the logFile
	}
}

更多关于Golang自定义日志包在其他文件中无法使用的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

■■■:

出于某些原因,Logger 包在其他文件中无法工作。

你能澄清一下“无法工作”具体是什么意思吗?是出现了错误,还是它的行为不符合你的预期?

更多关于Golang自定义日志包在其他文件中无法使用的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我应该在哪个位置、哪一行关闭 logFile?也许是在 InitLogs 函数外部?

logFile 本身的类型是 os.File,这就是为什么我认为应该将其包装为 io.writer。

  • 你可以从 InitLogs 函数返回 logFile,并在 main 函数中延迟关闭它。
  • Go 语言之旅

另一种方案是让 InitLogs 返回一个用于关闭日志文件的函数:

func InitLogs() (closer func() error) {
	// ...
	return logFile.Close
}
func main() {
	closeLogs := Logger.InitLogs()
	defer closeLogs()
	// ...
}

它的行为不符合我的预期。例如,在main函数中,我在第二行添加了一条日志消息Logger.Info.Println("This is an Info") // 这条输出没有保存到logFile中,这条消息以及整个应用程序中的任何其他消息都不会保存到我在InitLogs方法中创建的日志文件中。我希望将所有错误、警告和信息消息都保存到那个单一文件中。

func main() {
    fmt.Println("hello world")
}

问题在于 defer logFile.Close()InitLogs() 函数中过早关闭了日志文件。当 InitLogs() 返回时,文件会被立即关闭,导致后续日志写入失败。

以下是修正后的代码:

package Logger

import (
	"ConsulGitOpsOperator/packages/Config"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
)

var (
	Info    *log.Logger
	Warning *log.Logger
	Error   *log.Logger
	logFile *os.File
)

func InitLogs() {
	logPath := fmt.Sprintf("%s%s", Config.WorkingDir(), "/appLogs.txt")
	flag.Parse()
	
	var err error
	logFile, err = os.OpenFile(logPath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Printf("Error creating log file: %v\n", err)
		os.Exit(1)
	}
	
	writer := io.Writer(logFile)
	flags := log.Ldate | log.Ltime | log.Lshortfile
	Info = log.New(writer, "INFO: ", flags)
	Warning = log.New(writer, "WARNING: ", flags)
	Error = log.New(writer, "ERROR: ", flags)
	
	writeLog := io.MultiWriter(os.Stdout, writer)
	log.SetOutput(writeLog)
	
	Warning.Println("LogFile : " + logPath)
}

func CloseLogs() {
	if logFile != nil {
		logFile.Close()
	}
}

在主函数中使用时:

package main

import (
	"ConsulGitOpsOperator/packages/GenerateACLTokens"
	Logger "ConsulGitOpsOperator/packages/Logger"
)

func main() {
	Logger.InitLogs()
	defer Logger.CloseLogs()
	
	Logger.Info.Println("This is an Info")
	err := GenerateACLTokens.StartGeneratingToken()
	if err != nil {
		Logger.Error.Println("Error", err)
	}
}

另外,建议将日志文件路径中的反斜杠改为正斜杠,以保持跨平台兼容性:

logPath := fmt.Sprintf("%s/appLogs.txt", Config.WorkingDir())

这样修改后,日志文件会在整个程序运行期间保持打开状态,直到主函数结束时才关闭,确保所有日志都能正确写入文件。

回到顶部