logtail-python 0.2.10__py2.py3-none-any.whl → 0.3.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- logtail/__init__.py +1 -1
- logtail/flusher.py +15 -4
- logtail/frame.py +8 -2
- logtail/handler.py +9 -1
- {logtail_python-0.2.10.dist-info → logtail_python-0.3.1.dist-info}/METADATA +6 -8
- logtail_python-0.3.1.dist-info/RECORD +13 -0
- {logtail_python-0.2.10.dist-info → logtail_python-0.3.1.dist-info}/WHEEL +1 -1
- logtail_python-0.2.10.dist-info/RECORD +0 -13
- {logtail_python-0.2.10.dist-info → logtail_python-0.3.1.dist-info}/LICENSE.md +0 -0
- {logtail_python-0.2.10.dist-info → logtail_python-0.3.1.dist-info}/top_level.txt +0 -0
logtail/__init__.py
CHANGED
logtail/flusher.py
CHANGED
|
@@ -10,14 +10,17 @@ RETRY_SCHEDULE = (1, 10, 60) # seconds
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class FlushWorker(threading.Thread):
|
|
13
|
-
def __init__(self, upload, pipe, buffer_capacity, flush_interval):
|
|
13
|
+
def __init__(self, upload, pipe, buffer_capacity, flush_interval, check_interval):
|
|
14
14
|
threading.Thread.__init__(self)
|
|
15
15
|
self.parent_thread = threading.current_thread()
|
|
16
16
|
self.upload = upload
|
|
17
17
|
self.pipe = pipe
|
|
18
18
|
self.buffer_capacity = buffer_capacity
|
|
19
19
|
self.flush_interval = flush_interval
|
|
20
|
+
self.check_interval = check_interval
|
|
20
21
|
self.should_run = True
|
|
22
|
+
self._flushing = False
|
|
23
|
+
self._clean = True
|
|
21
24
|
|
|
22
25
|
def run(self):
|
|
23
26
|
while self.should_run:
|
|
@@ -27,6 +30,7 @@ class FlushWorker(threading.Thread):
|
|
|
27
30
|
last_flush = time.time()
|
|
28
31
|
time_remaining = _initial_time_remaining(self.flush_interval)
|
|
29
32
|
frame = []
|
|
33
|
+
self._clean = True
|
|
30
34
|
|
|
31
35
|
# If the parent thread has exited but there are still outstanding
|
|
32
36
|
# events, attempt to send them before exiting.
|
|
@@ -38,16 +42,17 @@ class FlushWorker(threading.Thread):
|
|
|
38
42
|
# `flush_interval` seconds have passed without sending any events.
|
|
39
43
|
while len(frame) < self.buffer_capacity and time_remaining > 0:
|
|
40
44
|
try:
|
|
41
|
-
# Blocks for up to
|
|
45
|
+
# Blocks for up to `check_interval` seconds for each item to prevent
|
|
42
46
|
# spinning and burning CPU unnecessarily. Could block for the
|
|
43
47
|
# entire amount of `time_remaining` but then in the case that
|
|
44
48
|
# the parent thread has exited, that entire amount of time
|
|
45
49
|
# would be waited before this child worker thread exits.
|
|
46
|
-
entry = self.pipe.get(block=(not shutdown), timeout=
|
|
50
|
+
entry = self.pipe.get(block=(not shutdown), timeout=self.check_interval)
|
|
51
|
+
self._clean = False
|
|
47
52
|
frame.append(entry)
|
|
48
53
|
self.pipe.task_done()
|
|
49
54
|
except queue.Empty:
|
|
50
|
-
if shutdown:
|
|
55
|
+
if shutdown or self._flushing:
|
|
51
56
|
break
|
|
52
57
|
shutdown = not self.parent_thread.is_alive()
|
|
53
58
|
time_remaining = _calculate_time_remaining(last_flush, self.flush_interval)
|
|
@@ -68,9 +73,15 @@ class FlushWorker(threading.Thread):
|
|
|
68
73
|
if response.status_code == 500 and getattr(response, "exception") != None:
|
|
69
74
|
print('Failed to send logs to Better Stack after {} retries: {}'.format(len(RETRY_SCHEDULE), response.exception))
|
|
70
75
|
|
|
76
|
+
self._clean = True
|
|
71
77
|
if shutdown and self.pipe.empty():
|
|
72
78
|
self.should_run = False
|
|
73
79
|
|
|
80
|
+
def flush(self):
|
|
81
|
+
self._flushing = True
|
|
82
|
+
while not self._clean or not self.pipe.empty():
|
|
83
|
+
time.sleep(self.check_interval)
|
|
84
|
+
self._flushing = False
|
|
74
85
|
|
|
75
86
|
def _initial_time_remaining(flush_interval):
|
|
76
87
|
return flush_interval
|
logtail/frame.py
CHANGED
|
@@ -60,6 +60,9 @@ def _parse_custom_events(record, include_extra_attributes):
|
|
|
60
60
|
def _remove_circular_dependencies(obj, memo=None):
|
|
61
61
|
if memo is None:
|
|
62
62
|
memo = set()
|
|
63
|
+
# Skip immutable types, which can't contain circular dependencies
|
|
64
|
+
if isinstance(obj, (str, int, float, bool)):
|
|
65
|
+
return obj
|
|
63
66
|
if id(obj) in memo:
|
|
64
67
|
return "<omitted circular reference>"
|
|
65
68
|
memo.add(id(obj))
|
|
@@ -69,8 +72,11 @@ def _remove_circular_dependencies(obj, memo=None):
|
|
|
69
72
|
new_dict[key] = _remove_circular_dependencies(value, memo)
|
|
70
73
|
return new_dict
|
|
71
74
|
elif isinstance(obj, list):
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
return [_remove_circular_dependencies(item, memo) for item in obj]
|
|
76
|
+
elif isinstance(obj, tuple):
|
|
77
|
+
return tuple(_remove_circular_dependencies(item, memo) for item in obj)
|
|
78
|
+
elif isinstance(obj, set):
|
|
79
|
+
return {_remove_circular_dependencies(item, memo) for item in obj}
|
|
74
80
|
else:
|
|
75
81
|
return obj
|
|
76
82
|
|
logtail/handler.py
CHANGED
|
@@ -12,6 +12,7 @@ from .frame import create_frame
|
|
|
12
12
|
DEFAULT_HOST = 'https://in.logs.betterstack.com'
|
|
13
13
|
DEFAULT_BUFFER_CAPACITY = 1000
|
|
14
14
|
DEFAULT_FLUSH_INTERVAL = 1
|
|
15
|
+
DEFAULT_CHECK_INTERVAL = 0.1
|
|
15
16
|
DEFAULT_RAISE_EXCEPTIONS = False
|
|
16
17
|
DEFAULT_DROP_EXTRA_EVENTS = True
|
|
17
18
|
DEFAULT_INCLUDE_EXTRA_ATTRIBUTES = True
|
|
@@ -23,6 +24,7 @@ class LogtailHandler(logging.Handler):
|
|
|
23
24
|
host=DEFAULT_HOST,
|
|
24
25
|
buffer_capacity=DEFAULT_BUFFER_CAPACITY,
|
|
25
26
|
flush_interval=DEFAULT_FLUSH_INTERVAL,
|
|
27
|
+
check_interval=DEFAULT_CHECK_INTERVAL,
|
|
26
28
|
raise_exceptions=DEFAULT_RAISE_EXCEPTIONS,
|
|
27
29
|
drop_extra_events=DEFAULT_DROP_EXTRA_EVENTS,
|
|
28
30
|
include_extra_attributes=DEFAULT_INCLUDE_EXTRA_ATTRIBUTES,
|
|
@@ -38,6 +40,7 @@ class LogtailHandler(logging.Handler):
|
|
|
38
40
|
self.include_extra_attributes = include_extra_attributes
|
|
39
41
|
self.buffer_capacity = buffer_capacity
|
|
40
42
|
self.flush_interval = flush_interval
|
|
43
|
+
self.check_interval = check_interval
|
|
41
44
|
self.raise_exceptions = raise_exceptions
|
|
42
45
|
self.dropcount = 0
|
|
43
46
|
# Do not initialize the flush thread yet because it causes issues on Render.
|
|
@@ -51,7 +54,8 @@ class LogtailHandler(logging.Handler):
|
|
|
51
54
|
self.uploader,
|
|
52
55
|
self.pipe,
|
|
53
56
|
self.buffer_capacity,
|
|
54
|
-
self.flush_interval
|
|
57
|
+
self.flush_interval,
|
|
58
|
+
self.check_interval,
|
|
55
59
|
)
|
|
56
60
|
self.flush_thread.start()
|
|
57
61
|
|
|
@@ -71,3 +75,7 @@ class LogtailHandler(logging.Handler):
|
|
|
71
75
|
except Exception as e:
|
|
72
76
|
if self.raise_exceptions:
|
|
73
77
|
raise e
|
|
78
|
+
|
|
79
|
+
def flush(self):
|
|
80
|
+
if self.flush_thread and self.flush_thread.is_alive():
|
|
81
|
+
self.flush_thread.flush()
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: logtail-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Logtail.com client library
|
|
5
5
|
Home-page: https://github.com/logtail/logtail-python
|
|
6
|
-
Download-URL: https://github.com/logtail/logtail-python/tarball/0.
|
|
6
|
+
Download-URL: https://github.com/logtail/logtail-python/tarball/0.3.1
|
|
7
7
|
Author: Logtail
|
|
8
8
|
Author-email: hello@logtail.com
|
|
9
9
|
License: ISC
|
|
@@ -11,20 +11,18 @@ Keywords: api,logtail,logging,client
|
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: License :: OSI Approved :: ISC License (ISCL)
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
|
-
Classifier: Programming Language :: Python :: 2
|
|
15
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
16
14
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
19
15
|
Classifier: Programming Language :: Python :: 3.7
|
|
20
16
|
Classifier: Programming Language :: Python :: 3.8
|
|
21
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
20
|
Classifier: Programming Language :: Python
|
|
23
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
22
|
Description-Content-Type: text/markdown
|
|
25
23
|
License-File: LICENSE.md
|
|
26
|
-
Requires-Dist: requests
|
|
27
|
-
Requires-Dist: msgpack
|
|
24
|
+
Requires-Dist: requests>=2.18.4
|
|
25
|
+
Requires-Dist: msgpack>=0.5.6
|
|
28
26
|
|
|
29
27
|
# [Better Stack](https://betterstack.com/logs) Python client
|
|
30
28
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
logtail/__init__.py,sha256=JRaSbr790ELJ9xcEfnnL5H2aVbNDlY2Llbq9dd2nM5w,252
|
|
2
|
+
logtail/compat.py,sha256=KbZmcmDpj_vbMotp16pADPwJ1FkEHGDNjKbOfCy-c10,141
|
|
3
|
+
logtail/flusher.py,sha256=5P9MY6wn8H2rF72DEEtN6X5NTpxCZXFvmMzoUj3QcsE,3749
|
|
4
|
+
logtail/formatter.py,sha256=nk4W1G95P19ijylPBJ8D9FlO_qbh3tfbv7xzCSfpDN8,968
|
|
5
|
+
logtail/frame.py,sha256=JtLvvSdQ5uSj5sYvC0-UDQfGASjqWtOxkmGkmMo97oA,3216
|
|
6
|
+
logtail/handler.py,sha256=5Z9wJQMc0nv72_wwNw_WGXKSCAwgb-z--5OS3c6I5i0,2994
|
|
7
|
+
logtail/helpers.py,sha256=ezDTLsTBAtCtIh_XptSYOiBrZFa-E9wo2SWTnjKgOOU,1156
|
|
8
|
+
logtail/uploader.py,sha256=qBhQjXKMKId4dHC1BRSgajQ6Zh-jOygQEnc5oj2zuN0,805
|
|
9
|
+
logtail_python-0.3.1.dist-info/LICENSE.md,sha256=aCBMqxfm7QNyFR9JiJ2GSMvhAURXN2E0yTcYNQloqI0,737
|
|
10
|
+
logtail_python-0.3.1.dist-info/METADATA,sha256=ALN6wj0EnzjeLsivrRODJHgZAOBtPeM63qTh2Ds-Rus,2125
|
|
11
|
+
logtail_python-0.3.1.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
|
|
12
|
+
logtail_python-0.3.1.dist-info/top_level.txt,sha256=QZIbQogN1yFBgjiJ-8NlYArVCL00gBoYbEUT_Ew8l-Q,8
|
|
13
|
+
logtail_python-0.3.1.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
logtail/__init__.py,sha256=JuOEcyNujGsnl6bXpXeFrTL6exQyA6zHw1C0TdS9rj4,253
|
|
2
|
-
logtail/compat.py,sha256=KbZmcmDpj_vbMotp16pADPwJ1FkEHGDNjKbOfCy-c10,141
|
|
3
|
-
logtail/flusher.py,sha256=kyV8ikYRaOBHQvp9aA8aDTFOeKFaHxbrWG1YplKbOkU,3311
|
|
4
|
-
logtail/formatter.py,sha256=nk4W1G95P19ijylPBJ8D9FlO_qbh3tfbv7xzCSfpDN8,968
|
|
5
|
-
logtail/frame.py,sha256=21q6jxu-1qrzs6v-fqnP7PFG6a80ZDFlPYEK5PYPYO8,2887
|
|
6
|
-
logtail/handler.py,sha256=IELZWp_GCeylyd2TXFjGX_z69IEMuvlsg56IbCJJYJ4,2706
|
|
7
|
-
logtail/helpers.py,sha256=ezDTLsTBAtCtIh_XptSYOiBrZFa-E9wo2SWTnjKgOOU,1156
|
|
8
|
-
logtail/uploader.py,sha256=qBhQjXKMKId4dHC1BRSgajQ6Zh-jOygQEnc5oj2zuN0,805
|
|
9
|
-
logtail_python-0.2.10.dist-info/LICENSE.md,sha256=aCBMqxfm7QNyFR9JiJ2GSMvhAURXN2E0yTcYNQloqI0,737
|
|
10
|
-
logtail_python-0.2.10.dist-info/METADATA,sha256=bDGWi7HeAXk82pZReTpfjvonjjGQqN773F4ccIsLnVo,2225
|
|
11
|
-
logtail_python-0.2.10.dist-info/WHEEL,sha256=-G_t0oGuE7UD0DrSpVZnq1hHMBV9DD2XkS5v7XpmTnk,110
|
|
12
|
-
logtail_python-0.2.10.dist-info/top_level.txt,sha256=QZIbQogN1yFBgjiJ-8NlYArVCL00gBoYbEUT_Ew8l-Q,8
|
|
13
|
-
logtail_python-0.2.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|