2017-10-19 676 views
0

我想用AOP實現一個日誌記錄概念,但打印日誌時我需要給我自己的方法名稱而不是默認值。在Logback中覆蓋方法名稱(%M轉換說明符)

更新(基於@glitch評論):

  • 我使用%M轉換符告訴的logback包括在每個日誌事件的方法名稱。

  • 我想回報某些 logback派生方法名稱spicifically;用於由我的AOP連接點發出的日誌事件。

  • 我不想在日誌事件的其他地方寫'實際方法名'我想要使​​用的方法名稱是正確的,即表示原始方法而不是攔截方法。

+0

你指的「默認」,這是否意味着你使用的是'%M'轉換說明在你的logback模式讓的logback推導方法的名字嗎?您是否想將其替換爲所有日誌事件或僅針對選定的日誌事件?是否必須替換它,或者在日誌消息的其他位置寫入其他方法名稱是否足夠? – glytching

+0

我在兩種方式使用日誌記錄,一種是正常的日誌記錄方法和aspectj AOP。對於正常的日誌記錄方法名稱是正確打印,但對於最終的Logger logger = LoggerFactory.getLogger(pjp.getSignature()。getDeclaringTypeName());這個記錄器打印aop方法而不是確切的方法,我使用'ProceedingJoinPoint' –

+0

在這裏我可以得到確切的方法名稱與pjp.getSignature()。getName(),但記錄器需要打印此方法名稱而不是aop方法名稱,如果這不是possbile我可以用這個方法名稱覆蓋%M –

回答

1

%M轉換說明符由ch.qos.logback.classic.pattern.MethodOfCallerConverter實現。實現相當簡單:

public String convert(ILoggingEvent le) { 
    StackTraceElement[] cda = le.getCallerData(); 
    if (cda != null && cda.length > 0) { 
     return cda[0].getMethodName(); 
    } else { 
     return CallerData.NA; 
    } 
} 

所以,你可以提供自己的實現。像這樣的事情也許......

public class CustomMethodOfCallerConverter extends ClassicConverter { 

    public String convert(ILoggingEvent le) { 
     StackTraceElement[] cda = le.getCallerData(); 
     if (cda != null && cda.length > 0) { 
      if (le.getMDCPropertyMap().containsKey("CUSTOM_METHOD_NAME_KEY")) { 
       String methodName = le.getMDCPropertyMap().get("CUSTOM_METHOD_NAME_KEY"); 
       // remove the MDC entry since we are only using MDC to pass the custom method name into this converter 
       le.getMDCPropertyMap().remove("CUSTOM_METHOD_NAME_KEY"); 
       return methodName; 
      } else { 
       return cda[0].getMethodName(); 
      } 
     } else { 
      return CallerData.NA; 
     } 
    } 
} 

...它使用MDC從您的連接點通過實際的方法名。在您的連接點上,您可以在調用記錄器之前放置MDC值,例如

MDC.put("CUSTOM_METHOD_NAME_KEY", pjp.getSignature().getName())); 

但是... Logback不提供任何方式讓您聲明自己的自定義轉換器。 Logback使用的轉換器在 ch.qos.logback.classic.PatternLayout的靜態初始化器中聲明,並且這不可擴展/可覆蓋。所以,我覺得你的選擇是:

  1. 在自己的代碼庫,即用自己的logback取代自己MethodOfCallerConverter創建ch.qos.logback.classic.pattern.MethodOfCallerConverter類。您可以使用的例子,我的上方,並 - 只要你把MDC的CUSTOM_METHOD_NAME_KEY值調用的記錄之前 - 它會做你想要什麼

  2. 繼續使用%M符,但對於AOP攔截方法添加附加的MDC屬性顯示實際的方法名稱。這會導致Logback方法名稱出現在所有日誌輸出中,同時出現actula方法名稱(如果可用)。例如:

    // put the actual method name in MDC 
    MDC.put("actualMethodName", pjp.getSignature().getName()); 
    
    // specify your pattern - in logback.xml - to include the actual method name 
    %d{yyyy-MM-dd HH:mm:ss}|[%thread]|%-5level|%logger{36}|%M%X{actualMethodName:-}|%msg%n 
    
  3. 停止使用%M符和記錄通過MDC所有方法名。這將導致正確的方法名稱出現,但它會要求您在每種方法中更新MDC(這聽起來很尷尬)。例如:

    // put the actual method name in MDC 
    MDC.put("actualMethodName", pjp.getSignature().getName()); 
    
    // specify your pattern - in logback.xml - to include the actual method name 
    %d{yyyy-MM-dd HH:mm:ss}|[%thread]|%-5level|%logger{36}|%X{actualMethodName}|%msg%n 
    
+0

謝謝你是一個天才,現在一切都像一個cham –

+0

由於Logback提供沒有註冊自己的'%M'轉換說明符的鉤子,你'擴展'通過模仿它的'MethodOfCallerConverter'進行Logback。這種方法有效,但它不是標準的,可能很脆弱;如果未來的Logback版本更改了「MethodOfCallerConverter」的名稱或命名空間,那麼您也必須更改「MethodOfCallerConverter」的版本。只是要記住一些事情.... – glytching