Ich versuche, erlang:trace/3
das dbg
Modul zu verwenden, um das Verhalten eines Live-Produktionssystems zu verfolgen, ohne den Server herunterzufahren.
Die Dokumentation ist undurchsichtig (um es milde auszudrücken) und es scheint keine nützlichen Online-Tutorials zu geben.
Was ich verbrachte den ganzen Tag versucht zu tun war erfassen , was in einer bestimmten Funktion geschieht , indem Sie versuchen eine Spur zu bewerben Module:Function
verwenden dbg:c
und dbg:p
aber ohne Erfolg überhaupt.
Hat jemand eine kurze Erklärung, wie Trace in einem lebenden Erlang-System verwendet wird?
Antworten:
Wenn Sie einen grafischen Tracer bevorzugen, versuchen Sie es einfach . Sie können die Funktionen auswählen, die Sie verfolgen möchten (derzeit für alle Prozesse), und sich mit der dbg-API befassen.
Es schützt jedoch nicht vor Überlastung und ist daher nicht für Produktionssysteme geeignet.
quelle
Die grundlegenden Schritte zur Ablaufverfolgung für Funktionsaufrufe befinden sich auf einem nicht aktiven Knoten:
> 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.
Sie können mehrere Funktionen gleichzeitig verfolgen. Fügen Sie Funktionen hinzu, indem Sie
tp
für jede Funktion aufrufen . Wenn Sie nach nicht exportierten Funktionen suchen möchten, müssen Sie aufrufentpl
. Um Funktionen zu entfernen, rufen Siectp
oderctpl
auf ähnliche Weise auf. Einige allgemeine TP-Aufrufe sind:> 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.
Das letzte Argument ist eine Übereinstimmungsspezifikation. Damit können Sie herumspielen
dbg:fun2ms
.Sie können die Prozesse auswählen, die mit dem Aufruf von p () verfolgt werden sollen. Die Artikel sind unter erlang: trace beschrieben. Einige Anrufe sind:
> 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
Ich denke, Sie müssen nie direkt anrufen
erlang:trace
, dadbg
so ziemlich alles für Sie erledigt ist.Eine goldene Regel für einen Live-Knoten besteht darin, nur eine Menge von Trace-Ausgaben für die Shell zu generieren, mit denen Sie eingeben können
dbg:stop_clear().
. :) :)Ich benutze oft einen Tracer, der sich nach einer Reihe von Ereignissen automatisch stoppt. Zum Beispiel:
dbg:tracer(process, {fun (_,100) -> dbg:stop_clear(); (Msg, N) -> io:format("~p~n", [Msg]), N+1 end, 0 }).
Wenn Sie für das Debuggen auf entfernten Knoten (oder mehrere Knoten) suchen, suchen
pan
,eper
,inviso
oderonviso
.quelle
dbg:n(Node)
richtet sichNode
für dieselbe Ablaufverfolgung ein wie der Knoten, auf dem Sie sich befinden.Auf Live-Systemen verfolgen wir selten die Shell. Wenn das System gut konfiguriert ist, sammelt es bereits Ihre Erlang-Protokolle, die auf der Shell gedruckt wurden. Ich muss nicht betonen, warum dies in einem Live-Knoten entscheidend ist ...
Lassen Sie mich näher auf die Rückverfolgung von Dateien eingehen:
Es ist möglich, eine Datei zu verfolgen, wodurch eine Binärausgabe erzeugt wird, die später konvertiert und analysiert werden kann. (zur weiteren Analyse oder automatisierten Steuerung usw.)
Ein Beispiel könnte sein:
Verfolgen Sie mehrere umschlossene Dateien (12 x 50 MB). Bitte überprüfen Sie immer den verfügbaren Speicherplatz, bevor Sie einen so großen Trace verwenden!
dbg:tracer(port,dbg:trace_port(file,{"/log/trace",wrap,atom_to_list(node()),50000000,12})).
dbg:p(all,[call,timestamp,return_to]).
Lassen Sie uns einen Blick auf eine grundlegende Ablaufverfolgungsbefehlssequenz werfen:
<1>
dbg:stop_clear().
<2>
dbg:tracer().
<3>
dbg:p(all,[call, timestamp]).
<4>
dbg:tp( ... ).
<5>
dbg:tpl( ... ).
<42>
dbg:stop_clear().
Sie können:
Fügen Sie Trigger hinzu, indem Sie einige fun () - s in der Shell definieren, um die Ablaufverfolgung zu einem bestimmten Zeitpunkt oder Ereignis zu stoppen. Rekursive fun () - s sind die besten, um dies zu erreichen, aber seien Sie sehr vorsichtig, wenn Sie diese anwenden.
Wenden Sie eine Vielzahl von Mustervergleichen an, um sicherzustellen, dass Sie nur den spezifischen Prozess mit dem spezifischen Funktionsaufruf mit dem spezifischen Argumenttyp verfolgen ...
Ich hatte vor einiger Zeit ein Problem, als wir den Inhalt einer ETS-Tabelle überprüfen mussten und beim Erscheinen eines bestimmten Eintrags die Ablaufverfolgung innerhalb von 2-3 Minuten stoppen mussten.
Ich schlage auch das Buch Erlang Programming von Francesco Cesarini vor. ( Erlang Programming @ Amazon )
quelle
Das 'dbg'-Modul ist ziemlich einfach. Es gibt zwei Hacks, die ich sehr häufig für die Aufgaben verwende, die ich normalerweise benötige.
Verwenden Sie den Erlang CLI / Shell-Erweiterungscode unter http://www.snookles.com/erlang/user_default.erl . Es wurde ursprünglich (soweit ich weiß) von Serge Aleynikov geschrieben und war ein nützliches Beispiel dafür, wie ich der Shell benutzerdefinierte Funktionen hinzufüge. Kompilieren Sie das Modul und bearbeiten Sie Ihre ~ / .erlang-Datei so, dass sie auf ihren Pfad verweist (siehe Kommentar oben in der Datei).
Verwenden Sie das Dienstprogramm " redbug ", das in der EPER- Sammlung von Dienstprogrammen enthalten ist. Es ist sehr einfach, mit 'dbg' in wenigen Sekunden Millionen von Ablaufverfolgungsereignissen zu erstellen. Dies in einer Produktionsumgebung zu tun, kann katastrophal sein. Für die Entwicklung oder Produktion macht es Redbug nahezu unmöglich, ein laufendes System mit einer durch Spuren verursachten Überlastung zu töten.
quelle