{"id":1117,"date":"2011-09-28T22:13:15","date_gmt":"2011-09-28T20:13:15","guid":{"rendered":"http:\/\/blog.benny-baumann.de\/?p=1117"},"modified":"2011-09-28T22:18:51","modified_gmt":"2011-09-28T20:18:51","slug":"uberblick-uber-projektaktivitat-gewinnen","status":"publish","type":"post","link":"https:\/\/blog.benny-baumann.de\/?p=1117","title":{"rendered":"\u00dcberblick \u00fcber Projektaktivit\u00e4t gewinnen"},"content":{"rendered":"<p>Manchmal hat man ein Projekt, von dem man gerne wissen m\u00f6chte, ob noch aktiv an diesem entwickelt wird. Aber nicht immer sind entsprechende Grafiken mit aussagekr\u00e4ftigen Zahlen verf\u00fcgbar. Eine recht einfache M\u00f6glichkeit, dennoch einen \u00dcberblick zu bekommen, ist ein Blick in die Commit Logs des Projektes. Wenn diese viel Aktivit\u00e4t zeigen, ist ein Projekt mit sehr hoher Wahrscheinlichkeit noch aktiv. Aber stupide Datumswerte sind oftmals recht schwer zu \u00fcberblicken. Etwas mehr Grafik w\u00e4re hier w\u00fcnschenswert. Und genau hier kann man mit etwas Bash Magic und ein wenig RRDTool nachhelfen.<!--more--><\/p>\n<p>Als erstes ben\u00f6tigt man hierzu nat\u00fcrlich eine Kopie des Repositories des Projektes, von dem man einen \u00dcberblick erhalten m\u00f6chte. In meinem Beispiel ist dies ispCP, da es dort derzeit Probleme zu geben scheint. Also holen wir uns das Repository:<\/p>\n<pre lang=\"bash\" escaped=\"true\">git svn clone -s --use-log-author http:\/\/www.isp-control.net:800\/ispcp_svn ispCP<\/pre>\n<p>Der Parameter -s sagt git-svn, dass das Default-Layout f\u00fcr das Repository verwendet wird, w\u00e4hrend mit &#8211;use-log-author die Authoren-Angabe aus dem urspr\u00fcnglichen Commit \u00fcbernommen wird. Zus\u00e4tzlich sollte man hier noch die Zuordnung von SVN-Usernamen zu Git-Nutzern angeben, da ich diese f\u00fcr ispCP jedoch nicht kenne, geht es auch ohne. Aus dieser Information lie\u00dfe sich ansonsten auch die Anzahl Commits je Autor errechnen und darstellen, aber das geht ein wenig weiter als f\u00fcr einen groben \u00dcberblick n\u00f6tig.<\/p>\n<p>Nachdem wir unser Repository geclont haben (kann bei SVN etwas dauern), kann die eigentliche Magie beginne. Als erstes ben\u00f6tigen wir hierzu eine RRD (Round Robin Database), in der wir unsre aggregierten Daten ablegen. Diese l\u00e4sst sich wie folgt erstellen:<\/p>\n<pre lang=\"bash\" escaped=\"true\">rrdtool create ispcp.rrd --start 1000000000 -s 60 DS:commits:ABSOLUTE:86400:0:65536 RRA:LAST:0:1:1440 RRA:LAST:0:60:720 RRA:LAST:0:720:730 RRA:LAST:0:1440:3000<\/pre>\n<p>Auf diese Weise erhalten wir unsere Archiv-Datei, in der nun lediglich noch unsere Daten abgelegt werden m\u00fcssen. Auch dies erlaubt uns die Bash mit Hilfe eines Einzeilers:<\/p>\n<pre lang=\"bash\" escaped=\"true\">git log|grep Date:|cut -d: -f2-|cut '-d ' -f 5-8|awk \"{ \/(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\/; print \\$1,\\$2,\\$4,\\$3}\"|xargs -i date --date={} +%s|sort|xargs -i rrdtool update ispcp.rrd -- {}:1<\/pre>\n<p>Dieser Befehl macht eine ganze Menge an Magie, weshalb ich ihn etwas auseinandernehmen m\u00f6chte:<\/p>\n<p>Der erste Teil liest von Git die Versionsgeschicht des aktuellen Repository aus. Aus der resultierenden Ausgabe wird das Datum eines jeden Commits gefiltert. Die beiden cut-Befehle sorgen nun daf\u00fcr, aus der Datumszeile nur das eigentliche Datum \u00fcbrig zu lassen. Die Zeitzone wird dabei entfernt, weil date damit nicht so recht arbeiten wollte. Auch m\u00f6chte Ddate das Datum mit dem Jahr vor der Zeit haben, weshalb mit awk die vier Felder &#8222;Monat Tag Uhrzeit Jahr&#8220; in die Reihenfolge &#8222;Monat Tag Jahr Uhrzeit&#8220; getauscht werden m\u00fcssen. Danach wird die so umgetauschte Uhrzeit an date \u00fcbergeben und in einen Unix-Zeitstempel umgewandelt. Die Zeitstempel aller Commits werden dann aufsteigend sortiert und an rrdtool \u00fcbergeben. Dabei erfolgt f\u00fcr jeden Zeitstempel ein Aufruf mit dem Hinweis, dass sich der Z\u00e4hler um eins erh\u00f6ht hat. Der stillschweigend \u00fcbergangene Befehl xargs ruft den danach aufgef\u00fchrten Befehl f\u00fchr jede Zeile der Eingabe einmalig auf, wobei {} auf der Befehlszeile durch den Inhalt der aktuellen Eingabezeile ersetzt wird.<\/p>\n<p>Was in diesem Befehl nicht beachtet wird, sind 2 Commits, die in der gleichen Sekunde stattgefunden haben. Diese werden uns aber von RRDTool als Warnmeldung geliefert, womit wir einen \u00dcberblick \u00fcber diese Vorkommnisse haben.<\/p>\n<p>Nun da wir unsere Daten haben, m\u00fcssen wir diese nat\u00fcrlich auch noch darstellen. Dies geht am einfachsten mit dem in RRDTool bereits enthaltenen Graphen-Tool:<\/p>\n<pre lang=\"bash\" escaped=\"true\">rrdtool graph ispcp.png --end now --start end-153600000s --step=86400 --width 1000 --height=512 DEF:commits=ispcp.rrd:commits:LAST CDEF:c=commits,UN,0,commits,IF,86400,* AREA:c#0000FF:\"Number of Commits\\l\"<\/pre>\n<p>Auch dieser Befehl ist eigentlich wieder recht einfach zu verstehen: Wir nehmen vom aktuellen Zeitpunkt bis zum Zeitpunkt vor 5 Jahren im Abstand von einem Tag eine Auswertung vor und wollen einen Graphen haben, der als Zeichenfl\u00e4che 1000&#215;512 Pixel ist. Dieser soll die Commits aus der Datei ispcp.rrd enthalten. Diese werden noch kurz skaliert und undefinierte Werte durch 0 ersetzt. Anschlie\u00dfend werden diese einfach gezeichnet.<\/p>\n<p>Und so einfach haben wir unseren \u00dcberblick!<br \/>\n<div id=\"attachment_1118\" style=\"width: 1091px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/blog.benny-baumann.de\/wp-content\/uploads\/ispcp_commitsperday.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1118\" src=\"http:\/\/blog.benny-baumann.de\/wp-content\/uploads\/ispcp_commitsperday.png\" alt=\"ispCP - Commits pro Tag\" title=\"ispCP - Commits pro Tag\" width=\"1081\" height=\"574\" class=\"size-full wp-image-1118\" srcset=\"https:\/\/blog.benny-baumann.de\/wp-content\/uploads\/ispcp_commitsperday.png 1081w, https:\/\/blog.benny-baumann.de\/wp-content\/uploads\/ispcp_commitsperday-300x159.png 300w, https:\/\/blog.benny-baumann.de\/wp-content\/uploads\/ispcp_commitsperday-1024x543.png 1024w\" sizes=\"auto, (max-width: 1081px) 100vw, 1081px\" \/><\/a><p id=\"caption-attachment-1118\" class=\"wp-caption-text\">ispCP - Commits pro Tag (Oktober 2006 - September 2011)<\/p><\/div><\/p>\n<p>Eine Stolperfalle hat das Ganze aber: Erh\u00e4lt man n\u00e4mlich einen leeren Graphen, ist die Ursache nicht ganz offensichtlich. Hier hilft es, wenn man beim Erstellen des RRD den Heartbeat m\u00f6glichst lange einstellt, was aber die erzielbare Aufl\u00f6sung stark reduziert. Bei Projekten, die aber nur selten Commits haben, erzielt man auf diese Weise recht brauchbare Ergebnisse, auch wenn einzelne Commits, die von langen Ruhephasen umgeben sind, ignoriert werden. An der Stelle sollte man also beim Interpretieren der Grafik etwas vorsichtig sein. F\u00fcr einen \u00dcberblick reicht es aber allemal. Auch ist, wie oben bereits erw\u00e4hnt, ein systematischer Fehler enthalten, wenn man h\u00e4ufig Commits in der selben Sekunde hat. In diesem Falle werden alle Commits einer Sekunde als nur ein Commit gewertet.<\/p>\n<p class=\"wp-flattr-button\"><a href=\"https:\/\/blog.benny-baumann.de\/?flattrss_redirect&amp;id=1117&amp;md5=26a27d17799803b20e948a06f02f0488\" title=\"Flattr\" target=\"_blank\"><img src=\"http:\/\/blog.benny-baumann.de\/wp-content\/plugins\/flattr\/img\/flattr-badge-large.png\" srcset=\"http:\/\/blog.benny-baumann.de\/wp-content\/plugins\/flattr\/img\/flattr-badge-large.png\" alt=\"Flattr this!\"\/><\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Manchmal hat man ein Projekt, von dem man gerne wissen m\u00f6chte, ob noch aktiv an diesem entwickelt wird. Aber nicht immer sind entsprechende Grafiken mit aussagekr\u00e4ftigen Zahlen verf\u00fcgbar. Eine recht einfache M\u00f6glichkeit, dennoch einen \u00dcberblick zu bekommen, ist ein Blick in die Commit Logs des Projektes. Wenn diese viel Aktivit\u00e4t zeigen, ist ein Projekt mit [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[29],"tags":[324,98,347,81,223],"class_list":["post-1117","post","type-post","status-publish","format-standard","hentry","category-software","tag-bash","tag-developement","tag-fun","tag-ispcp","tag-rrdtool"],"_links":{"self":[{"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/posts\/1117","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1117"}],"version-history":[{"count":4,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/posts\/1117\/revisions"}],"predecessor-version":[{"id":1120,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=\/wp\/v2\/posts\/1117\/revisions\/1120"}],"wp:attachment":[{"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1117"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1117"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.benny-baumann.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1117"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}