Skip to content

Commit 44ba7a6

Browse files
committed
add discard_logs_on_reconnect_error in asyncsender
Signed-off-by: enjoy-binbin <[email protected]>
1 parent ace80f4 commit 44ba7a6

File tree

3 files changed

+48
-7
lines changed

3 files changed

+48
-7
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@
1010
/build
1111
/dist
1212
.idea/
13+
venv/
14+
env/

fluent/asyncsender.py

+26-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3+
import socket
34
import threading
45
from queue import Queue, Full, Empty
56

@@ -50,9 +51,11 @@ def __init__(self,
5051
queue_maxsize=DEFAULT_QUEUE_MAXSIZE,
5152
queue_circular=DEFAULT_QUEUE_CIRCULAR,
5253
queue_overflow_handler=None,
54+
discard_logs_on_reconnect_error=False,
5355
**kwargs):
5456
"""
5557
:param kwargs: This kwargs argument is not used in __init__. This will be removed in the next major version.
58+
:discard_logs_on_reconnect_error: When set to true, will discard logs when reconnect error is reported.
5659
"""
5760
super(FluentSender, self).__init__(tag=tag, host=host, port=port, bufmax=bufmax, timeout=timeout,
5861
verbose=verbose, buffer_overflow_handler=buffer_overflow_handler,
@@ -66,6 +69,8 @@ def __init__(self,
6669
else:
6770
self._queue_overflow_handler = self._queue_overflow_handler_default
6871

72+
self._discard_logs_on_reconnect_error = discard_logs_on_reconnect_error
73+
6974
self._thread_guard = threading.Event() # This ensures visibility across all variables
7075
self._closed = False
7176

@@ -81,11 +86,7 @@ def close(self, flush=True):
8186
return
8287
self._closed = True
8388
if not flush:
84-
while True:
85-
try:
86-
self._queue.get(block=False)
87-
except Empty:
88-
break
89+
self._clear_queue()
8990
self._queue.put(_TOMBSTONE)
9091
self._send_thread.join()
9192

@@ -101,6 +102,13 @@ def queue_blocking(self):
101102
def queue_circular(self):
102103
return self._queue_circular
103104

105+
def _clear_queue(self):
106+
while True:
107+
try:
108+
self._queue.get(block=False)
109+
except Empty:
110+
break
111+
104112
def _send(self, bytes_):
105113
with self.lock:
106114
if self._closed:
@@ -120,8 +128,20 @@ def _send(self, bytes_):
120128

121129
return True
122130

131+
def _send_internal(self, bytes_):
132+
send_internal_result = super(FluentSender, self)._send_internal(bytes_)
133+
if send_internal_result is False:
134+
# when send_result is False, super() caught socket.error
135+
# and assigned the error to self.last_error
136+
if self._discard_logs_on_reconnect_error is True and isinstance(self.last_error, socket.gaierror):
137+
# clear the queue to avoid blocking and print the log
138+
self._clear_queue()
139+
print("%s. Please check address: (%s, %s)" % (str(self.last_error), self.host, self.port))
140+
141+
return send_internal_result
142+
123143
def _send_loop(self):
124-
send_internal = super(FluentSender, self)._send_internal
144+
send_internal = self._send_internal
125145

126146
try:
127147
while True:

tests/test_asyncsender.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,6 @@ def test_simple(self):
330330

331331

332332
class TestSenderUnlimitedSize(unittest.TestCase):
333-
Q_SIZE = 3
334333

335334
def setUp(self):
336335
super(TestSenderUnlimitedSize, self).setUp()
@@ -374,3 +373,23 @@ def test_simple(self):
374373
eq(3, len(el))
375374
eq("test.foo{}".format(NUM), el[0])
376375
eq({'bar': "baz{}".format(NUM)}, el[2])
376+
377+
378+
class TestSenderSocketGaierror(unittest.TestCase):
379+
def setUp(self):
380+
super(TestSenderSocketGaierror, self).setUp()
381+
self._sender = fluent.asyncsender.FluentSender(host="localhost_error",
382+
tag="test",
383+
discard_logs_on_reconnect_error=True)
384+
385+
def tearDown(self):
386+
self._sender.close()
387+
388+
def test_simple(self):
389+
with self._sender as sender:
390+
for _ in range(100):
391+
sender._queue.put(b"1")
392+
393+
sender._queue.put(fluent.asyncsender._TOMBSTONE)
394+
395+
self.assertEqual(self._sender._queue.qsize(), 0)

0 commit comments

Comments
 (0)