Updated GELFUDPHandler to not make a DNS query for every log message. #135
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I ran into performance issues in prod because I'm using GELFUDPHandler with a host that requires a DNS lookup (our graylog server is available at something like
monitoring.prod.example.com
). This resulted in a DNS lookup for every single log message because the CPython DatagramHandler usessocket.sendto()
like this:self.sock.sendto(s, self.address)
: https://github.com/python/cpython/blob/main/Lib/logging/handlers.py#L732The production-impacting issue we had was overwhelming our internal DNS server with too much traffic which slowed down logging and brought our web services to a crawl. Even for a healthy DNS server, the time to do a DNS lookup per log message is non-zero and worth saving, particularly for apps that do a lot of logging.
This Pull Request updates GELFUDPHandler to connect the socket to the address ahead of time using
socket.connect()
and then send the data usingsocket.sendall()
. Using wireshark, I've tested that the DNS lookup occurs duringconnect()
and notsendall()
. I've also been running this algorithm in production for months and seen the expected drop in traffic to the DNS server.To handle DNS changes, the code does make a new socket periodically and there's a
sock_max_age
parameter to control how often (I've set this to 1 hour in prod but figured 5 minutes was a more reasonable default in the library here).