/// <summary> /// Returns the specified number of log entries of the specified category, starting with the latest one. /// </summary> /// <param name="category">The category of the log entries to be returned (-1 for "all").</param> /// <param name="maxItems">The maximum number of items returned (-1 for "all").</param> /// <param name="logfilePath">For environments where "AppDomain.CurrentDomain.BaseDirectory" doesn't work reliably, the path to the nLog.csv file can be explicitly specified here.</param> /// <returns>A list of LogEntrys or null.</returns> public static List <ErrorLogEntry> GetLogEntries(LogEntryCategories category, int maxItems, DateTime startTime, DateTime endTime, string searchText, string myLogfilePath = null) { Exception ex; myLogfilePath = myLogfilePath ?? logFilePath; DataTable dtEntries = CsvHandler.ReadCSVFile(myLogfilePath, out ex); if (dtEntries == null || ex != null) { LastException = ex; return(null); } bool displayAllCategories = (int)category == -1 ? true : false; //determine if all entries have to be displayed List <ErrorLogEntry> entriesToReturn = new List <ErrorLogEntry>(); for (int i = dtEntries.Rows.Count - 1; i >= 0; i--) //iterate the table from bottom to top (new to old) { DateTime entryTime; string categoryString = category.ToString(); if (displayAllCategories || dtEntries.Rows[i].ItemArray[2].ToString() == categoryString) //category matches the input parameter { if (!DateTime.TryParse(dtEntries.Rows[i].ItemArray[0].ToString(), out entryTime)) { entryTime = endTime; } if (entryTime >= startTime && entryTime <= endTime) { if (string.IsNullOrEmpty(searchText) || (dtEntries.Rows[i].ItemArray[3].ToString().Contains(searchText) || dtEntries.Rows[i].ItemArray[4].ToString().Contains(searchText))) { ErrorLogEntry newLogEntry = new ErrorLogEntry() { Time = entryTime, LogLevel = dtEntries.Rows[i].ItemArray[1].ToString(), Category = dtEntries.Rows[i].ItemArray[2].ToString(), Message = dtEntries.Rows[i].ItemArray[3].ToString(), ExceptionText = dtEntries.Rows[i].ItemArray[4].ToString(), CodeLine = dtEntries.Rows[i].ItemArray[5].ToString() }; entriesToReturn.Add(newLogEntry); } } } if (maxItems > 0 && entriesToReturn.Count == maxItems) { break; } } return(entriesToReturn); }
/// <summary> /// Saves a new log entry. /// </summary> /// <param name="category">The category of the entry.</param> /// <param name="message">The text to be displayed.</param> /// <param name="exception">An optional Exception object.</param> public static void AddLogEntry(LogEntryCategories category, string message, Exception exception = null, string className = "", [CallerMemberName] string memberName = "", [CallerLineNumber] int sourceLineNumber = 0) { if (!WriteLogFile) { return; } #region LogLevel check if (LogLevel == LogLevels.None) { return; } if (category == LogEntryCategories.Debug || category == LogEntryCategories.Info || category == LogEntryCategories.Other) { if (LogLevel == LogLevels.ErrorsOnly) { return; } } #endregion if (message != null) { message = message.Replace(';', ',').Replace(Environment.NewLine, " |-> ").Replace("\"", "'"); //make sure that the message does not contain any line breaks (the current CSV reader does not support multiple multi-line columns) } message = (string.IsNullOrEmpty(className) ? null : className + ".") + memberName + "[" + sourceLineNumber + "]: " + message; if (exception != null && exception.Message != null) { exception = new Exception(exception.ToString().Replace(';', ',').Replace("\"", "'")); //prevent semicolons and apostrophe in exception messages because the exceptions are written to a CSV file } LogLevel logLevel = NLog.LogLevel.Info; switch (category) { case LogEntryCategories.Debug: logLevel = NLog.LogLevel.Debug; break; case LogEntryCategories.Error: logLevel = NLog.LogLevel.Error; break; case LogEntryCategories.Fatal: logLevel = NLog.LogLevel.Fatal; break; case LogEntryCategories.Info: logLevel = NLog.LogLevel.Info; break; case LogEntryCategories.Trace: logLevel = NLog.LogLevel.Trace; break; case LogEntryCategories.Warning: logLevel = NLog.LogLevel.Warn; break; default: logLevel = NLog.LogLevel.Error; break; } LogEventInfo newLogEntry = new LogEventInfo(logLevel, "", message); newLogEntry.Properties["category"] = category.ToString(); //custom field 'category' newLogEntry.Properties["codeLine"] = sourceLineNumber; //custom field 'codeLine' newLogEntry.Exception = exception; applicationLogger.Log(newLogEntry); if (category == LogEntryCategories.Error || category == LogEntryCategories.Fatal) //only store errors { lock (errorListLock) { if (LatestErrors == null) { LatestErrors = new List <LogEntry>(); } while (LatestErrors.Count > 1000) { LatestErrors.RemoveAt(0); } LatestErrors.Add(new ErrorLogEntry() { Category = category.ToString(), ExceptionText = exception?.ToString(), Message = message, Time = DateTime.Now, LogLevel = logLevel.ToString() }); } } //log event OnLogEvent?.Invoke(null, new ErrorLogEntry() { Category = category.ToString(), ExceptionText = exception.ToString(), Message = message, LogLevel = logLevel.ToString(), Time = DateTime.Now, CodeLine = sourceLineNumber.ToString() }); }