Задать вопрос
Delgus
@Delgus

Допустимо ли в проектах использовать logrus так?

Можно сконфигурировать логгер в main
package main

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

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

func configurateLogger() {
  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)
}


А потом просто вызывать logrus в других пакетах когда требуется залогировать ошибку, без объявления глобального логгера
package pkg

import "github.com/sirupsen/logrus"

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


Допустимо ли такое использование логгера? Или же лучше через параметры функции передавать как здесь указывали в ответах?
Как правильно объявить Logger в golang?

Я лично не припомню случая когда мне для тестов приходилось подменять логгер, но это опять таки можно сделать через функцию TestMain. Зачем параметром через функцию прокидывать если логрус позволяет и так работать?

UPD. Это пример если логирование всех ошибок приложения в одном стиле производится, но мне интересно у кого-нибудь был проект где требовалось несколько разных логеров?
  • Вопрос задан
  • 2361 просмотр
Подписаться 1 Простой Комментировать
Решения вопроса 1
@ghostiam
На Go писатель, серверов пинатель.
Опять отвечу я :-) (как и на вопрос по ссылке)
Да, вы можете использовать так как написали, сам logrus имеет в себе глобальный логер по умолчанию.

В чём суть передачи логера в параметрах?
Ну...
Мы избавляемся от глобальной переменной.
Передача логера происходит в функцию явно.
Мы можем передавать по разному настроенный логер в одну и ту же функцию.

Для малого приложения без разницы, как будет написано, с глобальными переменными или нет, но вот для большего приложения, поддержка станет сложнее.

UPD. Это пример если логирование всех ошибок приложения в одном стиле производится, но мне интересно у кого-нибудь был проект где требовалось несколько разных логеров?

Я бы не советовал передавать в функцию явно, если бы не натыкался на подводные камни глобалок...
Предположим, у вас есть функция парсинга сайтов и вам вдруг(требования меняются часто в реальных проектах) стало необходимо писать лог в файл по имени сайта, как вы будете это делать с глобальным логером?
С передачей логера по ссылке, это сделать очень просто:
А в случае теста, мы заменим логер в файл, на логер с выводом в консоль.
func main() {
	logger := logrus.New()

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

	DoParse(sites, logger)
}

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


Или часть приложения логировать в файл, а часть и в файл и на консоль выводить.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
Нет.
Так не можно. Функция configurateLogger() у вас бесполезная. Она только оперирует внутренней переменной logger. Чтобы переменную было заметно глобальней нужно объявлять ее в более широком контексте, снаружи функции(а не внутри оператором := ). А что бы ее было видно в других пакетах она должна именоваться с большой буквы var Logger = configurateLogger() и все это добро нужно импортировать в другие пакеты.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы