diff --git a/SYS/lhs_log.pbi b/SYS/lhs_log.pbi new file mode 100644 index 0000000..6ebab4f --- /dev/null +++ b/SYS/lhs_log.pbi @@ -0,0 +1,177 @@ +;************************************** +;* +;* lhs_log.pbi +;* +;* (c) by René Linder +;* (c) by Linder Hard- und Software +;* +;* Lizenz LGPL V2.1 + +;{ Short Documentation: +;* +;* lhs_log::App_Name = "Test App" +;* lhs_log::SetLogFile("test_app.log")) +;* lhs_log::SetMaxSize(32) +;* lhs_log::SetLogDateFormat("%yyyy.%mm.%dd %hh:%ii:%ss") +;* lhs_log::SetLogFileDateFormat("%yyyy_%mm_%dd_%hh_%ii_%ss") +;* lhs_log::Init() +;* lhs_log::Out("Log started.", #lhs_log::#Debug) +;* lhs_log::Close() +;} +CompilerIf #PB_Compiler_Thread <> 1 + CompilerError "Muss Threadsafe Kompiliert werden" + ;Need to be compiled threadsafe +CompilerEndIf + +DeclareModule lhs_log + Global.s App_Name = "lhs_Logger" + #Debug = 1 + #NoDebug = 0 + + Declare SetLogFile(LogFileName.s) + Declare SetMaxSize(Megabyte.i) + Declare SetLogFileDateFormat(DateFormat.s) + Declare SetLogDateFormat(DateFormat.s) + Declare Init() + Declare Out(ToLog.s, debugger.i = #NoDebug) + Declare Close() +EndDeclareModule + +Module lhs_log + Global File_ID.i + CompilerIf #PB_Compiler_OS = #PB_OS_Linux + Global LogFile.s = "/var/log/"+App_Name+".log" + CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows + Global LogFile.s = GetPathPart(ProgramFilename())+App_Name+ ".log" + CompilerElse + CompilerError "Andere Betriebssysteme als Windows und Linux werden nicht unterstützt" + ;Other Operatingsystems than Windows and Linux are currently unsupported + CompilerEndIf + + Global Exit.i = 0 + Global Mutex = CreateMutex() + Global Semaphore = CreateSemaphore() + Global ExitSemaphore = CreateSemaphore() + Global MaxSize.q = 32 * 1024 * 1024 + Global LastSize.q = 0 + Global LogFileDateFormat.s = "%yyyy_%mm_%dd_%hh_%ii_%ss" + Global LogDateFormat.s = "%yyyy.%mm.%dd %hh:%ii:%ss" + Global NewList Messages.s() + + Procedure SetMaxSize(Megabyte.i) + If Megabyte > 0 And Megabyte < 1025 + MaxSize = Megabyte * 1024 * 1024 + Else + MaxSize = 32 * 1024 * 1024 + EndIf + EndProcedure + + Procedure SetLogFile(LogFileName.s) + Protected.i TestFile_ID + + TestFile_ID = OpenFile(#PB_Any, LogFileName, #PB_File_Append | #PB_File_NoBuffering) + If IsFile(TestFile_ID) + LogFile = LogFileName + CloseFile(TestFile_ID) + ProcedureReturn #True + Else + ProcedureReturn #False + EndIf + EndProcedure + + Procedure SetLogFileDateFormat(DateFormat.s) + If Len(DateFormat)>4 + LogFileDateFormat = DateFormat + EndIf + EndProcedure + + Procedure SetLogDateFormat(DateFormat.s) + If Len(DateFormat)>4 + LogDateFormat = DateFormat + EndIf + EndProcedure + + Procedure CheckMaxSize() + If LastSize = 0 + LastSize = FileSize(LogFile) + EndIf + + ProcedureReturn Bool(LastSize < MaxSize) + EndProcedure + + Procedure UpdateLastSizeString(String.s) + LastSize + StringByteLength(String.s) + EndProcedure + + Procedure LogThread(nix) + Shared Mutex + Define ToWrite.s + File_ID = OpenFile(#PB_Any, LogFile, #PB_File_Append | #PB_File_NoBuffering) + If IsFile(File_ID) + Repeat + WaitSemaphore(Semaphore) + If Exit = 1 + LockMutex(Mutex) + If ListSize(Messages()) > 0 + Repeat + FirstElement(Messages()) + ToWrite = FormatDate(LogDateFormat, Date()) + " - " + Messages() + UpdateLastSizeString(ToWrite):WriteStringN(File_ID, ToWrite) + DeleteElement(Messages()) + Until ListSize(Messages()) = 0 + EndIf + CloseFile(File_ID) + UnlockMutex(Mutex) + Break + Else + LockMutex(Mutex) + FirstElement(Messages()) + ToWrite = FormatDate(LogDateFormat, Date()) + " - " + Messages() + UpdateLastSizeString(ToWrite) + If Not CheckMaxSize() + CloseFile(File_ID) + If CopyFile(LogFile, LogFile+FormatDate(LogFileDateFormat, Date())) + DeleteFile(LogFile) + EndIf + File_ID = OpenFile(#PB_Any, LogFile, #PB_File_Append | #PB_File_NoBuffering) + EndIf + WriteStringN(File_ID, ToWrite) + DeleteElement(Messages()) + UnlockMutex(Mutex) + EndIf + ForEver + SignalSemaphore(ExitSemaphore) + EndIf + EndProcedure + + Procedure Init() + File_ID = OpenFile(#PB_Any, LogFile, #PB_File_Append | #PB_File_NoBuffering) + If IsFile(File_ID) + CloseFile(File_ID) + Else + ProcedureReturn #False + EndIf + CreateThread(@LogThread(), 1) + ProcedureReturn #True + EndProcedure + + Procedure Out(ToLog.s, debugger.i = #NoDebug) + Shared Mutex + LockMutex(Mutex) + LastElement(Messages()) + AddElement(Messages()) + Messages() = ToLog + If debugger = #Debug + Debug ToLog + EndIf + UnlockMutex(Mutex) + SignalSemaphore(Semaphore) + EndProcedure + + Procedure Close() + Exit=1 + SignalSemaphore(Semaphore) + WaitSemaphore(ExitSemaphore) + EndProcedure + +EndModule