/// <summary> /// Convert to DateTime /// </summary> /// <returns></returns> public DateTime ToDateTime() { DateTime dt = Log9KUtil.UnixTimeStampToDateTime(UnixTime); dt = dt.AddMilliseconds(Milliseconds); return(dt); }
/// <summary> /// Add new duplication entry (Tuple of log entry (original) and collection of log entries (duplications)) /// </summary> /// <param name="entry"></param> /// <param name="timeOfOriginal"></param> private void AddNewDuplicationEntry(Log9KEntry entry, Log9KTime timeOfOriginal) { if (!CheckForDuplicationMethods()) { return; } int duplicationKey = KeyForDuplicationDictionary(entry); Log9KUtil.InvokeInUiThread(() => { if (DuplicationsDictionary.ContainsKey(duplicationKey)) { return; } ObservableCollection <DuplicationLeaf> times = new ObservableCollection <DuplicationLeaf>(); if (timeOfOriginal == null) { times = new ObservableCollection <Tuple <Log9KTime, uint> > { new DuplicationLeaf(entry.Time, entry.ID) }; } DuplicationNode de = new DuplicationNode( entry, times ); DuplicationsDictionary.Add(duplicationKey, de); }); }
/// <summary> /// ToString() /// </summary> /// <returns></returns> public override string ToString() { DateTime dt = Log9KUtil.UnixTimeStampToDateTime(UnixTime); dt = dt.AddMilliseconds(Milliseconds); string dateTimeFormat = Log9KCore.Settings.DateTimeFormat; return(dt.ToString(dateTimeFormat)); }
/// <summary> /// Writes bytes of entry to temporary file (serialization) /// </summary> /// <param name="entry">entry to write</param> protected void WriteToTempFile(Log9KEntry entry) { if (entry.Type == LogEntryTypes.CUSTOM && entry.CustomType == Log9KCore.INNER_LOG_TAB) { return; } byte[] entryBytes = EntryToBytes(entry); Log9KUtil.InvokeInUiThread(() => { Log9KUtil.AppendByteArrayToFile(FilenameTempFile, entryBytes); }); }
/// <summary> /// Read log entry from temp file on given linenumber /// </summary> /// <param name="lineNumber"></param> /// <returns></returns> protected Log9KEntry ReadEntry(uint lineNumber) { byte[] buffer; if (!Log9KUtil.ReadFixedSizeByteArrayEntry(FilenameTempFile, Log9KEntry.ENTRY_SIZE, lineNumber, out buffer)) { Log9KCore.Instance.InnerLog("Ошибка: Log9KUtil.ReadFixedSizeByteArrayEntry вернул false"); return(null); } Log9KEntry entry = EntryFromBytes(buffer); return(entry); }
/// <summary> /// Insert log entry to given position, in UI thread /// </summary> /// <param name="i"></param> /// <param name="entry"></param> protected void CollectionInsert(int i, Log9KEntry entry) { if (Application.Current == null) { return; } if (_logEntryCollection == null) { return; } Log9KUtil.InvokeInUiThread(() => { _logEntryCollection.Insert(i, entry); }); }
/// <summary> /// <para>Initialization method, used by constructors, creates folder for tab, inits filenames</para> /// <para>Метод инициализации, используемый всеми конструкторами. /// Создаёт папку под вкладку, задаёт имена файлов.</para> /// </summary> /// <param name="type"></param> protected void Init(TabTypes type) { TabType = type; if (TabType != TabTypes.CUSTOM) { TabTypeString = type.ToString(); } else { TabTypeString = CustomTabType; } if (IsAllTab()) { _dirname = Log9KCore.Settings.Folder + "/" + Log9KUtil.GetDayMonthYearString() + "/"; } else if (IsInnerLogTab()) { _dirname = Log9KCore.Settings.Folder + "/" + Log9KUtil.GetDayMonthYearString() + "/" + "." + Log9KCore.INNER_LOG_TAB; } else { _dirname = Log9KCore.Settings.Folder + "/" + Log9KUtil.GetDayMonthYearString() + "/" + TabTypeString; } if (IsAllTab()) { Log9KUtil.CreateDirIfNotExists(_dirname); _directoryNotCreated = false; } FilenameLogFile = _dirname + "/" + Log9KUtil.GetDayMonthYearHourMinuteSecondString() + Log9KCore.LOG_EXTENSION; try { // ReSharper disable once ReturnValueOfPureMethodIsNotUsed Path.GetFullPath(FilenameLogFile); } catch (Exception e) { Log9KCore.InnerLog("Ошибка: что-то не так с именем файла — " + e.Message, true); } FilenameTempFile = FilenameLogFile + Log9KCore.TEMP_LOG_EXTENSION; DuplicationsDictionary = new Dictionary <int, DuplicationNode>(); InitCollection(); InitTabHeader(); }
/// <summary> /// Make the tab with given type active /// </summary> public void SetActiveTab(string tabType) { Log9KTab tab = GetTab(tabType); if (tab != null) { if (!Log9KTabsCollection.Contains(tab)) { return; } Log9KUtil.BeginInvokeInUiThread(() => { CurrentTab = tab; }); } }
/// <summary> /// Add duplicate to existing entry, for adding new duplication entry use AddNewDuplicationEntry /// </summary> /// <param name="entry"></param> private void AddToDuplicationEntry(Log9KEntry entry) { if (!CheckForDuplicationMethods()) { return; } int duplicationKey = KeyForDuplicationDictionary(entry); Log9KUtil.InvokeInUiThread(() => { DuplicationNode duplicationEntry = DuplicationsDictionary[duplicationKey]; duplicationEntry.Item2.Add(new DuplicationLeaf(entry.Time, entry.ID)); if (duplicationEntry.Item2.Count == 2) { DuplicationsCollection.Add(duplicationEntry); } }); }
/// <summary> /// Append log entry ToString to current tab's log file /// </summary> /// <param name="entry"></param> private void AppendEntryToFile(Log9KEntry entry) { if (_directoryNotCreated) { Log9KUtil.CreateDirIfNotExists(_dirname); _directoryNotCreated = false; } if (Application.Current == null) { return; } Application.Current.Dispatcher.BeginInvoke( new Action(() => { Log9KUtil.AppendStringToFile(FilenameLogFile, entry.ToString()); }), DispatcherPriority.Background ); }
/// <summary> /// Load most recent logs from temporary file /// </summary> public override void LoadLastLogs() { LogEntryCollection.StartRemovingFromTop(); LogEntryCollection.Clear(); uint entriesNumber; bool success = Log9KUtil.GetEntriesNumberInFile( FilenameTempFile, Log9KEntry.ENTRY_SIZE, out entriesNumber ); if (!success) { Log9KCore.Instance.InnerLog("Ошибка: метод Log9KUtil.GetEntriesNumberInFile вернул false"); return; } if (Application.Current == null) { return; } Application.Current.Dispatcher.BeginInvoke( new Action(() => { bool notEnd = true; uint z = 0; for (uint i = entriesNumber; notEnd; i--) { Log9KEntry e = ReadEntry(i); if (e != null) { LogEntryCollection.Insert(0, e); } if (i == 0 || z >= LogEntryCollection.MaxCollectionSize) { notEnd = false; } z++; } }), DispatcherPriority.Background ); }
/// <summary> /// Remove at given index of log entry collection in UI thread /// </summary> /// <param name="i"></param> /// <returns></returns> private bool CollectionRemoveAt(int i) { if (Application.Current == null) { return(false); } if (_logEntryCollection == null) { return(false); } if ((i < 0) || (i >= _logEntryCollection.Count)) { return(false); } Log9KUtil.InvokeInUiThread(() => { if ((i < 0) || (i >= _logEntryCollection.Count)) { return; } _logEntryCollection.RemoveAt(i); }); return(true); }
/// <summary> /// Deserialization /// </summary> /// <param name="entry"></param> /// <returns></returns> public static Log9KEntry FromByteArray(byte[] entry) { int i = 0; Buffer.BlockCopy(entry, i, _idBytes, 0, SIZE_ID); i += SIZE_ID; Buffer.BlockCopy(entry, i, _typeBytes, 0, SIZE_TYPE); i += SIZE_TYPE; LogEntryTypes type = (LogEntryTypes)_typeBytes[0]; Buffer.BlockCopy(entry, i, _levelBytes, 0, SIZE_LEVEL); i += SIZE_LEVEL; Buffer.BlockCopy(entry, i, _isDuplicateBytes, 0, SIZE_IS_DUPLICATE); i += SIZE_IS_DUPLICATE; Buffer.BlockCopy(entry, i, _unixTimeBytes, 0, SIZE_UNIX_TIME); i += SIZE_UNIX_TIME; Buffer.BlockCopy(entry, i, _millisecondsBytes, 0, SIZE_MILLISECONDS); i += SIZE_MILLISECONDS; if (type == LogEntryTypes.CUSTOM) { Buffer.BlockCopy(entry, i, _customTypeBytes, 0, SIZE_CUSTOM_TYPE); } i += SIZE_CUSTOM_TYPE; Buffer.BlockCopy(entry, i, _messageBytes, 0, SIZE_MESSAGE); uint id = BitConverter.ToUInt32(_idBytes, 0); Levels level = (Levels)_levelBytes[0]; bool isDuplicate = BitConverter.ToBoolean(_isDuplicateBytes, 0); uint unixTime = BitConverter.ToUInt32(_unixTimeBytes, 0); int milliseconds = BitConverter.ToInt32(_millisecondsBytes, 0); string message = Log9KUtil.GetString(_messageBytes); message = Log9KUtil.SplitStringWithNullEnding(message); string customType = Log9KUtil.GetString(_customTypeBytes); customType = Log9KUtil.SplitStringWithNullEnding(customType); Log9KEntry e = new Log9KEntry(type, message, new Log9KTime(unixTime, milliseconds)) { ID = id, CustomType = customType, IsDuplicate = isDuplicate, Level = level }; if (type == LogEntryTypes.CUSTOM) { e.TypeString = customType; } return(e); }
/// <summary> /// Serialization /// </summary> /// <returns></returns> public byte[] ToByteArray() { byte[] idBytes = BitConverter.GetBytes(ID); byte[] typeBytes = new byte[1]; typeBytes[0] = (byte)Type; byte[] levelBytes = new byte[1]; levelBytes[0] = (byte)Level; byte[] isDuplicateBytes = new byte[1]; isDuplicateBytes[0] = IsDuplicate ? (byte)1 : (byte)0; byte[] unixTimeBytes = BitConverter.GetBytes(Time.UnixTime); byte[] millisecondsBytes = BitConverter.GetBytes(Time.Milliseconds); byte[] customTypeBytes = new byte[SIZE_CUSTOM_TYPE]; if (Type == LogEntryTypes.CUSTOM) { if (CustomType.Length > LENGTH_CUSTOM_TYPE) { Log9KCore.Instance.InnerLog("Ошибка: длина имени пользовательского типа больше чем " + LENGTH_CUSTOM_TYPE); return(null); } byte[] customType = Log9KUtil.GetBytes(CustomType); Buffer.BlockCopy(customType, 0, customTypeBytes, 0, customType.Length); } byte[] messageBytes = new byte[SIZE_MESSAGE]; string message = Message; if (Message.Length > LENGTH_MESSAGE) { message = Log9KUtil.TrimString(Message, LENGTH_MESSAGE); } byte[] messageBytesTmp = Log9KUtil.GetBytes(message); Buffer.BlockCopy(messageBytesTmp, 0, messageBytes, 0, messageBytesTmp.Length); int lengthSummary = ( idBytes.Length + typeBytes.Length + levelBytes.Length + isDuplicateBytes.Length + unixTimeBytes.Length + millisecondsBytes.Length + customTypeBytes.Length + messageBytes.Length ); if (lengthSummary != ENTRY_SIZE) { return(null); } byte[] entry = new byte[ENTRY_SIZE]; Log9KUtil.SumByteArrays( ref entry, idBytes, typeBytes, levelBytes, isDuplicateBytes, unixTimeBytes, millisecondsBytes, customTypeBytes, messageBytes ); return(entry); }
/// <summary> /// Load one newer log entry from temp file /// </summary> /// <returns></returns> public override bool LoadNewerLogEntry() { if (IsAddingNewestEntries) { return(false); } Log9KEntry entry = null; bool success = false; uint tries = 0; while (!success) { if (tries > 100) { break; } byte[] entryBytes; if (!Log9KUtil.ReadFixedSizeByteArrayEntry(FilenameTempFile, Log9KEntry.ENTRY_SIZE, LineNumberBottomTempFile, out entryBytes)) { return(false); } entry = EntryFromBytes(entryBytes); uint lastLogEntryInCollectionID = LogEntryCollection[LogEntryCollection.Count - 1].ID; uint entryIDshoulBe = lastLogEntryInCollectionID + 1; if (entry.ID != entryIDshoulBe) { if (entry.ID < entryIDshoulBe) { LineNumberBottomTempFile++; } else if (entry.ID > entryIDshoulBe) { LineNumberBottomTempFile--; } } else { success = true; } tries++; } if (tries > 100) { uint lineNumber = LineNumberBottomTempFile; for (int i = 0; i < 200; i++) { lineNumber--; if (ReadNewerLogEntryAndCheckIt(out entry, lineNumber)) { LineNumberBottomTempFile = lineNumber; break; } } for (int i = 0; i < 200; i++) { lineNumber++; if (ReadNewerLogEntryAndCheckIt(out entry, lineNumber)) { LineNumberBottomTempFile = lineNumber; break; } } } if (entry != null) { CollectionAdd(entry); } return(true); }