AOP日誌詳解

一、AOP日誌處理

AOP(Aspect-Oriented Programming,面向切面編程)是一種編程思想和技術,可以將一些與業務無關,卻在多個模塊或層中經常出現的重複操作,如日誌、事務、異常處理等,抽象為一些可重用的模塊,即切面(Aspect),並將其與業務模塊進行關聯。當業務模塊執行時,切面在特定的時機被織入到業務模塊中,從而達到了橫向抽取重複代碼的目的。

在使用AOP時,日誌處理是其中最常見的場景之一。我們可以使用AOP實現統一的日誌輸出、日誌記錄、日誌分析等功能,並且不對業務代碼進行侵入。

二、AOP日誌怎麼實現

AOP日誌的實現主要包括以下幾個步驟:

1.定義切面類

public class LogAspect {
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void pointCut(){}

    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        System.out.printf("LogBefore... srcClass:%s,method:%s\n",joinPoint.getTarget().getClass(),joinPoint.getSignature().getName());
    }

    @After("pointCut()")
    public void after(JoinPoint joinPoint){
        System.out.printf("LogAfter... srcClass:%s,method:%s\n",joinPoint.getTarget().getClass(),joinPoint.getSignature().getName());
    }
}

2.將切面類聲明為切面

@Aspect
@Component
public class LogAspect {
    ...
}

3.啟用AOP

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
    ...
}

三、AOP日誌記錄

日誌記錄是AOP日誌功能的重要組成部分。我們可以通過以下方式將日誌記錄到本地文件或其他數據存儲設備中。

1.使用Log4j2實現日誌記錄

@Configuration
public class LogConfig {
    @Bean
    public org.springframework.boot.logging.LoggingSystem loggingSystem() throws Exception {
        return new Log4j2LoggingSystem();
    }
}

2.配置Log4J2日誌輸出



    
        
            
        
        
            
                %d %p %c{1.} [%t] %m%n
            
            
                
                
            
            
        
    
    
        
            
            
        
        
            
        
    

四、AOP日誌管理

對於大型項目,日誌管理十分重要。我們需要合理的管理日誌文件,對日誌進行分析和監控,保障系統的正常運行。

1.使用ELK Stack對日誌進行集中管理

ELK Stack指的是Elasticsearch、Logstash、Kibana三者的組合。其中,Elasticsearch用於存儲日誌數據,Logstash用於收集、處理和轉化數據,Kibana用於展示、查詢和分析數據。

2.配置Logstash收集日誌

input {
  file {
    path => "/var/log/my-app.log"
    type => "my-app"
  }
}

filter {
  grok {
    match => [ "message", "%{TIMESTAMP_ISO8601:timestamp} \[%{WORD:thread}\] %{LOGLEVEL:loglevel} %{GREEDYDATA:msg}" ]
  }
}

output {
  elasticsearch {
    hosts => [ "localhost:9200" ]
    index => "my-app-%{+YYYY.MM.dd}"
  }
}

五、AOP日誌輸出

日誌輸出是AOP日誌功能中最常見的操作之一。我們可以通過以下方式將日誌輸出,方便進行調試和排查問題。

1.使用Logback實現日誌輸出


  
    
      %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
    
  

  
    
  

  
    
  

2.通過郵箱將日誌輸出

private void sendEmail(String subject, String content) {
    SimpleMailMessage message = new SimpleMailMessage();
    message.setTo("recipient@example.com");
    message.setSubject(subject);
    message.setText(content);
    sender.send(message);
}

六、AOP日誌多線程

多線程是現在的主流編程方式之一,而AOP日誌同樣支持多線程。我們可以通過以下方式處理多線程的日誌輸出。

1.使用ThreadLocal保存線程上下文

public class ContextHolder {
    private static ThreadLocal contextHolder = new ThreadLocal();

    public static Context getContext() {
        if (contextHolder.get() == null) {
            contextHolder.set(new Context());
        }
        return contextHolder.get();
    }

    public static void clear() {
        contextHolder.set(null);
    }
}

2.在切面中處理線程上下文

@Around("@annotation(log)")
public Object process(ProceedingJoinPoint joinPoint, Log log) throws Throwable {
    Context context = ContextHolder.getContext();
    context.setUsername(log.username());

    try {
        Object result = joinPoint.proceed();
        return result;
    } finally {
        ContextHolder.clear();
    }
}

七、AOP記錄日誌

記錄日誌是AOP日誌的核心功能之一,可以為我們提供詳細的系統運行記錄,方便日後排查問題。

1.AOP方式實現日誌記錄

@Aspect
@Component
public class LogAspect {
    private Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Pointcut("execution(* com.example.service.*.*(..))")
    public void pointCut(){}

    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        logger.info("LogBefore... srcClass:{},method:{}",joinPoint.getTarget().getClass(),joinPoint.getSignature().getName());
    }

    @After("pointCut()")
    public void after(JoinPoint joinPoint){
        logger.info("LogAfter... srcClass:{},method:{}",joinPoint.getTarget().getClass(),joinPoint.getSignature().getName());
    }
}

2.使用註解方式記錄日誌

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value();
}

@Service
public class UserService {
    @Log("Add user")
    public void addUser(User user) {
        ...
    }
}

八、AOP註解方式

AOP註解方式是AOP日誌的一種實現方式,可以更加方便地為業務代碼添加切面。我們可以使用Spring AOP註解實現AOP日誌的功能

1.在切面類中添加註解

@Aspect
@Component
public class LogAspect {
    private Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Pointcut("execution(* com.example.service.*.*(..))")
    public void pointCut(){}

    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        logger.info("LogBefore... srcClass:{},method:{}",joinPoint.getTarget().getClass(),joinPoint.getSignature().getName());
    }

    @After("pointCut()")
    public void after(JoinPoint joinPoint){
        logger.info("LogAfter... srcClass:{},method:{}",joinPoint.getTarget().getClass(),joinPoint.getSignature().getName());
    }
}

2.在業務類中添加註解

@Service
public class UserService {
    @LogAnnotation
    public void addUser(User user) {
        ...
    }
}

九、AOP實現日誌功能步驟

1.定義切面類

@Aspect
@Component
public class LogAspect {
    private Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Pointcut("execution(* com.example.service.*.*(..))")
    public void pointCut(){}

    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        logger.info("LogBefore... srcClass:{},method:{}",joinPoint.getTarget().getClass(),joinPoint.getSignature().getName());
    }

    @After("pointCut()")
    public void after(JoinPoint joinPoint){
        logger.info("LogAfter... srcClass:{},method:{}",joinPoint.getTarget().getClass(),joinPoint.getSignature().getName());
    }
}

2.聲明切面類

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
    @Bean
    public LogAspect logAspect() {
        return new LogAspect();
    }
}

3.使用切面類的日誌方法

@Service
public class UserService {
    public void addUser(User user) {
        LogAspect.logBefore();
        ...
        LogAspect.logAfter();
    }
}

十、Spring AOP的註解

在Spring中,我們可以使用註解的方式實現AOP功能。以下是Spring AOP中與AOP日誌相關的註解示例。

1.@Aspect註解:標明該類為切面類

2.@Pointcut註解:定義切點,通常使用execution表達式進行定義

3.@Before註解:在切點之前執行

4.@After註解:在切點之後執行

5.@Around註解:包含了@Before和@After的功能,可以精確控制執行時間點

6.@AfterReturning註解:在方法返回結果後執行

7.@AfterThrowing註解:在方法拋出異常時執行

十一、總結

AOP日誌是一個在現代開發中十分重要的功能,使用AOP方式實現日誌功能可以為我們提供更加簡潔、易讀的代碼和高效、精確的記錄和輸出方式。我們可以使用多種方式去實現AOP日誌,包括註解方式、XML配置方式以及Java配置方式等等。無論使用哪種方式,我們都需要深入了解AOP日誌的核心思想和實現方式,才能夠更加靈活地運用到業務場景之中。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/180157.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-22 05:11
下一篇 2024-11-22 05:11

相關推薦

  • Cron執行日誌用法介紹

    本文將從多個方面對cron執行日誌進行詳細闡述,包括cron執行日誌的定義、cron執行日誌的產生原因、cron執行日誌的格式以及如何解讀cron執行日誌。 一、定義 Cron是一…

    編程 2025-04-29
  • Hibernate日誌列印sql參數

    本文將從多個方面介紹如何在Hibernate中列印SQL參數。Hibernate作為一種ORM框架,可以通過列印SQL參數方便開發者調試和優化Hibernate應用。 一、通過配置…

    編程 2025-04-29
  • 使用Snare服務收集日誌:完整教程

    本教程將介紹如何使用Snare服務收集Windows伺服器上的日誌,並將其發送到遠程伺服器進行集中管理。 一、安裝和配置Snare 1、下載Snare安裝程序並安裝。 https:…

    編程 2025-04-29
  • Log4j日誌列印到Systemout.log

    Log4j是Apache的一個強大的日誌組件,可以幫助開發者更好地管理日誌。在Java應用程序中,很多開發者都會選擇使用Log4j來實現日誌輸出。本文將介紹如何使用Log4j將日誌…

    編程 2025-04-28
  • 如何將Linux系統日誌發送到日誌伺服器

    本文將介紹如何將Linux系統日誌發送到日誌伺服器,以方便管理和監控系統狀態。 一、安裝rsyslog軟體包 rsyslog是Linux系統上默認的系統日誌軟體,用於收集系統事件和…

    編程 2025-04-27
  • SpringBoot如何設置不輸出Info日誌

    本篇文章將帶您了解如何在SpringBoot項目中關閉Info級別日誌輸出。 一、為什麼要關閉Info日誌 在開發中,我們經常會使用Log4j、Logback等框架來輸出日誌信息,…

    編程 2025-04-27
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁碟中。在執行sync之前,所有的文件系統更新將不會立即寫入磁碟,而是先緩存在內存…

    編程 2025-04-25
  • 神經網路代碼詳解

    神經網路作為一種人工智慧技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網路的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網路模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web伺服器。nginx是一個高性能的反向代理web伺服器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25
  • Python輸入輸出詳解

    一、文件讀寫 Python中文件的讀寫操作是必不可少的基本技能之一。讀寫文件分別使用open()函數中的’r’和’w’參數,讀取文件…

    編程 2025-04-25

發表回復

登錄後才能評論