2

Now i decided to use leveled logger in my Go programm. At this moment it's logrus. But after some investigation (through pain) found that there are much loggers: glog, log15, logrus and so on. So, now i want try to use logrus and have
possibility to change it on another without fixing all my sources where log is used.

I tried to create my own package logger which only imports logrus:

package logger
import "github.com/Sirupsen/logrus"

func init() {
    logrus.SetFormater(new(logrus.TextFormater))    
}

In all other my sources a want to use i in such way: // main.go

package main
import log "logger"

func main() {
   log.Print(...)
   log.Debug(...)
   and so on
}

But compiler says me that there are no such methods in logger package. Is there a way just import some package A to my own package B and use in my code all methods of A through B?

The reason what i need this is to have a chance quickly change logrus to ahother logger in future which support same methods just replacing several lines of code in my own logger file without replacing import log "github.com/Sirupsen/logrus" on import log "github.com/some_bestlogger" over all sources

3 Answers 3

2

You can import your logger package simply for its side effects, and still use the logrus package directly:

package main

import (
    log "github.com/Sirupsen/logrus"
    _ "logger"
)

func main() {
    log.Print()
    log.Debug()
}

If you do want to be able to call those log function directly through your "logger" package, you will need to define the functions and delegate them to the "logrus" package internally.

Sign up to request clarification or add additional context in comments.

2 Comments

Seems i need explicitly define my own methods and call appropriate logrus methods. I thought that there is a way to do so implicitely (automatic way)
You could create a single New() function in your "logger" package, as well as a "Logger" interface, and return a "Logger" from whatever package you want to use.
1

to have a chance quickly change logrus to ahother logger in future which support same methods

You will never switch to anything else, as every logger has distinct method set. For example log15 doesn't have Print method, but Info. And completely different approach to logging fields (key-value pairs). You're worried about changing a single import line, but in fact you will need to change every single line which uses logger.

If you want to be able to easily switch between logging packages, you need to come up with own logging interface (or use one that fits you best) and use logging package of your choice behind the scenes. Only this approach gives you ability to minimise changes all around your code.

You could also provide an interface in your library and then provide a default logger which would use a particular implementation. Note that all logger packages I know provide some kind of Logger structure (e.g. logrus.Logger) which you could than attach to your interface. Then, instead of changing package name on import, you could use log = logger.New() across your application.

If you don't take these arguments and want to follow your path, from my perspective all you need is an alias. You can either fork one of the logging libraries and use own fork across your code (this would allow you to completely change the behaviour without affecting importers) or simply symlink your desired import path to, say, logrus (although this will not work with go get).

2 Comments

I will create own logger interface (Print, Printf, Error and so on) and maybe create my own implementation (std logger + leveled part + custom formatter + possibility write to syslog, like github.com/koding/logging). Logrus big and poor documented. In the fact i need just std log + levels of logging and keep all such code small and simple )
Also there is some problem which i found: many packages just use std log. If i create my own then these packages will write to std log, my app will write to my logger. Why std log has no levels? Is this not common task for logger?
0

I think what you need is an interface. Here is a very simple example.

package main

import (
    "os"

    "github.com/Sirupsen/logrus"
)

func init() {
    // Output to stdout instead of the default stderr
    // Can be any io.Writer, see below for File example
    logrus.SetOutput(os.Stdout)
}

type logInterface interface {
    Print()
}

type MyLogger struct{}

func (ml MyLogger) Print() {
    logrus.WithFields(logrus.Fields{
        "animal": "walrus",
        "size":   10,
    }).Info("A group of walrus emerges from the ocean")
}

func main() {
    mylogger := MyLogger{}

    mylogger.Print()
}

In this way, you can replace logrus with any other logging package, and you just need to update the Print function and don't have to change the code where the Print function is called.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.