Ich möchte eine Situation erstellen, in der alles auf einen bestimmten log.Logger wird auch an eine bestimmte Variable Array von Strings angehängt.io.MultiWriter vs. Golangs Pass-by-Wert
Der Typ der Variablen implementiert die io.Writer-Schnittstelle, daher sollte es einfach sein, diese über io.MultiWriter zu log.New() hinzuzufügen, aber ich habe anscheinend ein unlösbares Problem: Die io.Writer-Schnittstelle ist behoben und es ist unmöglich für die Variable, sich auf den gegebenen Wert von Golan zu beziehen.
Vielleicht wird es mehr Sinn, mit einem Beispiel machen:
package main
import "fmt"
import "io"
import "log"
import "os"
import "strings"
var Log *log.Logger
type Job_Result struct {
Job_ID int64
// other stuff
Log_Lines []string
}
// satisfies io.Writer interface
func (jr Job_Result) Write (p []byte) (n int, err error) {
s := strings.TrimRight(string(p),"\n ")
jr.Log_Lines= append(jr.Log_Lines,s)
return len(s), nil
}
func (jr Job_Result) Dump() {
fmt.Println("\nHere is a dump of the job result log lines:")
for n, s := range jr.Log_Lines{
fmt.Printf("\tline %d: %s\n",n,s)
}
}
func main() {
// make a Job_Result
var jr Job_Result
jr.Job_ID = 123
jr.Log_Lines = make([]string,0)
// create an io.MultiWriter that points to both stdout
// and that Job_Result var
var writers io.Writer
writers = io.MultiWriter(os.Stdout,jr)
Log = log.New(writers,
"",
log.Ldate|log.Ltime|log.Lshortfile)
// send some stuff to the log
Log.Println("program starting")
Log.Println("something happened")
Log.Printf("last thing that happened, should be %drd line\n",3)
jr.Dump()
}
Dies ist die Ausgabe, was nicht verwunderlich ist:
2016/07/28 07:20:07 testjob.go:43: program starting
2016/07/28 07:20:07 testjob.go:44: something happened
2016/07/28 07:20:07 testjob.go:45: last thing that happened, should be 3rd line
Here is a dump of the job result log lines:
Ich verstehe das Problem - Write() wird immer eine Kopie der Job_Result-Variable, so dass es pflichtgemäß angehängt wird und dann verschwindet die Kopie, da sie lokal ist. Ich sollte ihm einen Zeiger auf den Job_Result übergeben ... aber ich bin nicht der, der Write() aufruft, es wird vom Logger gemacht, und ich kann das nicht ändern.
Ich dachte, dies wäre eine einfache Lösung für die Erfassung von Protokollausgaben in ein Array (und es gibt andere Subscribe/Unsubscribe Zeug, die ich nicht angezeigt habe), aber es kommt alles auf diese problematische io.Write() Schnittstelle.
Pilotfehler? Schlechtes Design? Etwas, das ich nicht groke? Danke für jeden Hinweis.
Einfach und elegant. Ich habe mich zu sehr darauf konzentriert, dafür zu sorgen, dass die Write() -Signatur übereinstimmt, dass ich den Rest vergessen habe. Vielen Dank! – raindog308