Reputation: 3
I'm using a json.Decoder
to decode a net.Conn
into a custom struct. I would like to also log the original JSON string sent on the net.Conn
without modifying it.
I am looking for an efficient way to achieve this. I currently have the following code:
reader := bufio.NewReader(conn) // conn is a net.Conn
dec := json.NewDecoder(reader)
for {
// How can I also log the original data before decoding it into the struct?
var dst customStruct
if err = dec.Decode(&dst); err == io.EOF {
break
} else if err != nil {
log.Errorf("failed to decode message: %s", err)
break
}
// do something with dst...
}
Upvotes: 0
Views: 667
Reputation: 26
Use iotest.NewReadLogger to log the data as the data is read:
prefix := fmt.Sprintf("%p:", conn)
reader := bufio.NewReader(iotest.NewReadLogger(prefix, conn))
dec := json.NewDecoder(reader)
for {
var dst customStruct
if err = dec.Decode(&dst); err == io.EOF {
break
} else if err != nil {
log.Errorf("failed to decode message: %s", err)
break
}
// do something with dst...
}
If the read logger output does not match your taste, then copy the implementation and adjust as needed. The implementation is very simple.
Upvotes: 1
Reputation: 825
You can use ioutil.ReadAll()
and then print and decode from the bytes. But since you are reading all of the bytes without using a buffer, you should ideally put this behind a debug
flag check.
bs,err := ioutil.ReadAll()
if err != nil {
panic(err)
}
log.Printf("output: %s", string(bs))
var dst customStruct
if err := json.Unmarshal(bs, &dst); err != nil {
panic(err)
}
Upvotes: 0