Aktuelle Zeit: 12.12.2018 07:00

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: SimplePBLogger
BeitragVerfasst: 30.08.2018 13:41 
Offline
Benutzeravatar

Registriert: 19.07.2018 20:41
Hey,

ich hab mir einen kleinen Logger geschrieben, weil ich den für ein anderes Projekt verwenden will. Ist die erste kleine Sache, die ich PB fertiggestellt habe und sie spiegelt meinen aktuellen Stand in PB wider (bin ja noch nicht so lange dabei).

Ich bin nicht der Meinung, dass die Welt nur auf mein Progrämmchen mit den rudimentären Loggerfunktionen gewartet hat, aber falls jemand Zeit und Nerv hat, sich die Sache mal anzusehen und mir dann zu sagen, was alles falsch ist oder besser gelöst werden könnte, wäre das für mich ein sehr hilfreiches Feedback um mich weiterzuentwickeln. Stört euch bitte nicht an meinem ebenfalls rudimentären Englischkenntnissen, die Schule ist schon eine Weile her bei mir :?

Aktuelle Fassung vom 09.09.2018 (Copyright korrigiert)

Code:
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; + SimplePBLogger                                                                                             
; + Utility to log informations in PureBasic-Programs                                               
; + Version 0.3                                                                                                   
; + MIT License                                                                                                   
; + Copyright (c) 2018 Joachim Weiß
; + Permission is hereby granted, free of charge, to any person obtaining a copy
; + of this software and associated documentation files (the "Software"), to deal
; + in the Software without restriction, including without limitation the rights
; + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; + copies of the Software, and to permit persons to whom the Software is
; + furnished to do so, subject to the following conditions: +
; +                                                                                                                                       
; + The above copyright notice and this permission notice shall be included in all
; + copies or substantial portions of the Software.
; +                                                                                                                                       
; + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
; + SOFTWARE.                           
; + Hints:                                                                   
; + Before using the logger, initialize him! Use InitializeLogger an give him
; + as parameters the path, where the logfiles shall be stored and optional         
; + the maximal number of logfiles you want to have for your application     
; + (standard is 10 - with the maxNumber you can avoid to have too much files)
; + To write an Entry in a Logfile use WriteLogEntry. Select a LogLevel from   
; + the constants (or create there a new loglevel, if you want) and create   
; + the message you want to store. You have also the option to store variables
; + and their values etc. Please use SPBL_Parameter. Create a variable of     
; + this structure an add key/value-pairs to the \entries-map. Put the       
; + variable as the third parameter in the WriteLogEntry-call                 
; + If you want to export or import logfiles you can do this with the         
; + ExportLogFiles / ImportLogFiles-procedure. These procedures need the path
; + of the Destination where the files should be copied from/to. You have the
; + option to tell the procedures how many files have to be copied. If there 
; + are more files than to copy, the procedures take the youngest files of the
; + given number.                                                             
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


DeclareModule SimplePBLogger 
 
  #SPBL_DEBUG = "   Debug   "
  #SPBL_INFORMATION = "-  Information  -"
  #SPBL_WARNING = "!  Warning  !"
  #SPBL_ERROR = "*** ERROR ***"
 
  Structure SPBL_Parameter  ; for optional key/value-entries to write in Logfiles
    Map Entries.s()
  EndStructure
 
  ; Procedure to initialize the logger. Returns #True if successful
  ; If there are more logfiles than allowed (is set with the
  ; MaxNumberLogfiles parameter) the procedure will delete the oldest file(s)
  Declare.i InitializeLogger(LocationLogfile.s, MaxNumberLogfiles.i = 10)
 
  ; Procedure to write an entry into the logfile. Returns #True if succesfull
  ; This procedure will create an new logfile, if there is no one for the actual
  ; date.
  Declare.i WriteLogEntry(LogLevel.s, Message.s, *Parameters.SPBL_Parameter = #Null)
 
  ; Procedure to copy Logfiles from their standard location to another location
  ; e.g. for backup or for sendingt them to the programmer. Returns #True if successful
  Declare.i ExportLogFiles(TargetLocation.s, NumberOfFiles.i = 10)
 
  ; Procedure to copy Logfiles to their standard location e.g. to restore them
  ; Returns #True if successful
  Declare.i ImportLogFiles(FromLocation.s, NumberOfFiles.i = 10)
 
EndDeclareModule

Module SimplePBLogger
 
  EnableExplicit
 
  Structure Logfile ;
    Name.s
    Date.i
  EndStructure
 
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    #Separator = "\"
  CompilerElse
    #Separator = "/"
  CompilerEndIf
 
  Global.s Location
  Global.i MaxFiles
  Global NewList CurrentLogFiles.Logfile()
  Global LoggerMutex = CreateMutex()
 
  Global.i LoggerIsInitialized = #False
  #LOGFILE = 1
  #LOGDIRECTORY = 1
  #TARGETDIRECTORY = 2
 
 
  Procedure.i InitializeLogger(LocationLogFiles.s, MaxNumberLogfiles.i = 10)
    LockMutex(LoggerMutex)
    If ExamineDirectory(#LOGDIRECTORY, LocationLogFiles, "Logfile_*.txt")
      Location = LocationLogFiles
      MaxFiles = MaxNumberLogfiles
      While NextDirectoryEntry(#LOGDIRECTORY)
        AddElement(CurrentLogFiles())
        With CurrentLogFiles()
          \Name = DirectoryEntryName(#LOGDIRECTORY)
          \Date = DirectoryEntryDate(#LOGDIRECTORY, #PB_Date_Created)
        EndWith
      Wend 
      SortStructuredList(CurrentLogFiles(), #PB_Sort_Ascending,
                         OffsetOf(Logfile\Date), TypeOf(Logfile\Date))
      FinishDirectory(#LOGDIRECTORY)
      ; Make shure, that number of logfiles is lower than MaxFiles
      FirstElement(CurrentLogFiles())
      While ListSize(CurrentLogFiles()) > MaxFiles
        DeleteFile(CurrentLogFiles()\Name)
        DeleteElement(CurrentLogFiles(), 1)
      Wend
      LoggerIsInitialized = #True
    EndIf
    UnlockMutex(LoggerMutex)
    ProcedureReturn LoggerIsInitialized
  EndProcedure
   
  Procedure.i  WriteLogEntry(LogLevel.s, Message.s, *Parameters.SPBL_Parameter = #Null)
    Define.i Result = #False
    LockMutex(LoggerMutex)
    If LoggerIsInitialized
      Define.s Filename
      Filename = Location +
                 "Logfile_" + FormatDate("%yyyy_%mm_%dd", Date()) + ".txt"
      If OpenFile(#LOGFILE, Filename, #PB_File_Append)
        WriteStringN(#LOGFILE, "-------------------------------------------")
        WriteStringN(#LOGFILE, FormatDate("%hh:%ii:%ss: ", Date()))
        WriteStringN(#LOGFILE, LogLevel)
        WriteStringN(#LOGFILE, Message)
        If *Parameters <> #Null
          ForEach *Parameters\Entries()
            WriteStringN(#LOGFILE, MapKey(*Parameters\Entries()) + " => " +
                                   *Parameters\Entries())
          Next
        EndIf
        CloseFile(#LOGFILE)
        Result = #True
      EndIf
    EndIf
    UnlockMutex(LoggerMutex)
    ProcedureReturn Result
  EndProcedure
 
  Procedure ExportLogFiles(TargetLocation.s, NumberOfFiles.i = 10)
    Define.i Result = #False
    LockMutex(LoggerMutex)
    If LoggerIsInitialized
      If ExamineDirectory(#TARGETDIRECTORY, TargetLocation, "*.*")
        Define i.i = 1
        Define Destination.s
        SortStructuredList(CurrentLogFiles(), #PB_Sort_Descending,
                           OffsetOf(Logfile\Date), TypeOf(Logfile\Date))
        ForEach CurrentLogFiles()
          If i > NumberOfFiles
            Break
          EndIf
          Destination = TargetLocation
          If Right(TargetLocation, 1) <> #Separator
            Destination + #Separator
          EndIf
          Destination + GetFilePart(CurrentLogFiles()\Name)
          CopyFile(CurrentLogFiles()\Name, Destination)
          i + 1
        Next
        FinishDirectory(#TARGETDIRECTORY)
        Result = #True
      EndIf 
    EndIf
    UnlockMutex(LoggerMutex)
    ProcedureReturn Result
  EndProcedure
 
  Procedure ImportLogFiles(FromLocation.s, NumberOfFiles.i = 10)
    Define.i  Result = #False
    LockMutex(LoggerMutex)
    If LoggerIsInitialized
      If ExamineDirectory(#TARGETDIRECTORY, FromLocation, "Logfile_*.txt")
        Define i.i = 1
        Define Destination.s
        NewList FileList.Logfile()
        While NextDirectoryEntry(#TARGETDIRECTORY)
          AddElement(FileList())
          With FileList()
            \Name = DirectoryEntryName(#TARGETDIRECTORY)
            \Date = DirectoryEntryDate(#TARGETDIRECTORY, #PB_Date_Created)
          EndWith
        Wend     
        SortStructuredList(FileList(), #PB_Sort_Ascending,
                           OffsetOf(Logfile\Date), TypeOf(Logfile\Date))
        ForEach FileList()
          If i > NumberOfFiles
            Break
          EndIf
          Destination = FromLocation
          If Right(FromLocation, 1) <> #Separator
            Destination + #Separator
          EndIf
          Destination + GetFilePart(FileList()\Name)
          CopyFile(Destination, Location + FileList()\Name)
          i + 1
        Next     
        FinishDirectory(#TARGETDIRECTORY)
        Result = #True
      EndIf 
    EndIf
    UnlockMutex(LoggerMutex)
    ProcedureReturn Result
  EndProcedure
 
     
 
EndModule


 




Beispielcode:

Code:
; Examplecode for SimplePBLogger

Define.s LogDirectory = GetCurrentDirectory()
Define.i MaxNumberOfLogFiles = 25

Define loggerWorks = InitializeLogger(LogDirectory, MaxNumberOfLogFiles)
; you can check loggerWorks to find out if the logger can be used now.

WriteLogEntry(#SPBL_INFORMATION, "My first entry...")

; let's transport some information to the logfile
Define.i a = 10
Define.s b = "Hello"
Define information.SPBL_Parameter ; the wrapper for the variables
information\Entries("a") = Str(a)
information\Entries("b") = b
WriteLogEntry(#SPBL_INFORMATION, "Here are some values:", information)

; Export the logfiles
ExportLogFiles(GetTemporaryDirectory(), MaxNumberOfLogFiles)

; to get the logfiles back, but maximal 10 files (standardoption):
ImportLogFiles(GetTemporaryDirectory())
 


Zuletzt geändert von Qnode am 09.09.2018 19:16, insgesamt 3-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 14:26 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Ich habe das nur mal eben überflogen, aber ich denke hier solltest Du die beiden Zeilen (Delete...) besser tauschen, sonst löschst Du eine falsche Datei:
Code:
While ListSize(CurrentLogFiles()) > MaxFiles
  DeleteElement(CurrentLogFiles(), 1)
  DeleteFile(CurrentLogFiles()\Name)
Wend

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 14:43 
Offline
Benutzeravatar

Registriert: 20.04.2006 09:50
EnableExplicit musst du direkt ins Module schreiben, wenn du es da verwenden willst, und außerhalb lieber dem Kontext überlassen.
Code:
;EnableExplicit

DeclareModule SimplePBLogger
 
  EnableExplicit
 
  Define x = 44
 
EndDeclareModule

Module SimplePBLogger
 
  EnableExplicit

  Define y.i = 12
 
EndModule
Nett ist auch immer ein Beispiel Code. Den kannst du folgendermaßen ans Ende der Datei hängen:
Code:
...

CompilerIf #PB_Compiler_IsMainFile
 
   SimplePBLogger::InitializeLogger("/tmp/")
   SimplePBLogger::WriteLogEntry("my log level", "hallo")
 
CompilerEndIf

_________________
my pb stuff..
Bild..jedenfalls war das mal so.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 15:45 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Noch ein paar Mutex rein und es funktioniert auch mit Threads :wink:

_________________
Alles ist möglich, fragt sich nur wie...
Projekte EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 17:55 
Offline
Benutzeravatar

Registriert: 08.09.2004 00:57
Wohnort: Berlin
@#NULL

Ein EnableExplicit im Bereich des Modules reicht :wink:
Entweder im Declare Bereich, oder im Modulbereich, wenn es nur dort gelten soll. Doppelt gemoppelt bringt aber nur unnötigen Schreibaufwand.

_________________
PureBasic 5.70 | SpiderBasic 2.10 | Windows 10 Pro (x64) | Linux Mint 19.0 (x64)
"Ich möchte gerne die Welt verändern, doch Gott gibt den Quellcode nicht frei."
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 18:01 
Offline
Benutzeravatar

Registriert: 19.07.2018 20:41
#NULL hat geschrieben:
Nett ist auch immer ein Beispiel Code. Den kannst du folgendermaßen ans Ende der Datei hängen...


Autsch! Hatte Beispielcode vorbereitet und vergessen, ihn zu posten. Hier ist er:
Code:
; Examplecode for SimplePBLogger

Define.s LogDirectory = GetCurrentDirectory()
Define.i MaxNumberOfLogFiles = 25

Define loggerWorks = InitializeLogger(LogDirectory, MaxNumberOfLogFiles)
; you can check loggerWorks to find out if the logger can be used now.

WriteLogEntry(#SPBL_INFORMATION, "My first entry...")

; let's transport some information to the logfile
Define.i a = 10
Define.s b = "Hello"
Define information.SPBL_Parameter ; the wrapper for the variables
information\Entries("a") = Str(a)
information\Entries("b") = b
WriteLogEntry(#SPBL_INFORMATION, "Here are some values:", information)

; Export the logfiles
ExportLogFiles(GetTemporaryDirectory(), MaxNumberOfLogFiles)

; to get the logfiles back, but maximal 10 files (standardoption):
ImportLogFiles(GetTemporaryDirectory())
 


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 18:09 
Offline
Benutzeravatar

Registriert: 19.07.2018 20:41
HeX0R hat geschrieben:
Ich habe das nur mal eben überflogen, aber ich denke hier solltest Du die beiden Zeilen (Delete...) besser tauschen, sonst löschst Du eine falsche Datei:
Code:
While ListSize(CurrentLogFiles()) > MaxFiles
  DeleteElement(CurrentLogFiles(), 1)
  DeleteFile(CurrentLogFiles()\Name)
Wend



Hm, kannst du mir sagen warum? Ich hatte den Code ausgetestet und keine Fehler bemerkt (oder habe ich da was übersehen?). Aber ich verstehe, was du meinst und habe die Befehle umgestellt.


Zuletzt geändert von Qnode am 30.08.2018 18:19, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 18:15 
Offline
Benutzeravatar

Registriert: 19.07.2018 20:41
mk-soft hat geschrieben:
Noch ein paar Mutex rein und es funktioniert auch mit Threads :wink:

Verlockender Gedanke :D . Habe mit Mutex schon mal rumgespielt, aber ich mal sehen, ob ich das hier reingebastelt bekomme..."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 19:34 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Qnode hat geschrieben:
Hm, kannst du mir sagen warum? Ich hatte den Code ausgetestet und keine Fehler bemerkt (oder habe ich da was übersehen?). Aber ich verstehe, was du meinst und habe die Befehle umgestellt.


Ich denke Du wolltest die ältesten Datein löschen, wenn Du aber erst das Element löschst, wird das nachfolgende Element aktiv und DeleteFile löscht das zweitälteste.
In der Theorie, dürfte so das älteste File nie gelöscht werden (wie gesagt nix ausprobiert).

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: SimplePBLogger
BeitragVerfasst: 30.08.2018 21:29 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Part mit Mutex...

Code:
...
Global MutexWriteLog = CreateMutex()
 
  Procedure.i  WriteLogEntry(LogLevel.s, Message.s, *Parameters.SPBL_Parameter = #Null)
    Define.i Result = #False
    If LoggerIsInitialized
      LockMutex(MutexWriteLog)
      Define.s Filename
      Filename = Location +
                 "Logfile_" + FormatDate("%yyyy_%mm_%dd", Date()) + ".txt"
      If OpenFile(#LOGFILE, Filename, #PB_File_Append)
        WriteStringN(#LOGFILE, "-------------------------------------------")
        WriteStringN(#LOGFILE, FormatDate("%hh:%ii:%ss: ", Date()))
        WriteStringN(#LOGFILE, LogLevel)
        WriteStringN(#LOGFILE, Message)
        If *Parameters <> #Null
          ForEach *Parameters\Entries()
            WriteStringN(#LOGFILE, MapKey(*Parameters\Entries()) + " => " +
                                   *Parameters\Entries())
          Next
        EndIf
        CloseFile(#LOGFILE)
        Result = #True
      EndIf
      UnlockMutex(MutexWriteLog)
    EndIf
    ProcedureReturn Result
  EndProcedure
... 


Dann sollte aber auch immer in den Compiler-Option Threadsafe aktiviert sein, damit es auch nicht zu Problemen mit den Strings gibt.

_________________
Alles ist möglich, fragt sich nur wie...
Projekte EventDesigner v1.x / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf Webspace


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye