2011年4月29日 星期五

Show Transaction status for log file.

在查Spring Transaction 的時候,看到一個例子,
在Log日誌檔裡的每行加上Transaction 的狀態
[+] or [-] ,
主要是透過Reflect 的機制去取TransactionSynchronizationManager class
再取得isActualTransactionActive 屬性,來決定Transaction的狀態,
這邊log4j要使用xml格式,不能使用properties檔


TransactionIndicatingFilter.java
import static com.gfactor.emaildiscovery.utils.TransactionIndicatingUtil.getTransactionStatus;

import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;

public class TransactionIndicatingFilter extends Filter {
    @Override
    public int decide(LoggingEvent loggingEvent) {
        loggingEvent.setProperty("xaName", getTransactionStatus(true) );
        loggingEvent.setProperty("xaStatus", getTransactionStatus(false) );
        return Filter.NEUTRAL;
    }  
}

TransactionIndicatingUtil.java
package com.gfactor.emaildiscovery.utils;

public class TransactionIndicatingUtil {
 private final static String TSM_CLASSNAME = "org.springframework.transaction.support.TransactionSynchronizationManager";

 public static String getTransactionStatus(boolean verbose) {
  String status = null;

  try {
   ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
   
   if (contextClassLoader != null) {
    Class tsmClass = contextClassLoader.loadClass(TSM_CLASSNAME);
    Boolean isActive = (Boolean) tsmClass.getMethod("isActualTransactionActive", null).invoke(null, null);
    
    if (!verbose) {
     status = (isActive) ? "[ ] " : "[-] ";
    } else {
     String transactionName = (String) tsmClass.getMethod("getCurrentTransactionName", null).invoke(null,null);
     
     status = (isActive) ? "["   transactionName   "] " : "[no transaction] ";
    }
   } else {
    status = (verbose) ? "[ccl unavailable] " : "[x ]";
   }
  } catch (Exception e) {
   status = (verbose) ? "[spring unavailable] " : "[x ]";
  }
  return status;
 }
}


log4j.xml 在appender裡面加上filter class, param name加上[%X{xaStatus}]
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%d{HH:mm:ss} [%-5p] %F:%L - %m%n  Ts-[%X{xaStatus}] ," />
  </layout>
  <filter class="com.gfactor.emaildiscovery.utils.TransactionIndicatingFilter" />
 </appender>

沒有留言:

張貼留言