<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>guzik &#187; Programowanie</title>
	<atom:link href="http://guzik.net.pl/blog/category/tech/programowanie/feed/" rel="self" type="application/rss+xml" />
	<link>http://guzik.net.pl/blog</link>
	<description>Mój blog</description>
	<lastBuildDate>Wed, 16 May 2012 20:15:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>PHP i transakcje w MySQL</title>
		<link>http://guzik.net.pl/blog/2012/05/php-i-transakcje-w-mysql/</link>
		<comments>http://guzik.net.pl/blog/2012/05/php-i-transakcje-w-mysql/#comments</comments>
		<pubDate>Wed, 16 May 2012 20:15:38 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PDO]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=3832</guid>
		<description><![CDATA[Nie jestem programistą, ani Programistą PHP. Czasem robię code review lub piszę protezę dla jakichś systemów. Po ostatnim przeglądzie uważam, że warto wspomnieć o prostych sposobach na transakcje w (My)SQL. Jeśli mamy do dyspozycji PDO (PHP Data Objects) i PHP >= 5.1 (ew. 5.0 i PDO jako PECL), to możemy użyć gotowych mechanizmów do obsługi [...]]]></description>
			<content:encoded><![CDATA[<p>Nie jestem programistą, ani Programistą PHP. Czasem robię <em>code review</em> lub piszę protezę dla jakichś systemów.<br />
Po ostatnim przeglądzie uważam, że warto wspomnieć o prostych sposobach na transakcje w (My)SQL.</p>
<p>Jeśli mamy do dyspozycji <a href="http://www.php.net/manual/en/book.pdo.php">PDO (PHP Data Objects)</a> i PHP >= 5.1 (ew. 5.0 i PDO jako PECL), to możemy użyć gotowych mechanizmów do obsługi transakcji i <a href="http://php.net/manual/en/language.exceptions.php">wyjątków</a> (od PHP 5.0):</p>
<blockquote><p><code>try {<br />
&nbsp;&nbsp;$dbh-><a href="http://php.net/manual/en/pdo.begintransaction.php">beginTransaction</a>();<br />
&nbsp;&nbsp;$dbh-><a href="http://www.php.net/manual/en/pdo.exec.php">exec</a>('pierwsze zapytanie');<br />
&nbsp;&nbsp;$dbh->exec('drugie zapytanie');<br />
&nbsp;&nbsp;$dbh->exec('trzecie zapytanie');<br />
&nbsp;&nbsp;$dbh-><a href="http://www.php.net/manual/en/pdo.commit.php">commit</a>();<br />
} catch (<a href="http://www.php.net/manual/en/class.exception.php">Exception</a> $e) {<br />
&nbsp;&nbsp;$dbh-><a href="http://www.php.net/manual/en/pdo.rollback.php">rollBack</a>();<br />
&nbsp;&nbsp;echo $e-><a href="http://www.php.net/manual/en/exception.getmessage.php">getMessage</a>();<br />
}</code></p></blockquote>
<p><span id="more-3832"></span>Jeśli wystąpi jakikolwiek wyjątek, blok <code>try{}</code> jest przerywany i wykonuje się <code>catch{}</code>. Na końcu tego pierwszego mamy <code>commit()</code>, w przypadku wystąpienia błędu &#8211; wywołany zostanie <code>rollback()</code>.<br />
<code>try{} catch{}</code> znane jest z innych języków i jest przydatne &#8211; warto zapamiętać.</p>
<p>W przypadku, gdy nie używamy PDO, można użyć sztuczki z operatorami logicznymi:</p>
<blockquote><p><code>mysql_query("BEGIN");<br />
$r = mysql_query('pierwsze zapytanie');<br />
$r &#038;= mysql_query('drugie zapytanie');<br />
$r &#038;= mysql_query('trzecie zapytanie');<br />
if ($r)<br />
&nbsp;&nbsp;mysql_query('COMMIT');<br />
else<br />
&nbsp;&nbsp;mysql_query('ROLLBACK');</code></p></blockquote>
<p>Naturalnie brak tu obsługi błędów, bo po <code>else</code> <code>mysql_error()</code> zwróci nam to, co nastąpiło po ostatnim <code>mysql_query</code>, ale czasami i to wystarcza.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2012/05/php-i-transakcje-w-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gnatt &amp; dbms_scheduler</title>
		<link>http://guzik.net.pl/blog/2012/02/gnatt-dbms_scheduler/</link>
		<comments>http://guzik.net.pl/blog/2012/02/gnatt-dbms_scheduler/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 06:00:08 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[DB]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[dbms_scheduler]]></category>
		<category><![CDATA[Gnatt]]></category>
		<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=3737</guid>
		<description><![CDATA[Było zastosowanie Gnatt do kopii Oracle, to teraz do zadań harmonogramu Oracle (przez dbms_scheduler): set colsep ';' set head off; set feed off; set trimspool on; set linesize 32767; set pagesize 32767; set echo off; set termout off; set timing off; spool sched.csv SELECT 'Week ' &#124;&#124; TO_CHAR(SYSDATE-7, 'iw'), NEXT_DAY(trunc(SYSDATE)-14, 'MONDAY'), NEXT_DAY(trunc(SYSDATE)-7-1/60/60/24, 'SUNDAY') FROM dual; [...]]]></description>
			<content:encoded><![CDATA[<p>Było zastosowanie <a href="http://guzik.net.pl/blog/2012/02/gnatt-rman/">Gnatt do kopii Oracle</a>, to teraz do zadań harmonogramu Oracle (przez dbms_scheduler):</p>
<blockquote><p><code>set colsep ';'<br />
set head off;<br />
set feed off;<br />
set trimspool on;<br />
set linesize 32767;<br />
set pagesize 32767;<br />
set echo off;<br />
set termout off;<br />
set timing off;</p>
<p>spool sched.csv</p>
<p>SELECT 'Week ' || TO_CHAR(SYSDATE-7, 'iw'), NEXT_DAY(trunc(SYSDATE)-14, 'MONDAY'), NEXT_DAY(trunc(SYSDATE)-7-1/60/60/24, 'SUNDAY') FROM dual;<br />
<span id="more-3737"></span><br />
SELECT OWNER || '.' || JOB_NAME AS job, to_char(ACTUAL_START_DATE, 'YYYY-MM-DD HH24:MI:SS') as start_date, to_char(LOG_DATE, 'YYYY-MM-DD HH24:MI:SS') as end_date<br />
  FROM DBA_SCHEDULER_JOB_RUN_DETAILS<br />
 WHERE OWNER NOT IN ('EXFSYS', 'SYS')<br />
   AND TO_CHAR(LOG_DATE, 'iw') >= TO_CHAR(SYSDATE-7, 'iw')<br />
   AND TO_CHAR(ACTUAL_START_DATE, 'iw') < TO_CHAR(SYSDATE, 'iw')<br />
ORDER BY 1, 2, 3;</p>
<p>exit</code></p></blockquote>
<p>Podobnie jak poprzednio w wyniku otrzymamy plik sched.csv z zadaniami z minionego tygodnia, który ręcznie wczytujemy do Gnatt (ciągle brak przetwarzania wsadowego).<br />
Wywołanie:</p>
<blockquote><p><code>sqlplus -S '/ as sysdba' @sched.sql</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2012/02/gnatt-dbms_scheduler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bugzilla &amp; Lighttpd @ Gentoo</title>
		<link>http://guzik.net.pl/blog/2012/02/bugzilla-lighttpd-gentoo/</link>
		<comments>http://guzik.net.pl/blog/2012/02/bugzilla-lighttpd-gentoo/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 17:00:16 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=3721</guid>
		<description><![CDATA[W maju zeszłego roku opisałem próbę uruchomienia Icinga na Lighttpd pod Gentoo. Wróciłem jednakże po testach do Nagios i nie interesowałem się tym więcej. Gdyby ktoś chciał popróbować, to pod koniec zeszłego roku Icinga pojawiła się w drzewie portage. Dziś przymierzyłem się do Bugzilla na Lighttpd pod Gentoo. Jako, że Mozilla nie wspiera Bugzilla na [...]]]></description>
			<content:encoded><![CDATA[<p>W maju zeszłego roku opisałem próbę uruchomienia <a href="http://guzik.net.pl/blog/2011/05/icinga-i-lighttpd-lub-inny-apache-pod-gentoolinux/">Icinga na Lighttpd pod Gentoo</a>. Wróciłem jednakże po testach do Nagios i nie interesowałem się tym więcej. Gdyby ktoś chciał popróbować, to pod koniec zeszłego roku Icinga pojawiła się w <a href="http://packages.gentoo.org/package/net-analyzer/icinga">drzewie portage</a>.</p>
<p>Dziś przymierzyłem się do <a href="http://www.bugzilla.org/">Bugzilla</a> na Lighttpd pod Gentoo. Jako, że Mozilla nie wspiera Bugzilla na innym serwerze jak Apache, tak samo <em>ebuild</em> w Gentoo nie jest do tego przystosowany. Ale da się to zrobić. Poniżej moje zapiski z placu boju.<span id="more-3721"></span></p>
<p>1. Na początek instalacja:</p>
<blockquote><p><code>USE="-modperl" emerge bugzilla</code></p></blockquote>
<p>Flaga <code>modperl</code> jest dla Apache, więc nas nie interesuje.<br />
Domyślnie wybrana jest baza MySQL (flaga <code>mysql</code>), ale możemy zmienić na PostgreSQL (flaga <code>postgres</code>). Być może uda się również z Oracle, bo Bugzilla wspiera tą bazę przez <code>DBD-Oracle</code>, ale osobiście nie testowałem (choć mam <code><a href="http://guzik.net.pl/blog/2008/12/dbdoracle-problem-z-kompilacja/">DBD-Oracle</a></code>).<br />
Instalacja prawdopodobnie zakończy się powodzeniem, ale <code>webapp-config</code> już nie. Żąda Apache. Trzeba wywołać go ręcznie podając jako typ serwera <code>lighttpd</code>:</p>
<blockquote><p><code>/usr/sbin/webapp-config -I -s lighttpd -h localhost -u root -d /bugzilla bugzilla 3.6.8</code></p></blockquote>
<p>2. Dodatki:</p>
<blockquote><p><code>emerge dev-perl/GD dev-perl/GDTextUtil dev-perl/GDGraph dev-perl/MIME-tools dev-perl/libwww-perl dev-perl/Authen-SASL dev-perl/SOAP-Lite dev-perl/HTML-Parser dev-perl/Chart dev-perl/Template-GD dev-perl/XML-Twig dev-perl/PatchReader dev-perl/JSON-RPC dev-perl/Test-Taint dev-perl/HTML-Scrubber dev-perl/Email-MIME-Attachment-Stripper dev-perl/Email-Reply dev-perl/TheSchwartz dev-perl/Daemon-Generic dev-perl/Math-Random-Secure perl-ldap</code></p></blockquote>
<p>Nie wszystkie są potrzebne &#8211; zależy od konfiguracji, być może niektóre już są.<br />
<code>Authen::Radius</code> nie ma w Gentoo, więc (jeśli potrzebne) trzeba zainstalować dodatkowo poprzez:</p>
<blockquote><p><code>/usr/bin/perl install-module.pl Authen::Radius</code></p></blockquote>
<p>3. Przechodzimy do konfiguracji. Edytujemy plik <code>localconfig</code> i zmieniamy grupę z prawami której działa serwer WWW (<code>$webservergroup = 'lighttpd';</code>). Oczywiście resztę danych też powinnismy ustawić na tym etapie (np. dane do bazy).</p>
<p>4. Tworzymy brakujący katalog</p>
<blockquote><p><code>mkdir /var/www/localhost/htdocs/bugzilla/lib</code></p></blockquote>
<p>5. A następnie finalizujemy instalację:</p>
<blockquote><p><code>/var/www/localhost/htdocs/bugzilla/checksetup.pl</code></p></blockquote>
<p>6. Jeszcze tylko konfiguracja serwera WWW i gotowe. Tworzymy nowy plik, np. <code>/etc/lighttpd/bugzilla.conf</code> (opcjonalnie poniższe wstawiamy w <code>lighttpd.conf</code>) z następującą zawartością:</p>
<blockquote><p><code>server.modules += ("mod_cgi")<br />
server.modules += ("mod_access")</p>
<p>$HTTP["url"] =~ "^/bugzilla/.*" {<br />
        dir-listing.activate = "disable"<br />
        cgi.assign = (".cgi" => "")<br />
        index-file.names   = ("index.cgi")<br />
        url.access-deny = ("localconfig", "data/params")<br />
}</code></p></blockquote>
<p>Plik ten trzeba dodać do globalnej konfiguracji Lighttpd:</p>
<blockquote><p><code>include "bugzilla.conf"</code></p></blockquote>
<p>7. Restart serwera WWW i działa!</p>
<p>Nie udostępniam Bugzilla, więc poprawki do powyższego tekstu możecie zgłaszać w komentarzach.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2012/02/bugzilla-lighttpd-gentoo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gnatt &#8211; jest dobrze</title>
		<link>http://guzik.net.pl/blog/2012/02/gnatt-jest-dobrze/</link>
		<comments>http://guzik.net.pl/blog/2012/02/gnatt-jest-dobrze/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 21:59:01 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Gnatt]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=3708</guid>
		<description><![CDATA[Chyba nie taki kiepski ze mnie programista ;-) Gnatt doczekał się wersji 1.0.0.4 (opublikowanej). Zacząłem robić nawet listę zmian. Z najwazniejszych rzeczy: dodana zmiana &#8216;rozdzielczości&#8217;, konwersja daty (działa Unix timestamp jak wcześniej i sprawdziłem na formacie YYYY-MM-DD hh:mm:ss), grupowanie zadań. Ostatnia wyszczególniona zmiana jest chyba najistotniejsza. Na czym polega grupowanie zadań? Jeśli w pliku pojawi [...]]]></description>
			<content:encoded><![CDATA[<p>Chyba nie taki kiepski ze mnie programista ;-)<br />
Gnatt doczekał się wersji 1.0.0.4 (opublikowanej). Zacząłem robić nawet <a href="http://infowizja.nazwa.pl/projects/Gnatt/ChangeLog.txt">listę zmian</a>. Z najwazniejszych rzeczy:</p>
<ul>
<li>dodana zmiana &#8216;rozdzielczości&#8217;,</li>
<li>konwersja daty (działa Unix timestamp jak wcześniej i sprawdziłem na formacie YYYY-MM-DD hh:mm:ss),</li>
<li>grupowanie zadań.</li>
</ul>
<p><span id="more-3708"></span><br />
Ostatnia wyszczególniona zmiana jest chyba najistotniejsza. Na czym polega grupowanie zadań? Jeśli w pliku pojawi się więcej zadań (w różnych liniach) z tą samą nazwą, zostaną posklejane do jednego wiersza. Kolory mogą mieć różne.<br />
Przy takim przetwarzaniu przygotowanie pliku wejściowego jest łatwiejsze. Przykładowo, jeśli chcemy zobaczyć jak wyglądały kopie Oracle w poprzednim tygodniu wykonane za pomocą RMAN, potrzebny będzie wynik następującego polecenia:</p>
<blockquote><p><code>SELECT OBJECT_TYPE, START_TIME, END_TIME<br />
FROM V$RMAN_STATUS<br />
WHERE OPERATION = 'BACKUP'<br />
AND TO_CHAR(END_TIME, 'iw') &gt;= TO_CHAR(SYSDATE-7, 'iw')<br />
AND TO_CHAR(START_TIME, 'iw') &lt; TO_CHAR(SYSDATE, 'iw')<br />
ORDER BY 1,2</code></p></blockquote>
<p>Oczywiście trzeba jeszcze dokleić nagłówek. Z czasem postaram się zamieszczać gotowce do wklejenia, tymczasem możecie skorzystać z <a href="https://sourceforge.net/projects/orbada/">Orbady</a> (eksportuje do CSV).</p>
<p>I jeszcze jeden przykład &#8211; historia zadań Oracle (dbms_scheduler):</p>
<blockquote><p><code>SELECT OWNER || '.' || JOB_NAME, ACTUAL_START_DATE, LOG_DATE<br />
FROM DBA_SCHEDULER_JOB_RUN_DETAILS<br />
WHERE OWNER NOT IN ('EXFSYS', 'SYS')<br />
AND TO_CHAR(LOG_DATE, 'iw') &gt;= TO_CHAR(SYSDATE-7, 'iw')<br />
AND TO_CHAR(ACTUAL_START_DATE, 'iw') &lt; TO_CHAR(SYSDATE, 'iw')<br />
ORDER BY 1, 2</code></p></blockquote>
<p style="text-align: center;"><a href="http://guzik.net.pl/blog/wp-content/uploads/2012/02/output1.png"><img class="aligncenter  wp-image-3716" title="output" src="http://guzik.net.pl/blog/wp-content/uploads/2012/02/output1-300x10.png" alt="" width="400" height="50" /></a></p>
<p>W ostatniej chwili zauważyłem problem z wydłużaniem obrazka przy grupowaniu &#8211; poprawię to wkrótce.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2012/02/gnatt-jest-dobrze/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gnatt &#8211; czary z mleka</title>
		<link>http://guzik.net.pl/blog/2012/02/gnatt-czary-z-mleka/</link>
		<comments>http://guzik.net.pl/blog/2012/02/gnatt-czary-z-mleka/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 23:44:34 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[diagram Gantta]]></category>
		<category><![CDATA[Gantt]]></category>
		<category><![CDATA[Gnatt]]></category>
		<category><![CDATA[Visual C++]]></category>
		<category><![CDATA[wykres Gantta]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=3693</guid>
		<description><![CDATA[Odkąd pamiętam, przygotowując jakieś raporty, zawsze borykałem się z problemem wizualizacji wzajemnego oddziaływania trwających procesów, np. wpływ odbudowy grupy RAID na czas trwania kopii danych. Wiadomo, że przedstawienie danych tekstowych na wiele się nie zdaje, zwłaszcza jak trwających zadań jest wiele i powtarzają się w raportowanych okresie. Dobrym wyborem jest przedstawienie czasu trwania zadań na [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://guzik.net.pl/blog/wp-content/uploads/2012/02/output.png"><img src="http://guzik.net.pl/blog/wp-content/uploads/2012/02/output-150x80.png" alt="" title="output" width="150" height="80" class="alignright size-thumbnail wp-image-3694" /></a>Odkąd pamiętam, przygotowując jakieś raporty, zawsze borykałem się z problemem wizualizacji wzajemnego oddziaływania trwających procesów, np. wpływ odbudowy grupy RAID na czas trwania kopii danych.<br />
Wiadomo, że przedstawienie danych tekstowych na wiele się nie zdaje, zwłaszcza jak trwających zadań jest wiele i powtarzają się w raportowanych okresie.<br />
Dobrym wyborem jest przedstawienie czasu trwania zadań na diagramie Gantta. <span id="more-3693"></span>Pracowałem z kilkoma programami, ale żaden nie był na tyle wygodny, żebym przy nim pozostał i go mógł polecić do rysowania dowolnego wykresu. Głównie brakowało mi możliwości swobodnego ustawienia rozdzielczości. Ja operuję na minutach, a np. GanttProject na dniach. Chyba w Visio można było ustawić godziny jako jednostki, ale też nie wychodziło to dobrze.</p>
<p>I tak dziś postanowiłem napisać własny program, który naszkicuje wykres na podstawie danych wejściowych. W jakieś 2 godziny miałem działające rozwiązanie, głównie dzięki pomocy mojego potomstwa wchodzącego mi na głowę ;-) Kolejne dwie godziny poświęciłem na kosmetykę i już projekt jest gotowy do udostępnienia.<br />
Co dokładnie robi? Ano, na podstawie dostarczonych danych (plik CSV, format poniżej) generuje grafikę z wykresem. Całość nie wygląda może ładnie (nie ma wstążki :>), ale popracuję jeszcze nad tym.</p>
<p>Plik wsadowy z danymi powinien wyglądać tak (poszczególne pola separowane średnikiem):</p>
<ul>
<li>pierwsza linia: nazwa wykresu (nie używana); początek okresu; koniec okresu,</li>
<li>druga i kolejne linie to zdarzenia: nazwa#kolor (#kolor opcjonalnie &#8211; RRGGBB); początek zadania(; koniec zadania; początek zadania; koniec zadania; &#8230;).</li>
</ul>
<p>Jeśli zadanie wykonywane jest wielokrotnie (np. kopia przyrostowa), to czasy rozpoczęcia i zakończenia wpisujemy w jednej linii. Jeśli zadanie nie skończyło się w danym okresie lub nie podamy czasu zakończenia, odpowiedni słupek będzie dociągnięty do końca wykresu.</p>
<p>Czas podajemy jako liczba sekund od 1 stycznia 1970 r.</p>
<p><a href='http://guzik.net.pl/blog/wp-content/uploads/2012/02/zadania.csv'>Przykładowy plik</a> wygląda tak:</p>
<blockquote><p><code>tydzień 6;1328486400;1329091200<br />
Kopia&nbsp;INCR#505050;1328486000;1328496000;1328608800;1328616000;1328704200;1328736200;1328797800;1328815800<br />
Kopia&nbsp;FULL#505050;1328936400;1329197400<br />
Odbudowa&nbsp;RAID#FF0000;1328704200;1328749200<br />
Formatowanie&nbsp;wolumenu&nbsp;BACKUP;1328949800</code></p></blockquote>
<p>Czego nie ma, ale będzie już po weekendzie:</p>
<ul>
<li>zmiana &#8216;rozdzielczości&#8217;, na której brak narzekałem u innych &#8211; obecnie domyślnie jest 300 sekund (od tego zależy wielkość obrazu),</li>
<li>zmiana parametrów wykresu &#8211; np. wysokość linijek</li>
<li>wybór czcionki,</li>
<li>ramka</li>
<li>swobodny format daty (chyba jest coś do konwersji),</li>
<li>informacje z nagłówka (pierwsza linia) na wykresie,</li>
<li>i wszystko to, o co poprosicie ;-)</li>
</ul>
<p>W najbliższym czasie przygotuję zestawy skryptów do zasilania &#8211; np. zadania RMAN (Oracle), dbms_scheduler (Oracle) czy praca Bacula (<a href="http://guzik.net.pl/blog/2011/06/bweb-i-gentoo/">Bweb</a> przestałem już używać, a rysowałem w nim tylko takie wykresy).<br />
Jeśli macie jakieś pomysły na wykorzystanie, dajcie znać.</p>
<p>I najważniejsze &#8211; <a href="http://infowizja.nazwa.pl/projects/Gnatt/publish.htm">strona projektu</a>. Dwa dni temu poznałem <em>Publish</em> w Visual C#, więc teraz aktualizacje będą lepiej dystrybuowane :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2012/02/gnatt-czary-z-mleka/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>O (Net-)SNMP jeszcze trochę</title>
		<link>http://guzik.net.pl/blog/2011/12/o-net-snmp-jeszcze-troche/</link>
		<comments>http://guzik.net.pl/blog/2011/12/o-net-snmp-jeszcze-troche/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 13:36:38 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[SNMP]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=3560</guid>
		<description><![CDATA[O SNMP pisałem już kilka razy. Tym razem notka o rozszerzeniu możliwości serwera (Net-SNMP) i prezentacji danych we własnych OID&#8217;ach. Najprościej wykonać to można dodając do konfiguracji dyrektywę extend (kiedyś exec lub sh). Składnia wygląda tak: extend [MIBOID] NAME PROG ARGS A na przykładzie: extend .1.3.6.1.4.1.31337 Test /root/scripts/test.sh testarg1 Przy okazji pozdrawiam firmę Union &#038; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://guzik.net.pl/blog/tag/snmp/">O SNMP pisałem już kilka razy</a>. Tym razem notka o rozszerzeniu możliwości serwera (Net-SNMP) i prezentacji danych we własnych OID&#8217;ach.</p>
<p>Najprościej wykonać to można dodając do konfiguracji dyrektywę <code>extend</code> (kiedyś <code>exec</code> lub <code>sh</code>). Składnia wygląda tak:</p>
<blockquote><p><code>extend [MIBOID] NAME PROG ARGS</code></p></blockquote>
<p>A na przykładzie:</p>
<blockquote><p><code>extend .1.3.6.1.4.1.31337 Test /root/scripts/test.sh testarg1</code></p></blockquote>
<p>Przy okazji pozdrawiam firmę Union &#038; Comstar, której PEN (<em>Private Enterprise Number</em>) pożyczyłem :-) <span id="more-3560"></span><br />
Wadą tego rozwiązania jest fakt, że każdy wynik zwracany przez zewnętrzny program (<code>printf</code> czy <code>echo</code>) traktowany jest jak <code>STRING</code>. Gdy chcemy uzyskać <code>INTEGER</code> możemy wprawdzie posłużyć się kodem wyjścia, ale mamy do dyspozycji zakres 0-255. Do pomiaru temperatury w serwerowni czy na procesorze się może przyda, ale do sprawdzenia pamięci wykorzystywanej przez dany proces już niekoniecznie.</p>
<p>Net-SNMP umożliwia nam wykorzystanie Perl&#8217;a &#8211; a konkretnie modułu NetSNMP::agent, do tworzenia własnych wtyczek (chyba dla Python też jest wsparcie).<br />
Jako że kiepski ze mnie programista, a w szczególności programista Perl, postaram się wspierać swój przekaz kodem. I tak stworzenie agenta możemy wykonać następująco:</p>
<blockquote><p><code>use NetSNMP::agent;</p>
<p>my $agent = new NetSNMP::agent();</code></p></blockquote>
<p>Następnie tworzymy funkcję i rejestrujemy ją, by użyć przy wywołaniu konkretnego OID&#8217;a:</p>
<blockquote><p><code>sub callback_function {<br />
&nbsp;&nbsp;my ($handler, $registration_info, $request_info, $requests) = @_;<br />
&nbsp;&nbsp;my $request;<br />
&nbsp;&nbsp;for($request = $requests; $request; $request = $request->next()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;my $oid = $request->getOID();<br />
&nbsp;&nbsp;&nbsp;&nbsp;if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.31337.1.1.0")) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$request->setValue(ASN_INTEGER, hex(substr $valstring, 4, 2)-40);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}</p>
<p>$agent->register("callback function", ".1.3.6.1.4.1.31337.1", \&#038;callback_function);</code></p></blockquote>
<p>Funkcja jest wywoływana z czteroma parametrami: <code>HANDLER</code>, <code>REGISTRATION_INFO</code>, <code>REQUEST_INFO</code>, i <code>REQUESTS</code>. <code>REQUEST_INFO</code> może zawierać dwa tryby &#8211; <code>MODE_GET</code> i <code>MODE_GETNEXT</code>. Oczywiście przy jednokrotnym sprawdzaniu OID&#8217;a (np. przez Cacti) nie ma to znaczenia, ale gdybyśmy chcieli sprawdzić całe drzewo używając np. <code>snmpwalk</code>, to przy <code>MODE_GETNEXT</code> musimy podać adres kolejnego OID&#8217;a, który ma być sprawdzony po bieżącym. W przeciwnym razie <code>snmpwalk</code> skończy odczyt.</p>
<blockquote><p><code>$request->setOID(".1.3.6.1.4.1.31337.1.1.1");</code></p></blockquote>
<p>W odpowiedzi agent może zwrócić jeden spośród dwudziestu typów danych. Ja używam jedynie <code>ASN_INTEGER</code> i <code>ASN_OCTET_STR</code>. Resztę można znaleźć w dokumentacji.</p>
<p>Po stworzeniu modułu dodajemy jego wywołanie do Net-SNMP w pliku <code>snmpd.conf</code>:</p>
<blockquote><p><code>perl do "/root/scripts/test.pl"</code></p></blockquote>
<p>Następnie restartujemy demona i możemy odczytywać nasze dane. Należy pamiętać, że po każdej zmianie wtyczki niezbędne jest ponowne przeładowanie.</p>
<p>Czytaj też:</p>
<ul>
<li><a href="http://www.net-snmp.org/wiki/index.php/Tut:Extending_snmpd_using_perl">Extending snmpd using perl</a></li>
<li><a href="http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sect-System_Monitoring_Tools-Net-SNMP-Extending.html">RedHat Documentation: Extending Net-SNMP</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2011/12/o-net-snmp-jeszcze-troche/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zmiany w libwww-perl</title>
		<link>http://guzik.net.pl/blog/2011/11/zmiany-w-libwww-perl/</link>
		<comments>http://guzik.net.pl/blog/2011/11/zmiany-w-libwww-perl/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 22:03:15 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[libwww-perl]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=3466</guid>
		<description><![CDATA[Jakiś czas temu (dokładnie to 27 marca) z biblioteki libwww-perl wydzielony został moduł LWP::Protocol::https. Jak można przeczytać w dokumentacji od wersji 6.01 biblioteki nie zaszły żadne zmiany w kodzie tego modułu. W zeszłym tygodniu moduł został oznaczony jako stabilny w paczkach dla Gentoo (dev-perl/LWP-Protocol-https). Możliwa się stała jego aktualizacja i tym samym libwww-perl (dev-perl/libwww-perl). No [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu (dokładnie to 27 marca) z biblioteki <a href="http://search.cpan.org/~gaas/libwww-perl-6.03/">libwww-perl</a> wydzielony został moduł <a href="http://search.cpan.org/~gaas/LWP-Protocol-https-6.02/">LWP::Protocol::https</a>. Jak można przeczytać w dokumentacji od wersji 6.01 biblioteki nie zaszły żadne zmiany w kodzie tego modułu.<br />
W zeszłym tygodniu moduł został oznaczony jako stabilny w paczkach dla Gentoo (<a href="http://packages.gentoo.org/package/dev-perl/LWP-Protocol-https">dev-perl/LWP-Protocol-https</a>). Możliwa się stała jego aktualizacja i tym samym libwww-perl (<a href="http://packages.gentoo.org/package/dev-perl/libwww-perl">dev-perl/libwww-perl</a>). No i zaktualizowałem. I jednak coś się zmieniło.</p>
<p>SOAP::Lite, który korzysta z libwww-perl nagle zaczął zgłaszać błąd certyfikatu serwera (tzw. <em>self-signed</em>), z którego wywoływał żądanie:</p>
<blockquote><p><code>500 Can't connect to server:443 (certificate verify failed) at <strong>/usr/lib/nagios/plugins/sms.pl</strong> line 7<br />
</code></p></blockquote>
<p><span id="more-3466"></span><br />
Rozwiązanie problemu jest trywialne, weryfikację certyfikatu można wyłączyć ustawiając odpowiednią zmienną:</p>
<blockquote><p><code>$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;</code></p></blockquote>
<p>lub stosowną opcję (klasa <a href="http://search.cpan.org/~gaas/libwww-perl-6.03/lib/LWP/UserAgent.pm">LWP::UserAgent</a>):</p>
<blockquote><p><code>LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });</code></p></blockquote>
<p>I znów działa jak dawniej.</p>
<p>W wersji 5.837 i wcześniejszych biblioteki libwww-perl sprawdzanie było wyłączone. Ja aktualizowałem z 5.836.</p>
<p>Wnikliwy czytelnik zauważył pewnie nazwę wywoływanego skryptu. Jak można się domyśleć ma on strategiczne znaczenie. Eh&#8230;</p>
<p>Swoją drogą przy okazji zwróciłem uwagę na nazewnictwo, a właściwie numerację paczek w Gentoo. Otóż libwww-perl w wersji 6.03 nazywa się dev-perl/libwww-perl-6.30.0, z kolei moduł LWP::Protocol::https 6.02 to dev-perl/LWP-Protocol-https-6.20.0. Ktoś potrafi to wyjaśnić? W ebuild&#8217;zie w zmiennej <code>MODULE_VERSION</code> jest właściwa wersja.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2011/11/zmiany-w-libwww-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dzień Programisty</title>
		<link>http://guzik.net.pl/blog/2011/09/dzien-programisty/</link>
		<comments>http://guzik.net.pl/blog/2011/09/dzien-programisty/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 00:56:46 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[Programowanie]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=2150</guid>
		<description><![CDATA[W zeszłym roku chciałem coś napisać z okazji Dnia Programisty, ale skończyłem na tych dwóch odnośnikach (poniżej). W zasadzie nie opublikowałem tego, bo jakoś nie było czasu, ale zaśmieca mi Kokpit w WordPress (leży tez wpis z wakacji &#8217;08), więc puszczę jak jest. W sumie to chyba aktualne i dziś. Maciej Zbrzezny: Jak uczyć się [...]]]></description>
			<content:encoded><![CDATA[<p>W zeszłym roku chciałem coś napisać z okazji Dnia Programisty, ale skończyłem na tych dwóch odnośnikach (poniżej). W zasadzie nie opublikowałem tego, bo jakoś nie było czasu, ale zaśmieca mi Kokpit w WordPress (leży tez wpis z wakacji &#8217;08), więc puszczę jak jest. W sumie to chyba aktualne i dziś.</p>
<ul>
<li><a href="http://maciej-progtech.blogspot.com/2010/04/jak-uczyc-sie-c-pl.html">Maciej Zbrzezny: Jak uczyć się C#? [PL]</a></li>
<li><a rel="bookmark" href="http://blog.matthew.org.pl/2010/02/10/jakiego-jezyka-programowania-sie-nauczyc/">Matthew: Jakiego języka programowania się nauczyć?</a></li>
</ul>
<p>Jeśli ktoś pyta skąd i po co, to odpowiedź poniżej (na nic bardziej kreatywnego mnie teraz nie stać):</p>
<blockquote><p><code>mysql> SELECT DAYOFYEAR(CURDATE());<br />
+----------------------+<br />
| DAYOFYEAR(CURDATE()) |<br />
+----------------------+<br />
|                  256 |<br />
+----------------------+<br />
1 row in set (0.09 sec)</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2011/09/dzien-programisty/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dodanie czasu w GPS Track</title>
		<link>http://guzik.net.pl/blog/2011/08/dodanie-czasu-w-gps-track/</link>
		<comments>http://guzik.net.pl/blog/2011/08/dodanie-czasu-w-gps-track/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 23:07:50 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[GPS Track]]></category>
		<category><![CDATA[Visual C++]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=3173</guid>
		<description><![CDATA[W czerwcu w trakcie testowania aplikacji do śledzenia tras (via GPS) wspominałem o programie GPS Track. Aplikacja jest wystarczająca do zapisu samej ścieżki, ale niestety nie zapisuje znaczników czasu dla każdego punktu, więc jest bezużyteczna w przypadku korzystania z serwisu Endomondo (nie sprawdzałem jak zachowuje się Sports Tracker). Nie zapisuje też wysokości, tym samym tracimy [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.qcontinuum.org/gpstrack/"><img alt="" src="http://www.qcontinuum.org/gpstrack/gpstrack.gif" class="alignright" width="240" height="246" /></a>W czerwcu w trakcie testowania aplikacji do śledzenia tras (via GPS) wspominałem o programie <a href="http://www.qcontinuum.org/gpstrack/">GPS Track</a>. Aplikacja jest wystarczająca do zapisu samej ścieżki, ale niestety nie zapisuje znaczników czasu dla każdego punktu, więc jest bezużyteczna w przypadku korzystania z serwisu <a href="http://www.endomondo.com/">Endomondo</a> (nie sprawdzałem jak zachowuje się <a href="http://www.sports-tracker.com/">Sports Tracker</a>). Nie zapisuje też wysokości, tym samym tracimy rozszerzone informacje o treningu (Endomondo czy Google Earth sam sobie tego nie &#8216;dopisuje&#8217;).<span id="more-3173"></span></p>
<p>Możemy jednakże dodać odpowiednie atrybuty samemu i dostosować plik do wymagań Endomondo. Ja zrobiłem to tak:<br />
[csharp]OpenFileDialog fDialog = new OpenFileDialog();<br />
fDialog.Title = &#8222;Open GPX 1.0 File&#8221;;<br />
fDialog.Filter = &#8222;GPX Files|*.gpx&#8221;;<br />
if (fDialog.ShowDialog() == DialogResult.OK) {<br />
    Chilkat.Xml xml = new Chilkat.Xml();<br />
    xml.LoadXmlFile(fDialog.FileName.ToString());<br />
    Chilkat.Xml root = xml.FirstChild();<br />
    Chilkat.Xml seg = root.FindChild(&#8222;trkseg&#8221;);<br />
    Chilkat.Xml pt = seg.FirstChild();<br />
    DateTime pttime = DateTime.Parse(root.GetChildContent(&#8222;name&#8221;));<br />
    string oPath = Path.GetDirectoryName(fDialog.FileName) + &#8222;\\&#8221; + pttime.ToString(&#8222;yyyyMMdd-HHmmss&#8221;) + &#8222;.gpx&#8221;;<br />
    while (pt != null) {<br />
        pt.NewChild(&#8222;time&#8221;, pttime.ToString(&#8222;s&#8221;));<br />
        pttime = pttime.AddSeconds(2);<br />
//      listBox1.Items.Add(pt.GetAttrValue(&#8222;lat&#8221;));<br />
//      listBox1.Items.Add(pttime.ToString(&#8222;s&#8221;));<br />
        pt = pt.NextSibling();<br />
    }<br />
    xml.SaveXml(oPath);<br />
}<br />
[/csharp]<br />
Słowem komentarza:</p>
<ul>
<li>kompilowane w <a href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-csharp-express">Visual C# 2010</a> + <a href="http://chilkatsoft.com/xml-dotnet.asp">Chilkat XML .NET</a>,</li>
<li>czas w formacie <a href="http://pl.wikipedia.org/wiki/ISO_8601">ISO 8601</a> czy jak kto woli &#8211; <a href="http://msdn.microsoft.com/en-us/library/az4se3k1%28v=VS.100%29.aspx#Sortable"><em>sortable</em></a> (linia 12 i 15),</li>
<li>GPS Track po eksporcie ścieżki do GPX zapisuje w <code>name</code> czas początku rejestracji, więc można go pobrać do pierwszego punktu (linia 10), a następnie dodawać przesunięcie ustawione w programie (linia 13) &#8211; w moim przypadku 2 sekundy (tego nie ma w XML, więc trzeba to wiedzieć/sprawdzić ustawienie).</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2011/08/dodanie-czasu-w-gps-track/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPExcel</title>
		<link>http://guzik.net.pl/blog/2011/03/phpexcel/</link>
		<comments>http://guzik.net.pl/blog/2011/03/phpexcel/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 18:56:01 +0000</pubDate>
		<dc:creator>guzik</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHPExcel]]></category>

		<guid isPermaLink="false">http://guzik.net.pl/blog/?p=2769</guid>
		<description><![CDATA[Czasem spadają na mnie jakieś drobne projekty, którymi wcale nie chcę się zajmować, bo okazuje się, że wymaga to głębszego poznania tematu i zajmuje więcej czasu niż przerwa śniadaniowa. Tym razem dostałem do wypełnienia arkusz kalkulacyjny MS Excel danymi przesłanymi przez klienta. Dostępna technologia &#8211; PHP. Od razu zacząłem szukać gotowca i znalazłem! PHPExcel. Po [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" src="http://download.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=phpexcel&amp;DownloadId=65397&amp;Build=17672" alt="" width="349" height="80" />Czasem spadają na mnie jakieś drobne projekty, którymi wcale nie chcę się zajmować, bo okazuje się, że wymaga to głębszego poznania tematu i zajmuje więcej czasu niż przerwa śniadaniowa. Tym razem dostałem do wypełnienia arkusz kalkulacyjny MS Excel danymi przesłanymi przez klienta. Dostępna technologia &#8211; PHP.</p>
<p>Od razu zacząłem szukać gotowca i znalazłem! PHPExcel. Po krótkiej pracy z nim wiem, że nie jest to idealne narzędzie, ale może to wynikać z formatu pliku jaki obrabiałem i od tego jak i czym został wcześniej zapisany (wzór dostarczony z zewnątrz). Z dwóch wyglądających podobnie komórek po otwarciu i zapisaniu przez PHPExcel nagle jedna gubi formatowanie. Dziwne. Ale jako, że nie chciałem się zagłębiać, uznałem, że tak właśnie musi być.<br />
Jako, że arkusze nie są skomplikowane, to przed samym zapisem robię &#8216;normalizację&#8217; komórek, czyli ustawiam takie formatowanie, jakie jest w pliku źródłowym i wszystko działa.</p>
<p>Prócz wypełniania komórek odpowiednimi wartościami i zmianie formatowania nic więcej nie robiłem (a pewnie się da). Do takich celów, uważam, że projekt nadaje się wystarczająco.</p>
]]></content:encoded>
			<wfw:commentRss>http://guzik.net.pl/blog/2011/03/phpexcel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

