by mindc
Ten tutorial ma pokazać, w jak prosty sposób można stworzyć własne statystyki BOINC. Przy odrobinie wysiłku, można osiągnąć bardzo interesujące efekty. Dzięki temu, można wzbogacić swoja stronę www lub sygnaturkę. Wszelkie polecenia dotyczą systemu Linux, jednak nie powinno stanowić problemu, stworzeniu takich statystyk pod systemem Windows :)
Kolory: Wskazówki Uwagi Linia poleceń Kod
Zaczniemy od przygotowania oprogramowania.
W Debianie i pochodnych, sprawa wygląda prosto (w Ubuntu trzeba pamiętać o sudo przed apt-get):
# apt-get install perl rrdtool librrds-perl
Zainstalujemy w ten sposób Perl w wersji 5.10.0 i rrdtool w wersji 1.3.1.
Jeśli chcemy jedynie pobierać dane z schedulerów i dane obrabiać w inny sposób niż z pomocą rrdtool, można pominąć instalację tego pakietu.
Do generowania samych wykresów, używam rrdtool w wersji 1.2.26, ponieważ umożliwia on wykorzystywanie własnych czcionek. Wersja 1.2.27 już ignoruje ten parametr. Na dzień dzisiejszy wersje 1.3.x i 1.4.x także ignorują zewnętrzne czcionki użytkownika.
build-rrdtool-1.2.26.sh (wersja wspierająca czcionki użytkownika)
skrypt ściąga niezbędne pakiety, kompiluje i instaluje rrdtool w wersji 1.2.26 w katalogu /usr/local/rrdtool-1.2.26
build-rrdtool-1.4.4.sh (najnowsza wersja na dzień 2010-07-28)
skrypt ściąga niezbędne pakiety, kompiluje i instaluje rrdtool w wersji 1.4.4 w katalogu /usr/local/rrdtool-1.4.4
Nic nie stoi na przeszkodzie aby jednocześnie było zainstalowanych kilka wersji rrdtool. Obecnie do generowania wykresów używam wersji 1.2.26, a do generowania i aktualizacji samych plików rrd, wersji 1.3.1
Aby korzystać z biblioteki innej niż domyślna, należy w skryptach dopisać linijkę przed use RRDs;
Na przykład dla wersji 1.2.26
use RRDs;
zmieniamy na
use lib qw(/usr/local/rrdtool-1.2.26/lib/perl); use RRDs;
i analogicznie dla wersji 1.4.4
use lib qw(/usr/local/rrdtool-1.4.4/lib/perl); use RRDs;
Scieżki do bibliotek są prawidłowe, w przypadku wykorzystania skryptów instalacyjnych z tej strony.
Do uruchomienia skryptów wymagane jest zainstalowanie kilku modułów. Najprościej zainstalować je w następujący sposób:
# perl -MCPAN -e 'install qw(Digest::MD5 XML::Simple LWP::UserAgent Getopt::Long Time::HiRes)'
Aby instalacja modułów przebiegła bezproblemowo, musimy mieć działające środowisko do kompilacji oprogramowania (Linux). Nie wolno także zapomnieć o instalcji odpowiednich bibliotek, libxml2 i libxml2-dev.
W pliku tym przechowywana jest informacja, z których projektów mają być pobierane dane. Autoryzacja odbywa się poprzez podanie adresu email i hasła do projektu lub podania klucza. Można użyć również "słabego" klucza. Przykładowy plik config.xml:
<config> <account_email>TWÓJ_ADRES_EMAIL_DLA_BOINC</account_email> <account_passwd>TWOJE_HASŁO</account_passwd> <projects> <!-- DistributedDataMining Project --> <project> <project_url>http://www.distributeddatamining.org/DistributedDataMining/</project_url> <scheduler_url>http://www.distributeddatamining.org/DistributedDataMining_cgi/cgi</scheduler_url> </project> <!-- World Community Grid --> <project> <account_email>LOGIN_DO_WCG</account_email> <project_url>http://www.worldcommunitygrid.org/</project_url> </project> <!-- Collatz Conjecture --> <project> <project_url>http://boinc.thesonntags.com/collatz/</project_url> <!-- Alternatywne dane logowania <account_email>TWÓJ_ADRES_EMAIL_DLA_BOINC</account_email> <account_passwd>TWOJE_HASŁO</account_passwd> --> </project> <!-- POEM@home --> <project> <project_url>http://boinc.fzk.de/poem/</project_url> <!-- Można podać swój klucz dostępu do projektu/konta bezpośrednio, może to być także "słaby" klucz <account_key>????????????????????????????????</account_key> --> </project> <!-- PS3GRID --> <project> <project_url>http://www.ps3grid.net/</project_url> </project> <!-- MilkyWay@home --> <project> <project_url>http://milkyway.cs.rpi.edu/milkyway/</project_url> </project> <!-- SETI@Home --> <project> <project_url>http://setiathome.berkeley.edu/</project_url> </project> </projects> </config>
Plik konfiguracyjny należy dostosować do własnych potrzeb, analogicznie jak podano wyżej.
DistributedDataMining Project - należy koniecznie podać adres schedulera. Nie można go, jakimś dziwnym trafem, wyciągnąć ze strony głównej projektu. Pomimo tego, że standardowy klient BOINC robi to bez problemu :)
World Community Grid - należy podać swój login a nie adres email.
Skrypt pobierający dane bezpośrednio z schedulera wybranego projektu. Odczytuje on konfigurację z pliku config.xml. Generuje plik stats.xml z zebranymi danymi.
Skrypt, bez przeróbek, działa także pod systemami Windows. Należy jedynie zainstalować ActivePerl.
Wywołanie:
# ./get-stats.pl -c ŚCIEŻKA_DO_PLIKU_KONFIGURACYJNEGO/config.xml -o ŚCIEŻKA_DO_PLIKU_STATYSTYK/stats.xml
W przypadku wywołania bez podawania parametrów, skrypt domyślnie spróbuje otworzyć plik config.xml w bierzącym katalogu, podobnie z plikiem stats.xml, który zostanie utworzony w bierzącym katalogu
Aby zapewnić stały dopływ danych z schedulerów, należy co jakiś czas uruchamiać plik get-stats.pl z odpowiednimi parametrami. W tym celu należy dopisać linijkę do pliku konfiguracyjnego crond
Uruchamiamy w linii poleceń:
# crontab -e
Teraz po otwarciu domyślnego edytora, dodajemy linijkę:
*/15 * * * * PEŁNA_ŚCIEŻKA/get-stats.pl -c PEŁNA_ŚCIEŻKA/config.xml -o PEŁNA_ŚCIEŻKA/stats.xml
Wpis ten uruchamia skrytp pobierający dane co 15 minut. Zamiast PEŁNA_ŚCIEŻKA, należy podać wpisy odpowiednie dla swojej konfiguracji.
Przykładowy plik stats.xml
<stats> <host_cpid>?????????????????????????????????</host_cpid> <projects> <project> <project_name>Collatz Conjecture</project_name> <project_url>http://boinc.thesonntags.com/collatz/</project_url> <user_total_credit>1168738.915939</user_total_credit> <user_expavg_credit>388.189664</user_expavg_credit> <user_diff_credit>0</user_diff_credit> <last_update>1280161212</last_update> <hostid>??????</hostid> <request_delay>303</request_delay> </project> <project> <project_name>Cosmology@Home</project_name> <project_url>http://www.cosmologyathome.org/</project_url> <user_total_credit>118790</user_total_credit> <user_expavg_credit>348.566062</user_expavg_credit> <user_diff_credit>0</user_diff_credit> <last_update>1280161217</last_update> <hostid>??????</hostid> <request_delay>31</request_delay> </project> </projects> </stats>
Nie ma potrzeby własnoręcznego edytowania pliku stats.xml, chyba że się wie, co się robi.
W systemach Windows, możemy użyć odpowiednika Cron. Zaletą tego programiku, jest możliwość uruchomienia go jako usługi.
W tym momencie, można zakończyć czytanie, jeśli ktoś potrzebuje jedynie wyciągania danych z schedulera. Dane są łatwo dostępne w postaci pliku XML, który można parsować dowolnym oprogramowaniem.
Skrypt aktualizuje pliki rrd w podanym katalogu, na podstawie danych zgromadzonych w pliku stats.xml. Automatycznie tworzy brakujące pliki rrd, dla nowo dodanych projektów.
Każdy z plików rrd ma bardzo prostą strukturę:
--step=3600 DS:total:GAUGE:86400:0:U DS:expavg:GAUGE:86400:0:U DS:avgrac:COUNTER:86400:0:U RRA:LAST:0.5:1:20000
W przypadku opracowania własnej metody aktualizacji plików rrd, należy pamiętać, że dane dla typu COUNTER, muszą być liczbami całkowitymi.
Wywołanie:
# ./update-rrd.pl -i ŚCIEŻKA_DO_PLIKU_STATYSTYK/stats.xml -o ŚCIEŻKA_DO_KATALOGU_Z_PLIKAMI_RRD
Aby na bieżąco aktualizować pliki rrd, należy regularnie uruchamiać plik update-rrd.pl. W tym celu dopiszemy kolejną linijkę do pliku konfiguracyjnego dla crond
Uruchamiamy w linii poleceń:
# crontab -e
Teraz po otwarciu domyślnego edytora, dodajemy linijkę:
1 */1 * * * PEŁNA_ŚCIEŻKA/update-rrd.pl -i PEŁNA_ŚCIEŻKA/stats.xml -o PEŁNA_ŚCIEŻKA/
Wpis ten uruchamia skrypt aktualizujący pliki rrd, minutę po każdej pełnej godzinie. Zamiast PEŁNA_ŚCIEŻKA, należy podać wpisy odpowiednie dla swojej konfiguracji.
Generowane pliki rrd, przechowują dane z ostatnich 833 dni, z rozdzielczością 1h.
Bez problemu mozna zwiekszyć tą rozdzielczość, jednakże schedulery niektórych projektów mają ustawione ograniczecie na częstość zapytań. Objawia się to komunikatem last request too recent.
Przedstawione poniżej przykłady dotyczą wersji 1.2.26. Nowsze wersje, oferują większe możliwości konfigurowania elementów wykresu.
Wykres przedstawia nam zmiany całkowitej ilości kredytów w danym projekcie.
#!/usr/bin/perl -w use strict; use lib qw( /usr/local/rrdtool-1.2.26/lib/perl ); use RRDs; RRDs::graph "./example1.png", "--title=user_total_credit", "--start=-180d", "--lower-limit=0", "DEF:user_total_credit=www.primegrid.com.rrd:total:LAST", "AREA:user_total_credit#0066FF:Total", "GPRINT:user_total_credit:LAST:%lf%s\\n"; if ( my $err = RRDs::error ) { print $err } exit;
Wywołanie:
# ./example1.pl
W tym samym katalogu co plik example1.pl, musi znajdować się plik www.primegrid.com.rrd.
Wykres przedstawia nam zmiany RAC dla danego projektu.
#!/usr/bin/perl -w use strict; use lib qw( /usr/local/rrdtool-1.2.26/lib/perl ); use RRDs; RRDs::graph "./example2.png", "--title=user_expavg_credit", "--start=-90d", "--lower-limit=0", "DEF:user_expavg_credit=www.primegrid.com.rrd:expavg:LAST", "LINE1:user_expavg_credit#0000FF:Current", "GPRINT:user_expavg_credit:LAST:%lf%s\\n"; if ( my $err = RRDs::error ) { print $err } exit;
Wywołanie:
# ./example2.pl
W tym samym katalogu co plik example2.pl, musi znajdować się plik www.primegrid.com.rrd.
Wykres przedstawia nam przyrosty w ilości kredytów z rozdzielczością 1h dla danego projektu.
#!/usr/bin/perl -w use strict; use lib qw( /usr/local/rrdtool-1.2.26/lib/perl ); use RRDs; RRDs::graph "./example3.png", "--title=user_avgrac_credit", "--start=-5d", "DEF:user_avgrac_credit=www.primegrid.com.rrd:avgrac:LAST", #mnożymy wartości przez 3600 aby uzyskać przyrosty "na godzinę" a nie domyślne "na sekundę" "CDEF:user_avgrac_credit2=user_avgrac_credit,3600,*", "AREA:user_avgrac_credit2#0066FF:Last", "GPRINT:user_avgrac_credit2:LAST:%lf%s\\n"; if ( my $err = RRDs::error ) { print $err } exit;
Wywołanie:
# ./example3.pl
W tym samym katalogu co plik example3.pl, musi znajdować się plik www.primegrid.com.rrd.
Analogicznie do przykładu 1. ale tym razem na wykresie umieszczamy dane z dwóch projektów.
#!/usr/bin/perl -w use strict; use lib qw( /usr/local/rrdtool-1.2.26/lib/perl ); use RRDs; RRDs::graph "./example4.png", "--title=user_total_credit", "--start=-720d", "--lower-limit=0", "DEF:user_total0=www.primegrid.com.rrd:total:LAST", "DEF:user_total1=milkyway.cs.rpi.edu_milkyway.rrd:total:LAST", "AREA:user_total0#0066FF:PrimeGrid:STACK", "GPRINT:user_total0:LAST:%.2lf%s\\n", "AREA:user_total1#FF0000:MilkyWay\@home:STACK", "GPRINT:user_total1:LAST:%.2lf%s\\n"; if ( my $err = RRDs::error ) { print $err } exit;
# ./example4.pl
W tym samym katalogu co plik example4.pl, muszą znajdować się pliki www.primegrid.com.rrd oraz milkyway.cs.rpi.edu_milkyway.rrd.
Analogicznie do przykładu 2. ale tym razem na wykresie umieszczamy dane z dwóch projektów.
#!/usr/bin/perl -w use strict; use lib qw( /usr/local/rrdtool-1.2.26/lib/perl ); use RRDs; RRDs::graph "./example5.png", "--title=user_expavg_credit", "--start=-30d", "--lower-limit=0", "DEF:user_expavg0=szdg.lpds.sztaki.hu_szdg.rrd:expavg:LAST", "DEF:user_expavg1=www.primegrid.com.rrd:expavg:LAST", "LINE1:user_expavg0#FF0000:SZTAKI", "GPRINT:user_expavg0:LAST:%lf\\n", "LINE1:user_expavg1#FF00FF:PrimeGrid", "GPRINT:user_expavg1:LAST:%lf\\n"; if ( my $err = RRDs::error ) { print $err } exit;
Wywołanie:
# ./example5.pl
W tym samym katalogu co plik example5.pl, muszą znajdować się pliki www.primegrid.com.rrd oraz szdg.lpds.sztaki.hu_szdg.rrd.
Na tym przykładzie pokażę, jak przedstawić w legendzie wykresu, sumę ilości kredytów z dwóch projektów.
#!/usr/bin/perl -w use strict; use lib qw( /usr/local/rrdtool-1.2.26/lib/perl ); use RRDs; RRDs::graph "./example6.png", "--title=user_total_credit", "--start=-720d", "--width=720", "--lower-limit=0", "DEF:user_total0=www.primegrid.com.rrd:total:LAST", "DEF:user_total1=milkyway.cs.rpi.edu_milkyway.rrd:total:LAST", "AREA:user_total0#0066FF:PrimeGrid:STACK", "AREA:user_total1#FF0000:MilkyWay\@home:STACK", "CDEF:total=user_total0,user_total1,+",# tutaj liczymy sumę dwóch parametrów "GPRINT:total:LAST:TOTAL %.2lf";# a tutaj umieszczamy na wykresie if ( my $err = RRDs::error ) { print $err } exit;
Wywołanie:
# ./example6.pl
W tym samym katalogu co plik example6.pl, muszą znajdować się pliki www.primegrid.com.rrd oraz milkyway.cs.rpi.edu_milkyway.rrd.
Wszelkie operacje matematyczne w RRDTool, wykonywane są w polskiej notacji odwrotnej.
#!/usr/bin/perl -w use strict; use lib qw( /usr/local/rrdtool-1.2.26/lib/perl ); use RRDs; RRDs::graph "./example7.png", "--title=user_total_credit", "--start=-180d", "--lower-limit=0", "--color=BACK#7fff00", "--color=CANVAS#7f00ff", "--color=AXIS#ff007f", "--color=FONT#ff7f00", "--color=MGRID#ffff00", "--color=GRID#ff007f", "--color=SHADEA#007fff", "--color=SHADEB#00ffff", "--color=ARROW#ff0000", "DEF:user_total_credit=www.primegrid.com.rrd:total:LAST", "AREA:user_total_credit#000000:Total", "GPRINT:user_total_credit:LAST:%lf%s\\n"; if ( my $err = RRDs::error ) { print $err } exit;
Wywołanie:
# ./example7.pl
W tym samym katalogu co plik example7.pl, musi znajdować się plik www.primegrid.com.rrd.
Kolory samych danych, można łatwo zidentyfkować, analizując powyższe przykłady. Poniżej, definiowanie koloru dla tła, czcionek, siatki itd.
"--color=BACK#7fff00" #kolor tła całego wykresu "--color=CANVAS#7f00ff" #kolor tła wykresu danych "--color=AXIS#ff007f" #kolor osi x i y "--color=FONT#ff7f00" #kolor czcionek "--color=MGRID#ffff00" #kolor głównych podziałek na wykresie "--color=GRID#ff007f" #kolor pomocniczych podziałek na wykresie "--color=SHADEA#007fff" #kolor dla ramki lewej i górnej "--color=SHADEB#00ffff" #kolor dla ramki prawej i dolnej "--color=ARROW#ff0000" #kolor strzałki na wykresie
Każdemu kolorowi można przypisać także przeźroczystość. Na przykład: --color=FONT#FF0000 jest równoważny zapisowi --color=FONT#FF0000FF. Należy zwrócić uwagę na wartość na samym końcu definiowania koloru. Przeźroczystość ustawiona na 50%: --color=FONT#FF000080
fisher_yates_shuffle() przestawia w sposób losowy elementy tablicy podanej jako parametr.
sub fisher_yates_shuffle { my $array = shift; my $i; for ($i = @$array; --$i; ) { my $j = int rand ($i+1); next if $i == $j; @$array[$i,$j] = @$array[$j,$i]; } } # przykład my @array = (1,4,7,34,2); fisher_yates_shuffle(\@array); # przykładowa zawartość tablicy po wywołaniu funkcji # # (4,34,7,2,1) #
hsv2rgb() zmienia nam reprezentację barw w HSV na RGB. Bardzo ułatwia to uzyskanie efektu "spectrum".
# parametry wywołania funkcji # $h - barwa, zakres 0..359 # $s - nasycenie, zakres 0..1 # $v - natężenie, zakres 0..1 sub hsv2rgb { my ($h,$s,$v) = @_; my $hi = int($h/60) % 6; my $f = $h/60 - int($h/60); my $p = $v * (1 - $s); my $q = $v * (1 - $f * $s); my $t = $v * (1 - (1 - $f) * $s); for ($v,$t,$p,$q) { $_ *= 255; $_ = $_ > 255 ? 255 : $_; $_ = sprintf "%02x",int $_; } return "$v$t$p" if $hi == 0; return "$q$v$p" if $hi == 1; return "$p$v$t" if $hi == 2; return "$p$q$v" if $hi == 3; return "$t$p$v" if $hi == 4; return "$v$p$q" if $hi == 5; } # przykłady print hsv2rgb(0,1,1); # wynik ff0000 # czyli kolor czerwony print hsv2rgb(120,0.5,1); # wynik 8cff8c # czyli wypłowiały zielony :) print hsv2rgb(240,1,0.5); # wynik 00008c # czyli ciemno-niebieski
@2019-03-29T13:06:52+00:00