private void LoggingLevelChanged(object sender, SelectionChangedEventArgs e) { Logging.LogLevel level = (Logging.LogLevel)Enum.Parse(typeof(Logging.LogLevel), ((ComboBoxItem)LoggingSelection.SelectedItem).Tag.ToString()); Logging.SetLogLevel(level); if (level != (Logging.LogLevel)Enum.Parse(typeof(Logging.LogLevel), Properties.Settings.Default.LogLevel)) { Logging.Write($"Log Level set to {level.ToString()}"); Properties.Settings.Default.LogLevel = level.ToString(); } }
private void PersistQueuedItem(Logging.LogLevel logLevel, string logNameWithoutPathOrTimestampPrefix, string textToLog, string method, int threadID = -1) { /*Debug.WriteLine("Executing PersistQueuedItem via thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());*/ // Just exit if this is at an undesired logging level if (Convert.ToInt32(logLevel) < Convert.ToInt32(Logging._MinimumLogLevelToWrite)) { return; } // Create a string builder that represents all info we will log StringBuilder finalTextToLog = new StringBuilder(); finalTextToLog.Append(DateTime.UtcNow.ToString("yyyyMMdd_THHmmssZ") + " | " + logLevel.ToString() + " | " + textToLog); if (!string.IsNullOrEmpty(method)) { finalTextToLog.Append(" | " + "Method = " + method); } if (threadID != -1) { finalTextToLog.Append(" | " + "Thread = " + threadID.ToString()); } // Build the full base filename, including path. The final filename will be altered to include a timestamp prefix in the name // Note: Just for info, an alternative way to build the full path is: System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data/Logs/" + logNameWithoutPathOrTimestampPrefix); string logBaseFileName = Path.Combine(HttpRuntime.AppDomainAppPath, @"App_Data\Logs\" + logNameWithoutPathOrTimestampPrefix); // Extract the folder from the complete file path string logFileFolder = Path.GetDirectoryName(logBaseFileName); // Create folder if it doesn't exist already try { if (!Directory.Exists(logFileFolder)) { Directory.CreateDirectory(logFileFolder); } } catch { } // Check to see if we should cleanup any old log files // To reduce strain, let's only do log file maintenance after every 25 activities if ((Logging._LoggedItemCountSinceCleanup == 0) || ((Logging._LoggedItemCountSinceCleanup % 25) == 0)) { // Do log file cleanup in a separate thread CleanupOldLogFiles(logBaseFileName, Logging._LogFileRetentionDays); } // Increment the logged item count, but avoid maintaining a large number Logging._LoggedItemCountSinceCleanup++; if (Logging._LoggedItemCountSinceCleanup > 1024) { Logging._LoggedItemCountSinceCleanup = 0; } try { // Determine the filename we will use for logging (We will roll-over to new filename when date changes, or when current log file reaches max size threshold) string fullLogFileName = ""; DateTime existingLogTimeStamp = DateTime.MinValue; try { // Find list of today's files for current desired log filename suffix. // Loop through them to find the latest string[] logFiles = Directory.GetFiles(logFileFolder, DateTime.UtcNow.ToString("yyyyMMdd") + "*" + logNameWithoutPathOrTimestampPrefix, SearchOption.TopDirectoryOnly); foreach (string nextLogFile in logFiles) { try { string justFilename = Path.GetFileName(nextLogFile); DateTime logFileTimeStamp = DateTime.SpecifyKind(System.Xml.XmlConvert.ToDateTime(justFilename.Substring(0, 17), "yyyyMMdd_THHmmssZ"), DateTimeKind.Utc); if (logFileTimeStamp > existingLogTimeStamp) { fullLogFileName = nextLogFile; existingLogTimeStamp = logFileTimeStamp; } } catch { } } // If we found the latest existing file, we will use it unless it has already reached maximum size allowed if (fullLogFileName != "") { FileInfo LastLogFileInfo = new FileInfo(fullLogFileName); if (LastLogFileInfo.Length >= (Logging._LogFileMaxSizeInMB * 1024 * 1024)) { fullLogFileName = ""; } } } catch { } // If we don't have a useable name yet, start a new one (and keep track of it) if (fullLogFileName == "") { fullLogFileName = Path.Combine(logFileFolder, DateTime.UtcNow.ToString("yyyyMMdd_THHmmssZ") + " " + logNameWithoutPathOrTimestampPrefix); } lock (Logging._LogFileLock) // wait your turn - avoid concurrent access errors { using (FileStream logFileStream = new FileStream(fullLogFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { using (StreamWriter logWriter = new StreamWriter(logFileStream)) { // We need to make sure we are writing at the end of the file (to append text) logFileStream.Seek(0, SeekOrigin.End); // Append the final text to end of file logWriter.WriteLine(finalTextToLog.ToString()); // Close file and cleanup if (logWriter.BaseStream.CanWrite == true) { logWriter.Flush(); } } } } } catch { } }