如何根据golang中的“调用者”程序创建一个包以使用任何记录器?

As I can see, each developer has its own need and approach to solve same things/needs. As an example, logging. There are many logging packages that works in different ways and each developer choose the one that best fits their needs/preferences. Thinking on that, I would like to create a package that should use the caller's logging package. Is it possible? Someone have a way to do that?

Something like this:

Main code using logrus package:

package main

import (
    "os"

    "github.com/Sirupsen/logrus"

    "gitlab.com/tutume/_testing/globallogs/mypack"
)

var Log = logrus.New()

var myPack pack.Pack

func main() {
    isDebug := os.Getenv("MYAPP_LOGLEVEL")
    switch isDebug {
    case "Debug":
        Log.Level = logrus.DebugLevel
    case "Info":
        Log.Level = logrus.InfoLevel
    default:
        Log.Level = logrus.ErrorLevel
    }
    Log.Formatter = &logrus.TextFormatter{
        ForceColors: true,
    }

    Log.Debug("Debugging...")
    Log.Info("Informing...")
    Log.Error("Normal...")

    myPack.Logger = Log
    myPack.DoSomething()

}

mypack code:

package pack

type Pack struct {
    Logger interface{}
}

func (mp *Pack) DoSomething() {
    //  Logger.Debug("Debugging...")
    //  Logger.Info("Informing...")
    //  Logger.Error("Normal...")
}

If I understand what you're trying to do, you need to define an interface that a logging package would implement. If you define Logger as an empty interface, you won't be able to call any of those methods. Instead, you need to define an interface that contains the methods you want to use (Debug, Info, Error, etc.). Any logging package would then have to implement those methods. If a particular logging package doesn't have the right set of methods already, you would have to write some wrapper code to implement the interface as you define it.

I kept searching and found this post. Very interesting. As a infrastructure manager/technician, one thing that I've always missed from many software that I use (and have used) is the ability to have as deeper information as possible to identify and fix issues or even for logging everything for auditing/security proposal. Many times, we face with some issues that even in debug mode we aren't able to find the exactly cause of the problem, we ended up just finding the "probable" cause. Now getting back into development world, and seeing how developer are working with logs and libraries, I'm thinking that this could be one reason (the lack of "interoperability between the main programs and its libraries). As libraries usually have "their own" logging (or not loggin at all) and many times, doesn't give a "full control" on what is happening inside the library, in most cases the developer who is developing the main program (using such libraries) will not be able to give its own application the necessary logging details. Of course, I understand that in the open source world, if you want to have a more detailed information including from libraries that you use, as it is open source, you can simple make your changes and it is done. But then, this could make the use of a library (thinking in the advantage of using libraries mainly for not spending time to "recreate the wheel", in other world reusability) not as helpful as it should be. As the referenced post mentioned, one way to handle it is by always sending to the caller the "necessary" information to be handled. But usually it works for errors, fatals and maybe info level events. But for debug and trace for instance, it isn't "pratical" when developing libraries (for many reasons), and then I think that one big reason is that when a developer is developing a library, he will already need all debugs and traces for testing, but not necessarily sending back to the caller. Another way detailed in the post is by using handlers, but by doing this, the developer of the library will have much more work to do. As Andy answered (and is discussed in the post too), an alternative is to create an interface that will receive the main's program logger and use it and for this option to work properly, it should use the stdlib log (or some logging library that implement the most comum logging levels) in case the caller program doesn't case about logging. For my "wishes" right now (as I'm benning in programming again and totally beggining in Go), I will create some "ugly code" to handle my needs and keep learning and trying ways to accomplish the "perfect logging system" which by now, IMHO is using interfaces as Andy suggested.