So verwende ich eine strukturierte Logging-Bibliothek (logrus), und ich habe ein core
-Paket als Basis für einige andere Pakete verwendet, rufen Sie dieses Paket me/core
, dann einzelne Pakete wie me/foo-service
, me/bar-service
etc., die diese Core-Bibliothek für allgemeine Abhängigkeiten/Dienstprogramme wie Setup, Konfiguration laden, und ich wollte es auch für standardisierte Dinge wie Protokollierung verwenden, so dass ich me/core
in der Lage sein soll, die Protokollierung für die anderen Pakete zu konfigurieren Logrus können Sie Dinge tun wieZentralisierte Logging-Konfiguration beim Freigeben von Bibliotheken zwischen Paketen
import(
log "github.com/Sirupsen/logrus"
)
[...]
log.SetLevel(log.DebugLevel)
log.SetFormatter(&log.TextFormatter{FullTimestamp:true})
Dann tun;
log.Debug("Moo")
log.WithFields(log.Fields{"structured":"data"}).Debug("I have structure data")
bekommen eine Ausgabe wie
> DEBU[2016-04-12T22:11:38+01:00] Moo
> DEBU[2016-04-12T22:11:38+01:00] I have structure data structured=data
Deshalb möchte ich dies mit etwas in meinem me/foo-service
Paket konfigurieren, wie
import(
"me/core/logging"
)
func main(){
logging.Setup()
}
Nur aus verschiedenen Gründen, die ich in Probleme laufen lasse. Das Hauptproblem scheint, dass sowohl me/core
zu sein, und me/foo-service
haben eine weiterverkauft Version der logrus
Bibliothek, diese log.Set*
Befehle die Variable logrus.std
Logger ändern, die den Standard, global Logger hält, aber dies ist eine separate Instanz für beide Pakete, weil me/core/vendor/.../logrus/std
und me/foo-service/vendor/.../logrus/std
sind verschiedene Objekte.
Der erste, was ich versuchte, wurde eine Variable in me/core/logging
schaffen, die ich in den Eltern, so etwas wie
package logging
import(
log "github.com/Sirupsen/logrus"
)
var Log *log.Logger
func Setup(verbose bool){
Log = log.New()
if verbose{
Log.Level = log.DebugLevel
} else {
Log.Level = log.InfoLevel
}
Log.Formatter = &log.TextFormatter{FullTimestamp:true}
Log.Debug("Logging verbosely")
}
und das funktioniert für einfache Fälle wie dies
package main
import(
"me/core/logging"
)
func main() {
logging.Setup(parsedOptions.Verbose)
logging.Log.Debug("Moo")
}
jedoch versuchen, nutzen könnte Verwenden Sie die strukturierten Daten Fields
verursacht Probleme, kann ich nicht die lokalen vectored logrus
Felder wie
wie ich
cannot use "me/foo-service/vendor/github.com/Sirupsen/logrus".Fields literal (type "me/foo-service/vendor/github.com/Sirupsen/logrus".Fields) as type "me/core/vendor/github.com/Sirupsen/logrus".Fields in argument to logging.Log.WithFields
Und versuchen, das Feld in me/core/logging
mit etwas zu spiegeln wie
type Fields log.Fields
Hat Äther nicht funktionieren, weil es ist immer noch eine andere Art
cannot use logging.Fields literal (type logging.Fields) as type "me/core/vendor/github.com/Sirupsen/logrus".Fields in argument to logging.Log.WithFields
Ich kann mir auch keine Möglichkeit vorstellen, meinen lokalen log.std
von me/foo-service
an 0 zu übergebenwie es ist auch eine andere Art aufgrund der Vendored-Paket.
Meine Arbeit um für den Moment beinhaltet einen Spiegel jedes Verfahren zu schaffen, so in me/core/logging
Ich habe ein wie
package logging
import(
log "github.com/Sirupsen/logrus"
)
var Log *log.Logger
type Fields map[string]interface{}
func Setup(verbose bool){
Log = log.New()
if verbose{
Log.Level = log.DebugLevel
} else {
Log.Level = log.InfoLevel
}
Log.Formatter = &log.TextFormatter{FullTimestamp:true}
Log.Debug("Logging verbosely")
}
func Debug(msg interface{}){
Log.Debug(msg)
}
func WithFields(fields Fields) *log.Entry{
lf := log.Fields{}
for k,v := range fields{
lf[k] = v
}
return Log.WithFields(lf)
}
einrichten Aber das bedeuten würde einen Spiegel für jedes Verfahren zu schaffen, die wirklich ineffizient scheint .
Also ich möchte einen Vorschlag dafür, wie ich me/core/vendor/.../logrus/std
verfügbar machen kann me/foo-service
, oder wenn ich darüber völlig falsch denke, eine bessere Möglichkeit, es zu tun.
nenne ich denke, es ist im allgemeinen unerwünscht ist eine Bibliothek Anbieter haben es eigene deps ist, und zwar aus Gründen der Versionsinkompatibilität und der Duplizierung. Die App (Hauptpaket) sollte die Erwartungen der Verkäufer erfüllen und Konflikte lösen. –