public static PerfCounterFolderProcessor Create( FabricEvents.ExtensionsEvents traceSource, string logSourceId, ConfigReader configReader, string logDirectory, string outputFolderPath, out bool isEnabled, out List <string> additionalFoldersToTrim) { additionalFoldersToTrim = null; isEnabled = false; // Create a new instance of the folder processor PerfCounterFolderProcessor folderProcessor = new PerfCounterFolderProcessor(); // PerfCounterFolderProcessor is a singleton, so make sure there are no other instances. object original = Interlocked.CompareExchange(ref folderProcessorSingleton, folderProcessor, null); if (null != original) { traceSource.WriteError( logSourceId, "Cannot have more than one producer of type {0}, whose {1} value is {2}.", StandardPluginTypes.FolderProducer, FolderProducerValidator.FolderTypeParamName, FolderProducerValidator.ServiceFabricPerformanceCounters); return(null); } // Initialize the folder processor if (false == folderProcessor.Initialize(traceSource, logSourceId, configReader, logDirectory, outputFolderPath)) { return(null); } isEnabled = folderProcessor.perfCounterCollectionEnabled; if (isEnabled) { // In addition to the output folder, which is already trimmed by default, we also need // the perf counter binary folder and the perf counter binary archive folder to be trimmed. additionalFoldersToTrim = new List <string> { folderProcessor.perfCounterBinaryFolder }; if (false == folderProcessor.archiveFolderIsUnderBinaryFolder) { additionalFoldersToTrim.Add(folderProcessor.perfCounterBinaryArchiveFolder); } } return(folderProcessor); }
public FolderProducer(DiskSpaceManager diskSpaceManager, ProducerInitializationParameters initializationParameters) { this.diskSpaceManager = diskSpaceManager; // Initialization this.initParam = initializationParameters; this.logSourceId = string.Concat(this.initParam.ApplicationInstanceId, "_", this.initParam.SectionName); this.traceSource = new FabricEvents.ExtensionsEvents(FabricEvents.Tasks.FabricDCA); this.configReader = new ConfigReader(this.initParam.ApplicationInstanceId); this.additionalAppConfigSections = new List <string>(); this.serviceConfigSections = new List <string>(); // Read instance-specific settings from settings.xml this.GetSettings(); if (false == this.folderProducerSettings.Enabled) { // Producer is not enabled, so return immediately return; } if (this.configReader.IsReadingFromApplicationManifest && FolderProducerType.WindowsFabricCrashDumps == this.folderProducerSettings.Type) { this.serviceConfigSections.Add(ServiceConfig.ExeHostElement); } var additionalFoldersToTrim = new List <string>(); #if !DotNetCoreClr if (FolderProducerType.WindowsFabricPerformanceCounters == this.folderProducerSettings.Type) { // We will need information from the <PerformanceCounterLocalStore> section of the // service manifest. this.additionalAppConfigSections.Add(PerformanceCounterCommon.PerformanceCounterSectionName); // The performance counter binary files cannot be read while the OS is still // writing to them. Therefore, we make the files available to the consumer only // when the OS has finished writing to them. Hence we need a special processor // for these files. List <string> additionalPerfCounterFoldersToTrim; bool perfCounterCollectionEnabled; // There should be only one path in the path list for performance counters string perfCounterPath = this.folderProducerSettings.Paths[0]; this.perfCounterFolderProcessor = PerfCounterFolderProcessor.Create( this.traceSource, this.logSourceId, this.configReader, this.initParam.LogDirectory, perfCounterPath, out perfCounterCollectionEnabled, out additionalPerfCounterFoldersToTrim); if (null == this.perfCounterFolderProcessor) { return; } if (false == perfCounterCollectionEnabled) { return; } if (null != additionalPerfCounterFoldersToTrim) { additionalFoldersToTrim.AddRange(additionalPerfCounterFoldersToTrim); } } #endif if (null != this.initParam.ConsumerSinks) { foreach (object sinkAsObject in this.initParam.ConsumerSinks) { IFolderSink folderSink = null; try { folderSink = (IFolderSink)sinkAsObject; } catch (InvalidCastException e) { this.traceSource.WriteError( this.logSourceId, "Exception occured while casting a sink object of type {0} to interface IFolderSink. Exception information: {1}.", sinkAsObject.GetType(), e); } if (null == folderSink) { continue; } folderSink.RegisterFolders(this.folderProducerSettings.Paths); } } #if DotNetCoreClrLinux if (FolderProducerType.WindowsFabricCrashDumps == this.folderProducerSettings.Type) { const int filePermissions = Helpers.LINUX_USER_READ | Helpers.LINUX_USER_WRITE | Helpers.LINUX_USER_EXECUTE | Helpers.LINUX_GROUP_READ | Helpers.LINUX_GROUP_WRITE | Helpers.LINUX_GROUP_EXECUTE | Helpers.LINUX_OTHER_READ | Helpers.LINUX_OTHER_WRITE | Helpers.LINUX_OTHER_EXECUTE; Helpers.UpdateFilePermission(this.folderProducerSettings.Paths[0], filePermissions); using (FileStream fs = new FileStream("/proc/sys/kernel/core_pattern", FileMode.Open)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.Write(Path.Combine(this.folderProducerSettings.Paths[0], "%e.%p.dmp")); } } } #endif var foldersToTrim = this.folderProducerSettings.Paths.Concat(additionalFoldersToTrim).ToArray(); if (this.IsDiskSpaceManagementEnabled()) { foreach (string folderPath in foldersToTrim) { // Figure out the timestamp before which all files will be deleted this.diskSpaceManager.RegisterFolder( this.logSourceId, () => new DirectoryInfo(folderPath).EnumerateFiles("*", SearchOption.AllDirectories), f => f.LastWriteTimeUtc < DateTime.UtcNow - MinimumFileRetentionTime, // isSafeToDelete f => (!Utility.IgnoreUploadFileList.Exists(x => x.Equals(f)) && f.LastWriteTimeUtc >= DateTime.UtcNow - this.folderProducerSettings.DataDeletionAge)); // shouldBeRetained } } }