private static void ReadLineFromFile(LineParam lineParam)
 {
     Utility.PerformIOWithRetries(
         ctx =>
     {
         LineParam param = ctx;
         param.Line      = param.Reader.ReadLine();
     },
         lineParam);
 }
        internal void OnEtlFileReadStop(string fileName, bool isActiveEtl, string currentBookmark, string nextBookmark, bool fileReadAborted)
        {
            if (null == this.streamWriter)
            {
                // An error occurred during the creation of the buffered event
                // file. So just return immediately without doing anything.
                return;
            }

            if (false == fileReadAborted)
            {
                // Flush pending events
                this.FlushPendingEvents(isActiveEtl, currentBookmark, nextBookmark);
            }

            // We're done processing an ETL file. Before this ETL file is moved
            // to the archives, make sure all the events we've written so far are
            // flushed to the buffered event file.
            try
            {
                Utility.PerformIOWithRetries(
                    () =>
                {
                    try
                    {
                        this.streamWriter.Flush();
                    }
                    catch (System.Text.EncoderFallbackException ex)
                    {
                        // This can happen if the manifest file does not match the binary.
                        // Write an error message and move on.
                        this.TraceSource.WriteError(
                            this.LogSourceId,
                            "Exception occurred while flushing filtered ETW events to buffered event file. Exception information: {0}",
                            ex);
                    }
                });
            }
            catch (Exception e)
            {
                // Log an error and move on
                this.TraceSource.WriteExceptionAsError(
                    this.LogSourceId,
                    e,
                    "Failed to flush data to buffered event file.");
            }
        }
Beispiel #3
0
        internal static void Compress(string source, string archiveEntryName, out string tempArchivePath)
        {
            string archiveFullPath = Utility.GetTempFileName();

            Utility.PerformIOWithRetries(
                () =>
            {
                using (FileStream fs = new FileStream(archiveFullPath, FileMode.Create))
                {
                    // ZipArchive archive;
                    object archive = null;
                    try
                    {
                        try
                        {
                            // archive = new ZipArchive(fs, ZipArchiveMode.Create);
                            archive = ZipArchiveConstructor.Invoke(new[] { fs, ZipArchiveModeCreate });

                            // archive.CreateEntryFromFile(source, archiveEntryName, CompressionLevel.Optimal);
                            ZipFileExtCreateEntryFromFile.Invoke(
                                null,
                                new[] { archive, source, archiveEntryName, CompressionLevelOptimal });
                        }
                        catch (TargetInvocationException e)
                        {
                            throw e.InnerException;
                        }
                    }
                    finally
                    {
                        if (null != archive)
                        {
                            // archive.Dispose();
                            ZipArchiveDispose.Invoke(archive, null);
                        }
                    }
                }
            });

            tempArchivePath = archiveFullPath;
        }
Beispiel #4
0
        private bool LoadFromFile()
        {
            // Open the map file
            StreamReader reader            = null;
            bool         mapFileNotPresent = false;

            try
            {
                Utility.PerformIOWithRetries(
                    () =>
                {
                    try
                    {
                        FileStream fileStream = FabricFile.Open(this.fileFullPath, FileMode.Open, FileAccess.Read);
#if !DotNetCoreClrLinux
                        Helpers.SetIoPriorityHint(fileStream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
#endif
                        reader = new StreamReader(fileStream);
                    }
                    catch (FileNotFoundException)
                    {
                        mapFileNotPresent = true;
                    }
                    catch (DirectoryNotFoundException)
                    {
                        mapFileNotPresent = true;
                    }
                });
            }
            catch (Exception e)
            {
                this.traceSource.WriteExceptionAsError(
                    this.logSourceId,
                    e,
                    "Unable to open index map file {0}",
                    this.fileFullPath);
                return(false);
            }

            if (mapFileNotPresent)
            {
                return(true);
            }

            try
            {
                // Get the version line
                string versionLine = string.Empty;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        versionLine = reader.ReadLine();
                    });
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to read version line from index map file {0}",
                        this.fileFullPath);
                    return(false);
                }

                if (null == versionLine)
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "Index map file {0} does not contain a version line.",
                        this.fileFullPath);
                    return(false);
                }

                // Ensure that the version line is compatible
                string versionString = versionLine.Remove(0, VersionPrefix.Length);
                int    version;
                if (false == int.TryParse(
                        versionString,
                        out version))
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "Version {0} in index map file {1} cannot be parsed as an integer.",
                        versionString,
                        this.fileFullPath);
                    return(false);
                }

                if (version != this.fileFormatVersion)
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "Index map file {0} has incompatible file version '{1}'.",
                        this.fileFullPath,
                        version);
                    return(false);
                }

                // Read the map records from the file
                string mapRecord = null;
                for (;;)
                {
                    mapRecord = string.Empty;
                    try
                    {
                        Utility.PerformIOWithRetries(
                            () =>
                        {
                            mapRecord = reader.ReadLine();
                        });
                    }
                    catch (Exception e)
                    {
                        this.traceSource.WriteExceptionAsError(
                            this.logSourceId,
                            e,
                            "Unable to retrieve record from index map file {0}",
                            this.fileFullPath);
                        return(false);
                    }

                    if (null == mapRecord)
                    {
                        // Reached end of file
                        this.traceSource.WriteInfo(
                            this.logSourceId,
                            "Reached end of index map file {0}",
                            this.fileFullPath);
                        break;
                    }

                    this.ProcessMapRecord(mapRecord, this.fileFullPath);
                }
            }
            finally
            {
                reader.Dispose();
            }

            return(true);
        }
Beispiel #5
0
        private bool SaveToFile()
        {
            // Create a new temp file
            string tempFilePath = Utility.GetTempFileName();

            try
            {
                // Open the temp file
                StreamWriter writer = null;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FileStream fileStream = FabricFile.Open(tempFilePath, FileMode.Create, FileAccess.Write);
#if !DotNetCoreClrLinux
                        Helpers.SetIoPriorityHint(fileStream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
#endif
                        writer = new StreamWriter(fileStream);
                    });
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Failed to open temp file {0} for persisting index map.",
                        tempFilePath);
                    return(false);
                }

                try
                {
                    // Write the version information to the map file
                    string versionString = string.Concat(VersionPrefix, this.fileFormatVersion.ToString(CultureInfo.InvariantCulture));
                    try
                    {
                        Utility.PerformIOWithRetries(
                            () =>
                        {
                            writer.WriteLine(versionString);
                        });
                    }
                    catch (Exception e)
                    {
                        this.traceSource.WriteExceptionAsError(
                            this.logSourceId,
                            e,
                            "Failed to write version information to temp file {0} for persisting index map.",
                            tempFilePath);
                        return(false);
                    }

                    // Write the map records to the map file
                    foreach (TItem item in this.dictionary.Keys)
                    {
                        string mapRecord = string.Concat(
                            item.ToString(),
                            ", ",
                            this.dictionary[item].ToString(CultureInfo.InvariantCulture));

                        try
                        {
                            Utility.PerformIOWithRetries(
                                () =>
                            {
                                writer.WriteLine(mapRecord);
                            });
                        }
                        catch (Exception e)
                        {
                            this.traceSource.WriteExceptionAsError(
                                this.logSourceId,
                                e,
                                "Failed to write record {0} to temp file {1} for persisting index map.",
                                mapRecord,
                                tempFilePath);
                            return(false);
                        }
                    }
                }
                finally
                {
                    writer.Dispose();
                }

                // Copy the temp file as the new map file
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FabricFile.Copy(tempFilePath, this.fileFullPath, true);
                    });
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Failed to copy file {0} to {1} for persisting index map",
                        tempFilePath,
                        this.fileFullPath);
                    return(false);
                }

                this.traceSource.WriteInfo(
                    this.logSourceId,
                    "Index map file {0} created.",
                    this.fileFullPath);
            }
            finally
            {
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FabricFile.Delete(tempFilePath);
                    });
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Failed to delete temp file {0} which was created for persisting index map.",
                        tempFilePath);
                }
            }

            return(true);
        }
        private static bool LoadFromFile()
        {
            // Open the backup file
            StreamReader reader = null;
            bool         backupFileNotPresent = false;

            try
            {
                Utility.PerformIOWithRetries(
                    () =>
                {
                    try
                    {
                        FileStream fileStream = FabricFile.Open(backupFileFullPath, FileMode.Open, FileAccess.Read);
#if !DotNetCoreClrLinux
                        Helpers.SetIoPriorityHint(fileStream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
#endif
                        reader = new StreamReader(fileStream);
                    }
                    catch (FileNotFoundException)
                    {
                        backupFileNotPresent = true;
                    }
                    catch (DirectoryNotFoundException)
                    {
                        backupFileNotPresent = true;
                    }
                });
            }
            catch (Exception e)
            {
                Utility.TraceSource.WriteExceptionAsError(
                    LogSourceId,
                    e,
                    "Unable to open application activation table backup file {0}",
                    backupFileFullPath);
                return(false);
            }

            if (backupFileNotPresent)
            {
                return(true);
            }

            try
            {
                // Get the version line
                string versionLine = string.Empty;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        versionLine = reader.ReadLine();
                    });
                }
                catch (Exception e)
                {
                    Utility.TraceSource.WriteExceptionAsError(
                        LogSourceId,
                        e,
                        "Unable to read version line from application activation table backup file {0}",
                        backupFileFullPath);
                    return(false);
                }

                if (null == versionLine)
                {
                    Utility.TraceSource.WriteError(
                        LogSourceId,
                        "Application activation table backup file {0} does not contain a version line.",
                        backupFileFullPath);
                    return(false);
                }

                // Ensure that the version line is compatible
                if (false == versionLine.Equals(VersionString, StringComparison.Ordinal))
                {
                    Utility.TraceSource.WriteError(
                        LogSourceId,
                        "Application activation table backup file {0} has incompatible file version '{1}'.",
                        backupFileFullPath,
                        versionLine);
                    return(false);
                }

                // Read the application activation records from the file
                string activationRecord = null;
                for (;;)
                {
                    activationRecord = string.Empty;
                    try
                    {
                        Utility.PerformIOWithRetries(
                            () =>
                        {
                            activationRecord = reader.ReadLine();
                        });
                    }
                    catch (Exception e)
                    {
                        Utility.TraceSource.WriteExceptionAsError(
                            LogSourceId,
                            e,
                            "Unable to retrieve record from application activation table backup file {0}",
                            backupFileFullPath);
                        return(false);
                    }

                    if (null == activationRecord)
                    {
                        // Reached end of file
                        Utility.TraceSource.WriteInfo(
                            LogSourceId,
                            "Reached end of application activation table backup file {0}",
                            backupFileFullPath);
                        break;
                    }

                    ProcessActivationRecord(activationRecord, backupFileFullPath);
                }
            }
            finally
            {
                reader.Dispose();
            }

            return(true);
        }
        private static bool SaveToFile()
        {
            // Create a new temp file
            string tempFilePath = Utility.GetTempFileName();

            try
            {
                // Open the temp file
                StreamWriter writer = null;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FileStream fileStream = FabricFile.Open(tempFilePath, FileMode.Create, FileAccess.Write);
#if !DotNetCoreClrLinux
                        Helpers.SetIoPriorityHint(fileStream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
#endif
                        writer = new StreamWriter(fileStream);
                    });
                }
                catch (Exception e)
                {
                    Utility.TraceSource.WriteExceptionAsError(
                        LogSourceId,
                        e,
                        "Failed to open temp file {0} for backing up application activation table.",
                        tempFilePath);
                    return(false);
                }

                try
                {
                    // Write the version information to the backup file
                    try
                    {
                        Utility.PerformIOWithRetries(
                            () =>
                        {
                            writer.WriteLine(VersionString);
                        });
                    }
                    catch (Exception e)
                    {
                        Utility.TraceSource.WriteExceptionAsError(
                            LogSourceId,
                            e,
                            "Failed to write version information to temp file {0} for backing up application activation table.",
                            tempFilePath);
                        return(false);
                    }

                    // Write the activation records to the backup file
                    foreach (string appType in applicationEtwTracesStartTime.Keys)
                    {
                        foreach (string appInstanceId in applicationEtwTracesStartTime[appType].Keys)
                        {
                            DateTime activationTime   = applicationEtwTracesStartTime[appType][appInstanceId];
                            string   activationRecord = string.Join(
                                ",",
                                appInstanceId,
                                appType,
                                activationTime.ToBinary().ToString(),
                                activationTime.ToString());
                            try
                            {
                                Utility.PerformIOWithRetries(
                                    () =>
                                {
                                    writer.WriteLine(activationRecord);
                                });
                            }
                            catch (Exception e)
                            {
                                Utility.TraceSource.WriteExceptionAsError(
                                    LogSourceId,
                                    e,
                                    "Failed to write record {0} to temp file {1} for backing up application activation table.",
                                    activationRecord,
                                    tempFilePath);
                                return(false);
                            }
                        }
                    }
                }
                finally
                {
                    writer.Dispose();
                }

                // Copy the temp file as the new backup file
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FabricFile.Copy(tempFilePath, backupFileFullPath, true);
                    });
                }
                catch (Exception e)
                {
                    Utility.TraceSource.WriteExceptionAsError(
                        LogSourceId,
                        e,
                        "Failed to copy file {0} to {1} for backing up application activation table.",
                        tempFilePath,
                        backupFileFullPath);
                    return(false);
                }

                Utility.TraceSource.WriteInfo(
                    LogSourceId,
                    "Application activation table backup file {0} created.",
                    backupFileFullPath);
            }
            finally
            {
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FabricFile.Delete(tempFilePath);
                    });
                }
                catch (Exception e)
                {
                    Utility.TraceSource.WriteExceptionAsError(
                        LogSourceId,
                        e,
                        "Failed to delete temp file {0} which was created for backing up application activation table.",
                        tempFilePath);
                }
            }

            return(true);
        }
        private void ProcessEventsFromFile(string fileName)
        {
            this.TraceSource.WriteInfo(
                this.LogSourceId,
                "Processing ETW events from file {0}.",
                fileName);

            // Open the file
            ReadEventsFromFileParam readEventsParam = new ReadEventsFromFileParam();

            readEventsParam.StreamReader = null;
            readEventsParam.FileName     = fileName;
            try
            {
                Utility.PerformIOWithRetries(
                    this.OpenEtwEventCacheFile,
                    readEventsParam);
            }
            catch (Exception e)
            {
                this.TraceSource.WriteExceptionAsError(
                    this.LogSourceId,
                    e,
                    "Failed to open file {0} for read.",
                    fileName);
                return;
            }

            if (readEventsParam.FileNotFound)
            {
                Debug.Assert(null == readEventsParam.StreamReader, "StreamReader should remain unset if file is not found.");
                return;
            }

            // Read and process events from the file
            try
            {
                // Check the DCA version to make sure we can parse this file
                int version;
                if (false == this.CanParseFile(readEventsParam.StreamReader, fileName, out version))
                {
                    return;
                }

                // Upload the ETW events that we just retrieved
                this.TraceSource.WriteInfo(
                    this.LogSourceId,
                    "Starting delivery of ETW events from file {0} ....",
                    fileName);

                LineParam lineParam = new LineParam();
                lineParam.Reader = readEventsParam.StreamReader;
                for (;;)
                {
                    // Read an event from the file
                    try
                    {
                        ReadLineFromFile(lineParam);
                    }
                    catch (Exception e)
                    {
                        this.TraceSource.WriteExceptionAsError(
                            this.LogSourceId,
                            e,
                            "Failed to read event from file {0}.",
                            fileName);
                        break;
                    }

                    if (null == lineParam.Line)
                    {
                        // End of file reached
                        break;
                    }

                    DecodedEtwEvent etwEventInfo      = new DecodedEtwEvent();
                    string          nodeUniqueEventId = null;
                    if (false == this.ParseEventInfo(fileName, version, lineParam.Line, ref etwEventInfo, ref nodeUniqueEventId))
                    {
                        // Couldn't parse this event, so skip it and continue with the
                        // remaining events.
                        continue;
                    }

                    // Deliver the event to the consumer
                    this.eventSink.OnEtwEventAvailable(etwEventInfo, nodeUniqueEventId);
                    this.perfHelper.EventDeliveredToConsumer();

                    // If the consumer has asked for the event delivery period to
                    // be aborted, then do so immediately.
                    if (this.eventDeliveryPeriodAborted)
                    {
                        this.TraceSource.WriteInfo(
                            this.LogSourceId,
                            "The event delivery pass is being aborted. Therefore, no more events will be read from file {0}.",
                            fileName);
                        break;
                    }

                    // If we are in the process of stopping, then don't process
                    // any more events
                    if (this.Stopping)
                    {
                        this.TraceSource.WriteInfo(
                            this.LogSourceId,
                            "The consumer is being stopped. Therefore, no more events will be read from file {0}.",
                            fileName);
                        break;
                    }
                }

                this.TraceSource.WriteInfo(
                    this.LogSourceId,
                    "Finished delivery of ETW events from file {0}.",
                    fileName);
            }
            finally
            {
                readEventsParam.StreamReader.Dispose();
            }
        }
        private void WriteTraceEvent(DecodedEventWrapper eventWrapper, string nodesUniqueEventId)
        {
            if (null == this.streamWriter)
            {
                // An error occurred during the creation of the buffered event
                // file. So just return immediately without doing anything.
                return;
            }

            // NOTE: The order in which the information is written must match
            // the order of the EventLineParts enumeration defined in this class.
            string eventInfo = string.Format(
                CultureInfo.InvariantCulture,
                "{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}",
                eventWrapper.InternalEvent.EventRecord.EventHeader.ProviderId,
                eventWrapper.InternalEvent.EventRecord.EventHeader.EventDescriptor.Id,
                eventWrapper.InternalEvent.EventRecord.EventHeader.EventDescriptor.Version,
                eventWrapper.InternalEvent.EventRecord.EventHeader.EventDescriptor.Channel,
                eventWrapper.InternalEvent.EventRecord.EventHeader.EventDescriptor.Opcode,
                eventWrapper.InternalEvent.EventRecord.EventHeader.EventDescriptor.Task,
                eventWrapper.InternalEvent.EventRecord.EventHeader.EventDescriptor.Keyword,
                nodesUniqueEventId,
                eventWrapper.Timestamp.ToBinary(),
                eventWrapper.Timestamp,                    // We write the human-readable form for easier debugging
                eventWrapper.Level,
                eventWrapper.ThreadId,
                eventWrapper.ProcessId,
                eventWrapper.TaskName,
                eventWrapper.EventType,
                eventWrapper.EventText);

            eventInfo = eventInfo.Replace("\r\n", "\t").Replace("\n", "\t").Replace("\r", "\t");
            try
            {
                Utility.PerformIOWithRetries(
                    ctx =>
                {
                    string eventString = ctx;
                    try
                    {
                        this.streamWriter.WriteLine(eventString);
                    }
                    catch (System.Text.EncoderFallbackException ex)
                    {
                        // This can happen if the manifest file does not match the binary.
                        // Write an error message and move on.
                        this.TraceSource.WriteError(
                            this.LogSourceId,
                            "Exception occurred while writing filtered ETW event to buffered event file. Exception information: {0}",
                            ex);
                    }
                },
                    eventInfo);
            }
            catch (Exception e)
            {
                // Log an error and move on
                this.TraceSource.WriteExceptionAsError(
                    this.LogSourceId,
                    e,
                    "Failed to write ETW event to buffered event file.");
            }
        }
        public void OnEtwEventProcessingPeriodStart()
        {
            this.streamWriter = null;
            this.perfHelper.EtlReadPassBegin();

            // Build the full path to our buffered event file
            string tempCacheFileName = string.Format(
                CultureInfo.InvariantCulture,
                "{0}{1}.{2}",
                TempCacheFileNamePrefix,
                DateTime.Now.Ticks,
                TempCacheFileExtension);
            string tempCacheFileFullPath = Path.Combine(this.etwEventCache, tempCacheFileName);

            // Open the file
            StreamWriter writer = null;

            try
            {
                Utility.PerformIOWithRetries(
                    ctx =>
                {
                    string fileName       = ctx;
                    FileStream fileStream = FabricFile.Open(fileName, FileMode.Create, FileAccess.Write);
#if !DotNetCoreClr
                    Helpers.SetIoPriorityHint(fileStream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
#endif
                    writer = new StreamWriter(fileStream);
                },
                    tempCacheFileFullPath);
            }
            catch (Exception e)
            {
                // Log an error and move on. No events from this pass will be
                // written to the destination.
                this.TraceSource.WriteExceptionAsError(
                    this.LogSourceId,
                    e,
                    "Failed to create a new file in the buffered event directory. None of the events from this pass will be written to the event buffer.");
                return;
            }

            // Write the version number. This will help us read data from the file.
            try
            {
                Utility.PerformIOWithRetries(
                    () =>
                {
                    writer.WriteLine(EtlConsumerConstants.EtwEventCacheFormatVersionString);
                });
            }
            catch (Exception e)
            {
                // Log an error and move on. No events from this pass will be
                // written to the destination.
                this.TraceSource.WriteExceptionAsError(
                    this.LogSourceId,
                    e,
                    "Failed to write buffered event file format version number to file {0} in the buffered event file. None of the events from this pass will be written to the event buffer.",
                    tempCacheFileFullPath);
                return;
            }

            this.streamWriter = writer;
            this.TraceSource.WriteInfo(
                this.LogSourceId,
                "Filtered ETW events for consumer will be buffered in file {0}.",
                tempCacheFileFullPath);
        }
        public void OnEtwEventProcessingPeriodStop()
        {
            if (null == this.streamWriter)
            {
                // An error occurred during the creation of the buffered event
                // file. So just return immediately without doing anything.
                return;
            }

            // Close the buffered event file that we are currently working on.
            try
            {
                this.streamWriter.Dispose();
            }
            catch (System.Text.EncoderFallbackException ex)
            {
                // This can happen if the manifest file does not match the binary.
                // Write an error message and move on.
                this.TraceSource.WriteError(
                    this.LogSourceId,
                    "Exception occurred while closing buffered event file. Exception information: {0}",
                    ex);
            }

            // Make our buffered event files available for delivery to the consumer.
            // This includes:
            //  - the buffered event file that we wrote in this pass
            //  - any old buffered event files that we wrote in previous passes
            //    (and got interrupted before we could rename them for delivery to
            //    the consumer).
            string[] cacheFiles = FabricDirectory.GetFiles(
                this.etwEventCache,
                TempCacheFileNameSearchPattern);
            foreach (string cacheFile in cacheFiles)
            {
                try
                {
                    Utility.PerformIOWithRetries(
                        ctx =>
                    {
                        string fileName = ctx;
                        FabricFile.Move(
                            fileName,
                            Path.ChangeExtension(fileName, CacheFileNameExtension));
                    },
                        cacheFile);

                    this.TraceSource.WriteInfo(
                        this.LogSourceId,
                        "File containing filtered ETW events was renamed for delivery to consumer. Old name: {0}, new name: {1}.",
                        cacheFile,
                        Path.ChangeExtension(cacheFile, CacheFileNameExtension));
                }
                catch (Exception e)
                {
                    this.TraceSource.WriteExceptionAsError(
                        this.LogSourceId,
                        e,
                        "Buffered event file {0} could not be renamed for delivery to consumer.",
                        cacheFile);
                }
            }

            this.perfHelper.EtlReadPassEnd();
        }
        private void DeliverEventsToConsumer(object state)
        {
            this.perfHelper.EventDeliveryPassBegin();

            this.eventDeliveryPeriodAborted = false;

            // Perform any tasks necessary at the beginning of the event delivery pass
            this.eventSink.OnEtwEventDeliveryStart();

            // Get the files from the buffered event directory
            // We ignore files that are so old that they need to be deleted
            DateTime cutoffTime = DateTime.UtcNow.Add(-this.eventDeletionAge);

            DirectoryInfo dirInfo = new DirectoryInfo(this.etwEventCache);

            FileInfo[] eventFilesInfo = dirInfo.GetFiles(CacheFileNameSearchPattern)
                                        .Where(file => file.LastWriteTimeUtc.CompareTo(cutoffTime) > 0)
                                        .ToArray();

            // Sort the files such that the file with the most recent last-write
            // time comes first. We'll process files in that order so that in
            // case of huge backlogs the most recent (and hence likely to be
            // most interesting) traces are processed first.
            Array.Sort(eventFilesInfo, CompareFileLastWriteTimes);

            // Process each of the files
            int           filesProcessed    = 0;
            DateTime      processingEndTime = DateTime.Now.Add(this.eventDeliveryPassLength);
            List <string> filesToDelete     = new List <string>();

            foreach (FileInfo eventFileInfo in eventFilesInfo)
            {
                // Process events from the current file
                string eventFile = eventFileInfo.FullName;
                this.ProcessEventsFromFile(eventFile);
                filesProcessed++;

                // If the event delivery pass is being aborted, then don't process
                // any more files. Also, don't delete the current file because
                // its processing may have been interrupted. This file will be
                // processed again in the next pass.
                if (this.eventDeliveryPeriodAborted)
                {
                    this.TraceSource.WriteInfo(
                        this.LogSourceId,
                        "The event delivery pass is being aborted. Therefore, no more files in the buffered event directory will be processed.");
                    break;
                }

                // If we are in the process of stopping, then don't process any
                // more files. Also, don't delete the current file because its
                // processing may have been interrupted. This file will be
                // processed again when we are restarted.
                if (this.Stopping)
                {
                    this.TraceSource.WriteInfo(
                        this.LogSourceId,
                        "The consumer is being stopped. Therefore, no more files in the buffered event directory will be processed.");
                    break;
                }

                // Add the file to the list of files that we delete at the end
                // of the event delivery pass
                filesToDelete.Add(eventFile);

                if (0 > DateTime.Compare(processingEndTime, DateTime.Now))
                {
                    this.TraceSource.WriteInfo(
                        this.LogSourceId,
                        "Due to time limit on backlog processing, no more files in the buffered event directory will be processed in this pass.");
                    break;
                }
            }

            // Perform any tasks necessary at the end of the ETL processing pass
            this.eventSink.OnEtwEventDeliveryStop();

            // Delete the files that we successfully processed in this pass
            foreach (string fileToDelete in filesToDelete)
            {
                try
                {
                    Utility.PerformIOWithRetries(
                        ctx =>
                    {
                        string fileName = ctx;
                        FabricFile.Delete(fileName);
                    },
                        fileToDelete);
                }
                catch (Exception e)
                {
                    this.TraceSource.WriteExceptionAsError(
                        this.LogSourceId,
                        e,
                        "Failed to delete file {0}.",
                        fileToDelete);
                }
            }

            // Write performance-related information.
            this.perfHelper.RecordEventDeliveryBacklog(eventFilesInfo.Length - filesProcessed);
            this.perfHelper.EventDeliveryPassEnd();

            // Schedule the next pass
            this.eventDeliveryTimer.Start();
        }
Beispiel #13
0
        /// <summary>
        /// Updates the bookmark file with the last event read index.
        /// </summary>
        /// <param name="bookmarkFolder"></param>
        /// <param name="lastReadEventIndexPosition"></param>
        /// <param name="eventIndex"></param>
        /// <param name="bytesWritten"></param>
        /// <returns></returns>
        internal bool UpdateBookmarkFile(
            string bookmarkFolder,
            long lastReadEventIndexPosition,
            EventIndex eventIndex,
            out long bytesWritten)
        {
            bytesWritten = 0;
            FileStream   fs           = null;
            StreamWriter writer       = null;
            string       bookmarkFile = Path.Combine(bookmarkFolder, BookmarkFileName);

            if (false == FabricFile.Exists(bookmarkFile))
            {
                return(false);
            }

            try
            {
                // Open the bookmark file
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        fs     = new FileStream(bookmarkFile, FileMode.Open);
                        writer = new StreamWriter(fs);
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to open bookmark file {0} while processing events.",
                        bookmarkFile);
                    return(false);
                }

                // Move the stream position to the point where the event index needs to be written
                fs.Position = lastReadEventIndexPosition;

                long localBytesWritten = 0;

                // Write the timestamp and index of the last event read and close the file
                string lastEventReadString = string.Format("{0},{1},{2}", eventIndex.Timestamp.ToBinary(), eventIndex.Timestamp.ToString(), eventIndex.TimestampDifferentiator);
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        writer.WriteLine(lastEventReadString);
                        localBytesWritten = lastEventReadString.Length + 2;
                        writer.Dispose();
                        fs.Dispose();
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to write last event read {0} in bookmark file {1} while processing events.",
                        lastEventReadString,
                        bookmarkFile);
                    return(false);
                }

                // record bytes written
                bytesWritten = localBytesWritten;
            }
            finally
            {
                if (null != writer)
                {
                    writer.Dispose();
                }

                if (null != fs)
                {
                    fs.Dispose();
                }
            }

            return(true);
        }
Beispiel #14
0
        /// <summary>
        /// Retrieves the last event index processed.
        /// </summary>
        /// <param name="bookmarkFolder"></param>
        /// <param name="bytesRead"></param>
        /// <returns></returns>
        internal EventIndex ReadBookmarkFile(
            string bookmarkFolder,
            out long bytesRead)
        {
            bytesRead = 0;
            EventIndex lastEventIndex = new EventIndex();

            lastEventIndex.Set(DateTime.MinValue, -1);

            string bookmarkFile = Path.Combine(bookmarkFolder, BookmarkFileName);

            if (false == FabricFile.Exists(bookmarkFile))
            {
                // Bookmark file doesn't exist
                return(lastEventIndex);
            }

            StreamReader reader = null;

            try
            {
                // Open the file
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FileStream fileStream = FabricFile.Open(bookmarkFile, FileMode.Open, FileAccess.Read);
                        Helpers.SetIoPriorityHint(fileStream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
                        reader = new StreamReader(fileStream);
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to open bookmark file {0}.",
                        bookmarkFile);
                    return(lastEventIndex);
                }

                long localBytesRead = 0;

                // Get the version
                string versionString = string.Empty;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        versionString   = reader.ReadLine();
                        localBytesRead += versionString.Length + 2;
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to read version information from bookmark file {0}.",
                        bookmarkFile);
                    return(lastEventIndex);
                }

                // Check the version
                if (false == versionString.Equals(BookmarkFileFormatVersionString, StringComparison.Ordinal))
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "Unexpected version string {0} encountered in bookmark file {1}.",
                        versionString,
                        bookmarkFile);
                    return(lastEventIndex);
                }

                // Get information about the last event that we read
                string infoLine = string.Empty;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        infoLine        = reader.ReadLine();
                        localBytesRead += infoLine.Length + 2;
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to read information about last event read from bookmark file {0}.",
                        bookmarkFile);
                    return(lastEventIndex);
                }

                string[] infoLineParts = infoLine.Split(',');
                if (infoLineParts.Length != (int)LastEventReadInfoParts.Count)
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "The information in bookmark file {0} about the last event read is not in the expected format. {1}",
                        bookmarkFile,
                        infoLine);
                    return(lastEventIndex);
                }

                string lastEventTimestampString = infoLineParts[(int)LastEventReadInfoParts.LastEventTimestampLong].Trim();
                long   lastEventTimestampBinary;
                if (false == long.TryParse(lastEventTimestampString, out lastEventTimestampBinary))
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "Unable to retrieve timestamp of last event from bookmark file {0}.",
                        bookmarkFile);
                    return(lastEventIndex);
                }

                DateTime lastEventTimestamp = DateTime.FromBinary(lastEventTimestampBinary);

                string lastEventTimestampDifferentiatorString = infoLineParts[(int)LastEventReadInfoParts.LastEventIndex].Trim();
                int    lastEventTimestampDifferentiator;
                if (false == int.TryParse(lastEventTimestampDifferentiatorString, out lastEventTimestampDifferentiator))
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "Unable to retrieve timestamp differentiator of last event from bookmark file {0}.",
                        bookmarkFile);
                    return(lastEventIndex);
                }

                // record bytes read
                bytesRead = localBytesRead;

                lastEventIndex.Set(lastEventTimestamp, lastEventTimestampDifferentiator);
            }
            finally
            {
                if (null != reader)
                {
                    reader.Dispose();
                }
            }

            return(lastEventIndex);
        }
Beispiel #15
0
        /// <summary>
        /// Gets the file position where last event index is recorded.
        /// </summary>
        /// <param name="bookmarkFolder"></param>
        /// <param name="lastEventReadPosition"></param>
        /// <param name="bytesRead"></param>
        /// <returns></returns>
        internal bool GetLastEventReadPosition(
            string bookmarkFolder,
            out long lastEventReadPosition,
            out long bytesRead)
        {
            lastEventReadPosition = 0;
            bytesRead             = 0;

            string bookmarkFile = Path.Combine(bookmarkFolder, BookmarkFileName);

            if (false == FabricFile.Exists(bookmarkFile))
            {
                // Bookmark file doesn't exist
                return(false);
            }

            StreamReader reader = null;

            try
            {
                // Open the file
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FileStream fileStream = FabricFile.Open(bookmarkFile, FileMode.Open, FileAccess.Read);
                        Helpers.SetIoPriorityHint(fileStream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
                        reader = new StreamReader(fileStream);
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to open bookmark file {0}.",
                        bookmarkFile);
                    return(false);
                }

                long localBytesRead = 0;
                long streamPosition = 0;

                // Get the version
                string versionString = string.Empty;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        versionString   = reader.ReadLine();
                        localBytesRead += versionString.Length + 2;
                        streamPosition  = localBytesRead;
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to read version information from bookmark file {0}.",
                        bookmarkFile);
                    return(false);
                }

                // Check the version
                if (false == versionString.Equals(BookmarkFileFormatVersionString, StringComparison.Ordinal))
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "Unexpected version string {0} encountered in bookmark file {1}.",
                        versionString,
                        bookmarkFile);
                    return(false);
                }

                // Get information about the last event that we read
                string infoLine = string.Empty;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        infoLine        = reader.ReadLine();
                        localBytesRead += infoLine.Length + 2;
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to read information about last event read from bookmark file {0}.",
                        bookmarkFile);
                    return(false);
                }

                // record bytes read
                bytesRead = localBytesRead;

                lastEventReadPosition = streamPosition;
            }
            finally
            {
                if (null != reader)
                {
                    reader.Dispose();
                }
            }

            return(true);
        }
Beispiel #16
0
        /// <summary>
        /// Creates the bookmark file if it does not exist.
        /// </summary>
        /// <param name="bookmarkFolder"></param>
        /// <param name="bytesWritten"></param>
        /// <returns></returns>
        internal bool CreateBookmarkFile(
            string bookmarkFolder,
            out long bytesWritten)
        {
            FileStream   fs     = null;
            StreamWriter writer = null;

            bytesWritten = 0;
            string bookmarkFile = Path.Combine(bookmarkFolder, BookmarkFileName);

            if (true == FabricFile.Exists(bookmarkFile))
            {
                return(true);
            }

            try
            {
                // Create the bookmark file
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        fs     = new FileStream(bookmarkFile, FileMode.Create);
                        writer = new StreamWriter(fs);
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to create bookmark file {0} while processing events.",
                        bookmarkFile);
                    return(false);
                }

                long localBytesWritten = 0;

                // Write the version information
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        writer.WriteLine(BookmarkFileFormatVersionString);
                        localBytesWritten += BookmarkFileFormatVersionString.Length + 2;
                        writer.Flush();
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to write version information in bookmark file {0} while processing events.",
                        bookmarkFile);
                    return(false);
                }

                // Write the timestamp and index of the last event read and close the file
                int    lastEventIndex      = -1;
                string lastEventReadString = string.Format("{0},{1},{2}", DateTime.MinValue.ToBinary(), DateTime.MinValue.ToString(), lastEventIndex.ToString());
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        writer.WriteLine(lastEventReadString);
                        localBytesWritten += lastEventReadString.Length + 2;
                        writer.Dispose();
                        fs.Dispose();
                    },
                        this.methodExecutionInitialRetryIntervalMs,
                        this.methodExecutionMaxRetryCount,
                        this.methodExecutionMaxRetryIntervalMs);
                }
                catch (Exception e)
                {
                    this.traceSource.WriteExceptionAsError(
                        this.logSourceId,
                        e,
                        "Unable to write last event read {0} in bookmark file {1} while processing events.",
                        lastEventReadString,
                        bookmarkFile);
                    return(false);
                }

                // record bytes written
                bytesWritten = localBytesWritten;
            }
            finally
            {
                if (null != writer)
                {
                    writer.Dispose();
                }

                if (null != fs)
                {
                    fs.Dispose();
                }
            }

            return(true);
        }