成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Log42j 源代碼分析:日志回滾

libin19890520 / 1322人閱讀

摘要:前言一般都會(huì)對(duì)應(yīng)用程序日志做回滾處理,本文簡(jiǎn)要分析日志回滾實(shí)現(xiàn)觸發(fā)策略使用接口來抽象日志回滾觸發(fā)策略,使用了設(shè)計(jì)模式方法用于初始化策略,方法用于判斷是否需要回滾,接口的不同實(shí)現(xiàn)類對(duì)應(yīng)不同的策略組合模式,聚合不同的策略類基于時(shí)間的回滾策略基于

前言

一般都會(huì)對(duì)應(yīng)用程序日志做回滾處理,本文簡(jiǎn)要分析 log4j2 日志回滾實(shí)現(xiàn)

觸發(fā)策略

log4j2 使用 TriggeringPolity 接口來抽象日志回滾觸發(fā)策略,使用了 Strategy + Compose 設(shè)計(jì)模式

public interface TriggeringPolicy {
    void initialize(final RollingFileManager manager);
    boolean isTriggeringEvent(final LogEvent event);
}

initialize 方法用于初始化策略,isTriggeringEvent 方法用于判斷是否需要回滾,TriggeringPolicy 接口的不同實(shí)現(xiàn)類對(duì)應(yīng)不同的策略

// 組合模式,聚合不同的策略類
public final class CompositeTriggeringPolicy implements TriggeringPolicy {
    ...
}
// 基于時(shí)間的回滾策略
public final class TimeBasedTriggeringPolicy implements TriggeringPolicy {
    ...
}
// 基于文件大小的回滾策略
public final class SizeBasedTriggeringPolicy implements TriggeringPolicy {
    ...
}
基于時(shí)間的觸發(fā)策略 回滾策略

log4j2 使用 RolloverStrategy 接口抽象日志回滾策略

public interface RolloverStrategy {
    RolloverDescription rollover(final RollingFileManager manager)
        throws SecurityException;
}

rollover 方法并不直接執(zhí)行回滾操作,而是返回一個(gè) RolloverDescription 接口,該接口用于獲取日志回滾需要進(jìn)行的操作: Action

public interface RolloverDescription {
    String getActiveFileName();
    boolean getAppend();
    Action getSynchronous();
    Action getAsynchronous();
}
回滾動(dòng)作

log4j2 使用 Action 接口抽象日志回滾過程中的一系列動(dòng)作,使用了 Command + Compose 設(shè)計(jì)模式

public interface Action extends Runnable {
    boolean execute() throws IOException;
    void close();
    boolean isComplete();
}

AbstractAction 類是 Action 接口的抽象實(shí)現(xiàn),使用了 Method template 設(shè)計(jì)模式,子類通過 override execute 方法執(zhí)行不同的動(dòng)作

public synchronized void run() {
    if (!interrupted) {
        try {
            execute();
        } catch (final IOException ex) {
            reportException(ex);
        }
        complete = true;
        interrupted = true;
    }
}

public abstract boolean execute() throws IOException;

文件重命名,F(xiàn)ileRenameAction

文件刪除,DeleteAction

文件壓縮,GzCompressAction, ZipCompressAction

聚合,CompositeAction

回滾管理

log4j2 每個(gè) Appender 都有一個(gè) Manager 與之對(duì)應(yīng)(多對(duì)一), RollingFileAppender 對(duì)應(yīng)的 Manager 為RollingFileManager, 它管理著日志的寫入,回滾 .etc,類層次結(jié)構(gòu)

AbstractManager
    OutputStreamManager
        FileManager
            RollingFileManager

非常經(jīng)典的 面向?qū)ο?設(shè)計(jì),單一職責(zé). AbstractManager 保存 Manager 基本信息,例如 name(名字),count(引用計(jì)數(shù)),并提供靜態(tài)工廠方法根據(jù)名字獲取 Manager,這個(gè)方法同樣值得學(xué)習(xí)和借鑒

    public static  M getManager(final String name,
        final ManagerFactory factory, final T data) {
        // 獲取鎖
        LOCK.lock();
        try {
            @SuppressWarnings("unchecked")
            M manager = (M) MAP.get(name);
            if (manager == null) {
                // 使用工廠類創(chuàng)建具體的 Manager
                manager = factory.createManager(name, data);
                if (manager == null) {
                    throw new IllegalStateException("ManagerFactory [" + factory + "] 
                    unable to create manager for ["
                            + name + "] with data [" + data + "]");
                }
                MAP.put(name, manager);
            } else {
                manager.updateData(data);
            }
            // 增加引用計(jì)數(shù)
            manager.count++;
            return manager;
        } finally {
            // 釋放鎖
            LOCK.unlock();
        }
    }

RollingFileAppender 在 append LogEvent 時(shí)會(huì)先調(diào)用 RollingFileManager 的 checkRollover 方法嘗試進(jìn)行日志回滾,然后再調(diào)用父類的 append 方法,這種子類通過 override 方法 "攔截" 父類默認(rèn)實(shí)現(xiàn)增加自己的處理邏輯的方法很常見

// RollingFileAppender.java

@Override
public void append(final LogEvent event) {
    getManager().checkRollover(event);
    super.append(event);
}

RollingFileManager 的 checkRollover 方法使用上文提到的 觸發(fā)策略類 TriggeringPolicy 判斷是否符合觸發(fā)條件,如果符合調(diào)用 rollover 方法

public synchronized void checkRollover(final LogEvent event) {
    if (triggeringPolicy.isTriggeringEvent(event)) {
        rollover();
    }
}

不帶參數(shù)的 rollover 方法最終調(diào)用帶 RolloverStrategy(回滾策略)類型參數(shù)的版本,為了代碼顯示更加緊湊特意省略掉了日志輸出和異常處理邏輯,有幾個(gè)地方值得品味

使用信號(hào)量進(jìn)行同步,所以不要太頻繁打 log 觸發(fā)回滾,會(huì) block 線程

同步 Action 在當(dāng)前線程立即執(zhí)行,異步 Action 則啟動(dòng)一個(gè)線程執(zhí)行

如果異步 Action 很可執(zhí)行完畢(某些極端情況),finally 語句塊會(huì)釋放 semaphore

    private boolean rollover(final RolloverStrategy strategy) {
        semaphore.acquire();
        boolean success = false;
        Thread thread = null;
        try {
            final RolloverDescription descriptor = strategy.rollover(this);
            if (descriptor != null) {
                writeFooter();
                close();
                if (descriptor.getSynchronous() != null) {
                    success = descriptor.getSynchronous().execute();
                }
                if (success && descriptor.getAsynchronous() != null) {
                    thread = new Log4jThread(new AsyncAction(
                        descriptor.getAsynchronous(), this));
                    thread.start();
                }
                return true;
            }
            return false;
        } finally {
            if (thread == null || !thread.isAlive()) {
                semaphore.release();
            }
        }
    }
總結(jié)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/66823.html

相關(guān)文章

  • Log42j 代碼分析:plugin(插件)機(jī)制

    摘要:前言使用插件機(jī)制加載各種組件,本文簡(jiǎn)要分析插件機(jī)制實(shí)現(xiàn)注解注解提供了一種便捷的方法將一個(gè)類聲明成的插件,比如,單例類用來保存插件信息,暴露了一些方法從配置文件中加載內(nèi)置插件,使用了單例設(shè)計(jì)模式線程安全的數(shù)據(jù)結(jié)構(gòu)使用了一些多線程編程的最佳實(shí)踐 前言 log4j2 使用插件機(jī)制加載各種組件:appender, logger .etc,本文簡(jiǎn)要分析 log4j2 插件機(jī)制實(shí)現(xiàn) Plugin ...

    learning 評(píng)論0 收藏0
  • 分布式事務(wù)中間件Seata的設(shè)計(jì)原理

    摘要:如上圖所示,的實(shí)際上是已中間件的形式放在應(yīng)用層,不用依賴數(shù)據(jù)庫對(duì)協(xié)議的支持,完全剝離了分布式事務(wù)方案對(duì)數(shù)據(jù)庫在協(xié)議支持上的要求。 微信公眾號(hào)「后端進(jìn)階」,專注后端技術(shù)分享:Java、Golang、WEB框架、分布式中間件、服務(wù)治理等等。 在微服務(wù)架構(gòu)體系下,我們可以按照業(yè)務(wù)模塊分層設(shè)計(jì),單獨(dú)部署,減輕了服務(wù)部署壓力,也解耦了業(yè)務(wù)的耦合,避免了應(yīng)用逐漸變成一個(gè)龐然怪物,從而可以輕松擴(kuò)展,...

    Kylin_Mountain 評(píng)論0 收藏0
  • Python模塊分析:第4節(jié)-logging日志模塊

    摘要:上一篇文章模塊分析第節(jié)模塊一日志記錄的級(jí)別優(yōu)先級(jí),記錄調(diào)試的詳細(xì)信息,只在調(diào)試時(shí)開啟優(yōu)先級(jí),記錄普通的消息,報(bào)告錯(cuò)誤和警告等待。監(jiān)聽端口號(hào)上一篇文章模塊分析第節(jié)模塊 上一篇文章:Python模塊分析:第3節(jié)-typing模塊 一、日志記錄的級(jí)別 debug:優(yōu)先級(jí)10,記錄調(diào)試的詳細(xì)信息,只在調(diào)試時(shí)開啟 info:優(yōu)先級(jí)20,記錄普通的消息,報(bào)告錯(cuò)誤和警告等待。 warning:優(yōu)...

    MartinHan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<