분석 로그를 1MB 롤링과 14일 보관 기준으로 정리한다
- app/perf/audit/workflow 로그에 공통 RollingTextLogStore를 적용해 날짜별 파일이 1MB를 넘지 않도록 오래된 내용을 밀어내며 저장한다. - 공통 로그, 성능 로그, 감사 로그는 14일 보관으로 맞추고 워크플로우 상세 로그는 기존 설정을 따르되 최대 14일 상한을 적용한다. - RollingTextLogStoreTests 3건을 추가해 파일 크기 상한과 오래된 파일/날짜 디렉터리 정리 동작을 검증한다. - 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_logroll\\ -p:IntermediateOutputPath=obj\\verify_logroll\\ 경고 0 / 오류 0 - 검증: dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter RollingTextLogStoreTests -p:OutputPath=bin\\verify_logroll_tests\\ -p:IntermediateOutputPath=obj\\verify_logroll_tests\\ 통과 3 (기존 WorkspaceContextGeneratorTests.cs(76) nullable 경고 1건 유지)
This commit is contained in:
96
src/AxCopilot.Tests/Services/RollingTextLogStoreTests.cs
Normal file
96
src/AxCopilot.Tests/Services/RollingTextLogStoreTests.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System.IO;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
namespace AxCopilot.Tests.Services;
|
||||
|
||||
public class RollingTextLogStoreTests
|
||||
{
|
||||
[Fact]
|
||||
public void AppendLine_ShouldKeepNewestContentWithinMaxBytes()
|
||||
{
|
||||
var root = CreateTempDirectory();
|
||||
try
|
||||
{
|
||||
var path = Path.Combine(root, "sample.log");
|
||||
for (var i = 0; i < 12; i++)
|
||||
AxCopilot.Services.RollingTextLogStore.AppendLine(path, $"line-{i:00}-abcdefghijklmnopqrstuvwxyz", 120);
|
||||
|
||||
var text = File.ReadAllText(path);
|
||||
var bytes = new FileInfo(path).Length;
|
||||
|
||||
bytes.Should().BeLessOrEqualTo(120);
|
||||
text.Should().Contain("line-11");
|
||||
text.Should().NotContain("line-00");
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryDelete(root);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PurgeOldFiles_ShouldDeleteFilesOutsideRetentionWindow()
|
||||
{
|
||||
var root = CreateTempDirectory();
|
||||
try
|
||||
{
|
||||
var oldFile = Path.Combine(root, "old.log");
|
||||
var newFile = Path.Combine(root, "new.log");
|
||||
File.WriteAllText(oldFile, "old");
|
||||
File.WriteAllText(newFile, "new");
|
||||
File.SetLastWriteTime(oldFile, DateTime.Now.AddDays(-20));
|
||||
File.SetLastWriteTime(newFile, DateTime.Now.AddDays(-1));
|
||||
|
||||
AxCopilot.Services.RollingTextLogStore.PurgeOldFiles(root, "*.log", 14);
|
||||
|
||||
File.Exists(oldFile).Should().BeFalse();
|
||||
File.Exists(newFile).Should().BeTrue();
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryDelete(root);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PurgeOldDirectoriesByDateName_ShouldDeleteOldDateDirectories()
|
||||
{
|
||||
var root = CreateTempDirectory();
|
||||
try
|
||||
{
|
||||
var oldDir = Path.Combine(root, DateTime.Now.AddDays(-16).ToString("yyyy-MM-dd"));
|
||||
var newDir = Path.Combine(root, DateTime.Now.AddDays(-2).ToString("yyyy-MM-dd"));
|
||||
Directory.CreateDirectory(oldDir);
|
||||
Directory.CreateDirectory(newDir);
|
||||
|
||||
AxCopilot.Services.RollingTextLogStore.PurgeOldDirectoriesByDateName(root, 14);
|
||||
|
||||
Directory.Exists(oldDir).Should().BeFalse();
|
||||
Directory.Exists(newDir).Should().BeTrue();
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryDelete(root);
|
||||
}
|
||||
}
|
||||
|
||||
private static string CreateTempDirectory()
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), "AxCopilot.Tests", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
private static void TryDelete(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
Directory.Delete(path, recursive: true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user