Consider restructuring how logging is done in the worker
bmenrigh opened this issue · comments
Right now the way a connection is handled by a worker is a header struct is filled out with information about the request. Assuming the request goes well, that header struct is then encoded into a LoggedRequest object and returned with a nil error:
validConnLogging := LoggedRequest{Timestamp: time.Now().UTC().String(), Header: req_header, SourceIP: sourceIP, SourcePort: sourcePort, Destination: allHeaders["host"], EncodedConn: raw}
return validConnLogging, nil
If something goes wrong, we instead fill out an empty LoggedRequest and sends the error:
return LoggedRequest{}, err
The trouble with this is that in (almost?) all cases we want to log at least some basic information about the client that caused the error. I think we should change the Header struct to a information log struct where we store all the information we can log about a client. As soon as we get any bytes from the client we can put them in the raw_data field in the information struct. The same goes for when we learn the client IP and port. Then either on success or error we encode what we've recorded in the information struct into a LoggedRequest.
We could create a function that takes an information log struct and reads all the non-nil fields and fills out and returns a LoggedRequest struct. Then returning on error would look more like:
return BuildLogRequest(client_info), err
And success would look pretty much the same:
return BuildLogRequest(client_info), nil
This also gives us the opportunity to set the error message in the JSON we log. A log could look like:
{"error":"true", "error_message":"Request header failed regex validation", "src_ip":"1.2.3.4", "src_port":"5678", "raw_data":"476554202f746869735f4745545f7761735f47655420485454502f312e300d0a0d0a"}
I restructured logging in commit 07d6254 which fixes this issue.