Ejemplo n.º 1
0
        /// <inheritdoc/>
        public override void WriteLine(string message)
        {
            msgSb.Append(message);
            var final = msgSb.ToString();

            msgSb.Length = 0;
            if (!FL.IsShutdown)
            {
                FL.Trace(sourceName + ": " + final);
            }
        }
        /// <summary>
        /// Creates a new log file reader and adds it to the priority's log file enumerator.
        /// </summary>
        /// <param name="prio">The priority of files to write.</param>
        /// <param name="fileName">The name of the log file.</param>
        /// <param name="fromFsw">Indicates whether the reader was created from a FileSystemWatcher event.</param>
        private void AddNewReader(FieldLogPriority prio, string fileName, bool fromFsw)
        {
            // Must be within a lock(readerLock)!
            FL.Trace("AddNewReader, prio=" + prio + ", fileName=" + Path.GetFileName(fileName) + ", fromFsw=" + fromFsw);

            // Reject the new file if it's already in the queue (delayed FSW event after active scan)
            if (readers.ContainsKey(prio) &&
                readers[prio] != null &&
                readers[prio].ContainsFile(fileName))
            {
                // This file is already current or queued
                FL.Checkpoint("This file is already current or queued");
                return;
            }

            var reader = new FieldLogFileReader(fileName, true);
            ManualResetEvent h;

            if (!prioReadSignals.TryGetValue(prio, out h))
            {
                h = new ManualResetEvent(false);
                prioReadSignals[prio] = h;
            }
            reader.ReadWaitHandle = h;

            if (!readers.ContainsKey(prio) || readers[prio] == null)
            {
                // This is the first file of this priority
                readers[prio]        = new FieldLogFileEnumerator(reader);
                readers[prio].Error += FieldLogFileEnumerator_Error;
                readTasks[(int)prio] = Task <bool> .Factory.StartNew(readers[prio].MoveNext);

                // Signal the blocking ReadLogItem method that there's a new reader now
                newFilePrioEvent.Set();
            }
            else
            {
                // Chain the new reader after the last reader in the queue
                readers[prio].Append(reader, fromFsw);

                // TODO,DEBUG: What for?
                //newFilePrioEvent.Set();
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Advances the enumerator to the next log item of the currently read log file. If there
        /// are no more items in this file and there is a NextReader set, the first log item of the
        /// next file reader is selected. If there are no more items in this file and WaitMode is
        /// set, the method will block until another log item is appended to the current file or
        /// the wait operation is cancelled by a close event.
        /// </summary>
        /// <returns>true if the enumerator was successfully advanced to the next log item;
        /// false if the enumerator has passed the end of the collection.</returns>
        public bool MoveNext()
        {
            FieldLogFileReader nextReader = null;

            do
            {
                if (nextReader != null)
                {
                    FL.Trace(reader.ItemCount + " items read from " + Path.GetFileName(reader.FileName));
                    reader = nextReader;
                    FL.Trace("Switching to next reader " + Path.GetFileName(reader.FileName));
                }

                try
                {
                    item = reader.ReadLogItem();
                }
                catch (Exception ex)
                {
                    FL.Error(ex, "Reading item from log file");
                    OnError(ex);
                    // Skip the rest of the current file and continue with the next one if
                    // available. If this is the last file and WaitMode is set, this priority will
                    // not be monitored anymore.
                    item = null;
                }

                if (item == null && reader.IsClosing)
                {
                    // Close event must have been set
                    Dispose();
                    return(false);
                }
                nextReader = reader.NextReader;
            }while (item == null && nextReader != null);
            return(item != null);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Appends a new FieldLogFileReader at the end of this enumerator.
        /// </summary>
        /// <param name="newReader">The new reader to append.</param>
        /// <param name="fromFsw">Indicates whether the reader was created from a FileSystemWatcher event.</param>
        public void Append(FieldLogFileReader newReader, bool fromFsw)
        {
            FieldLogFileReader currentLastReader = LastReader;

            currentLastReader.NextReader = newReader;
            // Unset wait mode for this reader, now that we know where to continue after this file
            if (fromFsw)
            {
                // The file is newly created. Take some time to actually start reading the previous
                // file before switching to this one. Once the first item has been read from the
                // file, more items will likely exist in the file, and the file is read until the
                // end. Then it will still sit there waiting for more items until the rest of this
                // delay has elapsed (which is not a big problem, if we get any items from that
                // file at all).
#if NET20
                new Thread(() =>
                {
                    Thread.Sleep(1000);
                    currentLastReader.WaitMode = false;
                }).Start();
#else
                Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(1000);
                    currentLastReader.WaitMode = false;
                });
#endif
            }
            else
            {
                currentLastReader.WaitMode = false;
            }
            FL.Trace(
                "Appending next reader",
                "this=" + Path.GetFileName(currentLastReader.FileName) + "\nNext=" + Path.GetFileName(newReader.FileName) +
                "\nItems read from this=" + currentLastReader.ItemCount);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Handles a custom time measurement timer for saving the time data.
        /// </summary>
        /// <param name="state">Unused.</param>
        private void OnCustomTimer(object state)
        {
            if (key == FL.EnsureJitTimerKey)
            {
                return;
            }

            long ticks, ticksPc, ticksTt, localCounter;

            lock (syncLock)
            {
                // Do nothing if the stopwatch was just started again or current data has already
                // been written
                if (stopwatch.IsRunning || !writePending)
                {
                    return;
                }
                // Clear the flag while we're in the lock region
                writePending = false;

                // Fetch the data in the lock region
                localCounter = counter;
                // Subtract 4 ticks per measurement, determined by tests
                // TODO: 0-tick intervals have been observed many times. Is the correction needed at all?
                long correction = localCounter * 0;
                ticks = stopwatch.Elapsed.Ticks - correction;
                if (ticks < 0)
                {
                    ticks = 0;
                }
                if (localCounter > 0)
                {
                    ticksPc = ticks / localCounter;
                }
                else
                {
                    ticksPc = 0;
                }

                long counterTt = localCounter - prevCounter;
                if (counterTt > 0)
                {
                    ticksTt = (ticks - prevTicks) / counterTt;
                }
                else
                {
                    ticksTt = 0;
                }

                prevTicks   = ticks;
                prevCounter = localCounter;
            }

            // Total time
            // (Add 5 ticks for simple microseconds rounding)
            long roundTicks = ticks + 5;
            int  seconds    = (int)(roundTicks / 10000000);
            int  ms         = (int)((roundTicks % 10000000) / 10000);
            int  us         = (int)((roundTicks % 10000) / 10);

            // Per call, this time (since last item)
            long roundTicksTt = ticksTt + 5;
            int  secondsTt    = (int)(roundTicksTt / 10000000);
            int  msTt         = (int)((roundTicksTt % 10000000) / 10000);
            int  usTt         = (int)((roundTicksTt % 10000) / 10);

            // Per call time
            long roundTicksPc = ticksPc + 5;
            int  secondsPc    = (int)(roundTicksPc / 10000000);
            int  msPc         = (int)((roundTicksPc % 10000000) / 10000);
            int  usPc         = (int)((roundTicksPc % 10000) / 10);

            string text    = "Custom timer " + key + " at " + localCounter;
            string details =
                localCounter + " calls\n" +
                secondsPc.ToString() + "." +
                msPc.ToString("000") + "\u2009" +
                usPc.ToString("000") + " seconds per call (" + ticksPc + " ticks)\n" +
                secondsTt.ToString() + "." +
                msTt.ToString("000") + "\u2009" +
                usTt.ToString("000") + " seconds per call since last item (" + ticksTt + " ticks)\n" +
                seconds.ToString() + "." +
                ms.ToString("000") + "\u2009" +
                us.ToString("000") + " seconds total (" + ticks + " ticks)";

            FL.Trace(text, details);
        }