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 CHANGED
@@ -5,6 +5,6 @@ from .handler import LogtailHandler
5
5
  from .helpers import LogtailContext, DEFAULT_CONTEXT
6
6
  from .formatter import LogtailFormatter
7
7
 
8
- __version__ = '0.2.10'
8
+ __version__ = '0.3.1'
9
9
 
10
10
  context = DEFAULT_CONTEXT
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 1.0 seconds for each item to prevent
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=1.0)
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
- new_list = [_remove_circular_dependencies(item, memo) for item in obj]
73
- return new_list
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.2.10
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.2.10
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 >=2.18.4
27
- Requires-Dist: msgpack >=0.5.6
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,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.44.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -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,,