Использование трассировки и базы данных в Erlang - PullRequest
65 голосов
/ 23 декабря 2009

Я пытаюсь начать использовать erlang: trace / 3 и модуль dbg для отслеживания поведения работающей производственной системы без отключения сервера.

Документация является непрозрачной (мягко говоря), и в Интернете нет никаких полезных руководств.

То, что я потратил весь день, пытаясь сделать, было перехватить то, что происходило в конкретной функции, пытаясь применить трассировку к module: function, используя dbg: c и dbg: p, но безуспешно ...

У кого-нибудь есть краткое объяснение того, как использовать трассировку в действующей системе Эрланга?

Ответы [ 4 ]

91 голосов
/ 23 декабря 2009

Основные шаги трассировки для вызовов функций находятся на неживом узле:

> dbg:start().   % start dbg
> dbg:tracer().  % start a simple tracer process
> dbg:tp(Module, Function, Arity, []).   % specify MFA you are interested in
> dbg:p(all, c).   % trace calls (c) of that MFA for all processes.

... trace here

> dbg:stop_clear().   % stop tracer and clear effect of tp and p calls.

Вы можете отслеживать несколько функций одновременно. Добавьте функции, вызвав tp для каждой функции. Если вы хотите отследить неэкспортированные функции, вам нужно вызвать tpl. Чтобы удалить функции, вызовите ctp или ctpl аналогичным образом. Некоторые общие звонки по телефону:

> dbg:tpl(Module, '_', []).  % all calls in Module
> dbg:tpl(Module, Function, '_', []).   % all calls to Module:Function with any arity.
> dbg:tpl(Module, Function, Arity, []). % all calls to Module:Function/Arity.
> dbg:tpl(M, F, A, [{'_', [], [{return_trace}]}]).   % same as before, but also show return value.

Последний аргумент является спецификацией соответствия. Вы можете поиграть с этим, используя dbg:fun2ms.

Вы можете выбрать процессы для отслеживания с помощью вызова p (). Элементы описаны под erlang: trace. Некоторые звонки:

> dbg:p(all, c).   % trace calls to selected functions by all functions
> dbg:p(new, c).   % trace calls by processes spawned from now on
> dbg:p(Pid, c).   % trace calls by given process
> dbg:p(Pid, [c, m]).  % trace calls and messages of a given process

Полагаю, вам никогда не понадобится напрямую звонить erlang:trace, так как dbg сделает для вас почти все.

Золотое правило для живого узла - генерировать только объем вывода трассировки в оболочку, что позволяет вводить dbg:stop_clear().. :)

Я часто использую трассировщик, который автоматически останавливается после ряда событий. Например:

dbg:tracer(process, {fun (_,100) -> dbg:stop_clear();
                        (Msg, N) -> io:format("~p~n", [Msg]), N+1 end, 0
                    }).

Если вы ищете отладку на удаленных узлах (или нескольких узлах), найдите pan, eper, inviso или onviso.

22 голосов
/ 14 мая 2010

В живых системах мы редко прослеживаемся до оболочки. Если система хорошо настроена, то она уже собирает ваши журналы Erlang, которые были напечатаны в оболочку. Мне не нужно подчеркивать, почему это важно в любом живом узле ...

Позвольте мне подробно остановиться на трассировке файлов:

Можно отследить до файла, который будет производить двоичный вывод, который может быть преобразован и проанализирован позже. (для дальнейшего анализа или автоматизированной системы управления и т. д.)

Примером может быть:

  • Трассировка в несколько файлов (12x50 Мбайт). Пожалуйста, всегда проверяйте свободное место на диске перед использованием такой большой трассировки!

    dbg:tracer(port,dbg:trace_port(file,{"/log/trace",wrap,atom_to_list(node()),50000000,12})).
    

    dbg:p(all,[call,timestamp,return_to]).

    • Всегда проверяйте на тестовом узле, прежде чем вводить что-либо в оболочку живого узла!
    • Чаще всего рекомендуется иметь тестовый узел или узел реплики, чтобы сначала попробовать сценарии.

Тем не менее, давайте посмотрим на последовательность команд базовой трассировки:

<1> dbg:stop_clear().

  • Всегда начинайте с очистки портов трассировки и следите за тем, чтобы никакая предыдущая трассировка не мешала текущей трассе.

<2> dbg:tracer().

  • Запустить процесс трассировки.

<3> dbg:p(all,[call, timestamp]).

  • В этом случае мы отслеживаем все процессы и вызовы функций.

<4> dbg:tp( ... ).

  • Как видно из ответа Зеда.

<5> dbg:tpl( ... ).

  • Как видно из ответа Зеда.

<42> dbg:stop_clear().

  • Опять же, это необходимо для того, чтобы все записи были записаны на выход, и чтобы избежать любых последующих неудобств.

Вы можете:

  • добавьте триггеры, определив некоторые функции fun () в оболочке, чтобы остановить трассировку в определенное время или событие. Рекурсивные fun () - это лучшее для достижения этой цели, но будьте очень осторожны при их применении.

  • применять широкий спектр сопоставления с шаблоном, чтобы гарантировать, что вы отслеживаете только для конкретного процесса с конкретным вызовом функции с определенным типом аргументов ...

Некоторое время назад у меня была проблема, когда нам приходилось проверять содержимое таблицы ETS, и при появлении определенной записи нам приходилось останавливать трассировку в течение 2-3 минут.

Я также предлагаю книгу «Программирование на эрланге», написанную Франческо Чезарини. ( Erlang Programming @ Amazon )

9 голосов
/ 14 мая 2010

Модуль 'dbg' довольно низкоуровневый. Есть два хака, которые я использую очень часто для задач, которые мне обычно нужны.

  1. Используйте код расширения командной строки / оболочки Erlang на http://www.snookles.com/erlang/user_default.erl. Первоначально он был написан (насколько я знаю) Сергеем Алейниковым и был полезный пример "так вот как я добавляю пользовательские функции в оболочку". компилировать модуль и отредактируйте файл ~ / .erlang, указав путь к нему (см. комментарий вверху файла).

  2. Используйте утилиту " redbug ", которая входит в комплект утилит EPER . С помощью 'dbg' очень легко создавать миллионы событий трассировки за несколько секунд. дела поэтому в производственной среде может быть катастрофическим. Для разработки или производства, redbug делает практически невозможным уничтожение работающей системы с перегрузкой, вызванной трассировкой.

7 голосов
/ 18 декабря 2014

Если вы предпочитаете графический трассировщик, попробуйте erlyberly . Он позволяет вам выбрать функции, которые вы хотите отслеживать (для всех процессов в данный момент), и работает с dbg API.

Однако он не защищает от перегрузки, поэтому не подходит для производственных систем.

enter image description here

...