logtail-python 0.3.4__tar.gz → 0.4.0__tar.gz
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_python-0.3.4/logtail_python.egg-info → logtail_python-0.4.0}/PKG-INFO +8 -6
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail/__init__.py +1 -1
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail/flusher.py +13 -3
- {logtail_python-0.3.4 → logtail_python-0.4.0/logtail_python.egg-info}/PKG-INFO +8 -6
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail_python.egg-info/SOURCES.txt +9 -1
- {logtail_python-0.3.4 → logtail_python-0.4.0}/setup.py +6 -5
- logtail_python-0.4.0/tests/__pycache__/__init__.cpython-314.pyc +0 -0
- logtail_python-0.4.0/tests/__pycache__/test_flusher.cpython-314-pytest-9.1.1.pyc +0 -0
- logtail_python-0.4.0/tests/__pycache__/test_flusher.cpython-314.pyc +0 -0
- logtail_python-0.4.0/tests/__pycache__/test_formatter.cpython-314-pytest-9.1.1.pyc +0 -0
- logtail_python-0.4.0/tests/__pycache__/test_frame.cpython-314-pytest-9.1.1.pyc +0 -0
- logtail_python-0.4.0/tests/__pycache__/test_handler.cpython-314-pytest-9.1.1.pyc +0 -0
- logtail_python-0.4.0/tests/__pycache__/test_helpers.cpython-314-pytest-9.1.1.pyc +0 -0
- logtail_python-0.4.0/tests/__pycache__/test_uploader.cpython-314-pytest-9.1.1.pyc +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/test_flusher.py +33 -3
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/test_frame.py +1 -5
- {logtail_python-0.3.4 → logtail_python-0.4.0}/LICENSE.md +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/MANIFEST.in +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/README.md +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail/compat.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail/formatter.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail/frame.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail/handler.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail/helpers.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail/uploader.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail_python.egg-info/dependency_links.txt +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail_python.egg-info/requires.txt +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/logtail_python.egg-info/top_level.txt +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/requirements.txt +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/setup.cfg +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/test-requirements.txt +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__init__.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/__init__.cpython-311.pyc +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_flusher.cpython-311.pyc +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_formatter.cpython-311.pyc +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_frame.cpython-311.pyc +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_handler.cpython-311.pyc +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_helpers.cpython-311.pyc +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_uploader.cpython-311.pyc +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/test_formatter.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/test_handler.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/test_helpers.py +0 -0
- {logtail_python-0.3.4 → logtail_python-0.4.0}/tests/test_uploader.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: logtail-python
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Better Stack 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.4.0
|
|
7
7
|
Author: Logtail
|
|
8
8
|
Author-email: hello@logtail.com
|
|
9
9
|
License: ISC
|
|
@@ -12,13 +12,14 @@ Classifier: Intended Audience :: Developers
|
|
|
12
12
|
Classifier: License :: OSI Approved :: ISC License (ISCL)
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
20
|
Classifier: Programming Language :: Python
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.10
|
|
22
23
|
Description-Content-Type: text/markdown
|
|
23
24
|
License-File: LICENSE.md
|
|
24
25
|
Requires-Dist: requests>=2.18.4
|
|
@@ -34,6 +35,7 @@ Dynamic: keywords
|
|
|
34
35
|
Dynamic: license
|
|
35
36
|
Dynamic: license-file
|
|
36
37
|
Dynamic: requires-dist
|
|
38
|
+
Dynamic: requires-python
|
|
37
39
|
Dynamic: summary
|
|
38
40
|
|
|
39
41
|
# [Better Stack](https://betterstack.com/logs) Python client
|
|
@@ -26,6 +26,16 @@ class FlushWorker(threading.Thread):
|
|
|
26
26
|
while self.should_run:
|
|
27
27
|
self.step()
|
|
28
28
|
|
|
29
|
+
def _is_parent_alive(self):
|
|
30
|
+
try:
|
|
31
|
+
return self.parent_thread.is_alive()
|
|
32
|
+
except RuntimeError:
|
|
33
|
+
# Starting with Python 3.14, calling is_alive() on an
|
|
34
|
+
# already-terminated thread raises a RuntimeError instead of
|
|
35
|
+
# returning False (see the parent thread being torn down during
|
|
36
|
+
# interpreter shutdown). Treat that as "no longer alive".
|
|
37
|
+
return False
|
|
38
|
+
|
|
29
39
|
def step(self):
|
|
30
40
|
last_flush = time.time()
|
|
31
41
|
time_remaining = _initial_time_remaining(self.flush_interval)
|
|
@@ -34,7 +44,7 @@ class FlushWorker(threading.Thread):
|
|
|
34
44
|
|
|
35
45
|
# If the parent thread has exited but there are still outstanding
|
|
36
46
|
# events, attempt to send them before exiting.
|
|
37
|
-
shutdown = not self.
|
|
47
|
+
shutdown = not self._is_parent_alive()
|
|
38
48
|
|
|
39
49
|
# Fill phase: take events out of the queue and group them for sending.
|
|
40
50
|
# Takes up to `buffer_capacity` events out of the queue and groups them
|
|
@@ -54,11 +64,11 @@ class FlushWorker(threading.Thread):
|
|
|
54
64
|
except queue.Empty:
|
|
55
65
|
if shutdown or self._flushing:
|
|
56
66
|
break
|
|
57
|
-
shutdown = not self.
|
|
67
|
+
shutdown = not self._is_parent_alive()
|
|
58
68
|
time_remaining = _calculate_time_remaining(last_flush, self.flush_interval)
|
|
59
69
|
|
|
60
70
|
# Send phase: takes the outstanding events (up to `buffer_capacity`
|
|
61
|
-
# count) and sends them to the
|
|
71
|
+
# count) and sends them to the Better Stack endpoint all at once. If the
|
|
62
72
|
# request fails in a way that can be retried, it is retried with an
|
|
63
73
|
# exponential backoff in between attempts.
|
|
64
74
|
if frame:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: logtail-python
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Better Stack 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.4.0
|
|
7
7
|
Author: Logtail
|
|
8
8
|
Author-email: hello@logtail.com
|
|
9
9
|
License: ISC
|
|
@@ -12,13 +12,14 @@ Classifier: Intended Audience :: Developers
|
|
|
12
12
|
Classifier: License :: OSI Approved :: ISC License (ISCL)
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
20
|
Classifier: Programming Language :: Python
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.10
|
|
22
23
|
Description-Content-Type: text/markdown
|
|
23
24
|
License-File: LICENSE.md
|
|
24
25
|
Requires-Dist: requests>=2.18.4
|
|
@@ -34,6 +35,7 @@ Dynamic: keywords
|
|
|
34
35
|
Dynamic: license
|
|
35
36
|
Dynamic: license-file
|
|
36
37
|
Dynamic: requires-dist
|
|
38
|
+
Dynamic: requires-python
|
|
37
39
|
Dynamic: summary
|
|
38
40
|
|
|
39
41
|
# [Better Stack](https://betterstack.com/logs) Python client
|
|
@@ -26,9 +26,17 @@ tests/test_handler.py
|
|
|
26
26
|
tests/test_helpers.py
|
|
27
27
|
tests/test_uploader.py
|
|
28
28
|
tests/__pycache__/__init__.cpython-311.pyc
|
|
29
|
+
tests/__pycache__/__init__.cpython-314.pyc
|
|
29
30
|
tests/__pycache__/test_flusher.cpython-311.pyc
|
|
31
|
+
tests/__pycache__/test_flusher.cpython-314-pytest-9.1.1.pyc
|
|
32
|
+
tests/__pycache__/test_flusher.cpython-314.pyc
|
|
30
33
|
tests/__pycache__/test_formatter.cpython-311.pyc
|
|
34
|
+
tests/__pycache__/test_formatter.cpython-314-pytest-9.1.1.pyc
|
|
31
35
|
tests/__pycache__/test_frame.cpython-311.pyc
|
|
36
|
+
tests/__pycache__/test_frame.cpython-314-pytest-9.1.1.pyc
|
|
32
37
|
tests/__pycache__/test_handler.cpython-311.pyc
|
|
38
|
+
tests/__pycache__/test_handler.cpython-314-pytest-9.1.1.pyc
|
|
33
39
|
tests/__pycache__/test_helpers.cpython-311.pyc
|
|
34
|
-
tests/__pycache__/
|
|
40
|
+
tests/__pycache__/test_helpers.cpython-314-pytest-9.1.1.pyc
|
|
41
|
+
tests/__pycache__/test_uploader.cpython-311.pyc
|
|
42
|
+
tests/__pycache__/test_uploader.cpython-314-pytest-9.1.1.pyc
|
|
@@ -3,7 +3,7 @@ import os
|
|
|
3
3
|
from setuptools import setup
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
VERSION = '0.
|
|
6
|
+
VERSION = '0.4.0'
|
|
7
7
|
ROOT_DIR = os.path.dirname(__file__)
|
|
8
8
|
|
|
9
9
|
REQUIREMENTS = [
|
|
@@ -20,13 +20,14 @@ setup(
|
|
|
20
20
|
packages=['logtail'],
|
|
21
21
|
include_package_data=True,
|
|
22
22
|
license='ISC',
|
|
23
|
-
description='
|
|
23
|
+
description='Better Stack client library',
|
|
24
24
|
long_description=long_description,
|
|
25
25
|
long_description_content_type='text/markdown',
|
|
26
26
|
url='https://github.com/logtail/logtail-python',
|
|
27
27
|
download_url='https://github.com/logtail/logtail-python/tarball/%s' % (VERSION),
|
|
28
28
|
keywords=['api', 'logtail', 'logging', 'client'],
|
|
29
29
|
install_requires=REQUIREMENTS,
|
|
30
|
+
python_requires='>=3.10',
|
|
30
31
|
author='Logtail',
|
|
31
32
|
author_email='hello@logtail.com',
|
|
32
33
|
classifiers=[
|
|
@@ -34,11 +35,11 @@ setup(
|
|
|
34
35
|
'License :: OSI Approved :: ISC License (ISCL)',
|
|
35
36
|
'Operating System :: OS Independent',
|
|
36
37
|
'Programming Language :: Python :: 3',
|
|
37
|
-
'Programming Language :: Python :: 3.7',
|
|
38
|
-
'Programming Language :: Python :: 3.8',
|
|
39
|
-
'Programming Language :: Python :: 3.9',
|
|
40
38
|
'Programming Language :: Python :: 3.10',
|
|
41
39
|
'Programming Language :: Python :: 3.11',
|
|
40
|
+
'Programming Language :: Python :: 3.12',
|
|
41
|
+
'Programming Language :: Python :: 3.13',
|
|
42
|
+
'Programming Language :: Python :: 3.14',
|
|
42
43
|
'Programming Language :: Python',
|
|
43
44
|
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
44
45
|
],
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# coding: utf-8
|
|
2
2
|
from __future__ import print_function, unicode_literals
|
|
3
3
|
import mock
|
|
4
|
-
import sys
|
|
5
4
|
import time
|
|
6
5
|
import threading
|
|
7
6
|
import unittest
|
|
@@ -146,8 +145,39 @@ class TestFlushWorker(unittest.TestCase):
|
|
|
146
145
|
self.assertEqual(self.upload_calls, 1)
|
|
147
146
|
self.assertFalse(fw.should_run)
|
|
148
147
|
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
def test_is_parent_alive_handles_runtime_error(self):
|
|
149
|
+
# Starting with Python 3.14, is_alive() raises RuntimeError when
|
|
150
|
+
# called on an already-terminated thread instead of returning False.
|
|
151
|
+
# The worker must treat that as the parent no longer being alive.
|
|
152
|
+
_, _, fw = self._setup_worker()
|
|
153
|
+
fw.parent_thread = mock.MagicMock()
|
|
154
|
+
fw.parent_thread.is_alive.side_effect = RuntimeError('cannot join current thread')
|
|
155
|
+
|
|
156
|
+
self.assertFalse(fw._is_parent_alive())
|
|
157
|
+
|
|
158
|
+
def test_shutdown_condition_when_parent_is_alive_raises(self):
|
|
159
|
+
self.buffer_capacity = 10
|
|
160
|
+
num_items = 5
|
|
161
|
+
first_frame = list(range(self.buffer_capacity))
|
|
162
|
+
self.assertLess(num_items, self.buffer_capacity)
|
|
163
|
+
|
|
164
|
+
self.upload_calls = 0
|
|
165
|
+
def uploader(frame):
|
|
166
|
+
self.upload_calls += 1
|
|
167
|
+
self.assertEqual(frame, first_frame[:num_items])
|
|
168
|
+
return mock.MagicMock(status_code=202)
|
|
169
|
+
|
|
170
|
+
pipe, _, fw = self._setup_worker(uploader)
|
|
171
|
+
fw.parent_thread = mock.MagicMock()
|
|
172
|
+
fw.parent_thread.is_alive.side_effect = RuntimeError('cannot join current thread')
|
|
173
|
+
|
|
174
|
+
for i in range(num_items):
|
|
175
|
+
pipe.put(first_frame[i], block=False)
|
|
176
|
+
|
|
177
|
+
fw.step()
|
|
178
|
+
self.assertEqual(self.upload_calls, 1)
|
|
179
|
+
self.assertFalse(fw.should_run)
|
|
180
|
+
|
|
151
181
|
def test_shutdown_dont_raise_exception_in_thread(self):
|
|
152
182
|
original_excepthook = threading.excepthook
|
|
153
183
|
threading.excepthook = mock.Mock()
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from logtail.frame import create_frame
|
|
4
4
|
from logtail.handler import LogtailHandler
|
|
5
5
|
from logtail.helpers import LogtailContext
|
|
6
|
-
from sys import version_info
|
|
7
6
|
import datetime
|
|
8
7
|
import unittest
|
|
9
8
|
import logging
|
|
@@ -17,11 +16,8 @@ class TestLogtailLogEntry(unittest.TestCase):
|
|
|
17
16
|
# ISO timestamp must end with timezone info
|
|
18
17
|
self.assertTrue(frame['dt'].endswith("+00:00"))
|
|
19
18
|
|
|
20
|
-
# These tests require Python >= 3.7
|
|
21
|
-
if version_info.major == 2 or version_info.minor <= 6:
|
|
22
|
-
return
|
|
23
19
|
# Sent date matches log record date
|
|
24
|
-
date_ref = datetime.datetime.
|
|
20
|
+
date_ref = datetime.datetime.fromtimestamp(log_record.created, datetime.timezone.utc)
|
|
25
21
|
date_sent = datetime.datetime.fromisoformat(frame['dt'])
|
|
26
22
|
self.assertEqual(date_ref, date_sent)
|
|
27
23
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_flusher.cpython-311.pyc
RENAMED
|
File without changes
|
{logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_formatter.cpython-311.pyc
RENAMED
|
File without changes
|
|
File without changes
|
{logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_handler.cpython-311.pyc
RENAMED
|
File without changes
|
{logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_helpers.cpython-311.pyc
RENAMED
|
File without changes
|
{logtail_python-0.3.4 → logtail_python-0.4.0}/tests/__pycache__/test_uploader.cpython-311.pyc
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|