<dfn id="w48us"></dfn><ul id="w48us"></ul>
  • <ul id="w48us"></ul>
  • <del id="w48us"></del>
    <ul id="w48us"></ul>
  • Java日志系統(tǒng)框架的設(shè)計與實現(xiàn)

    時間:2024-07-18 23:56:05 SUN認證 我要投稿
    • 相關(guān)推薦

    Java日志系統(tǒng)框架的設(shè)計與實現(xiàn)

      在Java 領(lǐng)域,存在大量的日志組件,open-open收錄了21個日志組件。日志系統(tǒng)作為一種應(yīng)用程序服務(wù),對于跟蹤調(diào)試、程序狀態(tài)記錄、崩潰數(shù)據(jù)恢復(fù)都有著重要的作用,我們可以把Java日志系統(tǒng)看作是必不可少的跟蹤調(diào)試工具。

    Java日志系統(tǒng)框架的設(shè)計與實現(xiàn)

      1.簡介

      日志系統(tǒng)是一種不可或缺的跟蹤調(diào)試工具,特別是在任何無人職守的后臺程序以及那些沒有跟蹤調(diào)試環(huán)境的系統(tǒng)中有著廣泛的應(yīng)用。長期以來,日志系統(tǒng)作為一種應(yīng)用程序服務(wù),對于跟蹤調(diào)試、程序狀態(tài)記錄、崩潰數(shù)據(jù)恢復(fù)都有非常現(xiàn)實的意義。這種服務(wù)通常以兩種方式存在:

      1.日志系統(tǒng)作為服務(wù)進程存在。Windows中的的事件日志服務(wù)就屬于這種類型,該類型的日志系統(tǒng)通常通過消息隊列機制將所需要記錄的日志由日志發(fā)送端發(fā)送給日志服務(wù)。日志發(fā)送端和日志保存端通常不在同一進程當(dāng)中,日志的發(fā)送是異步過程。這種日志服務(wù)通常用于管理員監(jiān)控各種系統(tǒng)服務(wù)的狀態(tài)。

      2.日志系統(tǒng)作為系統(tǒng)調(diào)用存在。Java世界中的日志系統(tǒng)和Unix環(huán)境下諸多守護進程所使用的日志系統(tǒng)都屬于這種類型。日志系統(tǒng)的代碼作為系統(tǒng)調(diào)用被編譯進日志發(fā)送端,日志系統(tǒng)的運行和業(yè)務(wù)代碼的運行在同一進程空間。日志的發(fā)送多數(shù)屬于同步過程。這種日志服務(wù)由于能夠同步反映處系統(tǒng)運行狀態(tài),通常用于調(diào)試跟蹤和崩潰恢復(fù)。

      本文建立的日志系統(tǒng)基本屬于第二種類型,但又有所不同。該日志系統(tǒng)將利用Java線程技術(shù)實現(xiàn)一個既能夠反映統(tǒng)一線程空間中程序運行狀態(tài)的同步日志發(fā)送過程,又能夠提供快速的日志記錄服務(wù),還能夠提供靈活的日志格式配置和過濾機制。

      1.1系統(tǒng)調(diào)試的誤區(qū)

      在控制臺環(huán)境上調(diào)試Java程序時,此時往控制臺或者文本文件輸出一段文字是查看程序運行狀態(tài)最簡單的做法,但這種方式并不能解決全部的問題。有時候,對于一個我們無法實時查看系統(tǒng)輸出的系統(tǒng)或者一個確實需要保留我們輸出信息的系統(tǒng),良好的日志系統(tǒng)顯得相當(dāng)必要。因此,不能隨意的輸出各種不規(guī)范的調(diào)試信息,這些隨意輸出的信息是不可控的,難以清除,可能為后臺監(jiān)控、錯誤排除和錯誤恢復(fù)帶來相當(dāng)大的阻力。

      1.2日志系統(tǒng)框架的基本功能

      一個完備的日志系統(tǒng)框架通常應(yīng)當(dāng)包括如下基本特性:

      所輸出的日志擁有自己的分類:這樣在調(diào)試時便于針對不同系統(tǒng)的不同模塊進行查詢,從而快速定位到發(fā)生日志事件的代碼。

      日志按照某種標(biāo)準(zhǔn)分成不同級別:分級以后的日志,可以用于同一分類下的日志篩選。

      支持多線程:日志系統(tǒng)通常會在多線程環(huán)境中使用,特別是在Java系統(tǒng)當(dāng)中,因此作為一種系統(tǒng)資源,日志系統(tǒng)應(yīng)當(dāng)保證是線程安全的。

      支持不同的記錄媒介:不同的工程項目往往對日志系統(tǒng)的記錄媒介要求不同,因此日志系統(tǒng)必須提供必要的開發(fā)接口,以保證能夠比較容易的更換記錄介質(zhì)。

      高性能:日志系統(tǒng)通常要提供高速的日志記錄功能以應(yīng)對大系統(tǒng)下大請求流量下系統(tǒng)的正常運轉(zhuǎn)。

      穩(wěn)定性:日志系統(tǒng)必須是保持高度的穩(wěn)定性,不能因為日志系統(tǒng)內(nèi)部錯誤導(dǎo)致主要業(yè)務(wù)代碼的崩潰。

      1.3常用日志系統(tǒng)簡介

      在Java世界中,以下三種日志框架比較優(yōu)秀:

      1)Log4J

      最早的Java日志框架之一,由Apache基金會發(fā)起,提供靈活而強大的日志記錄機制。但是其復(fù)雜的配置過程和內(nèi)部概念往往令使用者望而卻步。

      2)JDK1.4LoggingFramework

      繼Log4J之后,JDK標(biāo)準(zhǔn)委員會將Log4J的基本思想吸收到JDK當(dāng)中,在JDK1.4中發(fā)布了第一個日志框架接口,并提供了一個簡單實現(xiàn)。

      3)CommonsLoggingFramwork

      該框架同樣是Apache基金會項目,其出現(xiàn)主要是為了使得Java項目能夠在Log4J和JDK1.4lLoggingFramework的使用上隨意進行切換,因此該框架提供了統(tǒng)一的調(diào)用接口和配置方法。

      2.系統(tǒng)設(shè)計

      由于Log4J得到廣泛應(yīng)用,從使用者的角度考慮,本文所設(shè)計的框架,采用了部分Log4J的接口和概念,但內(nèi)部實現(xiàn)則完全不同。使用Java實現(xiàn)日志框架,關(guān)鍵的技術(shù)在于前面提及的日志框架特性的內(nèi)部實現(xiàn),特別是:日志的分類和級別、日志分發(fā)框架的設(shè)計、日志記錄器的設(shè)計以及在設(shè)計中的高性能和高穩(wěn)定性的考慮。

      2.1系統(tǒng)架構(gòu)

      日志系統(tǒng)框架可以分為日志記錄模塊和日志輸出模塊兩大部分。日志記錄模塊負責(zé)創(chuàng)建和管理日志記錄器(Logger),每一個Logger對象負責(zé)按照不同的級別(LoggerLevel)接收各種記錄了日志信息的日志對象(LogItem),Logger對象首先獲取所有需要記錄的日志,并且同步地將日志分派給日志輸出模塊。日志輸出模塊則負責(zé)日志輸出器(Appender)的創(chuàng)建和管理,以及日志的輸出。系統(tǒng)中允許有多個不同的日志輸出器,日志輸出器負責(zé)將日志記錄到存儲介質(zhì)當(dāng)中。

      日志記錄器Logger是整個日志系統(tǒng)框架的用戶使用接口,程序員可以通過該接口記錄日志,為了實現(xiàn)對日志進行分類,系統(tǒng)設(shè)計允許存在多個Logger對象,每一個Logger負責(zé)一類日志的記錄,Logger類同時實現(xiàn)了對其對象本身的管理。LoggerLevel類定義了整個日志系統(tǒng)的級別,在客戶端創(chuàng)建和發(fā)送日志時,這些級別會被使用到。Logger對象在接收到客戶端創(chuàng)建和發(fā)送的日志消息時,同時將該日志消息包裝成日志系統(tǒng)內(nèi)部所使用的日志對象LogItem,日志對象除了發(fā)送端所發(fā)送的消息以外,還會包裝諸如發(fā)送端類名、發(fā)送事件、發(fā)送方法名、發(fā)送行號等等。這些額外的消息對于系統(tǒng)的跟蹤和調(diào)試都非常有價值。包裝好的LogItem最終被發(fā)送給輸出器,由這些輸出器負責(zé)將日志信息寫入最終媒介,輸出器的類型和個數(shù)均不固定,所有的輸出器通過AppenderManager進行管理,通常通過配置文件即可方便擴展出多個輸出器。

      2.2日志記錄部分的設(shè)計

      如前文所述,日志記錄部分負責(zé)接收日志系統(tǒng)客戶端發(fā)送來的日志消息、日志對象的管理等工作。下面詳細描述了日志記錄部分的設(shè)計要點:

      1.日志記錄器的管理

      系統(tǒng)通過保持多個Logger對象的方式來進行日志記錄的分類。每一個Logger對象代表一類日志分類。因此,Logger對象的名稱屬性是其唯一標(biāo)識,通過名稱屬性獲取一個Logger對象:

      1.LoggerLoggerlogger=Logger.getLogger(“LoggerName”);

      一般的,使用類名來作為日志記錄器的名稱,這樣做的好處在于能夠盡量減少日志記錄器命名之間的沖突(因為Java類使用包名),同時能夠?qū)⑷罩居涗浄诸惖帽M可能的精細。因此,假定有一UserManager類需要使用日志服務(wù),則更一般的使用方式為:

      2.LoggerLoggerlogger=Logger.getLogger(UserManager.class);

      2.日志分級的實現(xiàn)

      按照日志目的不同,將日志的級別由低到高分成五個級別:

      ◆DEBUG-表示輸出的日志為一個調(diào)試信息;

      ◆INFO-表示輸出的日志是一個系統(tǒng)提示;

      ◆WARN-表示輸出的日志是一個警告信息;

      ◆ERROR-表示輸出的日志是一個系統(tǒng)錯誤;

      ◆FATAL-表示輸出的日志是一個導(dǎo)致系統(tǒng)崩潰嚴(yán)重錯誤。

      這些日志級別定義在LoggerLevel接口中,被日志記錄器Logger在內(nèi)部使用。而對于日志系統(tǒng)客戶端則可使用Logger類接口對直接調(diào)用并輸出這些級別的日志,Logger的這些接口描述如下:

      3.publicvoiddebug(Stringmsg);//輸出調(diào)試信息

      4.publicvoidinfo(Stringmsg);//輸出系統(tǒng)提示

      5.publicvoidwarn(Stringmsg);//輸出警告信息

      6.publicvoidfatal(Stringmsg);//輸出系統(tǒng)錯誤

      7.publicvoiderror(Stringmsg);//輸出嚴(yán)重錯誤

      通過對Logger對象上這些接口的調(diào)用,直接為日志信息賦予了級別屬性,這樣為后繼的按照不同級別進行輸出的工作奠定了基礎(chǔ)。

      3.日志對象信息的獲取

      日志對象上包含了一條日志所具備的所有信息。通常這些信息包括:輸出日志的時間、Java類、類成員方法、所在行號、日志體、日志級別等等。在JDK1.4中可以通過在方法中拋出并且捕獲住一個異常,則在捕捉到的異常對象中已經(jīng)由JVM自動填充好了系統(tǒng)調(diào)用的堆棧,在JDK1.4中則可以使用java.lang.StackTraceElement獲取到每一個堆棧項的基本信息,通過對日志客戶端輸出日志方法調(diào)用層數(shù)的推算,則可以比較容易的獲取到StackTraceElement對象,從而獲取到輸出日志時的Java類、類成員方法、所在行號等信息。在JDK1.3或者更早的版本中,相應(yīng)的工作則必須通過將異常的堆棧信息輸出到字符串中,并分析該字符串格式得到。

      2.3日志輸出部分的設(shè)計

      日志輸出部分的設(shè)計具有一定的難度,在本文設(shè)計的日志系統(tǒng)中,日志的輸出、多線程的支持、日志系統(tǒng)的擴展性、日志系統(tǒng)的效率等問題都交由日志輸出部分進行管理。

      1.日志輸出器的繼承結(jié)構(gòu)

      在日志的輸出部分采用了二層結(jié)構(gòu),即定義了一個抽象的日志輸出器(AbstractLoggerAppender),然后從該抽象類繼承出實際的日志輸出器。AbstractLoggerAppender定義了一系列的對日志進行過濾的方法,而具體輸出到存儲媒介的方法則是一個抽象方法,由子類實現(xiàn)。在系統(tǒng)中默認實現(xiàn)了控制臺輸出器和文件輸出器兩種,其中控制臺輸出器的實現(xiàn)頗為簡單。

      2.文件輸出器的內(nèi)部實現(xiàn)

      在日志記錄部分的實現(xiàn)中,并沒有考慮多線程、高效率等問題,因此文件輸出器必須考慮這些問題的處理。在文件輸出器內(nèi)部使用java.lang.Vector定義了一個線程安全的高速緩沖,所有通過日志記錄部分分派到文件輸出器的日志被直接放置到該高速緩沖當(dāng)中。同時在文件輸出器內(nèi)部定義一個工作線程,負責(zé)定期將高速緩沖中的內(nèi)容保存到文件,在保存的過程中同時可以進行日志文件的備份等工作。由于采用了高速緩沖的結(jié)構(gòu),很顯然日志客戶端的調(diào)用已經(jīng)不再是一個同步調(diào)用,從而不再會需要等到文件操作后才返回,提高的系統(tǒng)調(diào)用的速度。該原理如圖3所示:

      2.4設(shè)計難點

      通過上述設(shè)計,一個具有良好擴展能力的高性能日志系統(tǒng)框架就已經(jīng)具有了一定的雛形。在設(shè)計過程中幾個難點問題需要進一步反思。

      一、是否整個系統(tǒng)應(yīng)當(dāng)采用完全異步的結(jié)構(gòu),通過類似于消息機制的方式來進行由日志客戶端發(fā)送日志給日志系統(tǒng)。這種方式可以作為日志系統(tǒng)框架另一種運行方式,在后繼設(shè)計中加以考慮。

      二、在文件輸出器中可以看到,目前雖然可以擴展多個日志輸出器,但是目前提供的抽象類中僅僅提供了對日志的過濾機制,而沒有提供的緩存機制,目前的緩存機制被放在文件輸出器中實現(xiàn),因此在未來的進一步設(shè)計中,可以將文件輸出器中的緩存機制上移到抽象類當(dāng)中。

      2.5設(shè)計模式

      在設(shè)計過程中我們特別注意使用了數(shù)個經(jīng)典的設(shè)計模式。如:Logger對象的創(chuàng)建使用了工廠方法模式(FactoryMethod)、由AbstractLoggerAppender和ConsoleAppender以及FileAppender構(gòu)成了策略模式(Strategy),除此以外,還大量使用了單例模式(Singleton)。在設(shè)計中適當(dāng)運用設(shè)計模式能夠加快設(shè)計進度、提高設(shè)計質(zhì)量。

      3.總結(jié)

      本文探討了日志系統(tǒng)的基本特性、實現(xiàn)日志系統(tǒng)的意義、方法和內(nèi)部結(jié)構(gòu),并且給出了一種基于Java平臺的日志系統(tǒng)的詳細設(shè)計。同時也指出日志系統(tǒng)會向服務(wù)化、異步化的方向發(fā)展。作為一種方便的跟蹤調(diào)試、數(shù)據(jù)恢復(fù)工具,應(yīng)當(dāng)提倡在適當(dāng)?shù)沫h(huán)境下對日志系統(tǒng)的使用。

    【Java日志系統(tǒng)框架的設(shè)計與實現(xiàn)】相關(guān)文章:

    sun認證java程序員須知Java日志框架09-11

    OA系統(tǒng)的設(shè)計與實現(xiàn)07-05

    企業(yè)OA系統(tǒng)的設(shè)計與實現(xiàn)06-28

    航標(biāo)業(yè)務(wù)系統(tǒng)架構(gòu)的設(shè)計和實現(xiàn)05-17

    OA系統(tǒng)網(wǎng)絡(luò)安全設(shè)計與實現(xiàn)08-21

    實現(xiàn)鼠標(biāo)畫圖的Java程序06-22

    Java多線程的實現(xiàn)方式07-08

    關(guān)于辦公自動化系統(tǒng)的設(shè)計與實現(xiàn)07-28

    Java動態(tài)代理實現(xiàn)AOP的方法07-22

    Java如何實現(xiàn)簡單的whois查詢09-21

    主站蜘蛛池模板: 久久国产精品99国产精| 国产精品亚洲аv无码播放| 日韩精品一区二区三区色欲AV| 国产精品99| 一区二区国产精品| 国产午夜精品一区二区三区小说 | 国产伦精品一区二区免费| 国产午夜精品一区二区三区| 亚洲麻豆精品国偷自产在线91| 国产精品内射婷婷一级二| 久久国产精品-久久精品| 精品亚洲国产成AV人片传媒| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 青青草原精品99久久精品66| 亚洲AV无码乱码精品国产| 国语自产精品视频| 国产成人无码精品久久久免费 | 国产精品爱搞视频网站| 国产三级久久久精品麻豆三级| 中文精品人人永久免费| 久久精品国产国产精品四凭| 国产A∨国片精品一区二区| 久久久精品午夜免费不卡| 国产精品自拍一区| 国内精品久久久久久野外| 99久久久精品| 国产亚洲精品一品区99热| 国产精品亚洲午夜一区二区三区| 91视频国产精品| 99精品在线观看| 精品国产_亚洲人成在线高清| 97久久精品国产精品青草| 97久久超碰国产精品2021| 91麻豆精品国产| 国产精品视频一区国模私拍| 国产精品视频一区二区三区经| 精品国产欧美一区二区| 亚洲精品你懂的| 99久久精品这里只有精品| 国产精品99无码一区二区| 国产精品麻豆欧美日韩ww|