Is it permissible in projects to use the logrus right?

You can configure the logger in main
package main

import (
"github.com/delgus/learn-log/pkg"
"github.com/sirupsen/logrus"
)

func main() {
configurateLogger()
logrus.Println("Hello")
pkg.Work("lala")
}

configurateLogger func() {
 logrus.StandardLogger().SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02T15:04:05.999"})
 level, err := logrus.ParseLevel("debug")
 if err != nil {
 level = logrus.InfoLevel
logrus.WithError(err).
 WithField("event", "start.parse_level_fail").
 Info("set log level to \"info\" by default")
}
logrus.SetLevel(level)
}


And then just call logrus in other packages when you want to salaryrate error, without declaring the global logger
package pkg

import "github.com/sirupsen/logrus"

func Work(string s) {
 logrus.Info(`i work`)
 logrus.Debugf(`string: %s`, s)
}


Is it permissible to use the logger? Or is it better using the function parameters to pass here as pointed out in the responses?
How to declare a Logger in golang?

I personally do not remember a case when I for tests had to supplant logger, but this again can be done through the function TestMain. Why the parameter through the function to pass if the Logrus allows you to work like this?

UPD. This is an example if logs all application errors in the same style is, but I wonder has anyone ever had a project which required several different data loggers?
April 7th 20 at 10:57
2 answers
April 7th 20 at 10:59
Solution
Again I will answer :-) (as to the question on the link)
Yes, you can use as you have written, he logrus has a global logger by default.

What is the transfer of logger in the settings?
Well...
We get rid of the global variable.
The transfer of the logger takes place in the function explicitly.
We can pass differently configured LOGER one and the same function.

For small applications without a difference, as will be written with global variables or not, but for a larger application, support will become more difficult.

UPD. This is an example if logs all application errors in the same style is, but I wonder has anyone ever had a project which required several different data loggers?

I would not advise to pass to the function explicitly, if I had not come across the pitfalls globallock...
Suppose you have a function of parsing of sites, and you suddenly(requirements change frequently in real projects) it became necessary to write the log to a file by the name of the website, as you will do it with a global logger?
With the transfer of logger on the link to do is very simple:
And in the case of the test, we replace the logger to a file for logger output to the console.
func main() {
 logger := logrus.New()

 sites := []string{
"example.com",
"google.com",
}

 DoParse(site, logger)
}

func DoParse(sites []string, logrus logger.FieldLogger) {
 for _, site := range sites {
 logger.Infof("Start parse site: %s", site)
 siteLogger := initLoggerForSite(site)
 parseSite(site, siteLogger)
}
}


Or part of the application log to a file, and and file and to the console output.
April 7th 20 at 11:01
No.
So it is not possible. Function configurateLogger() you are useless. It only operates internal variable logger. It was noticeable to a variable global you need to declare it in a wider context outside of the function(and not inside an operator := ). What would it been seen in other packages it should be named with a capital letter var Logger = configurateLogger() and all that stuff need to be imported into other packages.
approx. like so.
configurateLogger func() {
 logrus.StandardLogger().SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02T15:04:05.999"})
 level, err := logrus.ParseLevel("debug")
 if err != nil {
 level = logrus.InfoLevel
logrus.WithError(err).
 WithField("event", "start.parse_level_fail").
 Info("set log level to \"info\" by default")
}
logrus.SetLevel(level)
}

{"level":"info","msg":"Hello","time":"2020-02-10T12:56:59.86"}
{"level":"info","msg":"i work","time":"2020-02-10T12:56:59.861"}
{"level":"debug","msg":"string: lala","time":"2020-02-10T12:56:59.861"}


Why import if you can to Maine to configure and no steam on - Ferne_Hil commented on April 7th 20 at 11:04
func StandardLogger() *Loggerdoes not change the Logger at all, and gets very specific Logger, you must continue to use, and you don't use.
pkg mylogger
...
MyConcreteLogger := logrus.StandardLogger()
MyConcreteLogger.SetFormatter()
...
pkg anotherpackage
import "mylogger"
mylogger.MyConcreteLogger.Log() // here something like this should be
- rodolfo.Huels commented on April 7th 20 at 11:07
@Shaina10if you are confused StandardLogger then
I gave you a working example. it works
configurateLogger func() {
 logrus.SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02T15:04:05.999"})
 level, err := logrus.ParseLevel("debug")
 if err != nil {
 level = logrus.InfoLevel
logrus.WithError(err).
 WithField("event", "start.parse_level_fail").
 Info("set log level to \"info\" by default")
}
logrus.SetLevel(level)
}


This example works because inside Logrus already have a global variable std which is the standard logger and can be used in other places - Ferne_Hil commented on April 7th 20 at 11:10
@Shaina10, logrus has a global variable and is itself a singleton. - caden_Klocko commented on April 7th 20 at 11:13
@Mateo_Rosenbaum87, @valerie_Mills, read code and Yes, you are right. In my opinion, however, is a totally irresponsible architecture - to make the invisible global and allow her invisible to change. As for me - "not idiomatic for Go". Of course your code will then work. I would not do was not encourage magic. - rodolfo.Huels commented on April 7th 20 at 11:16
@Shaina10, that's why I'm against globallock, but I don't understand why I suggest to transfer all explicitly in the function...

As for me - "not idiomatic for Go". Of course your code will then work. I would not do was not encourage magic.

Totally agree! - caden_Klocko commented on April 7th 20 at 11:19

Find more questions by tags Go