Skip to content

Commit 0756cab

Browse files
committed
show N last log lines in exceptions (impl file_tail())
1 parent d243e49 commit 0756cab

File tree

3 files changed

+52
-17
lines changed

3 files changed

+52
-17
lines changed

testgres/config.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@
44
class TestgresConfig:
55
"""
66
Global config (override default settings).
7-
"""
87
9-
# shall we cache pg_config results?
10-
cache_pg_config = True
8+
Attributes:
9+
cache_initdb: shall we use cached initdb instance?
10+
cache_pg_config: shall we cache pg_config results?
11+
cached_initdb_dir: shall we create a temp dir for cached initdb?
12+
node_cleanup_full: shall we remove EVERYTHING (including logs)?
13+
error_log_lines: N of log lines to be included into exception (0=inf).
14+
"""
1115

12-
# shall we use cached initdb instance?
1316
cache_initdb = True
14-
15-
# shall we create a temp dir for cached initdb?
17+
cache_pg_config = True
1618
cached_initdb_dir = None
17-
18-
# shall we remove EVERYTHING (including logs)?
1919
node_cleanup_full = True
20+
error_log_lines = 20
2021

2122

2223
def configure_testgres(**options):

testgres/node.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
from .utils import \
3939
get_bin_path, \
40+
file_tail as _file_tail, \
4041
pg_version_ge as _pg_version_ge, \
4142
reserve_port as _reserve_port, \
4243
release_port as _release_port, \
@@ -168,12 +169,12 @@ def _maybe_stop_logger(self):
168169
self._logger.stop()
169170

170171
def _format_verbose_error(self, message=None):
171-
# list of important files
172+
# list of important files + N of last lines
172173
files = [
173-
os.path.join(self.data_dir, "postgresql.conf"),
174-
os.path.join(self.data_dir, "recovery.conf"),
175-
os.path.join(self.data_dir, "pg_hba.conf"),
176-
self.pg_log_name # main log file
174+
(os.path.join(self.data_dir, "postgresql.conf"), 0),
175+
(os.path.join(self.data_dir, "recovery.conf"), 0),
176+
(os.path.join(self.data_dir, "pg_hba.conf"), 0),
177+
(self.pg_log_name, TestgresConfig.error_log_lines)
177178
]
178179

179180
error_text = ""
@@ -183,14 +184,20 @@ def _format_verbose_error(self, message=None):
183184
error_text += message
184185
error_text += '\n' * 2
185186

186-
for f in files:
187+
for f, num_lines in files:
187188
# skip missing files
188189
if not os.path.exists(f):
189190
continue
190191

191-
# append contents
192-
with io.open(f, "r") as _f:
193-
lines = _f.read()
192+
with io.open(f, "rb") as _f:
193+
if num_lines > 0:
194+
# take last N lines of file
195+
lines = b''.join(_file_tail(_f, num_lines)).decode('utf-8')
196+
else:
197+
# read whole file
198+
lines = _f.read().decode('utf-8')
199+
200+
# append contents
194201
error_text += u"{}:\n----\n{}\n".format(f, lines)
195202

196203
return error_text

testgres/utils.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# coding: utf-8
22

3+
from __future__ import division
4+
35
import io
46
import os
57
import port_for
@@ -203,3 +205,28 @@ def pg_version_ge(version):
203205
min_ver = LooseVersion(version)
204206

205207
return cur_ver >= min_ver
208+
209+
210+
def file_tail(f, num_lines):
211+
"""
212+
Get last N lines of a file.
213+
"""
214+
215+
assert(num_lines > 0)
216+
217+
bufsize = 8192
218+
buffers = 1
219+
220+
end_pos = f.seek(0, os.SEEK_END)
221+
222+
while True:
223+
offset = max(0, end_pos - bufsize * buffers)
224+
pos = f.seek(offset, os.SEEK_SET)
225+
226+
lines = f.readlines()
227+
cur_lines = len(lines)
228+
229+
if cur_lines > num_lines or pos == 0:
230+
return lines[-num_lines:]
231+
232+
buffers = int(buffers * max(2, num_lines / max(cur_lines, 1)))

0 commit comments

Comments
 (0)