TransWikia.com

json.Decoding a TCP connection and logging the original data at the same time in Go

Stack Overflow Asked by mNv3akNdILYwEipFg0OcVwIuoB on December 27, 2021

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...

}
    

2 Answers

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.

Answered by Flimcy on December 27, 2021

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)
}

Answered by poWar on December 27, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP