package Ġcom . fire fly source . log Ċ Ċ import Ġcom . fire fly source . log . Log ConfigParser .* Ċ import Ġcom . fire fly source . log . internal . utils . Time Utils Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . channels . Channel . Factory . UN LIMIT ED Ċ import Ġjava . io .* Ċ import Ġjava . nio . charset . Charset Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Path Ċ import Ġjava . nio . file . Paths Ċ import Ġjava . time . LocalDateTime Ċ import Ġjava . time . Zone Id Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent .* Ċ import Ġjava . util . concurrent . Cancellation Exception ĊĊ Ċ /** Ċ Ġ* Ġ@ author ĠPeng ta o ĠQ iu Ċ Ġ*/ Ċ class ĠFile Log Ġ: ĠLog Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġstack Trace Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjava . lang . Boolean . getBoolean (" com . fire fly source . log . File Log . debug Mode ") ĊĊĠĠĠĠĠĠĠ Ġval Ġexecutor Ġ= Ġnew Single Thread Executor () ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfile Log Thread Scope : ĠCor outine Scope Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCor outine Scope ( executor . as Coroutine Dispatcher () Ġ+ ĠCor outine Name (" Fire fly File Log Thread ")) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġnew Single Thread Executor (): ĠExecutor Service Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠThreadPool Executor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 , Ġ 1 , Ġ 0 , ĠTimeUnit . MILLISECONDS , ĠLinked Transfer Queue () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ Ġrunnable Ġ-> ĠThread ( run nable , Ġ" fire fly - log - thread ") Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsealed Ġinterface ĠLog Message ĊĊĠĠĠ Ġ@ Jvm Inline ĊĠĠĠ Ġvalue Ġclass ĠWrite Log Message ( val Ġlog Item : ĠLog Item ) Ġ: ĠLog Message ĊĠĠĠ Ġobject ĠFlush Ġ: ĠLog Message ĊĠĠĠ Ġobject ĠStop Ġ: ĠLog Message ĊĊĊĠĠĠ Ġvar Ġlevel : ĠLogLevel Ġ= ĠLogLevel . from Name ( DEFAULT _ LOG _ LEVEL ) ĊĠĠĠ Ġvar Ġpath : ĠString Ġ= ĠDEFAULT _ LOG _ DIRECTORY . absolute Path ĊĠĠĠ Ġvar Ġlog Name : ĠString Ġ= ĠDEFAULT _ LOG _ NAME ĊĠĠĠ Ġvar Ġconsole Output : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġvar Ġfile Output : ĠBoolean Ġ= Ġtrue ĊĠĠĠ Ġvar Ġmax FileSize : ĠLong Ġ= ĠDEFAULT _ MAX _ FILE _ SIZE ĊĠĠĠ Ġvar Ġlog Formatter : ĠLog Formatter Ġ= ĠDEFAULT _ LOG _ FORMAT TER ĊĠĠĠ Ġvar Ġlog Name Formatter : ĠLog Name Formatter Ġ= ĠDEFAULT _ LOG _ NAME _ FORMAT TER ĊĠĠĠ Ġvar Ġlog Filter : ĠLog Filter Ġ= ĠDEFAULT _ LOG _ FILTER ĊĠĠĠ Ġvar Ġmax Split Time : ĠMax Split Time Enum Ġ= ĠMax Split Time Enum . DAY ĊĠĠĠ Ġvar Ġcharset : ĠCharset Ġ= ĠDEFAULT _ CHARSET ĊĊĠĠĠ Ġprivate Ġval Ġm dc : ĠM apped Diagnostic Context Ġ= ĠM apped Diagnostic Context Factory . getInstance (). mapped Diagnostic Context ĊĊĠĠĠ Ġprivate Ġval Ġoutput Ġ= ĠLog OutputStream () ĊĠĠĠ Ġprivate Ġval Ġchannel Ġ= ĠChannel < Log Message >( UN LIMIT ED ) ĊĠĠĠ Ġprivate Ġval Ġconsumer Job Ġ= Ġfile Log Thread Scope . launch Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġchannel . receive () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexit Ġ= Ġhandle Write Log Message ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( exit ) Ġbreak ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġprintln (" File Ġlog Ġ$ log Name Ġis Ġclosed .") ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġval Ġflush Tick Job Ġ= Ġfile Log Thread Scope . launch Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( 5 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . try Send ( Flush ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Write Log Message ( message : ĠLog Message ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( message ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠWrite Log Message Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Item Ġ= Ġmessage . log Item ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog Filter . filter ( log Item ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( console Output ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( log Formatter . format ( log Item )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file Output ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . write ( log Formatter . format ( log Item ), Ġlog Item . date ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠFlush Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . flush () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠStop Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġinner Ġclass ĠLog OutputStream Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġfile OutputStream : ĠBuffered OutputStream ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġwritten Size : ĠLong Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġlast Written Time : ĠLocalDateTime ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Log Name ( local DateTime : ĠLocalDateTime ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlog Name Formatter . format ( name , Ġlocal DateTime ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Log B ak Name ( local DateTime : ĠLocalDateTime , Ġindex : ĠInt ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlog Name Formatter . format B ak ( name , Ġlocal DateTime , Ġindex ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Log B ak Name ( local DateTime : ĠLocalDateTime ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġindex Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġb ak Name Ġ= Ġget Log B ak Name ( local DateTime , Ġindex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( Files . exists ( Paths . get ( path , Ġb ak Name ))) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġb ak Name Ġ= Ġget Log B ak Name ( local DateTime , Ġindex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġb ak Name ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġis Not Split By Time ( new LocalDateTime : ĠLocalDateTime ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Time Ġ= Ġlast Written Time ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire NotNull ( last Time ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( max Split Time ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMax Split Time Enum . DAY Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( last Time . year Ġ== Ġnew LocalDateTime . year ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . month Ġ== Ġnew LocalDateTime . month ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . day OfMonth Ġ== Ġnew LocalDateTime . day OfMonth ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMax Split Time Enum . HOUR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( last Time . year Ġ== Ġnew LocalDateTime . year ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . month Ġ== Ġnew LocalDateTime . month ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . day OfMonth Ġ== Ġnew LocalDateTime . day OfMonth ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . hour Ġ== Ġnew LocalDateTime . hour ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMax Split Time Enum . MINUTE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ( last Time . year Ġ== Ġnew LocalDateTime . year ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . month Ġ== Ġnew LocalDateTime . month ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . day OfMonth Ġ== Ġnew LocalDateTime . day OfMonth ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . hour Ġ== Ġnew LocalDateTime . hour ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġlast Time . minute Ġ== Ġnew LocalDateTime . minute ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun ĠgetFile LastModified Time ( log Path : ĠPath ): ĠLocalDateTime Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Time Ġ= Ġlast Written Time ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( last Time Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Time Ġ= ĠFiles . getLast Modified Time ( log Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Ġ= ĠLocalDateTime . from ( file Time . to Instant (). at Zone ( Zone Id . system Default ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Written Time Ġ= Ġtime ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtime ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġlast Time ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Output ( new Date : ĠDate , Ġcurrent Log Size : ĠLong ): ĠOutputStream Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitialize OutputStream ( new Date , Ġcurrent Log Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Ġ= Ġfile OutputStream ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire NotNull ( output ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġoutput ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġinitialize OutputStream ( new Date : ĠDate , Ġcurrent Log Size : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew LocalDateTime Ġ= ĠTime Utils . to LocalDateTime ( new Date ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Name Ġ= Ġget Log Name ( new LocalDateTime ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Path Ġ= ĠPaths . get ( path , Ġlog Name ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Files . exists ( log Path )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Modified Time Ġ= ĠgetFile LastModified Time ( log Path ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( isNot Split By Time ( new LocalDateTime )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( max FileSize Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( written Size Ġ== Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwritten Size Ġ= ĠFiles . size ( log Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Log Size Ġ+ Ġwritten Size Ġ> Ġmax FileSize ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Log Output And Backup Old Log ( log Name , Ġlog Path , Ġlast Modified Time ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġcreate Log Output If Null ( log Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġcreate Log Output If Null ( log Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġcreate Log Output And Backup Old Log ( log Name , Ġlog Path , Ġlast Modified Time ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġcreate Log Output If Null ( log Name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġcreate Log Output And Backup Old Log ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Name : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Path : ĠPath , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile LastModified DateTime : ĠLocalDateTime ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclose () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFiles . move ( log Path , ĠPaths . get ( path , Ġget Log B ak Name ( file LastModified DateTime ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile OutputStream Ġ= ĠBuffered OutputStream ( File OutputStream ( File ( path , Ġlog Name ), Ġtrue )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġcreate Log Output If Null ( log Name : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( file OutputStream Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile OutputStream Ġ= ĠBuffered OutputStream ( File OutputStream ( File ( path , Ġlog Name ), Ġtrue )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġwrite ( str : ĠString , Ġdate : ĠDate ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtext Ġ= Ġ( str Ġ+ ĠLog . CL ). toByteArray ( charset ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Ġ= Ġget Output ( date , Ġtext . size . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . write ( text ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwritten Size Ġ+= Ġtext . size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Written Time Ġ= ĠTime Utils . to LocalDateTime ( date ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . err . println (" write Ġlog Ġexception . Ġ" Ġ+ Ġe . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Ġ= Ġfile OutputStream ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( output Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwritten Size Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . err . println (" close Ġlog Ġwriter Ġexception . Ġ" Ġ+ Ġe . message ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġflush () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile OutputStream ?. flush () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . err . println (" flush Ġlog Ġexception . Ġ" Ġ+ Ġe . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠgetName (): ĠString Ġ= Ġlog Name ĊĊĠĠĠ Ġoverride Ġfun Ġis Trace Enabled (): ĠBoolean Ġ= Ġlevel . isEnabled ( LogLevel . TRACE ) ĊĊĠĠĠ Ġoverride Ġfun Ġtrace ( str : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Trace Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . TRACE . getName (), Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtrace ( str : ĠString ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Trace Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . TRACE . getName (), Ġnull , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtrace ( str : ĠString ?, Ġthrowable : ĠThrowable ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Trace Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . TRACE . getName (), Ġthrowable , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġis Debug Enabled (): ĠBoolean Ġ= Ġlevel . isEnabled ( LogLevel . DEBUG ) ĊĊĠĠĠ Ġoverride Ġfun Ġdebug ( str : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isDebugEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . DEBUG . getName (), Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdebug ( str : ĠString ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isDebugEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . DEBUG . getName (), Ġnull , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdebug ( str : ĠString ?, Ġthrowable : ĠThrowable ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isDebugEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . DEBUG . getName (), Ġthrowable , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġis Info Enabled (): ĠBoolean Ġ= Ġlevel . isEnabled ( LogLevel . INFO ) ĊĊĠĠĠ Ġoverride Ġfun Ġinfo ( str : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Info Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . INFO . getName (), Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinfo ( str : ĠString ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Info Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . INFO . getName (), Ġnull , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinfo ( str : ĠString ?, Ġthrowable : ĠThrowable ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Info Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . INFO . getName (), Ġthrowable , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġis Warn Enabled (): ĠBoolean Ġ= Ġlevel . isEnabled ( LogLevel . WARN ) ĊĊĠĠĠ Ġoverride Ġfun Ġwarn ( str : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Warn Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . WARN . getName (), Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġwarn ( str : ĠString ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Warn Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . WARN . getName (), Ġnull , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġwarn ( str : ĠString ?, Ġthrowable : ĠThrowable ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Warn Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . WARN . getName (), Ġthrowable , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġis Error Enabled (): ĠBoolean Ġ= Ġlevel . isEnabled ( LogLevel . ERROR ) ĊĊĠĠĠ Ġoverride Ġfun Ġerror ( str : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isError Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . ERROR . getName (), Ġnull , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġerror ( str : ĠString ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isError Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . ERROR . getName (), Ġnull , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġerror ( str : ĠString ?, Ġthrowable : ĠThrowable ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( isError Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( str , ĠLogLevel . ERROR . getName (), Ġthrowable , Ġobjs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . try Send ( Stop ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconsumer Job . cancel ( Cancellation Exception (" Cancel Ġfile Ġlog Ġexception .")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconsumer Job . join () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflush Tick Job . cancel ( Cancellation Exception (" Cancel Ġflush Ġfile Ġlog Ġexception .")) ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . close () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrite ( content : ĠString ?, Ġlevel : ĠString , Ġthrowable : ĠThrowable ?, Ġobjs : ĠArray < Any > ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġitem Ġ= ĠLog Item () ĊĠĠĠĠĠĠĠ Ġitem . level Ġ= Ġlevel ĊĠĠĠĠĠĠĠ Ġitem . name Ġ= Ġname ĊĠĠĠĠĠĠĠ Ġitem . content Ġ= Ġcontent ĊĠĠĠĠĠĠĠ Ġitem . objs Ġ= Ġobjs ĊĠĠĠĠĠĠĠ Ġitem . throwable Ġ= Ġthrowable ĊĠĠĠĠĠĠĠ Ġitem . date Ġ= ĠDate () ĊĠĠĠĠĠĠĠ Ġitem . mdc Data Ġ= Ġm dc . copyOf Context Map ĊĠĠĠĠĠĠĠ Ġitem . className Ġ= ĠClass Name Log Wrap . name . get () ĊĠĠĠĠĠĠĠ Ġitem . thread Name Ġ= ĠThread . currentThread (). name ĊĠĠĠĠĠĠĠ Ġif Ġ( stack Trace ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġitem . stack Trace Element Ġ= Ġget StackTrace Element () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwrite ( item ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget StackTrace Element (): ĠStack Trace Element ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġarr Ġ= ĠThread . currentThread (). stack Trace ĊĠĠĠĠĠĠĠ Ġval Ġstack Trace Element Ġ= Ġarr [ 4 ] ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( stack Trace Element Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stack Trace Element . className Ġ== Ġ" com . fire fly source . log . ClassName Log Wrap ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarr [ 6 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġstack Trace Element ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġstack Trace Element ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrite ( log Item : ĠLog Item ) Ġ{ ĊĠĠĠĠĠĠĠ Ġchannel . try Send ( Write Log Message ( log Item )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this Ġ=== Ġother ) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġif Ġ( java Class Ġ!= Ġother ?. java Class ) Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġother Ġas ĠFile Log ĊĊĠĠĠĠĠĠĠ Ġif Ġ( log Name Ġ!= Ġother . log Name ) Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠhashCode (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġlog Name . hashCode () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" File Log {" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" level =" Ġ+ Ġlevel Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ", Ġpath ='" Ġ+ Ġpath Ġ+ Ġ'\' '. toString () Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ", Ġname ='" Ġ+ Ġname Ġ+ Ġ'\' '. toString () Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ", Ġconsole Output =" Ġ+ Ġconsole Output Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ", Ġfile Output =" Ġ+ Ġfile Output Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ", Ġmax FileSize =" Ġ+ Ġmax FileSize Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ", Ġcharset =" Ġ+ Ġcharset Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ", Ġmax Split Time =" Ġ+ Ġmax Split Time . value Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ' }'. toString () ĊĠĠĠ Ġ} Ċ Ċ }