Log para Doctrine2 e ZF2

Bom dia pessoal!

Perguntaram num forum sobre como logar as alterações nas entidades usando Doctrine2 e Zend Framework 2. Ano passado eu criei uma série de módulos para usar nos meus projetos e me ajudar a me familiarizar com o ZF2, que na época ainda estava em beta, e um deles foi justamente logar todos os sqls feitos e todas as alterações nas entidades (inserir, alterar e remover).

Então hoje vou falar um pouco sobre isso.

Classe Abstrata

Como vamos usar 2 logs neste post, no meu caso uso 4 mas com outras finalidades, vamos criar uma classe abstrata com as funções em comum:

Não há muito mistério desde código. Apenas criarmos um logger estendendo do Zend\Log e definimos onde ele vai salvar o log e com que nome .

Logando SQL

Para logar todo sql feito no banco de dados, usando Doctrine, primeiro devemos criar uma classe:

Uma observação importante é que para nosso log funcionar, nossa classe deve implementar a interface Doctrine\DBAL\Logging\SQLLogger (linha 19).

A função startQuery é chamada automaticamente pelo Doctrine sempre antes de executar qualquer sql no banco de dados.

Com nossa função pronta, podemos passar a chamá-la. Vamos acrescentarmos algumas linhas na função onBootstrap do arquivo Module.php (pode ser o Application ou qualquer outro):

Primeiramente, não esqueça de adicionar os 2 uses no seu arquivo (linhas 3 e 4) e alterar a linha 4 para o caminho do seu SQLLogger.

Aqui criamos o nosso logger e o acrescentamos à corrente de logs do Doctrine, ou definimos uma caso esteja vazia.

Pronto, simples e rápido.

Um SELECT será salvo assim:

Ou no caso de um insert:

Update:

Delete:

 Logando Entidades

Outra função útil são as alterações nas entidades do projeto. Já podemos saber todas as alterações através do banco de dados, mas é muito baixo nível. Se uma entidade é dividida em várias tabelas por exemplo, fica complicado analisar as alterações.

O Doctrine nos oferece outro recurso para tratar as entidades e não somente o sql. Aí entra o sistema de eventos do Doctrine.

Assim como no ZF2, o Doctrine possui um sistema de eventos que e disparado sempre que algumas condições são alcançadas e podemos capturar estes eventos, para fazer ajustes antes de salvar ou, no nosso caso, criar um log.

Vamos ao código:

Devemos implementar a interface Doctrine\Common\EventSubscriber e definir quais eventos vamos “escutar” (linha 25). No nosso caso, vamos escutar o evento “onFlush” que acontece imediatamente antes de salvar no banco de dados.

Um detalhe importante de usar o onFlush é que como acontece antes de salvar no banco, se der algum erro você terá logado da mesma maneira. Eu preferi salvar no onFlush ao invés de outros eventos, como postFlush, postUpdate, postRemove e postPersist, pois se der algum erro eu preciso saber exatamente onde deu o erro, o que tentei salvar que gerou o erro? Sabendo qual a entidade e os dados facilita muito.

Usar o log no onFlush não é recomendado para fins de auditoria (usuário alterou registro X), justamente porque o dado ainda não foi salvo no banco.

Para quem já trabalha com Doctrine2 sabe que as operações vão sendo “acumuladas” com persist e remove e apenas executadas quando o “flush” é chamado. No “onFlush” todas as entidades alteradas estão disponíveis através das funções:

  • getScheduledEntityInsertions() = Entidades marcadas para serem inseridas.
  • getScheduledEntityUpdates() = Entidades que sofreram alteração.
  • getScheduledEntityDeletions() = Entidades marcadas para serem excluídas.

Para ativar o logger acrescente as linhas abaixo, por exemplo, no “config/autoload/local.php”:

E como fica nosso log?

Inserindo:

Alterando:

Excluindo:

Usando a função getEntityChangeSet, temos apenas os campos alterados, o que facilita vermos o que realmente foi alterado. No caso do insert o valor do campo antes será sempre “null”.

Referência:

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html

Até a próxima!

Leandro Silva

PHP developer since 1997, loves movies, music and dogs.

2 Comentários para: “Log para Doctrine2 e ZF2

  1. Pingback: LosLog no GitHub | Leandro Silva

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

*