pystatsd icon indicating copy to clipboard operation
pystatsd copied to clipboard

`socket.gaierror` is raised if the host is not known

Open southworthy opened this issue 5 years ago • 2 comments

Curious to know if this is intended behaviour or not.

Example:

>>> import statsd
>>> # use the default, "localhost"
... # there is _not_ a statsd server running on localhost:8125
... # initialises ok,
... sc = statsd.StatsClient()
>>> # this time, specify a random hostname
... # again, no statsd server running at this host
... # initialisation causes error
... sc = statsd.StatsClient(host='foobar')
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
  File "/usr/local/lib/python3.7/site-packages/statsd/client/udp.py", line 35, in __init__
    host, port, fam, socket.SOCK_DGRAM)[0]
  File "/usr/local/lib/python3.7/socket.py", line 748, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known

I'm wondering if it would be better to catch-pass this error? On the one hand, it's more in-line with the philosophy that errors with stats should not bring down the application, but on the other, I could imagine wanting to be sure that my application can log anything at all.

Perhaps a middle ground would be some kind of strict=True/False argument, which toggles between the behaviours?

southworthy avatar Nov 14 '19 19:11 southworthy

Wow this is some... old code. This was originally added in a completely different place in #6, and has moved along for the last 8 years.

I'd go so far as to say this is roughly deliberate but certainly open to re-evaluation, especially if there's a way to make it backwards compatible. It's also vaguely related to #125, since that would move the logic for when DNS resolution happens.

I don't have a super strong opinion here, other than "we don't want to do DNS lookups on every metric".

jsocol avatar Nov 14 '19 20:11 jsocol

Ok; I had a few ideas for how this could be done, hopefully at some point I'll be able to open a PR. I'll note down a few ideas here in case anyone else wants to try:

  • add keyword arg to switch between "error if I can't resolve the host" and "fail silently if I can't resolve the host"
  • add callback to invoke if host can't be resolved
  • don't try to resolve hostname until the first time you try to send a stat (and then have normal behaviour of catch-pass socket.error).
  • periodically re-resolve host, e.g sc = StatsClient(ttl=timedelta(minutes=5)) would automatically attempt to re-resolve the host on the next stat update after 5 minutes. (This might also help with #125)

southworthy avatar Nov 14 '19 21:11 southworthy