public override DateAndSequenceArchive GenerateArchiveFileName(string archiveFilePath, DateTime archiveDate, List <DateAndSequenceArchive> existingArchiveFiles) { FileNameTemplate archiveFileNameTemplate = GenerateFileNameTemplate(archiveFilePath); string dirName = Path.GetDirectoryName(archiveFilePath); archiveFilePath = Path.Combine(dirName, archiveFileNameTemplate.ReplacePattern("*").Replace("*", archiveDate.ToString(_archiveDateFormat))); return(new DateAndSequenceArchive(archiveFilePath, archiveDate, _archiveDateFormat, 0)); }
protected virtual string GenerateFileNameMask(string archiveFilePath, FileNameTemplate fileTemplate) { if (fileTemplate != null) { return(fileTemplate.ReplacePattern("*")); } else { return(string.Empty); } }
protected override DateAndSequenceArchive GenerateArchiveFileInfo(FileInfo archiveFile, FileNameTemplate fileTemplate) { string archiveFileName = Path.GetFileName(archiveFile.FullName) ?? ""; string fileNameMask = fileTemplate.ReplacePattern("*"); int lastIndexOfStar = fileNameMask.LastIndexOf('*'); if (lastIndexOfStar + _archiveDateFormat.Length <= archiveFileName.Length) { string datePart = archiveFileName.Substring(lastIndexOfStar, _archiveDateFormat.Length); DateTime fileDate; if (DateTime.TryParseExact(datePart, _archiveDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out fileDate)) { return(new DateAndSequenceArchive(archiveFile.FullName, fileDate, _archiveDateFormat, -1)); } } return(null); }
public override DateAndSequenceArchive GenerateArchiveFileName(string archiveFilePath, DateTime archiveDate, List <DateAndSequenceArchive> existingArchiveFiles) { int nextSequenceNumber = 0; FileNameTemplate archiveFileNameTemplate = GenerateFileNameTemplate(archiveFilePath); foreach (var existingFile in existingArchiveFiles) { nextSequenceNumber = Math.Max(nextSequenceNumber, existingFile.Sequence + 1); } int minSequenceLength = archiveFileNameTemplate.EndAt - archiveFileNameTemplate.BeginAt - 2; string paddedSequence = nextSequenceNumber.ToString().PadLeft(minSequenceLength, '0'); string dirName = Path.GetDirectoryName(archiveFilePath); archiveFilePath = Path.Combine(dirName, archiveFileNameTemplate.ReplacePattern("*").Replace("*", paddedSequence)); return(new DateAndSequenceArchive(archiveFilePath, archiveDate, _archiveDateFormat, nextSequenceNumber)); }
public override DateAndSequenceArchive GenerateArchiveFileName(string archiveFilePath, DateTime archiveDate, List <DateAndSequenceArchive> existingArchiveFiles) { int nextSequenceNumber = 0; FileNameTemplate archiveFileNameTemplate = GenerateFileNameTemplate(archiveFilePath); foreach (var existingFile in existingArchiveFiles) { if (existingFile.HasSameFormattedDate(archiveDate)) { nextSequenceNumber = Math.Max(nextSequenceNumber, existingFile.Sequence + 1); } } int minSequenceLength = archiveFileNameTemplate.EndAt - archiveFileNameTemplate.BeginAt - 2; string paddedSequence = nextSequenceNumber.ToString().PadLeft(minSequenceLength, '0'); string archiveFileNameWithoutPath = archiveFileNameTemplate.ReplacePattern("*").Replace("*", $"{archiveDate.ToString(_archiveDateFormat)}.{paddedSequence}"); string dirName = Path.GetDirectoryName(archiveFilePath); archiveFilePath = Path.Combine(dirName, archiveFileNameWithoutPath); archiveFilePath = Path.GetFullPath(archiveFilePath); // Rebuild to fix non-standard path-format return(new DateAndSequenceArchive(archiveFilePath, archiveDate, _archiveDateFormat, nextSequenceNumber)); }
/// <summary> /// <para> /// Archives the <paramref name="fileName"/> using a date and sequence style numbering. Archives will be stamped /// with the prior period (Year, Month, Day) datetime. The most recent archive has the highest number (in /// combination with the date). /// </para> /// <para> /// When the number of archive files exceed <see cref="P:MaxArchiveFiles"/> the obsolete archives are deleted. /// </para> /// </summary> /// <param name="fileName">File name to be archived.</param> /// <param name="pattern">File name template which contains the numeric pattern to be replaced.</param> /// <param name="logEvent">Log event that the <see cref="FileTarget"/> instance is currently processing.</param> private void ArchiveByDateAndSequence(string fileName, string pattern, LogEventInfo logEvent) { string baseNamePattern = Path.GetFileName(pattern); if (string.IsNullOrEmpty(baseNamePattern)) { return; } FileNameTemplate fileTemplate = new FileNameTemplate(baseNamePattern); string fileNameMask = fileTemplate.ReplacePattern("*"); string dateFormat = GetArchiveDateFormatString(this.ArchiveDateFormat); string dirName = Path.GetDirectoryName(Path.GetFullPath(pattern)); if (string.IsNullOrEmpty(dirName)) { return; } int minSequenceLength = fileTemplate.EndAt - fileTemplate.BeginAt - 2; int nextSequenceNumber; DateTime archiveDate = GetArchiveDate(fileName, logEvent); List<string> archiveFileNames; if (Directory.Exists(dirName)) { List<DateAndSequenceArchive> archives = FindDateAndSequenceArchives(dirName, fileName, fileNameMask, minSequenceLength, dateFormat, fileTemplate) .ToList(); // Find out the next sequence number among existing archives having the same date part as the current date. int? lastSequenceNumber = archives .Where(a => a.HasSameFormattedDate(archiveDate)) .Max(a => (int?)a.Sequence); nextSequenceNumber = (int)(lastSequenceNumber != null ? lastSequenceNumber + 1 : 0); archiveFileNames = archives .OrderBy(a => a.Date) .ThenBy(a => a.Sequence) .Select(a => a.FileName) .ToList(); } else { Directory.CreateDirectory(dirName); nextSequenceNumber = 0; archiveFileNames = new List<string>(); } string paddedSequence = nextSequenceNumber.ToString().PadLeft(minSequenceLength, '0'); string archiveFileNameWithoutPath = fileNameMask.Replace("*", string.Format("{0}.{1}", archiveDate.ToString(dateFormat), paddedSequence)); string archiveFileName = Path.Combine(dirName, archiveFileNameWithoutPath); RollArchiveForward(fileName, archiveFileName, allowCompress: true); archiveFileNames.Add(archiveFileName); EnsureArchiveCount(archiveFileNames); }
/// <summary> /// Archives the <paramref name="fileName"/> using a sequence style numbering. The most recent archive has the /// highest number. When the number of archive files exceed <see cref="P:MaxArchiveFiles"/> the obsolete /// archives are deleted. /// </summary> /// <param name="fileName">File name to be archived.</param> /// <param name="pattern">File name template which contains the numeric pattern to be replaced.</param> private void ArchiveBySequence(string fileName, string pattern) { FileNameTemplate fileTemplate = new FileNameTemplate(Path.GetFileName(pattern)); int trailerLength = fileTemplate.Template.Length - fileTemplate.EndAt; string fileNameMask = fileTemplate.ReplacePattern("*"); string dirName = Path.GetDirectoryName(Path.GetFullPath(pattern)); int nextNumber = -1; int minNumber = -1; var number2Name = new Dictionary<int, string>(); try { #if SILVERLIGHT && !WINDOWS_PHONE foreach (string s in Directory.EnumerateFiles(dirName, fileNameMask)) #else foreach (string s in Directory.GetFiles(dirName, fileNameMask)) #endif { string baseName = Path.GetFileName(s); string number = baseName.Substring(fileTemplate.BeginAt, baseName.Length - trailerLength - fileTemplate.BeginAt); int num; try { num = Convert.ToInt32(number, CultureInfo.InvariantCulture); } catch (FormatException) { continue; } nextNumber = Math.Max(nextNumber, num); minNumber = minNumber != -1 ? Math.Min(minNumber, num) : num; number2Name[num] = s; } nextNumber++; } catch (DirectoryNotFoundException) { Directory.CreateDirectory(dirName); nextNumber = 0; } if (minNumber != -1 && ShouldDeleteOldArchives()) { int minNumberToKeep = nextNumber - this.MaxArchiveFiles + 1; for (int i = minNumber; i < minNumberToKeep; ++i) { string s; if (number2Name.TryGetValue(i, out s)) { InternalLogger.Info("Deleting old archive {0}", s); File.Delete(s); } } } string newFileName = ReplaceNumberPattern(pattern, nextNumber); RollArchiveForward(fileName, newFileName, allowCompress: true); }