Голанг логрус - как сделать централизованную настройку?

Я использую логрус в приложении Go. Я считаю, что этот вопрос применим и к любому другому пакету ведения журнала (который не предлагает конфигурацию на основе внешних файлов).

logrus предоставляет функции для настройки различных конфигураций, например SetOutput, SetLevel и т. Д.

Как и в любом другом приложении, мне нужно вести журнал из нескольких исходных файлов / пакетов, кажется, вам нужно настроить эти параметры в каждом файле с помощью logrus.

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


person Dipen Bhikadya    schedule 15.05.2015    source источник


Ответы (2)


Вам не нужно устанавливать эти параметры в каждом файле с Logrus.

Вы можете импортировать Логрус как log:

import log "github.com/Sirupsen/logrus"

Тогда такие функции, как log.SetOutput(), являются просто функциями и модифицируют глобальный регистратор и применяются к любому файлу, который включает этот импорт.

Вы можете создать глобальную log переменную пакета:

var log = logrus.New()

Тогда такие функции, как log.SetOutput(), являются методами и изменяют ваш пакет глобально. Это неудобно, ИМО, если у вас есть несколько пакетов в вашей программе, потому что у каждого из них есть другой регистратор с разными настройками (но, возможно, это хорошо для некоторых случаев использования). Мне также не нравится этот подход, потому что он сбивает с толку goimports (который захочет вставить log в ваш список импорта).

Или вы можете создать свою собственную оболочку (что я и делаю). У меня есть собственный log пакет со своим logger var:

var logger = logrus.New()

Затем делаю функции верхнего уровня для обертывания Логруса:

func Info(args ...interface{}) {
    logger.Info(args...)
}

func Debug(args ...interface{}) {
    logger.Debug(args...)
}

Это немного утомительно, но позволяет мне добавлять функции, специфичные для моей программы:

func WithConn(conn net.Conn) *logrus.Entry {
    var addr string = "unknown"
    if conn != nil {
        addr = conn.RemoteAddr().String()
    }
    return logger.WithField("addr", addr)
}

func WithRequest(req *http.Request) *logrus.Entry {
    return logger.WithFields(RequestFields(req))
}

Итак, я могу делать такие вещи, как:

log.WithConn(c).Info("Connected")

(Я планирую в будущем обернуть logrus.Entry в свой собственный тип, чтобы лучше связать их; в настоящее время я не могу вызвать log.WithConn(c).WithRequest(r).Error(...), потому что не могу добавить WithRequest() к logrus.Entry.)

person Rob Napier    schedule 15.05.2015
comment
Спасибо за подробное объяснение! Раньше я также использовал свои собственные оболочки журналов с другими языками, но много раз находил их ненужными и накладными. Я думаю, что это упростит замену поставщика журналов. - person Dipen Bhikadya; 15.05.2015
comment
Как новичок в Golang, я очень ценю введение, включая информацию о глобальности ведения журнала. Не знал этого. - person Jens; 07.07.2019
comment
Это своего рода некро-пост, но я только что реализовал нечто подобное, а поля file и func - это местоположения файла / функции моего переопределения, где я вызываю logger.Info() и т.д ... Это имеет смысл, поскольку фактический callite для оператора журнала теперь находится внутри мой пакет-обертку, но хотел спросить, случилось ли это с вами и нашли ли вы способ обойти это. - person Tim Coker; 28.04.2020

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

package logging

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

func NewContextLogger(c log.Fields) func(f log.Fields) *log.Entry {
    return func(f log.Fields) *log.Entry {
        for k, v := range c {
            f[k] = v
        }
        return log.WithFields(f)
    }
}

package main

import (
    "logging"
)

func main {
    app.Logger = logging.NewContextLogger(log.Fields{
        "module":    "app",
        "id":   event.Id,
    })
    app.Logger(log.Fields{
        "startTime": event.StartTime,
        "endTime":   event.EndTime,
        "title":     event.Name,
    }).Info("Starting process")
}
person hurdlea    schedule 24.10.2017