News: Faz alguns dias que este blog está rodando em um VPS que aluguei na slicehost. Em um primeiro momento fiz a instalação Lamp padrão, contudo isso resultou em um pequeno inconveniente, consumo excessivo de memória ram:

# Consumo de memória com apache
mysql + apache2 rodando wordpress = 165 mb ram

Considerando que meu VPS tem apenas 256 mb de ram resolvi trocar o apache pelo nginx, o resultado foi bem agradável:

# Consumo de memória com nginx
mysql + fcgi + nginx rodando wordpress = 65 mb ram

O processo de instalação foi extremamente simples, e as configurações custaram alguns poucos momentos no google.

# Pacotes necessários:
apt-get install nginx mysql-server php5 php5-cgi php5-mysql spawn-fcgi

Arquivo de configuração do domínio no nginx
cat /etc/nginx/sites-enabled/tarzxvf.com

server {
    listen   80;
    server_name  tarzxvf.com www.tarzxvf.com;
    access_log  /var/log/nginx/tarzxvf.com.access.log;

    location / {
        root   /var/www/tarzxvf.com;
        index  index.html index.htm index.php;

        # this move feed requests to feedburner
        if ($http_user_agent !~ FeedBurner) {
            rewrite ^/feed/ http://feeds.feedburner.com/tarzxvf last;
        }

        # this serves static files that exist without running other rewrite tests
        if (-f $request_filename) {
            expires 30d;
            break;
        }

        # this sends all non-existing file or directory requests to index.php
        if (!-e $request_filename) {
            rewrite ^(.+)$ /index.php?q=$1 last;
        }
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/tarzxvf.com/$fastcgi_script_name;
        include fastcgi_params;
    }
}

Arquivo de inicialização do fcgi
cat /etc/init.d/spawn-fcgi

#! /bin/sh

### BEGIN INIT INFO
# Provides:          spawn-fcgi-php
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts FastCGI for PHP
# Description:       starts FastCGI for PHP using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=spawn-fcgi-php
PID=/var/run/spawn-fcgi-php.pid
DAEMON=/usr/bin/spawn-fcgi
DAEMON_OPTS="-f /usr/bin/php-cgi -a 127.0.0.1 -p 9000 -u www-data -g www-data -P $PID"

test -x $DAEMON || exit 0

set -e

case "$1" in
  start)
        echo "Starting $NAME: "
        start-stop-daemon --start --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS
        echo "done."
        ;;
  stop)
        echo "Stopping $NAME: "
        start-stop-daemon --stop  --pidfile $PID --retry 5
        rm -f $PID
        echo "done."
        ;;
  restart)
        echo "Stopping $NAME: "
        start-stop-daemon --stop  --pidfile $PID --retry 5
        rm -f $PID
        echo "done..."
        sleep 1
        echo "Starting $NAME: "
        start-stop-daemon --start --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS
        echo "done."
        ;;
  *)
        echo "Usage: /etc/init.d/$NAME {start|stop|restart}" >&2
        exit 1
        ;;
esac
exit 0

Título alternativo: How to get CPU usage per core with python
Teste de indexação do google ;)

Mais um post para a série “Parseando o /proc” [1]. Dessa vez sem motivo explícito, apenas diversão!

Ambientes de testes:

  • Ubunto c/ 1 núcleo e Python 2.6
  • Ubunto c/ 2 núcleos e Python 2.6
  • CentOS c/ 4 núcleos e Python 2.4.
  • Comparei os resultados através do htop e obtive uma proximidade alta nos valores, as diferenças se dão provavelmente pelo momento e duração da medição!

    Quem puder testar em ambientes com mais núcleos ou uso intensivo da CPU e comparar com as ferramentas do sistema por favor me de um feedback

    E quem rir da qualidade do meu inglês nos comentários eu vou banir o ip! :)

    ?View Code PYTHON
    #!/usr/bin/env python
    import time
    import os
     
    # [ reference ]
    # Detect number of cpus
    # http://www.boduch.ca/2009/06/python-cpus.html
    # Get cpu usage (But this example is not working 100%)
    # http://ubuntuforums.org/showpost.php?p=853257&postcount=4
     
    INTERVAL = 2
     
    class CPUUsage:
        def __init__(self):
            self.cores = self.detectCPUs()
     
        def createCoreArray(self):
            cores = []
            for i in range(self.cores):
                cores.append("")
            return cores
     
        def detectCPUs(self):
            if hasattr(os, "sysconf"):
                if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"):
                    ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
                    if isinstance(ncpus, int) and ncpus > 0:
                        return ncpus
            return 1 # Default
     
        def getTimeList(self):
            core = self.createCoreArray()
     
            statFile = file("/proc/stat", "r")
            if not self.cores == 1:
                statFile.readline()
     
            # this FOR will split lines from proc/stat for every active core
            for cid in range(self.cores):
                # when have just one core, split a different range
                if self.cores == 1:
                    core[cid] = statFile.readline().split(" ")[2:7] # 2:6
                else:
                    core[cid] = statFile.readline().split(" ")[1:6] # 1:5
            statFile.close()
     
            # convert all itens in splited list from STR to INT for every core
            for i in range(len(core[0])):
                for cid in range(self.cores):
                    core[cid][i] = int(core[cid][i])
     
            # return the core list now with INT values inside their cpu values
            # like this: ([core,1,values],[core,2,values],[core,3,values])
            return core
     
        def deltaTime(self,interval):
            coreT1=self.createCoreArray()
            coreT2=self.createCoreArray()
     
            # get core TIME 1 state per core
            coreT1 = self.getTimeList()
            # wait X seconds to get new state core
            time.sleep(interval)
            # get core TIME 2 state per core
            coreT2 = self.getTimeList()
     
            #Get the diference of coreT2.item[i] and coreT1.item[i] for every core
            for i in range(len(coreT1[0])):
                for cid in range(self.cores):
                    coreT2[cid][i] -= coreT1[cid][i]
            return coreT2
     
        def Usage(self):
            core = self.createCoreArray()
            cpuUsage = []
     
            core = self.deltaTime(INTERVAL)
     
            for cid in range(self.cores):
                # sum of user,system and nice usage
                tmp_use = core[cid][0] + core[cid][1]+core[cid][2]
                # 100.00 * usage / sum of usage + idle + waiting
                usage = "%.2f" % ((100.00 * tmp_use) / sum(core[cid]))
                cpuUsage.append(usage)
            return cpuUsage
     
    if __name__ == "__main__":
        # Show usage per core
        #print CPUUsage().Usage()
     
        x = 0
        for item in CPUUsage().Usage():
            x = x + 1
            print "CPU[%s]: %s" % (str(x),str(item))

    OK, então você usa linux e conhece o ‘top‘, item básico no repertório de qualquer sysadmin, que permite acompanhar algumas informações sobre a carga do sistema e processos. Essa ferramenta antiga e poderosa, é de uma idéia tão simples porem tão prática, que ganhou um termo para designar ferramentas semelhantes, ferramentas “top-like“.

    Para se enquadrar em uma ferramenta top-like o candidato tem que:

  • ser baseado em curses
  • ter atualizações em intervalos pré-definidos
  • ter formato tabulado
  • e opcionalmente permitir interação com os objetos analisados
  • Fiz uma lista com 16 ferramentas top-like disponíveis no Ubuntu 9.04. Enquanto fazia a pesquisa, encontrei pelo menos mais meia dúzia sem pacotes para o ubuntu, e se for considerar as que eu não encontrei esse número deve subir consideravelmente.

    Continue lendo!

    Esse meme está rolando em muitos planetas. Fiquei curioso e resolvi brincar!
    Aí está o resultado.

    Na tarde de sábado eu precisava pegar as portas abertas no servidor, da forma mais Real Time possível.  Primeira idéia? Naturalmente, foi parsear o resultado do netstat e ‘grepar’ o LISTEN ou OUÇA, mas depois imaginei que beber diretamente da fonte pudesse fazer o negócio andar mais rápido. Pesquisa daqui, pesquisa dali, aparentemente o netstat pega suas informações dos arquivos em /proc/net.

    Após umas horinhas consegui o protótipo inicial do código que preciso. Mas durante a caminhada perdi o foco e acabei brincando um pouco mais com o /proc/net/tcp, no fim tinha um netstat simplificado feito em Python.

    Então se alguém algum dia precisar recuperar informações de conexões ao estilo netstat aí está o código:

    ?View Code PYTHON
    #!/usr/bin/python
     
    # Criado por Ricardo Pascal, qualquer dúvida ou
    # contribuição mande para  'pascal.linux' no gmail!
    # Pode usar a vontade só lembre-se de citar a autoria ;)
    # Agradecimento ao pessoal do #python-br na freenode.
    # A galera lá sempre ajuda.
     
    PROC_TCP = "/proc/net/tcp"
    STATE = {
    	    '01':'ESTABLISHED',
    	    '02':'SYN_SENT',
    	    '03':'SYN_RECV',
    	    '04':'FIN_WAIT1',
    	    '05':'FIN_WAIT2',
    	    '06':'TIME_WAIT',
    	    '07':'CLOSE',
    	    '08':'CLOSE_WAIT',
    	    '09':'LAST_ACK',
    	    '0A':'LISTEN',
    	    '0B':'CLOSING'
    	}
     
    tcp_FH = open(PROC_TCP,'r')
    content = tcp_FH.readlines()
    content.pop(0) # remove header
    tcp_FH.close()
     
    def hex2dec(s):
        return int(s,16)
     
    def ip(s):
        return str(hex2dec(s[6:8])) +"."+ str(hex2dec(s[4:6])) +"."+ \
    	    str(hex2dec(s[2:4])) +"."+ str(hex2dec(s[0:2]))
     
    def remove_empty(list):
        return [x for x in list if x !='']
     
    def get_list(c):
        result = []
        result.append(['ID','IP','PORT','rIP','rPORT','STATS'])
        for lines in content:
    	line_array = remove_empty(lines.split(' '))
     
    	line = [line_array[0], line_array[1].split(':'), \
    		line_array[2].split(":"),line_array[3]]
     
    	line = [line[0], ip(line[1][0]), hex2dec(line[1][1]), \
    		ip(line[2][0]), hex2dec(line[2][1]), STATE[(line[3])]]
     
    	result.append(line)
        return result
     
    if __name__ == '__main__':
        for lines in get_list(content):
    	print lines

    PS. Quando eu tiver tempo eu refaço a cama de gato que ta ali na função get_list() e ip().

    Imagino que no final vou acabar usando o Standalone WSGI Server (engine do CherryPy) com a solução apresentada no Static. Mas até lá continuo fazendo meus testes com o CherryPy mesmo.

    É algo que me irrita profundamente, servidores mal aproveitados que por sua vez demandam mais servidores! Alem dos óbvios custos financeiros envolvidos, existe também o fator “Sysadmin puto da cara” e “Sysadmin pagando o pato por falha no desenvolvimento”.

    Essa é a recomendação de leitura da semana:
    Hardware is Expensive, Programmers are Cheap
    Hardware is Expensive, Programmers are Cheap II

    Vale citar que esses textos foram escritos em resposta a esse outro:
    Hardware is Cheap, Programmers are Expensive

    update 1:
    O Eri foi alem e consultou as fontes do texto sobre latência, e indicou esse como leitura para entender bem o conceito.
    ps. eu li e confirmo, realmente vale a pena ler o texto

    Oi, tudo bom?

    Para o sysadmin que ainda não leu, LEIA!
    Leia com cuidado, atenção, reflita sobre e depois leia de novo!

    http://lonesysadmin.net/2008/09/08/downtime/

    http://highscalability.com/latency-everywhere-and-it-costs-you-sales-how-crush-it

    nota mental: talvez seria uma boa eu traduzir e postar por aqui!

    E se possível eu gostaria de ver um post do Eri Ramos sobre o tema! Acho que ele pode ter uma boa história para contar  :)

    Ultimamente tem se falado muito sobre as modificações no processo de boot do linux feitas por dois desenvolvedores da Intel. As estimativas são de que em breve teremos máquinas com o boot de 10 segundos. Legal não?


    Para medir o tempo do boot foi usado o Bootchart um simpático pacote que vem nos repositórios do ubuntu! A instalação é da forma tradicional:

    apt-get install bootchart

    E pronto! Apenas isso, prático não? O resultado você pode conferir em um pós-boot no diretório /var/log/bootchart/

    Eis aqui o bootchart gerado no meu Notebook.