Saturday, December 1, 2012

SEMBOL TABLOSU

C ya da C++'de geliştirdiğimiz uygulamalarda hata ayıklama yapmamız gerektiğinde, kodu GNU c derleyeyicisi ile -g seçeneği ile derlememiz gerekir. Aksi halde gdb ile uygulamada hata ayıklamak istediğimizde sembol tablosunu bulamadığına ilişkin uyarı verecektir:
[guru@godel ~]$ g++ -o lottery lottery.cpp -std=c++11
[guru@godel ~]$ gdb lottery 
GNU gdb (GDB) Fedora (7.4.50.20120120-42.fc17)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/guru/lottery...(no debugging symbols found)...done.
(gdb) quit
[guru@godel ~]$ g++ -g -o lottery lottery.cpp -std=c++11
[guru@godel ~]$ gdb lottery 
GNU gdb (GDB) Fedora (7.4.50.20120120-42.fc17)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/guru/lottery...done.

lottery.cpp: Sayısal loto için 6 adet [1,49] aralığında birbirinden farklı sıralı sayı üretir

#include <iostream>
#include <algorithm>
#include <random>
#include <list>

using namespace std;

int main(){
   random_device rd; 
   mt19937 gen(rd());
   uniform_int_distribution<uint32_t> dist(1,49);
   list<uint32_t> lst;
   while ( lst.size() < 6 ){
      uint32_t r;
      do {
        r= dist(gen);
      } while(find(lst.begin(),lst.end(),r)!=lst.end());
      lst.push_front(r);
   }   
   lst.sort();
   for (auto x : lst)
       cout <<  x << endl;
   return 0;
}

-g seçeneği ile derlendiğinde çalıştırılabilir dosyanın içinde sembol tablosu da yer alacaktır. Hata ayıklayıcı sembol tablosunu, kod ile bellek alanlarını eşleştirmek için kullanmaktadır. Ancak bunun bir yan etkisi bulunmaktadır. Sembol tablosu çalıştırılabilir dosyanın içinde yer aldığı için dosyanın boyu büyümektedir. İstenirse sembol tablosunu çalıştırılabilir dosyanın dışına ayrı bir dosyaya alınabilir. Bunun için strip ve objcopy komutlarından yararlanıyoruz.
[guru@godel ~]$ objcopy --only-keep-debug lottery lottery.debug
[guru@godel ~]$ strip --strip-debug --strip-unneeded lottery
[guru@godel ~]$ objcopy --add-gnu-debuglink=lottery.debug lottery
[guru@godel ~]$ ls -lh lottery*
-rwxrwxr-x. 1 student student 17K Dec  1 16:05 lottery
-rw-rw-r--. 1 student student 506 Dec  1 15:50 lottery.cpp
-rwxrwxr-x. 1 student student 77K Dec  1 16:04 lottery.debug
[guru@godel ~]$ gdb lottery
GNU gdb (GDB) Fedora (7.4.50.20120120-42.fc17)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/guru/lottery...Reading symbols from /home/guru/lottery.debug...done.
(gdb) list 1,10
1 #include <iostream>
2 #include <algorithm>
3 #include <random>
4 #include <list>
5
6 using namespace std;
7
8 int main(){
9   random_device rd;
10   mt19937 gen(rd());
(gdb) list 11,20
11   uniform_int_distribution<uint32_t> dist(1,49);
12   list<uint32_t> lst;
13   while ( lst.size() < 6 ){
14      uint32_t r;
15      do {
16        r= dist(gen);
17      } while(find(lst.begin(),lst.end(),r)!=lst.end()) ;
18      numbers.push_front(r);
19   }
20   lst.sort();
(gdb) break 13
Breakpoint 1 at 0x401019: file lottery.cpp, line 13.
(gdb) break 20
Breakpoint 2 at 0x4010d2: file lottery.cpp, line 20.
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401019 in main() at lottery.cpp:13
2       breakpoint     keep y   0x00000000004010d2 in main() at lottery.cpp:20
(gdb) run
Starting program: /home/guru/lottery 

Breakpoint 1, main () at lottery.cpp:13
13   while ( lst.size() < 6 ){
(gdb) print lst
$1 = empty std::list
(gdb) cont
Continuing.

Breakpoint 2, main () at lottery.cpp:20
20   lst.sort();
(gdb) print lst
$2 = std::list = {[0] = 23, [1] = 42, [2] = 7, [3] = 22, [4] = 21, [5] = 36}
(gdb) cont
Continuing.
7
21
22
23
36
42
[Inferior 1 (process 2463) exited normally]
(gdb) quit


Solaris11'de NFS Paylaşımı Tanımlama ve Windows 7'den Erişim

ZFS, Sun Microsystems firmasında Jeff Bonwick ve Matthew Atrens'in başını çektiği bir ekip tarafından tarafından geliştirilmiş hem bir dosya hem de LVM (Logical Volume Management) sistemini içeren bir teknolojidir. Başlangıçta açık kaynak kodlu bir proje olarak Common Development and Distribution License modeli ile geliştirilen sistem artık Oracle firmasının ticari bir ürünüdür. Solaris 11 işletim sisteminin en önemli bileşenlerinden biri olarak öne çıkmaktadır. 

ZFS ile 278 sekizliği adreslemek mümkündür. Bu şimdilik teorik olarak ulaşılabilecek üst değeri ifade ediyor ve çok uzun süre ihtiyaçlarımızı karşılayacaktır. ZFS elbette bu kapasitenin ötesinde farklı yetenekler sunuyor. Bu yeteneklerden birkaç tanesi aşağıda sıralanmıştır:
  • Anlık yedek oluşturabilme, 
  • Kolay kurulum ve yönetim, 
  • Şifreleme, 
  • Sessiz onarım, 
  • Değişken blok boyutu tanımlayabilme, 
  • Little-endian/big-endian farklı sistemler arasında sorunsuz dosya sistemi aktarımı
Bu yazıda zfs üzerinde NFS tipinde bir dosya sisteminin nasıl yaratılacağı ve bu paylaşılan alana Windows 7'den nasıl erişilebileceği anlatılacaktır. İşleme shared isimli bir bölüm yaratarak başlıyoruz. Ardından bu bölüm nfs olarak tanımlanıyor ve paylaşıma açılıyor:

#zfs create rpool/shared
#zfs set share=name=shared,path=/rpool/shared,prot=nfs rpool/shared
name=shared,path=/rpool/shared,prot=nfs,public=true,sec=sys,rw=*
#zfs set sharenfs=on rpool/shared
#cat /etc/dfs/sharetab
/rpool/shared    shared    nfs     sec=sys,rw

Sistemin çalışabilmesi için NFS servisini açmak gerekir:
#svcadm enable svc:/network/nfs/server:default

Windows 7'ye Solaris 11'de paylaşıma açılan NFS bölümünü tanıtmak için öncelikle Windows'da NFS Client özelliğini açmak gerekir. Bunun için ilk olarak Control Panel'den Programs and Features seçilir:


Çıkan pencerede Turn Windows features on or off bağlantısı seçilir:


Çıkan diyalog kutusunda Services for NFS seçilir:


Windows yeniden başlatıldıktan sonra komut satırından mount komutu çalıştırılır: 

C:\Users\godel>showmount -e 192.168.1.3
Exports list on 192.168.1.3:
/rpool/shared                      All Machines

C:\Users\godel>mount -o mtype=hard 192.168.1.3:/rpool/shared z:
z: is now successfully connected to 192.168.1.3:/rpool/shared

The command completed successfully.


Monday, October 29, 2012

XMail E-POSTA SUNUCUSUNUN 64-Bit Windows MAKİNALARA KURULUMU

Kurumsal uygulamaların bir parçası olarak bazen test ortamlarında hafif-sıklet e-posta sunucusuna ihtiyaç duyarız. Bu amaçla XMail e-posta sunucusu kullanılabilinir. XMail açık kaynak kodlu bir projedir ve projenin sayfasına bu bağlantıdan erişebilirsiniz. Windows XP, Windows Server 2003/2008, Windows 7 makinalara kurulum yapılabilinir. Windows işletim sistemi için çalıştırılabilir dosyaları bu bağlantıdan  indirebilirsiniz. Ancak bu çalıştırılabilir dosyalar 32-bit Windows için oluşturulmuştur ve 64-bitlik Windows makinalar için Windows kayıtlarında aşağıdaki gibi bir düzenleme yapılması gerekir:

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\GNU] 
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\GNU\XMail]
MAIL_ROOT=d:\XMail
MAIL_CMD_LINE=

Kurulum ve temel ayarlar için aşağıdaki betiği kullanabilirsiniz:


@echo off
setlocal
REM  Note: Port used include 25 for SMTP, 110 for POP, 6017 for Admin services

set INSTALLDIR=%CD%
set MAIL_ADMIN=demoadmin
set DOMAIN=example.com

if not defined DRV          set DRV=D:
if not defined HOSTNAME     set HOSTNAME=%COMPUTERNAME%
if not defined DOMAIN       set DOMAIN=example.com
if not defined MAILROOT     set MAILROOT=%DRV%\XMail
if not defined MAILROOT_REG set MAILROOT_REG=%DRV%\\XMail

if exist %MAILROOT% (
  echo Stopping XMail Service
  net stop xmail
)

unzip -oq %INSTALLDIR%\XMail.zip -d %MAILROOT%
REM
REM Generate and install a registry entries from a .reg file for XMail
REM
echo Generating and setting Xmail registry entries

if not defined XMAIL_REG_FILE set XMAIL_REG_FILE=XMail_gen.reg

echo Windows Registry Editor Version 5.00 > %XMAIL_REG_FILE%
echo. >> %XMAIL_REG_FILE%
echo [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\GNU] >> %XMAIL_REG_FILE%
echo [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\GNU\XMail] >> %XMAIL_REG_FILE%
echo "MAIL_ROOT"="%MAILROOT_REG%" >> %XMAIL_REG_FILE%
echo "MAIL_CMD_LINE"="" >> %XMAIL_REG_FILE%

regedit /s %XMAIL_REG_FILE%
del/q %XMAIL_REG_FILE%
REM
REM Create the (1) domains.tab (2) smtpreply.tab (3) server.tab (4) aliasdomain.tab in the mail root directory
REM
REM 1. domains.tab
echo Creating Xmail domains.tab file
echo "%HOSTNAME%.%DOMAIN%" > %MAILROOT%\domains.tab

REM 2. Create empty smtprelay.tab
echo Creating Xmail smtpreplay.tab file
echo. > %MAILROOT%\smtprelay.tab

REM 3. server.tab
echo Creating Xmail server.tab file

echo # > %MAILROOT%\server.tab
echo # Server configuration file >> %MAILROOT%\server.tab
echo # Note : remember to use _REAL_ TABs and double quotes to format this file >> %MAILROOT%\server.tab
echo # >> %MAILROOT%\server.tab
echo "RootDomain" "%HOSTNAME%.%DOMAIN%" >> %MAILROOT%\server.tab
echo "SmtpServerDomain" "%HOSTNAME%.%DOMAIN%" >> %MAILROOT%\server.tab
echo "POP3Domain" "%HOSTNAME%.%DOMAIN%" >> %MAILROOT%\server.tab
echo "HeloDomain" "%HOSTNAME%.%DOMAIN%" >> %MAILROOT%\server.tab
echo "PostMaster" "%MAIL_ADMIN%@%HOSTNAME%.%DOMAIN%" >> %MAILROOT%\server.tab
echo "ErrorsAdmin" "%MAIL_ADMIN%@%HOSTNAME%.%DOMAIN%" >> %MAILROOT%\server.tab

REM
REM Add other settings
REM
echo "RemoveSpoolErrors" "0" >> %MAILROOT%\server.tab
echo "MaxMTAOps" "16" >> %MAILROOT%\server.tab
echo "ReceivedHdrType" "0" >> %MAILROOT%\server.tab
echo "FetchHdrTags" "+X-Deliver-To,+Received,To,Cc" >> %MAILROOT%\server.tab
echo "DefaultSmtpPerms" "MRVZ" >> %MAILROOT%\server.tab
echo. >> %MAILROOT%\server.tab

REM 4. aliasdomain.tab
echo Creating Xmail aliasdomain.tab file

echo "server1.example.com" "%HOSTNAME%.%DOMAIN%" > %MAILROOT%\aliasdomain.tab

REM 5. Create ctrlaccounts.tab with administrator username
echo "admin" "120009060a080054" > %MAILROOT%\ctrlaccounts.tab

echo Mail server: %HOSTNAME%.%DOMAIN%
echo Creating XMail User accounts

mkdir %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%

set USRLIST=user1 user2 sking jcooper wfaulk jstein istone mtwain jlondon cdickens ltolstoy fkafka szweig mmitch jausten achrist rsteven cdoyle wshake sfitzger
set USRPWD=120009060a080054

for %%i in (%MAIL_ADMIN% %USRLIST%) do (
  echo  Creating user: %%i
  echo "%HOSTNAME%.%DOMAIN%" "%%i" "%USRPWD%" 1 "%%i" "U" >> %MAILROOT%\mailusers.tab
  mkdir %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%\%%i
  echo "ReceiveEnable" "1" > %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%\%%i\user.tab
  echo "PopEnable" "1" >> %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%\%%i\user.tab
  mkdir %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%\%%i\mailbox
  mkdir %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%\%%i\Maildir
  mkdir %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%\%%i\Maildir\cur
  mkdir %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%\%%i\Maildir\new
  mkdir %MAILROOT%\domains\%HOSTNAME%.%DOMAIN%\%%i\Maildir\tmp
)

echo Installing XMail Server as a service

%MAILROOT%\bin\XMail --install-auto
echo Starting XMail Server service
net start xmail

echo XMAil Server service started.
endlocal

Kurulum tamamlandığında servisler listesinde XMail adlı bir servis görülecektir.
İstenildiğinde bu servis net stop xmail komutu ile durdurulabilinir.

Wednesday, October 17, 2012

MD-2012-III

Matematik dünyası dergisinin 2012-III sayısı çıktı. Abone olmak için bağlantıyı takip edin. Yeni sayının içeriğine buradan bakabilirsiniz. MD-2012-III sayısının giriş yazısını aşağıda alıntıladım:

George Bernard Shaw’un meşhur sözüdür: “Pek az kişi yılda iki üç kez düşünür. Ben ise haftada bir iki kez düşünerek dünya çapında bir üne kavuştum!” Aaa ne güzel, biz de haftada birkaç kez düşünelim o zaman... diyesi geliyor insanın.
Çok çabalayıp da anlatamadığım zaman, çok çaresiz kaldığımda, bazen kendimi
tutamayıp öğrencilere “düşünün” diyorum!
Sanki düşünmeyi ben çok iyi biliyormuşumu geçtim, sanki biri bana düşün dese,
ne yapacağımı biliyormuşum gibi...
Birine kolunu kaldır deseniz, o kişi eğer isterse kolunu kaldırır. Kolu yoksa bile kolunu kaldırması için ne yapması gerektiğini bilir ve kolunu kaldırmaya çalışabilir. Koş dersin koşar, yürü dersin yürür, dur dersin durur. En azından ne yapması gerektiğini bilir. Ama “düşün” denildiğinde kişinin ne yapması gerekiyor? Düşünmek ne kadar iradeyle ilgili?
Düşün dediğim öğrenci,
- Düşünüyorum hocam! dese - ki diyor bazen - ne cevap vereceğim?
- Hayır, düşünmüyorsun! Öyle mi düşünülür!
- Ya nasıl düşünülür?
- Bak işte böyle düşünülür...
Keşke bu senaryonun devamını getirebilsem. Zaten devamını getirebilsem kitabını yazardım. Okuyanlar da böylece sayemde düşünmeyi öğrenirlerdi!
Nasıl düşünüleceğini bilmesem de düşünmek için neler gerektiğini aşağı yukarı biliyorum.
Düşünmek için her şeyden önce kavramlara ihtiyaç vardır, tabii bir de bu kavramlar arasındaki ilişkilere. Kavram olmadan düşünülecek şey de olmaz zaten.
Matematikte kavramlar ve aralarındaki ilişkiler simgelerle ifade edilir. Simgeler de düşünceyi kaydetmeye yarar. Böylece hafızanın yükü önemli miktarda azalır ve düşüncede daha derine inilir, derine inilmese de daha ileri gidilir. Düşünceyi kaydetmek, yani yazıya geçirmek, bir dereyi geçmek için su yatağına yerleştirilen taşlar gibidir, o taşlara basıp daha ileri gidilir. Hatta geri dönüp silgiyle taşları siler, daha sağlam taşlarla yepyeni bir güzergâh belirleyebiliriz.
Matematik dışındaki alanlarda simge dünyası o kadar gelişmemiştir. Gene de bildiğimiz harflerle düşünce kaydedilebilir. Formüllerin ifade gücünün yanına yaklaşamasa da bildiğimiz düzyazı da düşünceyi simgeyle kaydetmeye yarar.
Lise öğrencisiyken bir deneme yazacaktım. Her hafta yaptığımız bir şeydi de neme yazmak. O zamanlar tahrir denirdi. Konuyu unuttum şimdi ama “eğitim herkese lazım” filan gibi doğruluğu bariz olan oldukça sıkıcı bir konuydu. Geceli gündüzlü üç hafta uğraştım. Sonunu bağlayamıyor, istediğim sonuca bir türlü ula şa mı yordum, hep bir yerlerde bir eksiklik beliriyordu. Üç hafta sonunda bir şimşek çaktı beynimde, yanılıyormuşum meğer! Savunduğum tez yanlışmış! 
Yazmak doğru düşünmeye yetmeyebilir. Ama yazmadan da doğru düşünülemez.
Ali Nesin

Wednesday, October 10, 2012

APACHE TOMCAT 6'DA GÜNLÜKLERİN SYSLOG SERVİSİNE YÖNLENDİRİLMESİ

Apache Tomcat 6'da günlükler $CATALINA_HOME/logs dizininde saklanmaktadır. Günlüğün yapılandırılması ise $CATALINA_HOME/conf/logging.properties dosyası üzerinden gerçeklenmektedir. Apache Tomcat günlük için tomcat-juli.jar paketini kullanmaktadır. İstenirse günlük oluşturmak için log4j kütüphanesi de kullanılabilinir. log4j kütüphanesi kullanılarak, günlükler veritabanı, syslog gibi farklı hedeflerde saklanabilir. Hem veritabanı hem de syslog servisi istemci-sunucu mimarisinde çalıştığı için günlükler merkezileştirilebilir. Böylelikle, çoklu tomcat sunucusunun olduğu bir yapıda, sunucuların yönetimi kolaylaşır, izlenebilirliği de iyileşir. Bunun yanında log4j ile ERROR yada üzeri seviyedeki günlüklerin e-posta olarak sistem ya da uygulama yöneticisine göndermek mümkün olabilir.

log4j ile günlükleri syslog servisinde toplamak için aşağıdaki adımları izlemek gerekir:

1. İlk olarak $CATALINA_BASE/lib dizininde log4j kütüphanesinin yapılandırma dosyasını (log4j.properties)  oluşturuyoruz:

log4j.rootLogger=INFO, CATALINA

# Define all the appenders
log4j.appender.CATALINA=org.apache.log4j.net.SyslogAppender
log4j.appender.CATALINA.layout= org.apache.log4j.PatternLayout
log4j.appender.CATALINA.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.CATALINA.SyslogHost=127.0.0.1
log4j.appender.CATALINA.Facility=local0
log4j.appender.CATALINA.threshold=DEBUG

log4j.appender.LOCALHOST=org.apache.log4j.net.SyslogAppender
log4j.appender.LOCALHOST.layout = org.apache.log4j.PatternLayout
log4j.appender.LOCALHOST.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.LOCALHOST.SyslogHost=127.0.0.1
log4j.appender.LOCALHOST.Facility=local0
log4j.appender.LOCALHOST.threshold=DEBUG

log4j.appender.MANAGER=org.apache.log4j.net.SyslogAppender
log4j.appender.MANAGER.layout = org.apache.log4j.PatternLayout
log4j.appender.MANAGER.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.MANAGER.SyslogHost=127.0.0.1
log4j.appender.MANAGER.Facility=local0
log4j.appender.MANAGER.threshold=DEBUG

log4j.appender.HOST-MANAGER=org.apache.log4j.net.SyslogAppender
log4j.appender.HOST-MANAGER.layout = org.apache.log4j.PatternLayout
log4j.appender.HOST-MANAGER.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.HOST-MANAGER.SyslogHost=127.0.0.1
log4j.appender.HOST-MANAGER.Facility=local0
log4j.appender.HOST-MANAGER.threshold=DEBUG

log4j.appender.CONSOLE=org.apache.log4j.net.SyslogAppender
log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.CONSOLE.SyslogHost=127.0.0.1
log4j.appender.CONSOLE.Facility=local0
log4j.appender.CONSOLE.threshold=DEBUG

# Configure which loggers log to which appenders
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=INFO, LOCALHOST
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager]=INFO, MANAGER
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager]=INFO, HOST-MANAGER

2. log4j kütüphanesinin güncel sürümünü (log4j-1.2.9.jar) projenin sayfasından indirip $CATALINA_BASE/lib dizinine kopyalıyoruz.

3. Apache tomcat'in proje sayfasında "extras" bölümünden tomcat-juli.jar ve tomcat-juli-adapters.jar dosyalarını indiriyoruz. tomcat-juli.jar dosyasını $CATALINA_BASE/bin dizinine tomcat-juli-adapters.jar dosyasını ise $CATALINA_BASE/lib dizinine kopyalıyoruz. Bu dosyalar adı geçen dizinlerde mevcuttur, dolayısı ile üzerinlerine yazmanız gerekecektir.

4. syslog servisinin 2,3,4,5 çalışma seviyelerinde açık olduğundan emin olun:



[root@station1 lib]# chkconfig --list syslog
syslog  0:off   1:off   2:on    3:on    4:on    5:on    6:off

5. syslog servisinin yapılandırması için iki dosya vardır. 
  • /etc/syslog.conf dosyasına aşağıdaki satırı ekliyoruz:
    local0.*   /var/log/tomcat/messages.log
  • /etc/sysconfig/syslog dosyasında SYSLOGD tanımının yapıldığı satırı aşağıdaki gibi düzenliyoruz:

          SYSLOGD_OPTIONS="-r -m 0"

6. Bu değişiklikleri yaptıktan sonra syslog servisini yeniden başlatıyoruz:

[root@station1 lib]# service syslog restart
Shutting down kernel logger:        [  OK  ]
Shutting down system logger:        [  OK  ]
Starting system logger:             [  OK  ]
Starting kernel logger:             [  OK  ]

7. Son olarak tomcat servisini başlatabiliriz.

Günlükleri veritabanında tutmak için MySQL sunucusunda tomcat_logs adında bir veritabanı yaratıyoruz:


mysql> create database tomcat_logs;
Query OK, 1 row affected (0.02 sec)


mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema | 
| mysql              | 
| test               | 
| tomcat_logs        | 
+--------------------+
3 rows in set (0.00 sec)

Günlüklerin saklanacağı tabloyu ise aşağıdaki create table ifadesi ile yaratıyoruz:

mysql> CREATE TABLE LOGS
    ->    (USER_ID VARCHAR(20) NOT NULL,
    ->     DATED   VARCHAR(40) NOT NULL,
    ->     LOGGER  VARCHAR(50) NOT NULL,
    ->     LEVEL   VARCHAR(10) NOT NULL,
    ->     MESSAGE VARCHAR(1000) NOT NULL
    ->    );
Query OK, 0 rows affected (0.01 sec)

Yukarıdaki sıralanan adımlardan ilkinde verilen log4j.properties dosyasında net.SyslogAppender yerine jdbc.JDBCAppender yazıyoruz:

log4j.rootLogger=WARN, DB

log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.layout=org.apache.log4j.PatternLayout
log4j.appender.DB.URL=jdbc:mysql://localhost:3306/tomcat_logs
log4j.appender.DB.driver=com.mysql.jdbc.Driver
log4j.appender.DB.user=tomcat
log4j.appender.DB.password=tomcat
log4j.appender.DB.sql=INSERT INTO LOGS VALUES('%x','%d','%C','%p','%m')

Son adım olarak MySQL Jdbc sürücüsünü $CATALINA_BASE/lib dizinine kopyalamak gerekir. 

Sunday, August 12, 2012

MySQL 5.5 ve PERFORMANCE_SCHEMA


Oracle firmasının Sun'ı satın alması ile birlikte sahip olduğu yazılımların sayısında bir artış oldu. Bu yazılımların en önemlilerinden biri MySQL'dir. MySQL, açık kaynak kodlu ilişkisel veritabanı uygulamaları arasında en yaygın olarak kullanılan veritabanı sunucusudur. Her ne kadar Oracle açık kaynak kod uygulama geliştiricilerle arası sorunlu olsa da MySQL'e yatırım yapmaya devam etti. Örneğin, Sun'dan devir aldığı OpenOffice, Hudson gibi açık kaynak kodlu projelerde, proje ekiplerini küstürmüş ve projeden ayrılmalarına neden olmuştur. Aynı durum kısmen MySQL için de geçerlidir. Ancak OpenOffice'de ve Hudson'da yaşanan durum MySQL'de yaşanmadı. Oracle MySQL'e yatırım yaptı ve geliştirmeye devam etti. Bunun arkasındaki neden, Oracle'ın Sun'ı satın almadan çok öncesinde Innobase firmasını satın almış olmasıdır. Innobase firması MySQL'deki  Depolama Motorlarından (=Storage Engine)  biri olan Innodb motorunun geliştiricisidir. Oracle, Innobase üzerinden, MySQL'e yatırım yapmaya ve MySQL'i geliştirmeye devam ediyor. 

Satın almadan sonraki ilk sürüm olan 5.5 ile çok sayıda yeni özellik geldi. Bunlardan biri de sunucunun davranışını ve performansını izlemeye olanak sağlayan performance_schema veritabanıdır. Sunucuyu başlattıktan sonra show databases komutu çalıştırıldığında, artık karşımıza performance_schema isimli yeni bir veritabanı çıkıyor:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
| test               |
| world              |
+--------------------+
4 rows in set (0.00 sec)


 performance_schema veritabanıyla beraber [aynı isimli] yeni bir Depolama Motoru ile de tanışıyoruz: PERFORMANCE_SCHEMA. performance_schema içindeki tablolarda, veritabanında gerçekleşen olaylar ile ilgili bilgiler saklanıyor. Bu tablolar view ya da bellekte depolanan geçici tablo olarak tanımlı olduklarından kalıcı değillerdir. Şimdi bu tablolara bir göz atalım:

mysql> show tables;
+----------------------------------------------+
| Tables_in_performance_schema                 |
+----------------------------------------------+
| cond_instances                               |
| events_waits_current                         |
| events_waits_history                         |
| events_waits_history_long                    |
| events_waits_summary_by_instance             |
| events_waits_summary_by_thread_by_event_name |
| events_waits_summary_global_by_event_name    |
| file_instances                               |
| file_summary_by_event_name                   |
| file_summary_by_instance                     |
| mutex_instances                              |
| performance_timers                           |
| rwlock_instances                             |
| setup_consumers                              |
| setup_instruments                            |
| setup_timers                                 |
| threads                                      |
+----------------------------------------------+
17 rows in set (0.00 sec)

Tabloların isimleri ve içerikleri bir sürümden diğer sürüme değişiklik gösterebilir. Eğer kurulum sonrasında herhangi bir tanımlama yapılmaz ise sunucu sistemle ilgili anlık bilgileri bu tablolara kaydetmeye başlamaz. Sunucuyu ya aşağıdaki gibi diğer seçenekler yanında performance_schema seçeneği ile çalıştırmak gerekir

$ mysqld --performance_schema 

ya da bu özelliği kalıcı olarak açmak için yapılandırma dosyasına (my.cnf/my.ini) aşağıdaki satırı eklemek yeterli olacaktır:

[mysqld]
performance_schema
performance_schema_events_waits_history_size=20
performance_schema_events_waits_history_long_size=15000


Eğer sunucu doğru yapılandırılmış ise performance_schema sistem değişkeninin değeri ON olmalıdır:

 
mysql> SHOW VARIABLES LIKE 'performance_schema';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| performance_schema | ON    |
+--------------------+-------+

Sunucuyu yeniden başlatmadan PERFORMANCE_SCHEMA motorunu etkinleştirmek için aşağıdaki komutu çalıştırmak yeterli olacaktır:

mysql> update performance_schema.setup_consumers set enabled='YES' where name='events_waits_current';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from performance_schema.setup_consumers;
+----------------------------------------------+---------+
| NAME                                         | ENABLED |
+----------------------------------------------+---------+
| events_waits_current                         | YES     |
| events_waits_history                         | YES     |
| events_waits_history_long                    | YES     |
| events_waits_summary_by_thread_by_event_name | YES     |
| events_waits_summary_by_event_name           | YES     |
| events_waits_summary_by_instance             | YES     |
| file_summary_by_event_name                   | YES     |
| file_summary_by_instance                     | YES     |
+----------------------------------------------+---------+
8 rows in set (0.00 sec)

 Benzer şekilde sunucuyu tekrar başlatmadan bu özelliği kapatmak için aşağıdaki komutu yazmak yeterli olacaktır:


mysql> update performance_schema.setup_consumers set enabled='NO' where name='events_waits_current';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from performance_schema.setup_consumers;
+----------------------------------------------+---------+
| NAME                                         | ENABLED |
+----------------------------------------------+---------+
| events_waits_current                         | NO      |
| events_waits_history                         | YES     |
| events_waits_history_long                    | YES     |
| events_waits_summary_by_thread_by_event_name | YES     |
| events_waits_summary_by_event_name           | YES     |
| events_waits_summary_by_instance             | YES     |
| file_summary_by_event_name                   | YES     |
| file_summary_by_instance                     | YES     |
+----------------------------------------------+---------+
8 rows in set (0.00 sec)