Динамическое изменение уровня zap-журнала для некоторого кода - PullRequest
0 голосов
/ 08 марта 2020

Я привык работать с java и log4j, в которых я мог динамически изменять уровень журнала для одного класса без каких-либо дополнительных (кодирующих) усилий.

Теперь, когда я работаю с golang ( zap для ведения журнала) - я ищу ту же функциональность, но не могу ее найти.

Существует ли простой способ динамического изменения уровня журнала для файла, пакета или части кода?

1 Ответ

2 голосов
/ 08 марта 2020

zap поддерживает log.Logger перенос через конструкторы, такие как NewStdLog , поэтому, если вы хотите продолжать использовать zap, будет работать следующий метод:


Если вы не хотите использовать сторонние регистраторы, следующий метод довольно прост, используя стандартную библиотеку go log.Logger:

Определите некоторые регистраторы приложений по умолчанию:

var (
    pkgname = "mypkgname"
    Info  = log.New(os.Stdout, "[INFO:"+pkgname+"] ", log.LstdFlags)
    Debug = log.New(ioutil.Discard, "[DBUG:"+pkgname+"] ", log.LstdFlags|log.Lshortfile)
    Trace = log.New(ioutil.Discard, "[TRCE:"+pkgname+"] ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile)
)

поэтому по умолчанию Info запишет в Stdout - но Debug & Trace будет go по умолчанию выключен.

Тогда можно, безопасно (т. е. безопасное для goroutine) включение / выключение этих log.Loggers во время запуска:

func init() {
    if v, ok := os.LookupEnv("DEBUG"); ok && v != "" {
        Info.Println("ENV VAR 'DEBUG' set: enabling debug-level logging")
        Debug.SetOutput(os.Stderr)
    }
}

или во время выполнения:

func httpServiceHandler(r *req) {
    if r.TraceingOn {
        Trace.SetOutput(os.Stderr)
    } else {
        Trace.SetOutput(ioutil.Discard)
    }
}

Регистрация на уровне pkg аналогичен любому другому log методу:

Debug.Printf("http request: %+v", r)

И если есть дорогостоящее событие журнала, которое вы не хотите генерировать - например, для регистратора установлено значение discard - вы можете безопасно проверить состояние логгера примерно так:

if Trace.Writer() != ioutil.Discard {
    // do expensive logging here

    // e.g. bs, _ = ioutil.ReadAll(resp.Body);  Trace.Println("RESP: RAW-http response:", string(bs))
}
...