欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

logback的FileAppender文件追加模式和沖突檢測(cè)解讀

 更新時(shí)間:2023年10月30日 10:02:11   作者:codecraft  
這篇文章主要為大家介紹了logback的FileAppender文件追加模式和沖突檢測(cè)解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下logback的FileAppender

FileAppender

ch/qos/logback/core/FileAppender.java

public class FileAppender<E> extends OutputStreamAppender<E> {
    public static final long DEFAULT_BUFFER_SIZE = 8192;
    static protected String COLLISION_WITH_EARLIER_APPENDER_URL = CODES_URL + "#earlier_fa_collision";
    /**
     * Append to or truncate the file? The default value for this variable is
     * <code>true</code>, meaning that by default a <code>FileAppender</code> will
     * append to an existing file and not truncate it.
     */
    protected boolean append = true;
    /**
     * The name of the active log file.
     */
    protected String fileName = null;
    private boolean prudent = false;
    private FileSize bufferSize = new FileSize(DEFAULT_BUFFER_SIZE);
    //......
}
FileAppender繼承了OutputStreamAppender,它定義了append、prudent、bufferSize屬性

start

public void start() {
        int errors = 0;
        if (getFile() != null) {
            addInfo("File property is set to [" + fileName + "]");
            if (prudent) {
                if (!isAppend()) {
                    setAppend(true);
                    addWarn("Setting \"Append\" property to true on account of \"Prudent\" mode");
                }
            }
            if (checkForFileCollisionInPreviousFileAppenders()) {
                addError("Collisions detected with FileAppender/RollingAppender instances defined earlier. Aborting.");
                addError(MORE_INFO_PREFIX + COLLISION_WITH_EARLIER_APPENDER_URL);
                errors++;
            } else {
                // file should be opened only if collision free
                try {
                    openFile(getFile());
                } catch (java.io.IOException e) {
                    errors++;
                    addError("openFile(" + fileName + "," + append + ") call failed.", e);
                }
            }
        } else {
            errors++;
            addError("\"File\" property not set for appender named [" + name + "].");
        }
        if (errors == 0) {
            super.start();
        }
    }
start方法要求fileName必須有值,在prudent模式下會(huì)強(qiáng)制開啟append;另外start的時(shí)候會(huì)執(zhí)行checkForFileCollisionInPreviousFileAppenders判斷是否有沖突,沒有沖突則執(zhí)行openFile方法

checkForFileCollisionInPreviousFileAppenders

protected boolean checkForFileCollisionInPreviousFileAppenders() {
        boolean collisionsDetected = false;
        if (fileName == null) {
            return false;
        }
        @SuppressWarnings("unchecked")
        Map<String, String> map = (Map<String, String>) context.getObject(CoreConstants.FA_FILENAME_COLLISION_MAP);
        if (map == null) {
            return collisionsDetected;
        }
        for (Entry<String, String> entry : map.entrySet()) {
            if (fileName.equals(entry.getValue())) {
                addErrorForCollision("File", entry.getValue(), entry.getKey());
                collisionsDetected = true;
            }
        }
        if (name != null) {
            map.put(getName(), fileName);
        }
        return collisionsDetected;
    }
checkForFileCollisionInPreviousFileAppenders方法從上下文讀取FA_FILENAME_COLLISION_MAP,判斷有沒有文件名重復(fù)的,有則返回true

openFile

public void openFile(String file_name) throws IOException {
        lock.lock();
        try {
            File file = new File(file_name);
            boolean result = FileUtil.createMissingParentDirectories(file);
            if (!result) {
                addError("Failed to create parent directories for [" + file.getAbsolutePath() + "]");
            }

            ResilientFileOutputStream resilientFos = new ResilientFileOutputStream(file, append, bufferSize.getSize());
            resilientFos.setContext(context);
            setOutputStream(resilientFos);
        } finally {
            lock.unlock();
        }
    }
openFile方法加鎖創(chuàng)建file,然后通過createMissingParentDirectories來創(chuàng)建不存在的父目錄,最后創(chuàng)建根據(jù)file、append參數(shù)、bufferSize來創(chuàng)建ResilientFileOutputStream

stop

public void stop() {
        super.stop();

        Map<String, String> map = ContextUtil.getFilenameCollisionMap(context);
        if (map == null || getName() == null)
            return;

        map.remove(getName());
    }
stop方法會(huì)獲取FA_FILENAME_COLLISION_MAP,移除當(dāng)前文件名

writeOut

protected void writeOut(E event) throws IOException {
        if (prudent) {
            safeWrite(event);
        } else {
            super.writeOut(event);
        }
    }
FileAppender覆蓋了OutputStreamAppender的writeOut方法,在prudent為true時(shí)執(zhí)行safeWrite

safeWrite

private void safeWrite(E event) throws IOException {
        ResilientFileOutputStream resilientFOS = (ResilientFileOutputStream) getOutputStream();
        FileChannel fileChannel = resilientFOS.getChannel();
        if (fileChannel == null) {
            return;
        }
        // Clear any current interrupt (see LOGBACK-875)
        boolean interrupted = Thread.interrupted();
        FileLock fileLock = null;
        try {
            fileLock = fileChannel.lock();
            long position = fileChannel.position();
            long size = fileChannel.size();
            if (size != position) {
                fileChannel.position(size);
            }
            super.writeOut(event);
        } catch (IOException e) {
            // Mainly to catch FileLockInterruptionExceptions (see LOGBACK-875)
            resilientFOS.postIOFailure(e);
        } finally {
            if (fileLock != null && fileLock.isValid()) {
                fileLock.release();
            }
            // Re-interrupt if we started in an interrupted state (see LOGBACK-875)
            if (interrupted) {
                Thread.currentThread().interrupt();
            }
        }
    }
safeWrite會(huì)通過fileChannel.lock()進(jìn)行加鎖,然后執(zhí)行fileChannel.position(size),最后通過父類writeOut進(jìn)行寫入;對(duì)于IOException會(huì)執(zhí)行resilientFOS.postIOFailure(e)

小結(jié)

logback的FileAppender繼承了OutputStreamAppender,它定義了append、prudent、bufferSize屬性,它使用的是ResilientFileOutputStream,其writeOut方法主要是新增了對(duì)prudent模式的支持,在prudent為true時(shí)采用的是safeWrite。

以上就是logback的FileAppender文件追加模式和沖突檢測(cè)解讀的詳細(xì)內(nèi)容,更多關(guān)于logback FileAppender沖突檢測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java 解壓與壓縮文件夾的實(shí)例詳解

    java 解壓與壓縮文件夾的實(shí)例詳解

    這篇文章主要介紹了 java 解壓與壓縮文件夾的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,掌握這樣的方法,需要的朋友可以參考下
    2017-10-10
  • http中g(shù)et請(qǐng)求與post請(qǐng)求區(qū)別及如何選擇

    http中g(shù)et請(qǐng)求與post請(qǐng)求區(qū)別及如何選擇

    這篇文章主要介紹了http中g(shù)et請(qǐng)求與post請(qǐng)求在應(yīng)用中應(yīng)該如何選擇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-09-09
  • Java實(shí)現(xiàn)大文件的分片上傳與下載(springboot+vue3)

    Java實(shí)現(xiàn)大文件的分片上傳與下載(springboot+vue3)

    這篇文章主要為大家詳細(xì)介紹了java基于springboot+vue3如何大文件的分片上傳與下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2023-06-06
  • 一文精通Java中的volatile關(guān)鍵字

    一文精通Java中的volatile關(guān)鍵字

    volatile是java中的關(guān)鍵詞之一,這篇文章主要給大家介紹了關(guān)于Java中volatile關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Nacos(SpringBoot)配置加載及刷新方式

    Nacos(SpringBoot)配置加載及刷新方式

    文章主要介紹了NacosConfigAutoConfiguration的配置加載及刷新過程,包括NacosConfigBeanDefinitionRegistrar的注冊(cè)、NacosPropertySource的處理、自動(dòng)刷新機(jī)制以及NacosValueAnnotationBeanPostProcessor的實(shí)現(xiàn)
    2024-12-12
  • FluentMybatis實(shí)現(xiàn)mybatis動(dòng)態(tài)sql拼裝和fluent api語法

    FluentMybatis實(shí)現(xiàn)mybatis動(dòng)態(tài)sql拼裝和fluent api語法

    本文主要介紹了FluentMybatis實(shí)現(xiàn)mybatis動(dòng)態(tài)sql拼裝和fluent api語法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • springboot?加載本地jar到maven的實(shí)現(xiàn)方法

    springboot?加載本地jar到maven的實(shí)現(xiàn)方法

    如何在SpringBoot項(xiàng)目中加載本地jar到Maven本地倉庫,使用Maven的install-file目標(biāo)來實(shí)現(xiàn),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Scala常用List列表操作方法示例

    Scala常用List列表操作方法示例

    這篇文章主要介紹了Scala常用List列表操作方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Ajax登錄驗(yàn)證實(shí)現(xiàn)代碼

    Ajax登錄驗(yàn)證實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了jQuery+ajax實(shí)現(xiàn)用戶登錄驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Object.wait()與Object.notify()的用法詳細(xì)解析

    Object.wait()與Object.notify()的用法詳細(xì)解析

    以下是對(duì)java中Object.wait()與Object.notify()的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-09-09

最新評(píng)論