Utilizar insert em uma coluna do tipo cblob pelo log4j

Antes leia o artigo “Utilizar datasource no log4j” para conseguir realizar esse processo.

Continuando o artigo anterior, se deseja persistir o Stacktrace em uma coluna do tipo Blob em seu banco de dados, comece criando a tabela com esse script, lembrando que o nome e tipo de coluna deve depender do banco de dados que está utilizando:

CREATE TABLE LOGS
(
   DATED timestamp NOT NULL,
   NIVEL varchar(10) NOT NULL,
   LOGGER varchar(1000) NOT NULL,
   MENSAGEM varchar(1000) NOT NULL,
   STACKTRACE clob(10000) NOT NULL
);

 
Após criado sua tabela, abra o arquivo log4j.properties e adicione a propriedade formatando seu INSERT para que não tenha problema na ordem de inserção de valores nas colunas.

log4j.appender.JDBC.layout=org.apache.log4j.EnhancedPatternLayout
log4j.appender.JDBC.layout.ConversionPattern=INSERT INTO LOGS (nivel,dated,logger,mensagem,stacktrace) VALUES('%p', '%d{yyyy-MM-dd HH:mm:ss.SSS}','%C.%M(%F:%L)','%m%n','%throwable{100}')

No parâmetro %throable, você pode escolher adicionar mais ou menos informação, para isso existe os seguintes possíveis valores.

%throwable {short} ou {1} a saída será a primeira linha da pilha.
%throwable {none} ou {0} irá suprimir a pilha.
%throwable{n}, onde n é igual ao número de linhas a ser impressa.

No nosso caso utilizamos n igual a 100 linhas, vai do gosto de cada cliente. Eu particularmente acredito que não tenha necessidade de armazenar mais do que isso, além de dificultar a leitura do erro. Raros casos são necessários ler mais do que 100 linhas para identificar problema.

Abraços,
André Rezende

Utilizar datasource no log4j

Passei por um perrengue para descobrir como fazer o log ser persistido no banco de um jndi configurado.
Após passar por esse trabalho todo, do qual tive que ler várias documentações, pretendo descrever passo a passo esse processo que não é nada complicado.

Não quero descrever o uso do LOG4J ou sua finalidade, e sim ser compartilhar o uso de um novo appender do qual obtém uma conexão de banco de dados que foi configurado em seu servidor de aplicação.

Crie sua classe appender, pode ser conforme abaixo:

package br.com.rezende.log4j.appender;

import java.sql.Connection;
import java.sql.SQLException;
import javax.faces.context.FacesContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.apache.log4j.jdbc.JDBCAppender;
import org.apache.log4j.spi.LoggingEvent;

public class MeuJDBCAppender extends JDBCAppender {

private static Logger LOGGER = Logger.getLogger(NGSAppender.class);
private DataSource dataSource;
private static String dataSourceJNDIName;
private static Context context;

/**
* Inicializa o contexto e o datasource.
*/
static {
   try {
    context = new InitialContext();
    dataSourceJNDIName = "jdbc/DS";
   }catch (NamingException e) {
    LOGGER.error(e.getMessage(), e);
   }
}

/**
* Obtém o nome do datasource configurado no Servidor de aplicações.
*
* @return Connection
*/
public Connection getConnection() throws SQLException {
 if (this.dataSource == null) {
  if (this.getDataSourceJNDIName() == null) {
  LOGGER.error("Nome do datasource está vazio.");
  return null;
 }
 try {
  this.dataSource = (DataSource) context.lookup(this
  .getDataSourceJNDIName());
 } catch (NamingException e) {
  LOGGER.error("Problema em obter o datasource");
  throw new SQLException(e);
 }
}
  try {
    return this.dataSource.getConnection();
  } catch (SQLException e) {
    LOGGER.error("Existe problema em obter um nome de datasource.");
    throw e;
  }
}

  public String getDataSourceJNDIName() {
    return dataSourceJNDIName;
  }

}

Mapeie na sua propriedade seu novo appender dentro do log4j.properties:


log4j.rootCategory=ERROR, JDBC, Console

# Console appender
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
# JDBC Database
log4j.appender.JDBC = br.com.rezende.log4j.appender.MeuJDBCAppender
log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout

Para inserir os valores em seu banco, visualize o próximo post, pois é necessário criar a tabela de log e formatar o seu INSERT para persistir a respectiva informação de stacktrace.

Abraços,
André Rezende