quinta-feira, 12 de junho de 2014

xargs composto

Os logs do Apache têm uma linha para cada requisição e eu precisava saber qual a última requisição de cada um dos clientes mais frequentes (para saber o horário em que ocorreram). Cada linha do log se parece com esta:

172.16.160.30 - - [12/Jun/2014:12:02:16 -0300] "GET /a.html HTTP/1.1" 200 4712

Eu já tinha uma fórmula simples para achar os IPs dos clientes mais trabalhadores (sort | uniq -c | sort -n):

grep -Po "^\S+" access_log | sort | uniq -c | sort -n | tail -5

Assim, eu consigo os 5 IPs mais ocupados em ordem crescente.

Para cada um desses IPs, é preciso executar um novo grep, buscando apenas a última linha. Para isso, usei o xargs em combinação com o bash:

xargs -I{} bash -c "grep {}  access_log | tail -1"

Restou apenas retirar o número de ocorrências (adicionado pelo uniq -c). O grep ajuda novamente:

grep -Po "\S+$"

O -P indica uma expressão regular ao estilo do Perl e o -o indica que o resto da linha deve ser excluída. A expressão regular procura o último conjunto de caracteres que não contém um espaço. O primeiro grep usava uma expressão semelhante para achar o IP (primeira coluna do arquivo).

O resultado é mais assustador que a soma das partes:

grep -Po "^\S+" access_log | sort | uniq -c | sort -n | tail -5 \
  | grep -Po "\S+$" \
  | xargs -I{} bash -c "grep {}  access_log | tail -1"

Estou pensando se não seria prático descartar a ferramenta cara de BI e trocá-la por arquivos texto e shell.

segunda-feira, 9 de junho de 2014

O micro da sogra

O micro da sogra sofria tanto quanto a casa com a bagunça da família. Frequentemente, era preciso desinstalar, reinstalar ou instalar alguma coisa. Por muitos anos, houve resistência dura contra a migração para o Linux, mesmo a máquina sendo usada predominantemente para jogar Paciência ou para navegar na Web.

Então, fiquei surpreso quando finalmente foi aceita minha sugestão de que fosse instalado o Ubuntu (eu não insisti muito, juro). Em realidade, eu não estava plenamente convencido de que seria uma boa ideia, dado o histórico de dependência do sistema de Redmond. Mesmo assim, achei que valia a pena tentar.

Instalei o Ubuntu 12.04 LTS e três jogos de cartas bem completos. Criei uma conta para cada habitante da casa (exceto para os de quatro patas) e configurei a rede.

Passados vários meses, confirmo que foi uma excelente troca. Não houve nenhuma ocorrência com software deixando de funcionar ou com softwares suspeitos surgindo do nada com avisos ameaçadores (Seu micro pode estar infectado!). Surpreendi-me até a encontrar o LibreOffice sendo usado e bem avaliado!

De quando em vez, rodo o Update Manager para manter a máquina atualizada e é só esse o trabalho que esse micro tem dado. Sucesso total para o Ubuntu.

terça-feira, 3 de junho de 2014

Raspberry Pi

No final dos anos 1980, o melhor computador disponível era o Archimedes da Acorn. Os primeiros modelos tinham de 512KB a 1MB de RAM e operavam a 4MIPs. O A3000, lançado em 1989, custava 650 libras. Seriam mais de R$5 mil reais hoje (1370 libras de 2012 segundo a calculadora do Banco da Inglaterra), sem contar com as taxas de importação. Em terras brasileiras, tínhamos MSX, PCs, e não muito mais que isso.

Então, com o lançamento do Raspberry Pi, aproveitei a oportunidade de ter alguma coisa semelhante a um Archimedes. O processador é da mesma família, pelo menos (não vamos levantar a questão óbvia de que todos os celulares tem um ARM dentro hoje em dia).

Encomendei da loja inglesa ModMyPi um Pi modelo B (512MB de RAM), uma caixa, e um cartão microSD categoria 10 de 32GB (contendo vários sistemas operacionais para o Pi, inclusive o RISC OS). Gastei 55 libras (uns R$200). Cabos, eu tinha vários sobrando em casa, então só precisei comprar um cabo HDMI para ligar o Pi à TV. Usei um carregador de celular como fonte de energia.

Ele não é muito rápido, mas pode decodificar vídeo. Então, uma de suas utilidades é exibir filmes. Basta gravar o vídeo num pendrive e usar o OpenELEC ou o RaspBMC (ambos os sistemas vêm gravados no cartão de memória).

Apesar de ser bastante modesto na sua capacidade de processamento, ele é rápido o suficiente para emular os computadores de 8 bits dos anos 1980. O primeiro sistema que testei foi o Fuse (emulador de Spectrum). Os jogos são primitivos, mas divertidos. World of Spectrum deve ter quase todos os jogos já escritos para o Spectrum.

Então, essa pequena e barata caixa tem o potencial para tornar-se, sem exigir conhecimento técnico avançado, um centro de diversão, substituindo (com a ajuda da TV) o DVD, o videogame (com jogos mais limitados, claro) e o aparelho de som. Tudo isso consumindo 700mA. Quando tivermos celulares com saída de vídeo e várias portas USB, não haverá motivo para possuir qualquer outro computador (Ubuntu Edge foi a primeira tentativa desse gênero).

segunda-feira, 2 de junho de 2014

Procurando um valor no Oracle

Uma aplicação de ERP estava gerando um erro e eu precisava encontrar o registro no banco de dados (Oracle). As tabelas têm nomes inescrutáveis, então decidi que eu tinha que pesquisar todas para encontrar o valor que enxergava no monitor.

A solução foi bastante simples; com a ajuda dos metadados, percorri todas as colunas de tipos interessantes a procura do valor.


declare
  s varchar2(4096);
begin
  for i in (select * 
            from all_tab_cols 
            where owner='XY' 
                  and data_type in ('NUMBER','VARCHAR2') 
            order by table_name) 
  loop
    begin
      execute immediate 'select '||i.column_name
                     ||' from xy.'||i.table_name
                     ||' where '||i.column_name||'=''145960''' 
              into s;
      dbms_output.put_line(i.table_name||'.'||i.column_name);
    exception when no_data_found then null;
    end;
  end loop;
end;
Isto é, determinei que no esquema XY apenas interessam as colunas NUMBER e VARCHAR2 e pesquisei coluna por coluna todas as tabelas. Por sorte, XY tem, ao todo, pouco mais que 1 milhão de registros. O valor que eu procurava era 145960, como se pode deduzir da consulta gerada para cada coluna. Se a consulta não retorna nada, o Oracle lança o erro no_data_found. Por isso, o dbms_output.put_line() só é executado quando o valor for encontrado.

Em poucos segundos, encontrei a tabela e a coluna. Devido ao sucesso fácil, não encontrei motivos para transformar a consulta numa procedure ou numa function.

quinta-feira, 29 de maio de 2014

Java e seus problemas

Os dois primeiros dos cinco objetivos iniciais da linguagem Java eram:
  1. Que a linguagem deve ser simples,orientada a objetos e familiar;
  2. Que seja robusta e segura.
A sintaxe inicial era, de fato, simples. Com o tempo foram adicionadas complicações, como os tipos genéricos. Por ser simples, robusta e segura, no entanto, a linguagem sempre foi prolixa.
Justamente pela quantidade de código necessária para executar as atividades mais simples, mesmo os mais ávidos programadores Java parecem não gostar de programar em Java. E então vemos uma grande quantidade de frameworks nos quais pode-se programar em XML e fazer muito pouco em Java. 
Então, jogam-se pela janela a robustez e a segurança para que se possa diminuir o número de linhas em Java. Aparentemente, o número de linhas em XML não tem relevância. Adoto a filosofia Lisp: não gosto de diferenciar configuração de programação. Se troco uma linha de código por dez de configuração, o sistema fica mais complexo.
As evoluções na sintaxe tratam de tornar a linguagem mais flexível, mas têm que conviver com o modelo antigo de execução. Java, entretanto, não foi criada para ser uma ferramenta de ponta. Ela foi criada para ser o novo COBOL. Por isso, ela deveria, creio eu, tentar manter a sintaxe simples, acessível, e legível. Surpreendentemente, coisas simples, como strings multilinhas e sintaxe para hashes, não foram adicionados à sintaxe ainda.
Parece-me que Java está tentando muito ser o que não é e está sofrendo por isso.

quarta-feira, 21 de maio de 2014

Monitorando a infraestrutura

Recentemente, passei por muitos problemas com a infraestrutura da Oracle (e a falta de interesse do suporte em resolvê-los). Para assegurar-me de que não havia um problema de rede, resolvi monitorar dois serviços básicos: o banco e o ldap.

Usando Perl e o netcat (comando nc no Linux), escrevi um pequeno script para monitorar as conexões do servidor de aplicações.

#!/usr/bin/perl

$|=1;
my $dump;
my %hosts=(srv1=>1521,srv2=>389);
my $out;
for my $host (keys %hosts) {
  my $port=$hosts{$host};
  $out=`nc -z $host $port`;
  if($out!~/succeeded/) {
    open($dump,'>>', '/tmp/monitor.txt');
    print $dump `date`;
    print $dump "$host $port Failed\n";
    close($dump);
  }
}

O hash %hosts associa cada servidor a uma porta e o comando "nc -z" realiza o trabalho de testar a conexão. Se o resultado não contiver a palavra "succeeded", imprime-se a data e a combinação de servidor e porta que falhou.

Ele registra apenas as tentativas mal-sucedidas para evitar que o arquivo monitor.txt cresça muito.

Adicionei uma linha à cron, para executar o script uma vez por minuto:

* * * * * /home/forinti/monitor.pl

E assim constatei que meus problemas nada tinham a ver com a rede.

quinta-feira, 8 de maio de 2014

Supercotas

As cotas nas universidades não cessam de gerar polêmica, mas é difícil encontrar alguma opinião sobre a necessidade de diversidade no âmbito acadêmico. Sim, porque o objetivo das cotas é, justamente, dar mais cor ao meio universitário.

Comumente, as universidades são vistas como um meio para uma carreira lucrativa, não como centros de produção de conhecimento. Quem vê o curso superior como preparação para o mercado de trabalho, pode muito bem ignorar a necessidade de variedade; quem o vê com objetivos mais amplos, não pode ignorar a importância da diversidade.

Atualmente, essa injeção de diversidade concentra-se justamente na dimensão racial/étnica. É um começo, mas o processo seletivo continua o mesmo; selecionam-se candidatos capazes de guardar um volume enciclopédico de conhecimento e que tenham o tempo necessário para a preparação. Nesse sentido, os cotistas não são muito diferentes dos demais.

Eu proponho que as cotas sejam transformadas em supercotas e creio que, no processo, criaríamos um vestibular mais democrático ainda.

A solução é simples: as vagas seriam sorteadas entre todos os aprovados com a nota mínima. Desta forma, seria atingida de maneira simples a diversidade máxima. Todas as dimensões de diversidade seriam contempladas num único sistema, sem que nenhum segmento fosse destacado: negros, índios, mulheres, pobres, ricos, criativos, concentrados, distraídos, etc.

Além disso, o vestibular atual cria a ilusão de que os que não são aprovados merecem seu destino e isso acaba por abafar a discussão sobre o número de vagas. Para a educação primária e secundária, ninguém discute a necessidade de haver vagas para todos, mas para o terceiro grau aceita-se que existam vagas para apenas 5% dos candidatos. Num sistema por sorteio, encontrando-se todos os candidatos nas mesmas condições, é de se esperar que cresça a pressão por mais vagas nas universidades públicas.