Custom package Logger doesn't work for other files

Hello everyone, I have an issue to use the different logs from my custom Logger package in other files of the project. So here is my Logger package with InitLogs() method.
I have only one module in the application ‘ConsulGitOpsOperator/packages’ and all other custom packages are located here. I can use Methods from other packages in main function, but for some reason the Logger package doesn’t work for other files. Could you please help me to find a solution?

Any help is appreciated!!

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
}

And this is the way how I import it and use in the main function

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
	}
}

Can you clarify what you mean by “doesn’t work?” Are you getting an error, or is it not behaving how you would expect?

It is not behaving as I would expect. For example, you see in the main function I added in the second line a log message ‘Logger.Info.Println(“This is an Info”) // the output is NOT saved in the logFile’ and this message or any other message throughout the application will not be saved in the log file which I create in the method InitLogs. I want to save all the error, warning and info messages in that single file.

You close the file when InitLogs returns. You can’t write to the closed file later. Is there no panic?

Isn’t this redundant? *File already implements Writer.

Where should I close the logFile, on which line? Maybe outside of the function InitLogs?

The logFile itself has type of os.File, that’s why I thought iy should have wrapped it as a io.writer.

  • You can return the logFile from InitLogs and defer its closure in main.

  • A Tour of Go

1 Like

Another option is for InitLogs to return a function to close the log file(s):

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