/// <summary> /// Create a log file scanner /// </summary> /// <param name="pathAndMask">File path and mask with glob syntax (i.e. /var/log/auth*.log)</param> /// <param name="maxFileSizeBytes">Max size of file (in bytes) before it is deleted or 0 for unlimited</param> /// <param name="fileProcessingIntervalMilliseconds">How often to process files, in milliseconds, less than 1 for manual processing, in which case <see cref="ProcessFiles"/> must be called as needed.</param> /// <param name="encoding">Encoding or null for utf-8. The encoding must either be single or variable byte, like ASCII, Ansi, utf-8, etc. UTF-16 and the like are not supported.</param> /// <param name="maxLineLength">Maximum line length before considering the file a binary file and failing</param> public LogFileScanner(string pathAndMask, long maxFileSizeBytes = 0, int fileProcessingIntervalMilliseconds = 0, Encoding encoding = null, int maxLineLength = 8192) { // glob syntax, replace all backslash to forward slash PathAndMask = pathAndMask; PathAndMask.ThrowIfNullOrEmpty(nameof(pathAndMask), "Must pass a non-empty path and mask to log file scanner"); // set properties this.maxFileSize = maxFileSizeBytes; this.encoding = encoding ?? Encoding.UTF8; this.maxLineLength = maxLineLength; try { // add initial files foreach (WatchedFile file in LogFileScanner.GetFiles(PathAndMask)) { watchedFiles.Add(file); } } catch { // generally catching all exceptions and not reporting is bad, but in this case we don't care, // we will try to get files on every ProcessFiles call and can throw the exception then } // setup timer to process files if (fileProcessingIntervalMilliseconds > 0) { fileProcessingTimer = new System.Timers.Timer(fileProcessingIntervalMilliseconds); fileProcessingTimer.Elapsed += (sender, args) => ProcessFiles(); fileProcessingTimer.Start(); } }
private HashSet <WatchedFile> GetCurrentWatchedFiles() { // read in existing files that match the mask in the directory being watched HashSet <WatchedFile> watchedFilesCopy = new HashSet <WatchedFile>(); foreach (WatchedFile file in LogFileScanner.GetFiles(PathAndMask)) { watchedFilesCopy.Add(file); } lock (watchedFiles) { // remove files that no longer exist foreach (WatchedFile existing in watchedFiles.ToArray()) { if (!watchedFilesCopy.Contains(existing)) { Logger.Debug("Removing parsed log file {0}", existing.FileName); watchedFiles.Remove(existing); } } // add new files foreach (WatchedFile newFile in watchedFilesCopy) { // add the file, will fail if it already exists if (watchedFiles.Add(newFile)) { Logger.Debug("Adding parsed log file {0}", newFile.FileName); } } // make a copy of everything so we can enumerate outside a lock watchedFilesCopy.Clear(); foreach (WatchedFile file in watchedFiles) { watchedFilesCopy.Add(file); } } return(watchedFilesCopy); }