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