private void ApplySessionSelection()
 {
     foreach (ListViewItem item in sessionListView.Items)
     {
         Reader.Session ses = (Reader.Session)item.Tag;
         ses.Visible = item.Checked;
     }
 }
Exemplo n.º 2
0
        public Record(DataFlags dataflags, ulong msgNum, DateTime time, ReaderThreadInfo threadInfo, Reader.Session session, string msg)
        {
            MsgNum     = msgNum;
            Time       = time;
            Thread     = threadInfo.Thread;
            ThreadName = threadInfo.ThreadName;
            Level      = threadInfo.Level;
            Logger     = threadInfo.Logger;
            StackDepth = threadInfo.Depth;
            MethodName = threadInfo.MethodName;
            Caller     = threadInfo.StackTop;
            Session    = session;

            if ((dataflags & DataFlags.MethodEntry) != DataFlags.None)
            {
                // This is a method entry record.  It always contains exactly one line of text.
                IsEntry = true;
                Lines   = new string[] { string.Format("{{{0}: entered", MethodName.Name) };
            }
            else if ((dataflags & DataFlags.MethodExit) != DataFlags.None)
            {
                // Method exit records always contain exactly one line of text.
                IsExit = true;
                Lines  = new string[] { string.Format("}}{0}: exiting", MethodName.Name) };
            }
            else
            {
                // The message text for this record may contain newlines.  Split the
                // message into one or more lines.
                Lines = msg.Split(_splitArg);

                if (Lines.Length > 1)
                {
                    // It's common for a carriage return to exist at the
                    // end of each line.  Remove them.
                    for (int i = 0; i < Lines.Length; ++i)
                    {
                        Lines[i] = Lines[i].TrimEnd('\r');
                    }

                    // It's common for the last line to be empty.  If so, remove it.
                    if (Lines.Last().Trim() == string.Empty)
                    {
                        Lines = Lines.Take(Lines.Length - 1).ToArray();
                    }
                }

                IsCollapsed = Lines.Length > 1 && !Settings.Default.ExpandNewlines;
            }

            // Each line also has a bool to indicate if it is bookmarked
            // and a row index it may map to.
            IsBookmarked = new bool[Lines.Length];
            RowIndices   = new int[Lines.Length];
        }
Exemplo n.º 3
0
        // This constructs a missing MethodEntry Record from the given ReaderStackEntry.
        // This is for MethodEntry records lost due to wrapping.
        public Record(ReaderThreadInfo threadInfo, ExplicitStackEntry methodEntry, Reader.Session session)
        {
            IsEntry = true;
            //IsExit = false;
            MsgNum     = 0;                 // TBD
            Time       = DateTime.MinValue; // TBD
            Index      = 0;                 // TBD
            Thread     = threadInfo.Thread;
            ThreadName = threadInfo.ThreadName;
            Level      = methodEntry.Level;
            Logger     = methodEntry.Logger;
            StackDepth = methodEntry.Depth;
            MethodName = methodEntry.Method;
            Lines      = new string[] { string.Format("{{{0}: entered (replaces record lost due to wrapping)", MethodName.Name) };
            Session    = session;

            // Each record also has a bool to indicate if it is bookmarked
            // and a row index it may map to.
            IsBookmarked = new bool[1];
            RowIndices   = new int[1];
        }
Exemplo n.º 4
0
        private void sessionCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            Reader.Session session        = (Reader.Session)sessionCombo.SelectedItem;
            long           sessionSize    = 0;
            double         sessionPercent = 0;

            if (session == SessionObjects.AllSessionObjects.Last())
            {
                sessionSize = _reader.Size - session.SessionStartPos;
            }
            else
            {
                Reader.Session nextSession = SessionObjects.AllSessionObjects[session.Index + 1];
                sessionSize = nextSession.SessionStartPos - session.SessionStartPos;
            }

            sessionPercent = (double)sessionSize / (double)_reader.Size;
            string sizeMsg = string.Format("{0:N0} ({1:P1} of file)", sessionSize, sessionPercent);

            sessionListView.Items.Clear();

            sessionListView.Items.Add(new ListViewItem(new string[] { "Creation time (UTC)", session.CreationTimeUtc.ToString() + " UTC" }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Creation time (logger's TZ)", session.CreationTimeLoggersTZ.ToString() + " " + session.LoggersTimeZone }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Creation time (local TZ)", ToLocalTZ(session.CreationTimeUtc) }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Last timestamp", ToLocalTZ(session.LastRecordTimeUtc) }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Elapsed time", (session.LastRecordTimeUtc - session.CreationTimeUtc).ToString() }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Circular logging started", session.InCircularPart.ToString() }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Last record number", session.LastRecordNum.ToString("N0") }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Record count", session.RecordsRead.ToString("N0") }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Records lost by wrapping", (session.LastRecordNum - session.RecordsRead).ToString("N0") }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Max session size (KB)", session.MaxKb.ToString("N0") }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Session size (bytes)", sizeMsg }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "Loggers assembly version", session.LoggersAssemblyVersion }));
            sessionListView.Items.Add(new ListViewItem(new string[] { "GUID", session.FileGuid.ToString() }));

            sessionNameCol.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            sessionValueCol.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
        }
        // This generates replacements for missing entry/exit records that were lost when
        // the log wrapped, but whose counterparts were not lost.
        // Called when we read the first line for this thread in the circular part of the log.
        // The thread's true call stack (logged with each thread's first record in each block)
        // was just read from the log and is passed via the actualStack parameter.
        internal void MakeMissingRecords(ExplicitStackEntry[] actualStack, List <Record> generatedRecs, Reader.Session session)
        {
            // We only do this once per thread, for the first record in the circular log for each
            // thread.  If MissingEntryRecords is not null, we already did it.
            if (!_missingRecsGenerated)
            {
                _missingRecsGenerated = true;
                var MissingEntryRecords = new List <Record>();

                // StackTop is the "top" entry in the stack determined by
                // pushing MethodEntry records and then popping
                // them off when MethodExit records are found in the log.
                // That stack becomes inaccurate
                // due to records being lost when the log wraps.
                // However, the true stack for this thread was explicitly
                // recorded in the circular part of the log and has now been
                // passed to this method as actualStack.
                // By comparing the items in the two stacks, we can generate
                // the missing MethodEntry records (for items that are in
                // actualStack but not in the StackTop stack) and the missing
                // MethodExit records (for items that are in the StackTop stack
                // but not the actualStack).  We also "fix" the StackTop stack.

                // this.Depth was set to actualStack.Length before this method was called.
                // If this.Depth is 0, actualStack is null.
                // The top stack entry comes first in actualStack.
                int actualStackIndex = 0;

                // The key property of each stack entry is the line number where
                // each method call starts in the log.  For example, suppose the StackTop
                // stack and the actualStack contain entries with the
                // following line numbers.
                //
                // StackTop:    400 300 200 100
                // actualStack: 600 500 100
                //
                // In the example, the StackTop calls at 400, 300, and 200 must have exited
                // in the lost part of the log (because they don't appear in actualStack),
                // so we generate MethodExit records to replace those that were lost.
                // We also pop the entries for 400, 300, and 200 off the StackTop stack.
                //
                // The calls at 600 and 500 occurred in the lost part of the log and have
                // not exited yet, so we generate MethodEntry records to replace those lost
                // records.  We also push the generated MethodEntry records onto the
                // StackTop stack.
                //
                // The method call at line 100 occurred before the lost part of the log and
                // still has not exited (because it appears in both stacks).
                //
                // All the generated MethodExit records will be inserted before all the
                // generated MethodEntry records, and all pops must be done before all pushes.

                // We start at the top of each stack and loop until all entries are examined or
                // we find the point where both stacks match.
                while (StackTop != null || actualStackIndex < Depth)
                {
                    // At least one of the stacks is not exhausted.
                    if (StackTop == null)
                    {
                        // Only the actualStack has entries remaining, all of which represent
                        // methods whose method entry records were lost.
                        MissingEntryRecords.Add(new Record(this, actualStack[actualStackIndex], session));
                        ++actualStackIndex;
                    }
                    else if (actualStackIndex == Depth)
                    {
                        // Only the StackTop stack has entries remaining, all of which represent
                        // methods whose exits were lost.
                        generatedRecs.Add(new Record(StackTop));
                        Pop();
                    }
                    else if (StackTop.MsgNum > actualStack[actualStackIndex].EntryLineNum)
                    {
                        generatedRecs.Add(new Record(StackTop));
                        Pop();
                    }
                    else if (StackTop.MsgNum < actualStack[actualStackIndex].EntryLineNum)
                    {
                        MissingEntryRecords.Add(new Record(this, actualStack[actualStackIndex], session));
                        ++actualStackIndex;
                    }
                    else
                    {
                        // Once they are equal, all others will be equal.
                        break;
                    }
                }

                // Now do the Pushes for the generated entry records.
                MissingEntryRecords.Reverse();
                foreach (Record entryRec in MissingEntryRecords)
                {
                    entryRec.Caller = StackTop;
                    Push(entryRec);
                }

                generatedRecs.AddRange(MissingEntryRecords);
            }
        }