2015-07-11 13 views
12

Ich bin auf der Suche nach einer Möglichkeit, ein Call-Graph für Golang-Projekte zu generieren. Ähnliches wie Doxygen's diagram functionality für C++ - Klassen (mit der Option CALL_GRAPH = YES).Erstellen von Call-Graph in Golang

Bisher fand ich

http://saml.rilspace.org/profiling-and-creating-call-graphs-for-go-programs-with-go-tool-pprof
oder
http://blog.golang.org/profiling-go-programs

Diese Proben des Call-Stack des Programms 100 mal pro Sekunde, während das Programm ausgeführt wird, und erstellt ein Diagramm nützlich für die Profilierung. Wenn Ihr Programm die meiste Zeit in Funktionen spielt, die für Sie nicht relevant sind, fand ich diese Lösung nicht sehr nützlich.

Dann gibt es das:

https://godoc.org/golang.org/x/tools/go/callgraph/static

, die aus ihrer Beschreibung klingt wie das, was ich brauchen würde, aber es scheint keine Dokumente zu sein, und ich verstehe nicht, wie es zu benutzen.

Ich fand auch

https://github.com/davecheney/graphpkg/blob/master/README.md
und
https://github.com/paetzke/go-dep-graph/blob/master/README.org

aber sie schaffen nur Abhängigkeitsgraphen.

Antwort

9

einen Blick hier nehmen: http://dave.cheney.net/2014/10/22/simple-profiling-package-moved-updated

func main() { 
    defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop() 
    // Rest of program 
} 

erstellen und ausführen Programm wie pro normal. Sie verlassen nun die Profilierung Haken siehe erwähnt:

2015/07/12 09:02:02 profile: cpu profiling enabled, cpu.pprof 

Führen Sie Ihr Programm (Bank es, durch sie laufen, usw.) das Profil während der Laufzeit zu erzeugen. Sobald Sie getroffen haben, was Sie wollen, beenden und dann den Anruf-Diagramm erzeugen:

go tool pprof --pdf $YOURPROGBINARY cpu.pprof > cgraph.pdf 

Sie auch go tool pprof $YOURPROGBINARY cpu.pprof laufen kann eine interaktive Eingabeaufforderung zu erhalten, wo Sie top10 oder web zur Erzeugung eines svg aufrufen können. Geben Sie an der pprof-Eingabeaufforderung help ein, um eine Liste der Befehle abzurufen.

z.B. - hier ist die CPU-Profil für einen Pufferpool Implementierung schrieb ich:

~/Desktop go tool pprof poolio cpu.pprof 
Entering interactive mode (type "help" for commands) 
(pprof) top5 
24770ms of 35160ms total (70.45%) 
Dropped 217 nodes (cum <= 175.80ms) 
Showing top 5 nodes out of 74 (cum >= 650ms) 
     flat flat% sum%  cum cum% 
    12520ms 35.61% 35.61% 12520ms 35.61% runtime.mach_semaphore_wait 
    9300ms 26.45% 62.06%  9360ms 26.62% syscall.Syscall 
    1380ms 3.92% 65.98%  2120ms 6.03% encoding/json.(*encodeState).string 
    1030ms 2.93% 68.91%  1030ms 2.93% runtime.kevent 
    540ms 1.54% 70.45%  650ms 1.85% runtime.mallocgc 

Und hier ist eine schnelle Möglichkeit, eine PNG aus der Aufforderung zu generieren:

(pprof) png > graph.png 
Generating report in graph.png 

Welche diese Ausgänge:

callgraph-example-poolio

+0

Mit dieser Methode wird beschrieben in der erste Link, den ich erwähnt habe; Ich habe vergessen auf die ursprüngliche Seite zu verlinken. Für mich gibt das keine befriedigenden Ergebnisse; Ich sehe viele Funktionsaufrufe, die für mich nicht interessant sind, aber ich sehe die Funktionsaufrufe, an denen ich überhaupt interessiert bin, nicht. Nach einigen Profiling-Läufen sehe ich einige der interessanten Funktionen, aber nie alle. Gibt es kein statisches Werkzeug, das einfach durch den Code geht und Graphen erstellt? – alex

+0

Eines meiner Probleme ist, dass ich mich auch für Funktionen interessiere, die nur einmal ausgeführt werden (während des Setups). Gibt es eine Möglichkeit, die Abtastrate des Werkzeugs zu erhöhen, z. die Wahrscheinlichkeit steigt, dass auch kurze Lauffunktionen abgetastet werden? – alex

+0

Die Abtastrate ist in runtime/pprof.go: 587 über Laufzeit fest codiert.SetCPUProfileRate (hz) mit hz = 100, d.h. 100 Abtastungen pro Sekunde. Wenn man runtime.SetCPUProfileRate (wishedSamplingRate) * vor * Aufruf von profile.Start() aufruft, kann man dies überschreiben. Der Versuch, die Abtastrate nach dem Aufruf von profile.Start() einzustellen, funktioniert nicht ("runtime: cpu profile rate kann nicht eingestellt werden, bis das vorherige Profil beendet ist."). – alex

9

Sie waren in der Nähe mit ... /x/tools/go/callgraph/static. Ich bin mir ziemlich sicher go install golang.org/x/tools/cmd/callgraph ist was du willst. Sobald es installiert ist, führe es ohne Argumente aus, um zu sehen, ob es vollständig genutzt wird.

(Im Allgemeinen sind die Dinge unter ... /x/tools/ sind etwas wiederverwendbare Pakete mit Kommandozeilen-Frontends unter leben ... /x/tools/cmd, können Sie sie alle mit go install golang.org/x/tools/cmd/..., die wörtliche /... Matches alle Unterpakete installieren).

z. nur callgraph produziert Gebrauchsausgabe ausgeführt wird, die mit Beginn des Einsatzes:

callgraph: die grafische Darstellung eines Go-Programm der Anruf angezeigt werden soll.

Verbrauch:

callgraph [-algo=static|cha|rta|pta] [-test] [-format=...] <args>...

Flags:

-algo Gibt den Aufruf-Graph-Konstruktion Algorithmus, von:

 static  static calls only (unsound) 
     cha   Class Hierarchy Analysis 
     rta   Rapid Type Analysis 
     pta   inclusion-based Points-To Analysis 

     The algorithms are ordered by increasing precision in their 
     treatment of dynamic calls (and thus also computational cost). 
     RTA and PTA require a whole program (main or test), and 
     include only functions reachable from main. 

-test das Paket des Tests in der Analyse.

-format Gibt das Format an, in dem die Kanten der Aufrufgraphen angezeigt werden. Eines:

 digraph  output suitable for input to 
        golang.org/x/tools/cmd/digraph. 
     graphviz output in AT&T GraphViz (.dot) format. 

Es kann beliebig formatierte Ausgabe erzeugen oder graphviz oder digraph Ausgang (Go Template-Syntax). Die letzte ist ein Tool, das Sie mit go install golang.org/x/tools/cmd/digraph installieren können (und noch einmal, volle/help Nutzung wird gesehen, indem es ohne Argumente ausgeführt wird) und kann Anfragen über willkürlich gerichtete Graphen (einschließlich Aufruf Graphen offensichtlich) beantworten.

+0

Danke! Ich experimentierte mit Callgraph mit den verschiedenen Algo-Flags und versuchte, ein PDF mit graphviz/dot zu erstellen oder die Ausgabe von Callgraph mit Digraph abzufragen.Leider enthält die Ausgabe von Callgraph meist go libs und das Erzeugen einer PDF aus der Ausgabe von Callgraph ergibt nichts brauchbares. Die Abfragefunktionen von Digraph können hilfreich sein. Die beste Lösung für mich wäre, wenn ich die go lib-Funktionsaufrufe herausfiltern könnte - insbesondere die tief verschachtelten, für die mein Code nicht einmal verantwortlich ist. Vielleicht kann ich nur eine Nachbearbeitung mit dem Ergebnis von Callgraph machen. – alex

+0

Es gibt noch ein weiteres Hindernis, das mich daran hindert, Callgraph zu verwenden - es funktioniert nicht, wenn ich ZeroMQ-Bindungen (github.com/pebbe/zmq3) importiere. Die erste Ausgabe ist "cgo pkg-config not supported" und dann viele "undeclared name" -Fehler vom zmq-Paket, obwohl sie im Paket deklariert sind. – alex