Logging einer Prozedur richtig und optional

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Logging einer Prozedur richtig und optional

    Guten Morgen,

    schreibe ein Programm für Kalibrierungen, und wollte bei einer bestimmten Kalibrierung eine Log-Datei über den Verlauf von dieser. Die Prozedur sieht bis jetzt so aus.

    VB.NET-Quellcode

    1. Public Function SetMessPointAndMeasure(messPoint As Single, calibrationHoldTimeForReading As Integer, Optional shunt As Single = Nothing) As CalibrationStepResult 'TODO:Maybe method for calibrator initialize
    2. Dim actualReading As Single
    3. Dim calibrationStepResult As CalibrationStepResult
    4. Dim signalDeviation As KeyValuePair(Of Single, Single)
    5. With calibration
    6. .PressureCalibrator.SetPressureControlMode(PressureCalibratorPpc.PpcControlMode.StaticMode)
    7. .PressureCalibrator.SetTargetPressure(messPoint)
    8. My.Application.Log.WriteEntry()
    9. Log.WriteLog("Pressure set to " & messPoint & " bar")
    10. While Not .PressureCalibrator.PressureReady()
    11. Thread.Sleep(500)
    12. End While
    13. Log.WriteLog($"Pressure set successfully. Waiting {calibrationHoldTimeForReading / 1000} sec. for reading...")
    14. Thread.Sleep(calibrationHoldTimeForReading) 'BUG: Setting in DLL
    15. Log.WriteLog("Trying to read")
    16. 'KeysightNEEDED
    17. 'actualReading = DigitalMultimeter.Read()
    18. If Not IsNothing(shunt) Then
    19. actualReading = GetCurrentFromMeasuredVoltage(actualReading, shunt)
    20. End If
    21. .OutputSignalList.Add(actualReading)
    22. signalDeviation = GetSignalDeviation(messPoint, actualReading)
    23. Log.WriteLog("Read successful---Pressure:" & messPoint & " signal:" & actualReading)
    24. calibrationStepResult = New CalibrationStepResult(messPoint, actualReading, signalDeviation.Key, signalDeviation.Value) 'TODO:Check for output type
    25. .CalibrationSteps.Add(calibrationStepResult)
    26. End With
    27. Return calibrationStepResult
    28. End Function

    Variable calibrationist ein private Field im CalibrationManager (Klasse der oben gennanten Methode) und enthält Info über die Klaibrierung

    Diese wird aber mehrmals ausgeführt in einer höheren Methode DoCalibrationAsync, die von der Klasse CalibrationManager ausgeführt wird, die für den Kaibriervorgang zuständig ist und so aussieht:

    VB.NET-Quellcode

    1. ​Public Function DoCalibrationAsync(calibrationHoldTimeForReading As Integer, Optional progress As IProgress(Of CalibrationStepResult) = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task 'TODO:Check for Type and check how to log the best way
    2. With calibration
    3. Return Task.Run((Sub()
    4. If IsNothing(cancellationToken) Then
    5. cancellationToken = CancellationToken.None
    6. End If
    7. If Not .PressureCalibrator.SerialPort.IsOpen() Then
    8. .PressureCalibrator.SerialPort.Open()
    9. End If
    10. .PressureCalibrator.SetPressureUnit(PressureUnit.bar)
    11. For Each point In .InputList
    12. Dim measureResult = SetMessPointAndMeasure(point, calibrationHoldTimeForReading)
    13. cancellationToken.ThrowIfCancellationRequested()
    14. If Not IsNothing(progress) Then
    15. progress.Report(measureResult)
    16. End If
    17. Next
    18. .PressureCalibrator.Vent()
    19. .PressureCalibrator.SerialPort.Close()
    20. End Sub), cancellationToken)
    21. End With
    22. End Function

    Die Idee ist die Klasse CalibrationManager kriegt eine Prop z.B LogRequested as Boolean, welche dann entscheidet, ob die Kalibrierung bzw. die Methoden, die das Log unterstützen würden, geloggt werden.

    Geht es anders als jetzt vor jedem Log.Write zu checken ob LogRequested oder If IsNothing(Log.Write)... o.ä zu machen bzw. ist diese die vernünftige Art zu loggen? Ich kenne über die Existenz von My.Application.Log etc..aber 1. ich habs sie noch nie benutzt 2.Was ich gelesen habe ist alles über Events und Exceptions.(Was aber auch nicht heissen soll... ?( )
    Die hier benutzte Log Klasse, ist selbstgeschrieben, einfach eine Write-Methode, und 3 Props FileName, FilePath, FullPath (ReadOnly)

    Danke im Voraus und schönen Tag ^^
    RG
    Life doesn't give you a datasheet. Sometimes the docs are wrong and you have to try it.

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „rgomez“ ()

    @rgomez Ich sehe folgende Möglichkeiten, an das Loggen heranzugehen:
    • Es gibt eine Shared Boolean Variable, die sagt, ob geloggt werden soll oder nicht bzw. eine Shared Enumber Variable, die sagt, welche Prozesse geloggt werden.
      Das selbe mit Parameter statt Shared Variablen.
    • Jede Prozedur fragt ab, ob sie loggen soll oder nicht (einfacher If-Konstrukt) und dann wird geloggt oder nicht.
    • Es wird immer geloggt und die loggende Prozedur entscheidet in einem If / Switch, was wenn ja geloggt wird.
    • Wenn es iwann einen "fertigen" Zustand gibt, der nicht mehr loggen soll, kann das ganze auch mit einem Compilerschalter gemacht werden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hab das schon mehrfach in einem ähnlichen Konstrukt wie @RodFromGermany gelöst. Funktioniert sehr gut.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @Mono Jou, das ist bei mir in der Shared Enumber Variable versteckt, war ein bissel verdrückt ausgekehrt verkehrt ausgedrückt. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke für die Antworten.
    Also d.h muss tatsächlich bei jedem Log.Write checken ob log.requested.

    Soll dann es so aussehen? Die Klasse von DoCalibrationAsync hat die Shared Variable logRequested. Wenn DoCalibrationAsync gecallt wird, passt er seine shared Variable zu SetMessPointAndMeasure, welcher dann BEI JEDER Log.Write entscheidet ob im log schreiben oder nicht.

    VB.NET-Quellcode

    1. Public Function DoCalibrationAsync(calibrationHoldTimeForReading As Integer,Optional progress As IProgress(Of CalibrationStepResult) = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task
    2. Return Task.Run((Sub()
    3. If IsNothing(cancellationToken) Then
    4. cancellationToken = CancellationToken.None
    5. End If
    6. If Not .PressureCalibrator.SerialPort.IsOpen() Then
    7. .PressureCalibrator.SerialPort.Open()
    8. End If
    9. .PressureCalibrator.SetPressureUnit(PressureUnit.bar)
    10. For Each point In .InputList
    11. 'CODE ADDED
    12. Dim measureResult = SetMessPointAndMeasure(point, calibrationHoldTimeForReading, logRequested) 'ADDED CODED: Parameter logRequested
    13. cancellationToken.ThrowIfCancellationRequested()
    14. If Not IsNothing(progress) Then
    15. progress.Report(measureResult)
    16. End If
    17. Next
    18. .PressureCalibrator.Vent()
    19. .PressureCalibrator.SerialPort.Close()
    20. End Sub), cancellationToken)
    21. End With
    22. End Function


    und dann

    VB.NET-Quellcode

    1. Public Function SetMessPointAndMeasure(messPoint As Single, calibrationHoldTimeForReading As Integer,logRequested as Boolean, Optional shunt As Single = Nothing) As CalibrationStepResult
    2. Dim actualReading As Single
    3. Dim calibrationStepResult As CalibrationStepResult
    4. Dim signalDeviation As KeyValuePair(Of Single, Single)
    5. With calibration
    6. .PressureCalibrator.SetPressureControlMode(PressureCalibratorPpc.PpcControlMode.StaticMode)
    7. .PressureCalibrator.SetTargetPressure(messPoint)
    8. My.Application.Log.WriteEntry()
    9. If logRequested
    10. Log.WriteLog("Pressure set to " & messPoint & " bar")
    11. End If
    12. While Not .PressureCalibrator.PressureReady()
    13. Thread.Sleep(500)
    14. End While
    15. If logRequested
    16. Log.WriteLog($"Pressure set successfully. Waiting {calibrationHoldTimeForReading / 1000} sec. for reading...")
    17. End If
    18. Thread.Sleep(calibrationHoldTimeForReading) 'BUG: Setting in DLL
    19. If logRequested
    20. Log.WriteLog("Trying to read")
    21. End If
    22. 'KeysightNEEDED
    23. 'actualReading = DigitalMultimeter.Read()
    24. If Not IsNothing(shunt) Then
    25. actualReading = GetCurrentFromMeasuredVoltage(actualReading, shunt)
    26. End If
    27. .OutputSignalList.Add(actualReading)
    28. signalDeviation = GetSignalDeviation(messPoint, actualReading)
    29. If logRequested
    30. Log.WriteLog("Read successful---Pressure:" & messPoint & " signal:" & actualReading)
    31. End If
    32. calibrationStepResult = New CalibrationStepResult(messPoint, actualReading, signalDeviation.Key, signalDeviation.Value) 'TODO:Check for output type
    33. .CalibrationSteps.Add(calibrationStepResult)
    34. End With
    35. Return calibrationStepResult
    36. End Function

    Dann auch die Log Klasse etwas "besser" machen mit LogLevel etc etc...

    Die Frage ist aber, wenn man z.B eine lange Prozedur hat, in der keine oder wenige Schleifen vorhanden sind, und man will z.B in 50 Punkte ein LogEntry haben, muss man im ernst 50 If's schreiben??? Das ist echt unschön.....und mega redundant
    Life doesn't give you a datasheet. Sometimes the docs are wrong and you have to try it.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „rgomez“ ()

    rgomez schrieb:

    muss man im ernst 50 If's schreiben???

    RodFromGermany schrieb:

    Es wird immer geloggt und die loggende Prozedur entscheidet in einem If / Switch, was wenn ja geloggt wird.
    In Log.WriteLog() steht ein einziges solches If in der 1. Zeile (danach noch beliebig mehr).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    MIr sieht der code aus post#6 in mehrfacher Hinsicht abenteuerlich aus:
    1) Async-Pattern ist imo nicht so gemeint, dass man da anonyme Methoden schreibt, über 18 Zeilen hin
    2) Ich sehe nicht, dass mit der Rückgabe von SetMessPointAndMeasure() iwas gemacht würde.
    3)

    VB.NET-Quellcode

    1. While Not .PressureCalibrator.PressureReady()
    2. Thread.Sleep(500)
    3. End While
    gibts dazu echt keine Alternative?