Использование трассировки и базы данных в Erlang

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

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

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

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

4 ответа

Решение

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

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

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

> 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 аналогичным образом. Некоторые общие вызовы tp:

> 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,

На живых системах мы редко прослеживаемся до оболочки. Если система хорошо настроена, то она уже собирает ваши журналы 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, написанную Франческо Чезарини. ( Erlang Programming @ Amazon)

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

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

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

Другие вопросы по тегам