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

Java手寫一個(gè)日志框架的示例代碼

 更新時(shí)間:2023年12月29日 09:43:57   作者:樂(lè)樂(lè)家的樂(lè)樂(lè)  
日志框架是一種用于記錄和管理應(yīng)用程序運(yùn)行時(shí)信息的軟件組件,它通常提供了一套API讓開發(fā)人員能夠在代碼中插入日志語(yǔ)句,下面我們就來(lái)學(xué)習(xí)一下如何手寫一個(gè)日志框架吧

什么是日志框架

日志框架是一種用于記錄和管理應(yīng)用程序運(yùn)行時(shí)信息的軟件組件。它通常提供了一套API(Application Programming Interface),讓開發(fā)人員能夠在代碼中插入日志語(yǔ)句,以便在應(yīng)用程序運(yùn)行時(shí)生成有關(guān)其狀態(tài)和執(zhí)行流的信息。

一個(gè)優(yōu)秀的日志框架應(yīng)該具備的功能:

  • 級(jí)別控制: 日志框架通常支持多個(gè)日志級(jí)別,如 DEBUG、INFO、WARN、ERROR 等。開發(fā)人員可以根據(jù)需要選擇記錄的信息級(jí)別,以便在不同場(chǎng)景中控制日志輸出。
  • 輸出目標(biāo): 日志框架支持將日志信息輸出到不同的目標(biāo),如控制臺(tái)、文件、數(shù)據(jù)庫(kù)、遠(yuǎn)程服務(wù)器等。這使得開發(fā)人員能夠根據(jù)實(shí)際需求選擇合適的輸出方式。
  • 性能優(yōu)化: 一些日志框架支持異步日志記錄,以減少對(duì)應(yīng)用程序性能的影響。它們可能使用緩沖機(jī)制、線程池等技術(shù),以提高日志記錄的效率。
  • 靈活性: 日志框架提供了靈活的配置選項(xiàng),使得開發(fā)人員能夠根據(jù)實(shí)際需求進(jìn)行定制和調(diào)整。

常見的Java日志框架包括 Log4j、Logback、java.util.logging 等。

手寫一個(gè)簡(jiǎn)單的日志框架應(yīng)該怎么做

首先,我們需要明確我們要做的功能。

從日漸成熟的日志框架中,我們總計(jì)日志框架的核心功能有;

  • 級(jí)別控制(DEBUG、INFO、WARN、ERROR)
  • 輸出(控制臺(tái)輸出、文件輸出)
  • 性能優(yōu)化(做到不浪費(fèi)性能)

我寫了一個(gè)簡(jiǎn)單的源碼

import java.io.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * LeLog類用于記錄不同日志級(jí)別的消息。
 */
public class LeLog {
    /**
     * 日志級(jí)別的枚舉: INFO, WARN, ERROR
     */
    public enum LogLevel {
        INFO, WARN, ERROR
    }

    private static Class<?> defaultClass; // 用于日志記錄的默認(rèn)類
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); // 日志記錄的日期格式
    private static Map<Class<?>, LeLog> instances = new HashMap<>(); // 存儲(chǔ)LeLog實(shí)例的映射
    private Class<?> clazz; // 與日志關(guān)聯(lián)的類

    /**
     * 構(gòu)造函數(shù),設(shè)置默認(rèn)日志記錄的類。
     * @param clazz 與日志關(guān)聯(lián)的類
     */
    public LeLog(Class<?> clazz) {
        this.clazz = clazz;
        defaultClass = clazz; // 設(shè)置默認(rèn)日志記錄的類
    }

    /**
     * 多例模式創(chuàng)建實(shí)例
     * @param clazz 類
     * @return LeLog實(shí)例
     */
    public static synchronized LeLog getLeLog(Class<?> clazz) {
        if (!instances.containsKey(clazz)) {
            LeLog instance = new LeLog(clazz);
            instances.put(clazz, instance);
        }
        return instances.get(clazz);
    }

    /**
     * 將日志消息寫入控制臺(tái)和文件。
     * @param level 日志級(jí)別
     * @param logName 日志名稱
     * @param message 日志消息
     */
    private static void write(LogLevel level, String logName, String message) {
        // 創(chuàng)建并格式化日志消息
        String timeStamp = dateFormat.format(new Date());
        String threadName = Thread.currentThread().getName();
        long threadId = Thread.currentThread().getId();
        String logMessage = timeStamp + " [" + level + "] "
                + "Thread: " + threadName + " (ID: " + threadId + ") "
                + logName + " - " + message;
        // 輸出日志消息到控制臺(tái)
        System.out.println(logMessage);
        // 將日志消息寫入文件
        writeToFile(logMessage);
    }

    /**
     * 獲取日志文件路徑。
     * @return 日志文件路徑
     */
    private static String getLogFile() {
        Properties prop = new Properties();
        try (FileInputStream input = new FileInputStream("le.log.properties")) {
            prop.load(input);
            String logFilePath = prop.getProperty("logFilePath");

            File logFolder = new File(logFilePath);
            if (!logFolder.exists()) {
                logFolder.mkdirs();
            }

            String logFileName = prop.getProperty("logFileName");
            return logFilePath + "/" + logFileName + "_" + LocalDate.now() + ".log";
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 將日志消息寫入文件。
     * @param message 日志消息
     */
    private static void writeToFile(String message) {
        String logFile = getLogFile();
        if (logFile != null) {
            try (PrintWriter out = new PrintWriter(new FileWriter(logFile, true))) {
                out.println(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 記錄INFO級(jí)別的日志消息。
     * @param message 日志消息
     */
    public static void info(String message){
        write(LeLog.LogLevel.INFO,defaultClass.getName(),message);
    }

    /**
     * 記錄WARN級(jí)別的日志消息。
     * @param message 日志消息
     */
    public static void warn(String message){
        write(LogLevel.WARN,defaultClass.getName(),message);
    }

    /**
     * 記錄ERROR級(jí)別的日志消息。
     * @param message 日志消息
     */
    public static void error(String message){
        write(LogLevel.ERROR,defaultClass.getName(),message);
    }

}

代碼結(jié)構(gòu)和核心思路

LeLog 類是一個(gè)用于記錄不同日志級(jí)別消息的工具類。以下是它的核心思路和代碼結(jié)構(gòu):

日志級(jí)別枚舉: LeLog 定義了一個(gè)LogLevel枚舉,包括 INFO、WARN 和 ERROR 三個(gè)級(jí)別,分別表示信息、警告和錯(cuò)誤。

    /**
     * 日志級(jí)別的枚舉: INFO, WARN, ERROR
     */
    public enum LogLevel {
        INFO, WARN, ERROR
    }

類與實(shí)例關(guān)聯(lián): LeLog 通過(guò)多例模式創(chuàng)建實(shí)例,每個(gè)實(shí)例與一個(gè)特定的類關(guān)聯(lián)。這種設(shè)計(jì)使得每個(gè)類都有自己的日志記錄器,方便了解來(lái)自不同類的日志信息。

    private static Map<Class<?>, LeLog> instances = new HashMap<>(); // 存儲(chǔ)LeLog實(shí)例的映射
    private Class<?> clazz; // 與日志關(guān)聯(lián)的類

    /**
     * 構(gòu)造函數(shù),設(shè)置默認(rèn)日志記錄的類。
     * @param clazz 與日志關(guān)聯(lián)的類
     */
    public LeLog(Class<?> clazz) {
        this.clazz = clazz;
        defaultClass = clazz; // 設(shè)置默認(rèn)日志記錄的類
    }

    /**
     * 多例模式創(chuàng)建實(shí)例
     * @param clazz 類
     * @return LeLog實(shí)例
     */
    public static synchronized LeLog getLeLog(Class<?> clazz) {
        if (!instances.containsKey(clazz)) {
            LeLog instance = new LeLog(clazz);
            instances.put(clazz, instance);
        }
        return instances.get(clazz);
    }

日志消息格式化: 在 write 方法中,使用 SimpleDateFormat 對(duì)日期進(jìn)行格式化,同時(shí)獲取線程信息和日志級(jí)別,將這些信息拼接成格式化的日志消息。

    /**
     * 將日志消息寫入控制臺(tái)和文件。
     * @param level 日志級(jí)別
     * @param logName 日志名稱
     * @param message 日志消息
     */
    private static void write(LogLevel level, String logName, String message) {
        // 創(chuàng)建并格式化日志消息
        String timeStamp = dateFormat.format(new Date());
        String threadName = Thread.currentThread().getName();
        long threadId = Thread.currentThread().getId();
        String logMessage = timeStamp + " [" + level + "] "
                + "Thread: " + threadName + " (ID: " + threadId + ") "
                + logName + " - " + message;
        // 輸出日志消息到控制臺(tái)
        System.out.println(logMessage);
        // 將日志消息寫入文件
        writeToFile(logMessage);
    }

輸出到控制臺(tái)和文件: LeLog 將日志消息輸出到控制臺(tái),并通過(guò) writeToFile 方法將消息寫入到文件。日志文件路徑和文件名從配置文件中讀取,提高了靈活性。日志文件名中包含當(dāng)前日期,每天生成一個(gè)新的日志文件,方便按日期查看日志。

# 日志輸出路徑
logFilePath=logs/xxx/xx
# 日志輸出名稱
logFileName=xia_le
    /**
     * 獲取日志文件路徑。
     * @return 日志文件路徑
     */
    private static String getLogFile() {
        Properties prop = new Properties();
        try (FileInputStream input = new FileInputStream("le.log.properties")) {
            prop.load(input);
            String logFilePath = prop.getProperty("logFilePath");

            File logFolder = new File(logFilePath);
            if (!logFolder.exists()) {
                logFolder.mkdirs();
            }

            String logFileName = prop.getProperty("logFileName");
            return logFilePath + "/" + logFileName + "_" + LocalDate.now() + ".log";
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 將日志消息寫入文件。
     * @param message 日志消息
     */
    private static void writeToFile(String message) {
        String logFile = getLogFile();
        if (logFile != null) {
            try (PrintWriter out = new PrintWriter(new FileWriter(logFile, true))) {
                out.println(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

使用方法

使用 LeLog 記錄日志非常簡(jiǎn)單。首先,通過(guò) LeLog.getLeLog(Class clazz) 方法獲取 LeLog 實(shí)例,然后通過(guò)該實(shí)例的 info、warnerror 方法記錄不同級(jí)別的日志消息。以下是一個(gè)簡(jiǎn)單的示例:

public class TestOne {
    private static final LeLog leLog = LeLog.getLeLog(TestOne.class);
    public void test(){
        leLog.info("This is an information message.");
        leLog.warn("This is a warning message.");
        leLog.error("This is an error message.");
    }
}

public class TestTwo {
    private static final LeLog leLog = LeLog.getLeLog(TestTwo.class);
    public void test(){
        leLog.info("This is an information message.");
        leLog.warn("This is a warning message.");
        leLog.error("This is an error message.");
    }
}

public class Main {
    public static void main(String[] args) {
        new TestOne().test();
        new TestTwo().test();
    }
}

控制臺(tái)輸出如下

文件輸出如下:

后期優(yōu)化

這個(gè)類可以說(shuō)是漏洞百出,我寫出來(lái)不過(guò)是給大伙提供一個(gè)思路和一個(gè)敢于手寫框架造輪子的程序員桀驁不馴的心。

那這個(gè)類來(lái)說(shuō),值得噴的點(diǎn)有哪些:

  • 異常處理你是一點(diǎn)沒(méi)做?。?/li>
  • 文件輸出類型太單一,我只做了windows的日志路徑,Linux上的你是一點(diǎn)沒(méi)做??!
  • 文件的格式問(wèn)題,現(xiàn)在日志都流行是json格式的,以便于是以后在NoSql數(shù)據(jù)庫(kù)展示和分析。
  • 過(guò)濾我也是一個(gè)都么看見。
  • 異常追蹤呢?
  • 最重要的是一個(gè)框架的靈活性,你這個(gè)你不覺(jué)得笨重嗎?
  • 字符編碼和亂碼問(wèn)題呢,System.out.println很耗費(fèi)性能的好吧。
  • ..........太多了,懶得吐槽。

以上就是Java手寫一個(gè)日志框架的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Java日志框架的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java基礎(chǔ)入門 Swing中間容器的使用

    Java基礎(chǔ)入門 Swing中間容器的使用

    這篇文章主要介紹了Java基礎(chǔ)入門 Swing中間容器的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 分布式系統(tǒng)下調(diào)用鏈追蹤技術(shù)面試題

    分布式系統(tǒng)下調(diào)用鏈追蹤技術(shù)面試題

    這篇文章主要為大家介紹了分布式系統(tǒng)下調(diào)用鏈追蹤技術(shù)面試問(wèn)題合集,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-03-03
  • JavaScript中的closest方法示例詳解

    JavaScript中的closest方法示例詳解

    這篇文章主要介紹了JavaScript中closest方法的相關(guān)資料,closest()是JavaScript中的一個(gè)非常實(shí)用的?DOM?方法,用于查找與當(dāng)前元素匹配的最近的祖先元素,它支持?CSS?選擇器,可以應(yīng)用于事件委托、動(dòng)態(tài)內(nèi)容處理等場(chǎng)景,需要的朋友可以參考下
    2025-02-02
  • 詳解java并發(fā)之重入鎖-ReentrantLock

    詳解java并發(fā)之重入鎖-ReentrantLock

    這篇文章主要介紹了java并發(fā)之重入鎖-ReentrantLock,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • springboot?sleuth?日志跟蹤問(wèn)題記錄

    springboot?sleuth?日志跟蹤問(wèn)題記錄

    Spring?Cloud?Sleuth是一個(gè)在應(yīng)用中實(shí)現(xiàn)日志跟蹤的強(qiáng)有力的工具,使用Sleuth庫(kù)可以應(yīng)用于計(jì)劃任務(wù)?、多線程服務(wù)或復(fù)雜的Web請(qǐng)求,尤其是在一個(gè)由多個(gè)服務(wù)組成的系統(tǒng)中,這篇文章主要介紹了springboot?sleuth?日志跟蹤,需要的朋友可以參考下
    2023-07-07
  • Mybatis批量更新對(duì)象數(shù)據(jù)的兩種實(shí)現(xiàn)方式

    Mybatis批量更新對(duì)象數(shù)據(jù)的兩種實(shí)現(xiàn)方式

    這篇文章主要介紹了Mybatis批量更新對(duì)象數(shù)據(jù)的兩種實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫(kù)數(shù)據(jù)

    JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫(kù)數(shù)據(jù)

    MySQL是最流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),在WEB應(yīng)用方面MySQL是最好的。本文將利用JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫(kù)數(shù)據(jù)功能,需要的可以參考一下
    2022-03-03
  • Spring中@Scope的幾種取值方式

    Spring中@Scope的幾種取值方式

    這篇文章主要介紹了Spring中@Scope的幾種取值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 一篇文章帶你了解jdk1.8新特性--為什么使用lambda表達(dá)式

    一篇文章帶你了解jdk1.8新特性--為什么使用lambda表達(dá)式

    Lambda是一個(gè)匿名函數(shù),我們可以把Lambda表達(dá)式理解為是一段可以傳遞的代碼,本篇文章就帶你了解,希望能給你帶來(lái)幫助
    2021-08-08
  • Java漢字轉(zhuǎn)成漢語(yǔ)拼音工具類

    Java漢字轉(zhuǎn)成漢語(yǔ)拼音工具類

    這篇文章主要為大家詳細(xì)介紹了Java漢字轉(zhuǎn)成漢語(yǔ)拼音工具類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05

最新評(píng)論