Выделение трассировки стека python
Я работаю над довольно сложным проектом, и время от времени я должен сузить проблемы, смотря на следы стека. Они случаются очень долго и включают в себя "мой" код, стандартный библиотечный код и код сторонних библиотек одновременно. Большую часть времени реальная проблема заключается в "моем" коде и мгновенном обнаружении ее в трассировке стека, это немного сложно для глаз. Под "моим" кодом я имею в виду код, находящийся в текущем рабочем каталоге.
Итак, я понял, что хочу что-то, что будет раскрашивать трассировки стека и выделять строки, которые являются моими. Сравните оригинал с выделен.
Я мог бы написать python script, который мог бы использовать этот способ:
nosetests | colorize_stack_trace.py
Но я считаю, что есть более быстрый и элегантный способ сделать это с помощью набора инструментов Linux. Любые идеи?
UPD:
Используя суперкарт, предложенный Деннисом Уильямсоном, промежуточный результат следующий за функцией bash:
pyst() {
rc=/tmp/spcrc;
echo '#################### ### # # # ########################################' > $rc;
echo ' blk 0 r ^(.*)$' >> $rc;
echo ' mag b 0 r ^\s*File "'`pwd`'/(.*)"' >> $rc;
spc -c $rc;
}
Теперь я могу сделать:
nosetests 2>&1 | pyst
Не слишком элегантный, но работает в некоторой степени. Остались две проблемы:
- Я не вижу никакого вывода перед завершением носетей. То есть Я не вижу прогресса.
- Мне нужно снова и снова писать 2 > & 1.
UPD 2:
Задавая этот вопрос, я имел в виду главным образом nosetests
. И я просто нашел отличное решение: rednose плагин для носа. Он выделяет пути, которые являются локальными, и делает еще много удобных возможностей для чтения.
Возвращаясь к исходному вопросу: проблемы, которые я заметил с помощью supercat, не относятся к нему полностью, но его проблема в потоковой передаче, промывке, пересылке, перенаправлении Unix. Так как в качестве ответа на заданный вопрос я принимаю ответ, который предлагает supercat.
Ответы
Ответ 1
Посмотрите Supercat (spc). Он выполняет подсветку ANSI и HTML и может быть настроен для вашего конкретного вывода. Он поставляется с некоторыми файлами конфигурации для файлов исходного кода в C и Python, например, файлы журналов, Changelogs, diff и другие.
На основе предложения Дейва Кирби для vim это делает нечто похожее:
less -p regex file_name
или
some_command | less -p regex
Ответ 2
На самом деле, есть отличная библиотека подсветки синтаксиса Python, которая называется Pygments, которая также может подсвечивать обратные вызовы.
Итак, все, что вам нужно сделать, это:
$ easy_install pygments # downloads and installs pygments
$ cat traceback.txt | pygmentize -l pytb
"pytb" - это ярлык для PythonTracebackLexer. Также есть специальный лексер для Python 3 Tracebacks, который называется "py3tb".
Вы можете форматировать вывод в различных форматах (включая html, latex, svg, несколько форматов изображений и т.д.). Но есть также средство форматирования терминала (и если вам интересно... конечно, есть разные цветовые темы!).
Вы можете использовать -f html
, чтобы выбрать другой форматер (в этом случае, форматер HTML).
Ответ 3
Для этого есть хороший модуль:
Вам просто нужно скачать и установить его через pip:
pip install colored-traceback
Импортируйте его в файл верхнего уровня вашего проекта, например:
if DEBUG:
import colored_traceback
colored_traceback.add_hook()
И вы получите такую трассировку для каждого файла underling (цвета меняются):
Traceback (most recent call last):
File "./workflowy.py", line 525, in <module>
main()
File "./workflowy.py", line 37, in main
projects = cli.load_json(args, input_is_pipe)
File "./workflowy.py", line 153, in load_json
return json.load(sys.stdin)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 290, in load
**kw)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 383, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
Ответ 4
Возможно, вы могли бы использовать модуль cgitb (короткий официальный документ здесь) в качестве отправной точки (он создает приятные HTML-трассировки). Это должно быть относительно просто сделать необходимые вам изменения (например, добавить цветовой тег в соответствии с файловым путем). Но, конечно, это возможно только в том случае, если вы хотите использовать браузер для просмотра трасс.
Ответ 5
В качестве отправной точки для раскраски (и в противном случае форматирования) текста вы, вероятно, захотите посмотреть curses library. Также смотрите этот практический способ, который выглядит полезным.
Что касается переопределения встроенной обработки ошибок Python для всех программ... Я никогда не пробовал, но я бы подумал, что это потребует некоторых довольно низких изменений. Вы всегда можете обернуть свой код огромным блоком try/except, но я предполагаю, что вы не хотите этого делать. Я одобряю более унифицированный подход к написанию небольшого script, который делает одно и делает это хорошо: он принимает вход и, если это трассировка стека, раскрашивает его. В противном случае передайте текст без изменений. Использование трубы, как вы сказали, может быть лучшим способом. (В этом случае для pipe stderr вы хотите сделать что-то вроде этого, которое объединяет stderr с stdout перед конвейером: cmd1 2>&1 | cmd2
)
Ответ 6
Также вы можете открыть файл трассировки с помощью vim, используя команду :cfile
. Затем вы можете открыть выделенный ant интерактивный список файлов в трассировке с помощью команды :copen
и перейти между этими файлами с помощью набора связанных команд vim.
Ответ 7
Вот один из них, использующий ipython:
import sys
from IPython.core.ultratb import ColorTB
print(''.join(ColorTB().structured_traceback(*sys.exc_info())))
Ответ 8
Загрузите текст в vim:
nosetests | vim -
Установите vim, чтобы выделить все строки, соответствующие поиску
:set hlsearch
Искать строки с "вашим" путем
/.*/path/to/my/code.*
Voila - все линии с вашим путем будут выделены.
Если вы хотите также выделить следующую строку, вы также можете сделать это:
/.*/path/to/my/code.*\n.*