diff --git a/WinNUT_V2/WinNUT-Client_Common/Logger.vb b/WinNUT_V2/WinNUT-Client_Common/Logger.vb index d04cbc8..03059cf 100644 --- a/WinNUT_V2/WinNUT-Client_Common/Logger.vb +++ b/WinNUT_V2/WinNUT-Client_Common/Logger.vb @@ -7,23 +7,38 @@ ' ' This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY +Imports System.Globalization Imports System.IO Public Class Logger #Region "Constants/Shared" - Private Shared ReadOnly BASE_FILE_NAME = ProgramName ' "WinNUT-CLient" Private Const LOG_FILE_CREATION_SCHEDULE = Logging.LogFileCreationScheduleOption.Daily - ' The LogFileCreationScheduleOption doesn't present the string format of what it uses - Private Const LOG_FILE_DATESTRING = "yyyy-MM-dd" + +#If DEBUG Then + Private Shared ReadOnly DEFAULT_DATETIMEFORMAT = DateTimeFormatInfo.InvariantInfo +#Else + Private Shared ReadOnly DEFAULT_DATETIMEFORMAT = DateTimeFormatInfo.CurrentInfo +#End If + + ' The subfolder that will contain logs. - Public Const LOG_SUBFOLDER = "\Logs\" + Public Const LOG_SUBFOLDER = "Logs" + + Private Shared ReadOnly BASE_FILE_NAME = ProgramName + Private ReadOnly TEventCache As New TraceEventCache() #End Region +#Region "Private/backing values" + Private LogFile As Logging.FileLogTraceListener - Private ReadOnly TEventCache As New TraceEventCache() - Public LogLevelValue As LogLvl Private L_CurrentLogData As String Private LastEventsList As New List(Of Object) + Private _DateTimeFormatInfo As DateTimeFormatInfo = DEFAULT_DATETIMEFORMAT + +#End Region + + Public LogLevelValue As LogLvl + Public Event NewData(sender As Object) #Region "Properties" @@ -77,6 +92,16 @@ Public Class Logger End Get End Property + Public Property DateTimeFormatInfo As DateTimeFormatInfo + Get + Return _DateTimeFormatInfo + End Get + Set(value As DateTimeFormatInfo) + _DateTimeFormatInfo = value + End Set + End Property + + #End Region Public Sub New(LogLevel As LogLvl) @@ -89,11 +114,22 @@ Public Class Logger .Append = True, .AutoFlush = True, .LogFileCreationSchedule = LOG_FILE_CREATION_SCHEDULE, - .CustomLocation = baseDataFolder & LOG_SUBFOLDER, + .CustomLocation = Path.Combine(baseDataFolder, LOG_SUBFOLDER), .Location = Logging.LogFileLocation.Custom } - LogTracing("Log file is initialized at " & LogFile.FullLogFileName, LogLvl.LOG_NOTICE, Me) + LogTracing(String.Format("{0} {1} Log file init", LongProgramName, ProgramVersion), LogLvl.LOG_NOTICE, Me) + + If LastEventsList.Count > 0 Then + ' Fill new file with the LastEventsList buffer + LogFile.WriteLine("==== History of " & LastEventsList.Count & " previous events ====") + + For index As Integer = 0 To LastEventsList.Count - 1 + LogFile.WriteLine(String.Format("[{0}] {1}", index + 1, LastEventsList(index))) + Next + End If + + LogFile.WriteLine("==== Begin Live Log ====") End Sub ''' @@ -132,17 +168,7 @@ Public Class Logger ''' What generated this message. ''' A user-friendly, translated string to be shown. Public Sub LogTracing(message As String, LvlError As LogLvl, sender As Object, Optional LogToDisplay As String = Nothing) - Dim Pid = TEventCache.ProcessId - Dim SenderName - ' Handle a null sender - If sender Is Nothing Then - SenderName = "Nothing" - Else - SenderName = sender.GetType.Name - End If - - Dim EventTime = Now.ToLocalTime - Dim FinalMsg = EventTime & " Pid: " & Pid & " " & SenderName & " : " & message + Dim FinalMsg = FormatLogLine(message, LvlError, sender) ' Always write log messages to the attached debug messages window. #If DEBUG Then @@ -166,4 +192,15 @@ Public Class Logger RaiseEvent NewData(sender) End If End Sub + + Private Function FormatLogLine(message As String, logLvl As LogLvl, Optional sender As Object = Nothing) + Dim Pid = TEventCache.ProcessId + Dim SenderName = "Nothing" + + If sender IsNot Nothing Then + SenderName = sender.GetType.Name + End If + + Return String.Format("{0} [{1}, {2}]: {3}", Date.Now.ToString(_DateTimeFormatInfo), Pid, SenderName, message) + End Function End Class diff --git a/WinNUT_V2/WinNUT-Client_Common/WinNUT_Globals.vb b/WinNUT_V2/WinNUT-Client_Common/WinNUT_Globals.vb index 6886b81..5b21384 100644 --- a/WinNUT_V2/WinNUT-Client_Common/WinNUT_Globals.vb +++ b/WinNUT_V2/WinNUT-Client_Common/WinNUT_Globals.vb @@ -12,57 +12,62 @@ Imports System.IO Public Module WinNUT_Globals #Region "Constants/Shareds" - Private DEFAULT_DATA_PATH As String -#End Region - Public LongProgramName As String - Public ProgramName As String - Public ProgramVersion As String - Public ShortProgramVersion As String - Public GitHubURL As String - Public Copyright As String - Public IsConnected As Boolean +#If DEBUG Then + Public ReadOnly IsDebugBuild = True + ' If debugging, keep any generated data next to the debug executable. + Private ReadOnly DESIRED_DATA_PATH As String = Path.Combine(Environment.CurrentDirectory) +#Else + Public ReadOnly IsDebugBuild = False + Private ReadOnly DESIRED_DATA_PATH As String = Environment.GetFolderPath( + Environment.SpecialFolder.ApplicationData)) +#End If + + Private ReadOnly FALLBACK_DATA_PATH = Path.GetTempPath() + Private ReadOnly DATA_DIRECTORY_NAME = "WinNut-Client" + + Public ReadOnly ProgramName = My.Application.Info.ProductName + Public ReadOnly LongProgramName = My.Application.Info.Description + Public ReadOnly ProgramVersion = Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString + Public ReadOnly ShortProgramVersion = ProgramVersion.Substring(0, ProgramVersion.IndexOf(".", ProgramVersion.IndexOf(".") + 1)) + Public ReadOnly GitHubURL = My.Application.Info.Trademark + Public ReadOnly Copyright = My.Application.Info.Copyright + + Public IsConnected = False Public ApplicationData As String - ' Public LogFile As String - ' Handle application messages and debug events. - ' Public WithEvents LogFile As Logger ' As New Logger(False, 0) - ' Logging - Public WithEvents LogFile As Logger + Public WithEvents LogFile As Logger = New Logger(LogLvl.LOG_DEBUG) Public AppIcon As Dictionary(Of Integer, Drawing.Icon) Public StrLog As New List(Of String) - ' Public LogFilePath As String - Public Sub Init_Globals() -#If DEBUG Then - ' If debugging, keep any generated data next to the debug executable. - DEFAULT_DATA_PATH = Path.Combine(Environment.CurrentDirectory, "Data") -#Else - DEFAULT_DATA_PATH = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "\WinNUT-Client") -#End If +#End Region - LongProgramName = My.Application.Info.Description - ProgramName = My.Application.Info.ProductName - ProgramVersion = Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString - ShortProgramVersion = ProgramVersion.Substring(0, ProgramVersion.IndexOf(".", ProgramVersion.IndexOf(".") + 1)) - GitHubURL = My.Application.Info.Trademark - Copyright = My.Application.Info.Copyright - IsConnected = False - LogFile = New Logger(LogLvl.LOG_DEBUG) - SetupAppDirectory() - End Sub - Sub SetupAppDirectory() - If Not Directory.Exists(DEFAULT_DATA_PATH) Then - Try - Directory.CreateDirectory(DEFAULT_DATA_PATH) - ApplicationData = DEFAULT_DATA_PATH - Catch ex As Exception - LogFile.LogTracing(ex.ToString & " encountered trying to create app data directory. Falling back to temp.", - LogLvl.LOG_ERROR, Nothing) - ApplicationData = Path.GetTempPath() & "\WinNUT_Data\" - Directory.CreateDirectory(ApplicationData) - End Try - End If + Public Sub Init_Globals() + ApplicationData = GetAppDirectory(DESIRED_DATA_PATH) End Sub + + ''' + ''' Do everything possible to find a safe place to write to, with the appended to it. If + ''' the requested option is unavailable, we fall back to the temporary directory for the current user. + ''' + ''' The requested directory, with appended to it. + ''' The best possible option available as a writable data directory. + Private Function GetAppDirectory(requestedDir As String) As String + requestedDir = Path.Combine(requestedDir, DATA_DIRECTORY_NAME) + + Try + Directory.CreateDirectory(requestedDir) + LogFile.LogTracing("Successfully created or opened requested data directory for WinNUT." & + vbNewLine & "requestedDir: " & requestedDir, LogLvl.LOG_DEBUG, Nothing) + Return requestedDir + + Catch ex As Exception + LogFile.LogTracing(ex.ToString & " encountered trying to create app data directory. Falling back to temp.", + LogLvl.LOG_ERROR, Nothing) + + Directory.CreateDirectory(FALLBACK_DATA_PATH) + Return FALLBACK_DATA_PATH + End Try + End Function End Module