Echo: Logger always writes to os.Stderr

Created on 5 Mar 2017  Â·  11Comments  Â·  Source: labstack/echo

package config

import (
    "os"

    "github.com/labstack/gommon/log"
)

// SetLoggerOutput sets the log path
func SetLoggerOutput(cfgLogPath string, debug string) error {
    if debug == "true" {
        log.SetOutput(os.Stderr)
        log.SetLevel(log.DEBUG)
    } else {
        logPath, err := os.OpenFile(cfgLogPath, os.O_APPEND|os.O_CREATE, 0755)
        if err != nil {
            return err
        }
        log.SetOutput(logPath)
        log.SetLevel(log.WARN)
    }
    return nil
}

Regardless of the value of debug it always writes to os.Stderr. I ditched Logrus for Echo's logger. Thanks for the awesome framework!

wontfix

Most helpful comment

@vishr ofc

package main

import (
    "flag"
    "net/http"
    "os"

    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
    "github.com/labstack/gommon/log"
)

func main() {
    e := echo.New()
    e.GET("/", func(ctx echo.Context) error {
        ctx.Logger().Debug("woot woot!\n")

        return ctx.NoContent(http.StatusOK)
    })

    loggerConfig := middleware.DefaultLoggerConfig

    f, err := os.OpenFile("/var/log/api.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
    if err != nil {
        log.Errorf("cannot open '/var/log/api.log', (%s)", err.Error())
        flag.Usage()
        os.Exit(-1)
    }

    defer f.Close()

    loggerConfig.Output = f

    e.Debug = true

    e.Use(middleware.LoggerWithConfig(loggerConfig))
    e.Use(middleware.Recover())

    if e.Debug {
        e.Logger.SetLevel(log.DEBUG)
    }

    e.Logger.Fatal(e.Start(":8080"))
}

All 11 comments

@adred Regardless of this logic, have you tried writing to a file directly? I tried code below:

package main

import (
    "github.com/labstack/gommon/log"
    "os"
)

func main() {
    file, _ := os.Create("/tmp/out.txt")
    log.SetOutput(file)
    log.Error("hello")
}

Sorry for the late reply. It still does not work.

Can you make sure your gommon is update to date? I test this code on mac.

This is my current code. It now creates the file. I thought that was the issue but still no logs are written. I'm using Fedora 25. I'll try updating the package tonight. Thanks for taking time to reply.

// SetLoggerOutput sets the log path
func SetLoggerOutput(cfgLogPath string, debug bool) error {
    if debug == true {
        log.SetOutput(os.Stderr)
        log.SetLevel(log.DEBUG)
    } else {
        var file *os.File
        if _, err := os.Stat(cfgLogPath); os.IsNotExist(err) {
            file, err = os.Create(cfgLogPath)
            if err != nil {
                return err
            }
            defer file.Close()
        }
        log.SetOutput(file)
        log.SetLevel(log.WARN)
    }

    return nil
}

Hi, can I save all the logs to database instead stdout?

I see in documents that needs an io.Writer but I want to save in my database.

Don't know why, it just saves INFO logs, here's the file:

19:46 $ cat api.log
{"time":"2017-06-01T13:32:36.797183103-05:00","id":"","remote_ip":"192.168.1.50","host":"192.168.1.50:8080","method":"GET","uri":"/some/url/17","status":200, "latency":314143039,"latency_human":"314.143039ms","bytes_in":0,"bytes_out":3134}
{"time":"2017-06-03T10:45:48.640288865-05:00","id":"","remote_ip":"192.168.0.3","host":"192.168.0.3:8080","method":"GET","uri":"/some/26/other/129/16/url","status":200, "latency":2544021986,"latency_human":"2.544021986s","bytes_in":0,"bytes_out":0}

But, here's the standard output, it logs the types, like ERROR or DEBUG

⇨ http server started on [::]:8080
{"time":"2017-06-08T19:39:34.074115639-05:00","level":"DEBUG","prefix":"echo","file":"service.go","line":"199","message":"runing new WS hub (on-demand-26-136-23): 26, 136"}
{"time":"2017-06-08T19:39:34.240292103-05:00","level":"ERROR","prefix":"echo","file":"echo.go","line":"277","message":"code=404, message=Not Found"}

My config:

loggerConfig := middleware.DefaultLoggerConfig

if *env == string(EnvTypeProduction) {
  f, err := os.OpenFile("/var/log/api.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
  if err != nil {
    os.Exit(-1)
  }

  defer f.Close()

  loggerConfig.Output = f

  if *debug == "1" {
    e.Debug = true
  }
} else {
  e.Debug = true
}

e.Use(middleware.LoggerWithConfig(loggerConfig))
e.Use(middleware.Recover())

if e.Debug {
  e.Logger.SetLevel(log.DEBUG)
}

e.Logger.Fatal(e.Start(fmt.Sprintf(":%s", *port)))

@nebiros Can you trim down your code to a minimal working example for debugging?

@vishr ofc

package main

import (
    "flag"
    "net/http"
    "os"

    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
    "github.com/labstack/gommon/log"
)

func main() {
    e := echo.New()
    e.GET("/", func(ctx echo.Context) error {
        ctx.Logger().Debug("woot woot!\n")

        return ctx.NoContent(http.StatusOK)
    })

    loggerConfig := middleware.DefaultLoggerConfig

    f, err := os.OpenFile("/var/log/api.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
    if err != nil {
        log.Errorf("cannot open '/var/log/api.log', (%s)", err.Error())
        flag.Usage()
        os.Exit(-1)
    }

    defer f.Close()

    loggerConfig.Output = f

    e.Debug = true

    e.Use(middleware.LoggerWithConfig(loggerConfig))
    e.Use(middleware.Recover())

    if e.Debug {
        e.Logger.SetLevel(log.DEBUG)
    }

    e.Logger.Fatal(e.Start(":8080"))
}

You have a couple of logging system here:

  • Logger middleware for which you are setting up the output loggerConfig.Output = f
  • e.Logger which defaults to stdout, you need to set its output to f as well e.Logger.SetOutput(f).

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

absinsekt picture absinsekt  Â·  4Comments

toorop picture toorop  Â·  4Comments

linux-support picture linux-support  Â·  3Comments

vishr picture vishr  Â·  3Comments

dre1080 picture dre1080  Â·  4Comments