Posts de July, 2009

[Tiago Motta] Roda: Eu também já recriei

Friday, July 31st, 2009

Uma das discussões mais quentes do momento, e também uma das mais antigas, é sobre a mania que nós desenvolvedores temos de reinventar a roda. Eu mesmo já reinventei diversas vezes e hoje olho para trás e vejo quanto tempo poderia ter poupado ao usar alguma ferramenta já pronta, ou apenas ter adaptado uma que não se encaixava perfeitamente aos meus requisitos.

Há claro excessões, em que seu requisito é tão mínimo que reimplementar uma solução é mais rápido do que aprender uma já existente no mercado. Como foi o caso de um sistema que estávamos desenvolvendo em PHP e precisávamos de um framework apenas para separar a lógica da renderização de templates por tema. Validamos rapidamente diversos frameworks MVC e percebemos que era mais fácil criar em meia hora a seguinte classe:

class Renderizador {    function Renderizador($tema=null) {     $this->_dir = dirname(__FILE__) . "/templates/" . $this->tema;    }    public function put($nome,$obj) {     $this->$nome = $obj;    }    public function show($template) {     include(  $this->_dir . "/" . $template . ".php");    }}

A utilização dela era mais simples ainda. No exemplo abaixo as variáveis inseridas no renderizador ficam disponiveis para o template listagem.php através de $this, que nada mais é do que um arquivo php comum.

$renderizador = new Renderizador('cinza');$renderizador->put('lista',[1,2,3,4]);$renderizador->show('listagem');

Simples, sem precisar aprender nenhum framework ou linguagem de marcação nova. Em duas horas o time já estava trabalhando com a lógica separada da apresentação. Contudo essa é a exceção.

Em geral já recriei diversas rodas desnecessariamente desperdiçando muito tempo. Framework de mapeamento objeto relacional, CMS, blog e até mesmo o TimerTask do Java são alguns dos exemplos. Esse último me rendeu uma longa discussão com o Phillip Calçado na época em que ele trabalhava aqui. Felizmente ele foi persistente em me fazer desistir daquela implementação.

De qualquer forma, o importante é a lição aprendida. Hoje tento usar ao máximo ferramentas já disponíveis, e quando alguma não me atende perfeitamente, ao invés de começá-la do zero eu a altero e contribuo, como foi o caso de uma recente alteração que precisei fazer no fakeweb.

Outros membros da equipe também já vem de longe com esta mesma filosofia e estão constantemente contribuindo como Guilherme Cirne ao contribuir com o WillPaginate, o Anselmo também contribuindo com o Fakeweb e o Bruno Carvalho contribuindo com o TralhaController e o ExceptionNotifier.

O importante é aproveitar aquilo que a comunidade já lhe oferece pronto e testado. Economiza tempo seu, e do próximo desenvolvedor, que dará manutenção a algo que é padrão, com muita discussão em fóruns e muitas soluções documentadas.

[Cristiano Casado] Nagios aditivado .. run run

Thursday, July 30th, 2009

Faltam detalhes para colocar uma instalação distribuída de Nagios em ambiente de produção para monitorar a rede e infra-estrutura na Globo.com.  Um destes detalhes está sendo atacado neste momento com bastante critério e paciência: performance.  Uma instalação básica com configurações de “fábrica” do Nagios podem servir bem para ambientes de pequeno e médio porte com 100-200 servidores.  Só que o cenário aqui é bem diferente.  Em ambiente de produção espero ter 1200 servidores sob os “olhares” do Nagios, e desta forma é preciso seguir algumas recomendações que explico em tópicos abaixo:

  • configurar os diretórios dos arquivos de check result (check_result_path) e de status (status_file) como filesystem tmpfs.  No primeiro ocorre intensa operação de escrita/leitura e o arquivo de status é lido pela camada CGI do Nagios.  Armazenar estas informações em ramdisk evita interrupções e I/O de disco.
  • optar por plugins compilados ( C/C++) para executar os checks reduz significativamente o load nos seus servidores Nagios.
  • ao utilizar plugins em perl (muitos deles disponíveis nesta linguagem) compilar o Nagios para utilizar o seu interpretador perl embedded.  A opção para o script de configure é –enable-embedded-perl.
  • otimizar os checks nos hosts utilizando o plugin check_fping ao invés do plugin padrão check_ping.
  • utilizar precache dos objetos de configuração para acelerar a inicialização do sistema com a opção -u do binário nagios.
  • programar checks regulares para hosts é desnecessário, uma vez que o mesmo possuirá serviços relacionados e a falha do check de um dos serviços força um host check sob demanda.  Para isso atribuir o valor 0 na diretiva check_interval no arquivo de definição de hosts.
  • em instalações distribuidas, incrementar o check de external commands na instalação do Nagios central.  Isso faz com que o Nagios verifique comandos externos assim que possível.  A diretiva command_check_interval deve ter o valor -1.
  • verificar sempre a latência nos checks de hosts e services para estabelecer o melhor valor para a concorrência de checks.  Desta forma você poderá controlar o load que o Nagios impõe aos seus hosts monitorados com a diretiva max_concurrent_checks.
  • cuidado ao utilizar módulos (broker module) para exportar dados do Nagios para softwares de terceiros, pois a dependência de operações externas pode ser blocante para a execução de checks no Nagios.
  • o setup de seu hardware influenciará diretamente na performance do sistema de monitoração.  CPU e memória com tecnologia atuais favorecem o sistema, porém o Nagios por natureza de sua arquitetura é I/O intensive.  Evitar sistemas de arquivos lentos ( discos IDE antigos e NFS), optando por discos UltraSCSI ou FastIDE para armazenar plugins, arquivo de status log, etc.

Antes mesmo de aplicar novas configurações é muito importante não abrir mão de backup dos seus arquivos de configuração e também utilizar as métricas que o Nagios oferece para plotar gráficos onde você poderá comparar como o sistema se comporta ao alterar estas configurações.

Para criar os gráficos o Nagios oferece o utilitário nagiostats que oferece um output compatível com o mrtg para contadores importantes do sistema como número de service checks executados em determinada janela de tempo, latência, tempo de execução de service checks, entre outros.

# /usr/bin/nagiostats –mrtg –data=AVGPSVHSTLAT,AVGPSVSVCLAT,PROGRUNTIME,NAGIOSVERPID
950
554
0d 3h 33m 21s
Nagios 3.0.6 (pid=1861)

[Victor Pantoja] Criando um Makefile para Aplicações Django

Tuesday, July 28th, 2009

Na empresa em que trabalho, criamos a excelente cultura de automatizar tudo que pode ser automatizado.

Nessa filosofia, apresento aqui a maneira que me parece bem interessante de rodar uma aplicação django:

$make runserver

Bem prático, não?

Tudo que fiz foi criar um makefile com a seguinte macro:

runserver:
        @echo "Running aplicacao seu_dominio:3001..."
        @export PYTHONPATH=`pwd`:`pwd`/dango_project:$$PYTHONPATH && \
                export DJANGO_SETTINGS_MODULE=dango_project.settings.dev && \
                cd dango_project && python manage.py runserver seu_dominio:3001

Explicando melhor, imagine que você criou o django project projetoTeste. Imagine agora que, dentro deste projeto, você criou um diretório settings contendo o arquivo dev.py (settings para ambiente de desenvolvimento: lembrando que o settings.py pode ter o nome que você quiser! Recomendo apenas que faça sentido).

Substitua em runserver a variável aplicacao pelo nome fantasia que você quer dar para o seu projeto e dango_project por projetoTeste.

runserver:
        @echo "Running minha aplicacao teste teste.com:3001..."
        @export PYTHONPATH=`pwd`:`pwd`/projetoTeste:$$PYTHONPATH && \
                export DJANGO_SETTINGS_MODULE=projetoTeste.settings.dev && \
                cd projetoTeste && python manage.py runserver seu_dominio:3001

Claro que o Makefile e o projetoTeste está no mesmo nível (mesmo diretório pai).

Existem diversas maneiras de se criar esse Makefile e não vou tomar o vosso tempo com isso.

O runserver é legal para aplicações locais. Para coisas sérias, recomendo o WSGI.

[Victor Pantoja] Configurando o WSGI e o Apache para Renderizar Estáticos do Django

Tuesday, July 28th, 2009

Levantei uma aplicação simples que usa o admin do django com algumas alterações de CSS e template. Crei um diretório /media no meu projeto para colocar os arquivos CSS que criei.

Tudo rodando muito bem com o tradicional runserver 3001 (costumo criar um make para isso).

Claro que chamar uma URL passando a porta fica, no mínimo, deselegante. Solução: usar mod_proxy, mod_python ou WSGI. Optei por este último por diversos motivos que fogem do escopo deste post.

Configuração feita, para minha surpresa o CSS não estava sendo encontrado… Tentei alterar as configurações do WSGI várias vezes, e nada. Acabei percebendo que o problema não era apenas com o CSS, mas como tudo que fosse estático (normalmente, dentro de /admin_media ou /media)

Depois de uma batalha de algumas horas com o WSGI e uma dica no grupo de discussão do Django, consegui configurá-lo para funcionar bem. O problema era basicamente o apache, que procurava o diretório de media em seu docroot.

A solução que escolhi está postada abaixo (preservei algumas informações e removi alguns tabs para caber na tela):

<VirtualHost *:80>
        ServerName seu_dominio_.com

ErrorLog "|/usr/sbin/cronolog /usr/local/logs/dir/apache/projeto_%Y%m%d_error.log"
CustomLog "|/usr/sbin/cronolog /usr/local/logs/dir/apache/projeto_%Y%m%d_access.log" combined

        DocumentRoot "/usr/local/django/projeto"

        Alias /media/ "/usr/local/django/path_deploy/projeto/media/"

        <Location "/media/">
                SetHandler None
                <LimitExcept GET>
                        Require valid-user
                </LimitExcept>

                Order Allow,Deny
                Allow from all
        </Location>

Alias /admin_media/ "/var/lib/python-support/python2.5/django/contrib/admin/media/"

        <Location "/admin_media/">
                SetHandler None
                <LimitExcept GET>
                        Require valid-user
                </LimitExcept>

                Order Allow,Deny
                Allow from all
        </Location>

        WSGIScriptReloading on
        WSGIScriptAlias / /usr/local/django/path_deploy/projeto/django.wsgi
        WSGIDaemonProcess nome_do_deamon user=usuario group=grupo processes=2 threads=25 stack-size=524288

        <Directory /usr/local/django/path_deploy/projeto>
                Order deny,allow
                Allow from all
        </Directory>

 </VirtualHost>

Claro que eu precisei criar um usuário para a aplicação. Sempre crio um usuário específico para cada aplicação que desenvolvo (boa prática).

Só uma observação: sempre que o apache receber uma requisição /media ou /admin_media ele irá tratar sozinho, sem repassar para a aplicação. Isso pode ser interessante para questões de carga na aplicação.

[Bernardo Heynemann] Continuous Integration – Integrating People

Tuesday, July 28th, 2009

Introduction I know it has been a while since I wrote anything and I can come up with a number of good excuses as to why: New job at globo.com. Learning A LOT and working hard to improve our current development ecosystem. Pyccuracy and Skink maturing….(read more)

[Victor Pantoja] Telas do Firefox 4 na WEB

Tuesday, July 28th, 2009

A Mozilla divulgou algumas imagens do que pode vir a ser a versão 4.0 do Firefox para Windows. Segundo a empresa, a idéia é encorajar os usuários a comentar e dar sugestões para o desenvolvimento da nova versão do browser.

Uma das novidades descritas é a barra de localização mais iconográfica e colorida. Na proposta, quando o usuário digita sobre a barra, ela ficaria verde. Se estiver em repouso, a tonalidade harmoniza com o resto dos ícones. A cor fica azul se estiver ocioso e vermelho quando está carregando, entre outras possibilidades.

[Tiago Motta] Dica rápida de charset para projetos rails com mysql

Saturday, July 18th, 2009

Se você está trabalhando em um projeto ruby on rails com banco mysql, e o charset definido tanto no servidor como no database.xml é UTF-8, tome o cuidado para que inserções no banco por conta de terceiros também seja feito neste charset.

Um simples insert feito na mão utilizando o cliente padrão do mysql pode te atrapalhar bastante. E o erro ficará bem difícil de encontrar pois este mesmo client exibirá o texto corretamente e só o rails entregará o dado incorreto, fazendo você acreditar que o problema está no ruby.

Para evitar isso, sempre que fizer inserts na mão e de massa de dados execute como primeira linha o seguinte comando:

charset utf8;

[Rafael Biriba] Liberdade aos desenvolvedores: Atualize seu Navegador

Tuesday, July 14th, 2009

 

http://www.atualizeseunavegador.net/

http://www.atualizeseunavegador.net/ | http://www.updateyourbrowser.net/

 

Navengando um pouquinho em blogs de amigos, encontrei o AtualizeSeuNavegador.net. O site informa ao usuário diversos pontos ruins ao utilizar um navegador desatualizado !

Mas especificamente, o site foi feito para os usuários do Internet Explorer 6 atualizar seus navegadores ! Para explicar melhor, eis o trecho retirado do site:

Navegadores antigos como o Internet Explorer 6 (lançado em 2001) não exibem sites dentro dos padrões web, são repletos de bugs, não oferecem as funcionalidades dos browsers atuais como navegação por abas ou gerenciador de downloads e estão submetidos a sérios problemas de segurança como vírus e malware.

Ainda comprometem a qualidade da exibição de sites e limitam a criação de desenvolvedores, que precisam perder tempo adaptando o site para rodar nesses navegadores obsoletos.

De acordo com as estatísticas do meu blog, os usuários de IE6 correpondem a 20% das visitas, seguido de IE7: 16%, IE8: 5%, Firefox: 55% e Outros: 14%.

Como o IE6 está fora dos padrões web, ao fazer um site qualquer, há uma certa preocupação no lado do desenvolvedor em adaptar o site para ser compatível com o IE6. Se você reparar com atenção, verá que o tema do seu blog possui um css específico para o IE6.

Para o usuário final, isso não faz a menor diferença (com exceção das falhas de segurança), mas para o desenvolvedor isso é uma limitação, uma “dor de cabeça”, que pode ser eliminada !

Ajude a divulgar a idéia do Atualize seu navegador, e vamos rapidamente acabar com o Internet Explorer 6 ! (Liberdade aos Desenvolvedores :) )

Para fazer parte desse movimento basta inserir o código javascript abaixo, assim quando um usuário IE6 entrar no seu site, vai aparecer a seguinte barrinha:

updateyourbrowser-exemplo

Insira o código da barrinha dentro do <head> do seu site:

<script type="text/javascript" src="http://updateyourbrowser.net/asn.js"> </script>

Ou se preferir, insira o código do banner em seu site ou blog:

<a href="http://updateyourbrowser.net/" title="Atualize seu
Navegador"><img src="http://updateyourbrowser.net/asn.jpg"
border="0" alt="Atualize seu Navegador" /></a>

Atualize seu NavegadorBom, para mais informações visite:

http://www.updateyourbrowser.net/ ou http://www.atualizeseunavegador.net/

 

Querem uma dica ? Instalem o navegador Firefox ! Seguro, rápido e simples ! Ainda mais agora com a nova versão 3.5, ainda mais rápido ! Aproveite :)

[Tiago Peczenyj] Quando o FakeWeb deu um grande susto pt 2: o changelog

Thursday, July 9th, 2009

Como falei anteriormente, o FakeWeb nos deu susto.

Olhando no CHANGELOG na versão que estavamos acostumados a usar o correto era fazer :string => “mensagem que veio no ‘body’” ,entretanto nas versões mais atuais isso foi substituido por :body => ‘tcharam’ … e é este exemplo que esta no site. Como isso quebra o backward compatibility, foi documentado no changelog mas passou despercebido. É claro que a versão mais antiga não vai funcionar que nem a nova.

Se tentassem executar os testes antigos no fakeweb 1.2.4 receberia
esta exception:

Deprecation warning: FakeWeb’s :string option has been renamed to :body.
Just replace :string with :body in your FakeWeb.register_uri calls.

Este é um exemplo onde mudar a forma como utilizamos uma biblioteca ou qualquer software causam todo o tipo de problemas quando não prestamos atenção a todos os detalhes.

[Tiago Peczenyj] Quando o FakeWeb deu um grande susto pt 2: o changelog

Thursday, July 9th, 2009


Como falei anteriormente, o FakeWeb nos deu susto.

Olhando no CHANGELOG na versão que estavamos acostumados a usar o correto era fazer :string => “mensagem que veio no ‘body’” ,entretanto nas versões mais atuais isso foi substituido por :body => ‘tcharam’ … e é este exemplo que esta no site. Como isso quebra o backward compatibility, foi documentado no changelog mas passou despercebido. É claro que a versão mais antiga não vai funcionar que nem a nova.

Se tentassem executar os testes antigos no fakeweb 1.2.4 receberia
esta exception:

Deprecation warning: FakeWeb’s :string option has been renamed to :body.
Just replace :string with :body in your FakeWeb.register_uri calls.

Este é um exemplo onde mudar a forma como utilizamos uma biblioteca ou qualquer software causam todo o tipo de problemas quando não prestamos atenção a todos os detalhes.