Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging globally (across packages)

Tags:

logging

go

I have spent a lot of time now searching and reading posts on the subject but have note yet managed to fully get my question answered - or perhaps I just need more clarification on existing answers.

I have read this post which has the same title as mine, but it's about logging across go routines rather than packages.

What I'm trying to solve is logging across the main app and any packages it uses. I need a logger that can log to multiple locations (which can be done with io.MultiWriter) and can do things like log.Error() and log.Debug()

I know there are packages that do this and I know how to implement those things myself.

What I can't get my head around is how to properly use it with my packages.

One way is of course to create the logger in main and then pass it around to all functions that need logging. But it seems awkward.

My ideal solution would be to have a logger like the built in global logger from the log package, but with the added functionality as above.

I mostly want this for optional debug logging within packages, so I can turn this on in a production version if needed.

What is the proper way to do this?

like image 608
IamNaN Avatar asked Apr 09 '15 12:04

IamNaN


1 Answers

I'm posting the solution worked for me!. I just created my own package, and I used the init function.

package logging

import (
    "io"
    logging "log"
    "os"

    "github.com/Sirupsen/logrus"
)

var (
    log *logrus.Logger
)

func init() {
    f, err := os.OpenFile("logs/application.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)

    if err != nil {
        logging.Fatalf("error opening file: %v", err)
    }

    log = logrus.New()

    //log.Formatter = &logrus.JSONFormatter{}

    log.SetReportCaller(true)

    mw := io.MultiWriter(os.Stdout, f)
    log.SetOutput(mw)
}

// Info ...
func Info(format string, v ...interface{}) {
    log.Infof(format, v...)
}

// Warn ...
func Warn(format string, v ...interface{}) {
    log.Warnf(format, v...)
}

// Error ...
func Error(format string, v ...interface{}) {
    log.Errorf(format, v...)
}

var (

    // ConfigError ...
    ConfigError = "%v type=config.error"

    // HTTPError ...
    HTTPError = "%v type=http.error"

    // HTTPWarn ...
    HTTPWarn = "%v type=http.warn"

    // HTTPInfo ...
    HTTPInfo = "%v type=http.info"
)

And on any package, just import my package and I execute the (Info, Warn, Error) function

package main

import (

    log "logging"
)

func main() {
    log.Error(log.ConfigError, "Testing the error")
}

The log entry will be saved rendered on the screen and it will be saved on a file.

like image 143
ctreminiom Avatar answered Sep 20 '22 00:09

ctreminiom