Updated
This commit is contained in:
@@ -7,7 +7,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EonaCat.MemoryGuard" Version="1.0.0" />
|
<PackageReference Include="EonaCat.MemoryGuard" Version="1.2.4" />
|
||||||
|
<PackageReference Include="EonaCat.Versioning" Version="1.2.6">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="EonaCat.Versioning.Helpers" Version="1.0.2" />
|
||||||
<PackageReference Include="EonaCat.Web.RateLimiter" Version="1.0.3" />
|
<PackageReference Include="EonaCat.Web.RateLimiter" Version="1.0.3" />
|
||||||
<PackageReference Include="EonaCat.Web.Tracer" Version="2.0.2" />
|
<PackageReference Include="EonaCat.Web.Tracer" Version="2.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -1,331 +1,406 @@
|
|||||||
using EonaCat.Logger;
|
namespace EonaCat.Logger.Test.Web
|
||||||
using EonaCat.Logger.EonaCatCoreLogger;
|
|
||||||
using EonaCat.Logger.EonaCatCoreLogger.Extensions;
|
|
||||||
using EonaCat.Logger.EonaCatCoreLogger.Models;
|
|
||||||
using EonaCat.Logger.LogClient;
|
|
||||||
using EonaCat.Logger.Managers;
|
|
||||||
using EonaCat.Logger.Test.Web;
|
|
||||||
using EonaCat.MemoryGuard;
|
|
||||||
using EonaCat.Versioning.Helpers;
|
|
||||||
using EonaCat.Web.RateLimiter;
|
|
||||||
using EonaCat.Web.RateLimiter.Endpoints.Extensions;
|
|
||||||
using Logger = EonaCat.Logger.Logger;
|
|
||||||
using LogLevel = EonaCat.Logger.LogClient.LogLevel;
|
|
||||||
|
|
||||||
MemoryGuard.StartDevelopment();
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
|
||||||
int onLogCounter = 0;
|
|
||||||
var defaultColor = Console.ForegroundColor;
|
|
||||||
|
|
||||||
// Add services to the container.
|
|
||||||
Logger logger = new Logger();
|
|
||||||
logger.UseLocalTime = true;
|
|
||||||
logger.LoggerSettings.Id = "TEST";
|
|
||||||
logger.LoggerSettings.LogInfo();
|
|
||||||
logger.LoggerSettings.LogWarning();
|
|
||||||
logger.LoggerSettings.LogError();
|
|
||||||
logger.LoggerSettings.LogCritical();
|
|
||||||
logger.LoggerSettings.LogDebug();
|
|
||||||
logger.LoggerSettings.LogTrace();
|
|
||||||
logger.LoggerSettings.LogTraffic();
|
|
||||||
logger.LoggerSettings.OnLog += LoggerSettings_OnLog;
|
|
||||||
logger.LoggerSettings.UseMask = true;
|
|
||||||
|
|
||||||
// Configure the client
|
|
||||||
var centralOptions = new LogCentralOptions
|
|
||||||
{
|
{
|
||||||
ServerUrl = "https://localhost:7282",
|
using EonaCat.Logger;
|
||||||
ApiKey = "716a964de381979df4303bf93fc091d3",
|
using EonaCat.Logger.EonaCatCoreLogger;
|
||||||
ApplicationName = "MyApp",
|
using EonaCat.Logger.EonaCatCoreLogger.Extensions;
|
||||||
ApplicationVersion = "1.0.0",
|
using EonaCat.Logger.EonaCatCoreLogger.Models;
|
||||||
Environment = "Production",
|
using EonaCat.Logger.LogClient;
|
||||||
BatchSize = 50,
|
using EonaCat.Logger.Managers;
|
||||||
FlushIntervalSeconds = 5
|
using EonaCat.Logger.Test.Web;
|
||||||
};
|
using EonaCat.MemoryGuard;
|
||||||
|
using EonaCat.Versioning.Helpers;
|
||||||
|
using EonaCat.Web.RateLimiter;
|
||||||
|
using EonaCat.Web.RateLimiter.Endpoints.Extensions;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
var logClient = new LogCentralClient(centralOptions);
|
public class Program
|
||||||
|
|
||||||
// Create the adapter
|
|
||||||
var adapter = new LogCentralEonaCatAdapter(logger.LoggerSettings, logClient);
|
|
||||||
|
|
||||||
// Now all EonaCat.Logger logs will be sent to LogCentral automatically
|
|
||||||
await logger.LogAsync("This is a test log message sent to LogCentral!", ELogType.INFO).ConfigureAwait(false);
|
|
||||||
|
|
||||||
Console.WriteLine(DllInfo.EonaCatVersion);
|
|
||||||
Console.WriteLine(VersionHelper.GetInformationalVersion());
|
|
||||||
|
|
||||||
var jsonLogger = new JsonFileLoggerProvider().CreateLogger("MyCategory") as JsonFileLogger;
|
|
||||||
jsonLogger?.SetContext("CorrelationId", "abc-123");
|
|
||||||
jsonLogger?.SetContext("UserId", "john.doe");
|
|
||||||
jsonLogger?.LogInformation("User logged in");
|
|
||||||
|
|
||||||
void LoggerSettings_OnLog(EonaCatLogMessage message)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
|
||||||
Console.WriteLine($"LogCounter: {++onLogCounter} {message}");
|
|
||||||
Console.ForegroundColor = defaultColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
var options = new FileLoggerOptions();
|
|
||||||
options.MaxRolloverFiles = 5;
|
|
||||||
//options.FileSizeLimit = 1 * 1024 * 1024 / 4;
|
|
||||||
options.UseLocalTime = true;
|
|
||||||
options.UseMask = true;
|
|
||||||
builder.Logging.AddEonaCatFileLogger(fileLoggerOptions: options, filenamePrefix: "web");
|
|
||||||
builder.Logging.AddEonaCatConsoleLogger();
|
|
||||||
|
|
||||||
TcpLoggerOptions tcpLoggerOptions = new TcpLoggerOptions
|
|
||||||
{
|
|
||||||
Host = "192.168.1.1",
|
|
||||||
Port = 12345,
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.Logging.AddEonaCatTcpLogger((tcpLoggerOptions) =>
|
|
||||||
{
|
|
||||||
tcpLoggerOptions.Port = 12345;
|
|
||||||
tcpLoggerOptions.Host = "192.168.1.1";
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.Services.AddRazorPages();
|
|
||||||
|
|
||||||
//var rateLimitOptions = new RateLimitOptions
|
|
||||||
//{
|
|
||||||
// Capacity = 10,
|
|
||||||
// Duration = TimeSpan.FromMinutes(1)
|
|
||||||
//};
|
|
||||||
|
|
||||||
//builder.Services.AddRateLimiting(rateLimitOptions);
|
|
||||||
var rateOptions = new RateLimiterOptions();
|
|
||||||
rateOptions.OutputLimitMessageAsHtml = false;
|
|
||||||
rateOptions.OutputLimitMessageAsXml = false;
|
|
||||||
rateOptions.OutputLimitMessageAsJson = true;
|
|
||||||
|
|
||||||
rateOptions.AddDefaultConfiguration(config =>
|
|
||||||
config.AddIpResolver().AddRule(3, TimeSpan.FromSeconds(10))
|
|
||||||
);
|
|
||||||
|
|
||||||
RateLimiterMiddleware.OnLimitResponseCreated += RateLimiterMiddlewareOnLimitResponseCreatedAsync;
|
|
||||||
|
|
||||||
async void RateLimiterMiddlewareOnLimitResponseCreatedAsync(object? sender, HttpContext httpContext)
|
|
||||||
{
|
|
||||||
await httpContext.Response.WriteAsync(" THIS IS MY CUSTOM RATE LIMIT MESSAGE").ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//builder.Services.UseWebRateLimiter(rateOptions);
|
|
||||||
builder.Services.UseWebRateLimiter(rateOptions);
|
|
||||||
builder.Services.UseWebRateLimiter(rateOptions =>
|
|
||||||
{
|
|
||||||
// Configures the default rateLimitConfiguration
|
|
||||||
rateOptions.AddDefaultConfiguration(rateLimitConfiguration =>
|
|
||||||
{
|
{
|
||||||
// throttling is based on request ip
|
public static async Task Main(string[] args)
|
||||||
rateLimitConfiguration.AddIpResolver()
|
|
||||||
// add general rules for all ips
|
|
||||||
.AddRule(3, TimeSpan.FromSeconds(10)) // 3 requests could be called every 10 seconds
|
|
||||||
.AddRule(30, TimeSpan.FromMinutes(1)) // 30 requests could be called every 1 minute
|
|
||||||
.AddRule(500, TimeSpan.FromHours(1)); // 500 requests could be called every 1 hour
|
|
||||||
});
|
|
||||||
});
|
|
||||||
builder.Services.AddMemoryCache();
|
|
||||||
|
|
||||||
|
|
||||||
var app = builder.Build();
|
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
|
||||||
if (!app.Environment.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseExceptionHandler("/Error");
|
|
||||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
|
||||||
app.UseHsts();
|
|
||||||
}
|
|
||||||
|
|
||||||
//EonaCat.Web.RateLimiter.RateLimiterOptions options = new EonaCat.Web.RateLimiter.RateLimiterOptions();
|
|
||||||
//options.LimitMessage = "FUCKING NOOB!";
|
|
||||||
//options.WriteLimitMessageToResponse = true;
|
|
||||||
//options.WriteLimitMessageStatusCodeToResponse = true;
|
|
||||||
//app.UseRateLimiter(options);
|
|
||||||
//RateLimiterMiddleware.OnLimitResponseCreated += RateLimiterMiddleware_OnLimitResponseCreatedAsync;
|
|
||||||
//async void RateLimiterMiddleware_OnLimitResponseCreatedAsync(object? sender, HttpContext httpContext)
|
|
||||||
//{
|
|
||||||
// await httpContext.Response.WriteAsync("THIS IS MY CUSTOM RATE LIMIT MESSAGE");
|
|
||||||
//}
|
|
||||||
|
|
||||||
//app.UseWebTracer();
|
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
|
||||||
app.UseStaticFiles();
|
|
||||||
|
|
||||||
app.UseRouting();
|
|
||||||
app.UseAuthorization();
|
|
||||||
app.UseWebRateLimiter();
|
|
||||||
|
|
||||||
app.MapRazorPages().RateLimit();
|
|
||||||
|
|
||||||
void RunLoggingExceptionTests()
|
|
||||||
{
|
|
||||||
var loggerSettings = new LoggerSettings();
|
|
||||||
loggerSettings.FileLoggerOptions.UseLocalTime = true;
|
|
||||||
loggerSettings.UseLocalTime = true;
|
|
||||||
loggerSettings.Id = "TEST";
|
|
||||||
loggerSettings.TypesToLog.Add(ELogType.INFO);
|
|
||||||
|
|
||||||
var logger = new LogManager(loggerSettings);
|
|
||||||
for (var i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
throw new Exception($"Normal Exception {i}");
|
var _config = new MemoryGuardConfiguration
|
||||||
}
|
{
|
||||||
catch (Exception exception)
|
MonitoringInterval = TimeSpan.FromSeconds(5),
|
||||||
{
|
AnalysisInterval = TimeSpan.FromSeconds(10),
|
||||||
logger.WriteAsync(exception).ConfigureAwait(false);
|
PredictionInterval = TimeSpan.FromSeconds(15),
|
||||||
Console.WriteLine($"Normal ExceptionLogged: {i}");
|
LeakDetectionThreshold = TimeSpan.FromSeconds(5),
|
||||||
|
SuspiciousObjectThreshold = TimeSpan.FromSeconds(3),
|
||||||
|
CaptureStackTraces = true,
|
||||||
|
EnableAutoRemediation = true,
|
||||||
|
AutoSaveReports = true,
|
||||||
|
MemoryPressureThreshold = 500 * 1024 * 1024, // 500MB
|
||||||
|
BackgroundAnalysisInterval = TimeSpan.FromMinutes(1),
|
||||||
|
OptimizationInterval = TimeSpan.FromMinutes(10),
|
||||||
|
PatternDetectionInterval = TimeSpan.FromMinutes(3)
|
||||||
|
};
|
||||||
|
|
||||||
|
MemoryGuard.Initialize(_config);
|
||||||
|
AllocationInterceptor.Initialize(MemoryGuard.Instance);
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
int onLogCounter = 0;
|
||||||
|
var defaultColor = Console.ForegroundColor;
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
Logger logger = new Logger();
|
||||||
|
logger.UseLocalTime = true;
|
||||||
|
logger.LoggerSettings.Id = "TEST";
|
||||||
|
logger.LoggerSettings.LogInfo();
|
||||||
|
logger.LoggerSettings.LogWarning();
|
||||||
|
logger.LoggerSettings.LogError();
|
||||||
|
logger.LoggerSettings.LogCritical();
|
||||||
|
logger.LoggerSettings.LogDebug();
|
||||||
|
logger.LoggerSettings.LogTrace();
|
||||||
|
logger.LoggerSettings.LogTraffic();
|
||||||
|
logger.LoggerSettings.OnLog += LoggerSettings_OnLog;
|
||||||
|
logger.LoggerSettings.UseMask = true;
|
||||||
|
|
||||||
|
// Configure the client
|
||||||
|
var centralOptions = new LogCentralOptions
|
||||||
|
{
|
||||||
|
ServerUrl = "https://localhost:7282",
|
||||||
|
ApiKey = "716a964de381979df4303bf93fc091d3",
|
||||||
|
ApplicationName = "MyApp",
|
||||||
|
ApplicationVersion = "1.0.0",
|
||||||
|
Environment = "Production",
|
||||||
|
BatchSize = 50,
|
||||||
|
FlushIntervalSeconds = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
var logClient = new LogCentralClient(centralOptions);
|
||||||
|
|
||||||
|
// Create the adapter
|
||||||
|
var adapter = new LogCentralEonaCatAdapter(logger.LoggerSettings, logClient);
|
||||||
|
|
||||||
|
// Now all EonaCat.Logger logs will be sent to LogCentral automatically
|
||||||
|
await logger.LogAsync("This is a test log message sent to LogCentral!", ELogType.INFO).ConfigureAwait(false);
|
||||||
|
|
||||||
|
Console.WriteLine(DllInfo.EonaCatVersion);
|
||||||
|
Console.WriteLine(VersionHelper.GetInformationalVersion());
|
||||||
|
|
||||||
|
|
||||||
|
// Generate a memory leak for testing
|
||||||
|
var jsonLogger = new JsonFileLoggerProvider().CreateLogger("MyCategory") as JsonFileLogger;
|
||||||
|
jsonLogger?.SetContext("CorrelationId", "abc-123");
|
||||||
|
jsonLogger?.SetContext("UserId", "john.doe");
|
||||||
|
jsonLogger?.LogInformation("User logged in");
|
||||||
|
|
||||||
|
void LoggerSettings_OnLog(EonaCatLogMessage message)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine($"LogCounter: {++onLogCounter} {message}");
|
||||||
|
Console.ForegroundColor = defaultColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = new FileLoggerOptions();
|
||||||
|
options.MaxRolloverFiles = 5;
|
||||||
|
//options.FileSizeLimit = 1 * 1024 * 1024 / 4;
|
||||||
|
options.UseLocalTime = true;
|
||||||
|
options.UseMask = true;
|
||||||
|
builder.Logging.AddEonaCatFileLogger(fileLoggerOptions: options, filenamePrefix: "web");
|
||||||
|
builder.Logging.AddEonaCatConsoleLogger();
|
||||||
|
|
||||||
|
TcpLoggerOptions tcpLoggerOptions = new TcpLoggerOptions
|
||||||
|
{
|
||||||
|
Host = "192.168.1.1",
|
||||||
|
Port = 12345,
|
||||||
|
};
|
||||||
|
|
||||||
|
builder.Logging.AddEonaCatTcpLogger((tcpLoggerOptions) =>
|
||||||
|
{
|
||||||
|
tcpLoggerOptions.Port = 12345;
|
||||||
|
tcpLoggerOptions.Host = "192.168.1.1";
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.AddRazorPages();
|
||||||
|
|
||||||
|
//var rateLimitOptions = new RateLimitOptions
|
||||||
|
//{
|
||||||
|
// Capacity = 10,
|
||||||
|
// Duration = TimeSpan.FromMinutes(1)
|
||||||
|
//};
|
||||||
|
|
||||||
|
//builder.Services.AddRateLimiting(rateLimitOptions);
|
||||||
|
var rateOptions = new RateLimiterOptions();
|
||||||
|
rateOptions.OutputLimitMessageAsHtml = false;
|
||||||
|
rateOptions.OutputLimitMessageAsXml = false;
|
||||||
|
rateOptions.OutputLimitMessageAsJson = true;
|
||||||
|
|
||||||
|
rateOptions.AddDefaultConfiguration(config =>
|
||||||
|
config.AddIpResolver().AddRule(3, TimeSpan.FromSeconds(10))
|
||||||
|
);
|
||||||
|
|
||||||
|
RateLimiterMiddleware.OnLimitResponseCreated += RateLimiterMiddlewareOnLimitResponseCreatedAsync;
|
||||||
|
|
||||||
|
async void RateLimiterMiddlewareOnLimitResponseCreatedAsync(object? sender, HttpContext httpContext)
|
||||||
|
{
|
||||||
|
await httpContext.Response.WriteAsync(" THIS IS MY CUSTOM RATE LIMIT MESSAGE").ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//builder.Services.UseWebRateLimiter(rateOptions);
|
||||||
|
builder.Services.UseWebRateLimiter(rateOptions);
|
||||||
|
builder.Services.UseWebRateLimiter(rateOptions =>
|
||||||
|
{
|
||||||
|
// Configures the default rateLimitConfiguration
|
||||||
|
rateOptions.AddDefaultConfiguration(rateLimitConfiguration =>
|
||||||
|
{
|
||||||
|
// throttling is based on request ip
|
||||||
|
rateLimitConfiguration.AddIpResolver()
|
||||||
|
// add general rules for all ips
|
||||||
|
.AddRule(3, TimeSpan.FromSeconds(10)) // 3 requests could be called every 10 seconds
|
||||||
|
.AddRule(30, TimeSpan.FromMinutes(1)) // 30 requests could be called every 1 minute
|
||||||
|
.AddRule(500, TimeSpan.FromHours(1)); // 500 requests could be called every 1 hour
|
||||||
|
});
|
||||||
|
});
|
||||||
|
builder.Services.AddMemoryCache();
|
||||||
|
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (!app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseExceptionHandler("/Error");
|
||||||
|
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||||
|
app.UseHsts();
|
||||||
|
}
|
||||||
|
|
||||||
|
//EonaCat.Web.RateLimiter.RateLimiterOptions options = new EonaCat.Web.RateLimiter.RateLimiterOptions();
|
||||||
|
//options.LimitMessage = "FUCKING NOOB!";
|
||||||
|
//options.WriteLimitMessageToResponse = true;
|
||||||
|
//options.WriteLimitMessageStatusCodeToResponse = true;
|
||||||
|
//app.UseRateLimiter(options);
|
||||||
|
//RateLimiterMiddleware.OnLimitResponseCreated += RateLimiterMiddleware_OnLimitResponseCreatedAsync;
|
||||||
|
//async void RateLimiterMiddleware_OnLimitResponseCreatedAsync(object? sender, HttpContext httpContext)
|
||||||
|
//{
|
||||||
|
// await httpContext.Response.WriteAsync("THIS IS MY CUSTOM RATE LIMIT MESSAGE");
|
||||||
|
//}
|
||||||
|
|
||||||
|
//app.UseWebTracer();
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
app.UseAuthorization();
|
||||||
|
app.UseWebRateLimiter();
|
||||||
|
|
||||||
|
app.MapRazorPages().RateLimit();
|
||||||
|
|
||||||
|
void RunLoggingExceptionTests()
|
||||||
|
{
|
||||||
|
var loggerSettings = new LoggerSettings();
|
||||||
|
loggerSettings.FileLoggerOptions.UseLocalTime = true;
|
||||||
|
loggerSettings.UseLocalTime = true;
|
||||||
|
loggerSettings.Id = "TEST";
|
||||||
|
loggerSettings.TypesToLog.Add(ELogType.INFO);
|
||||||
|
|
||||||
|
var logger = new LogManager(loggerSettings);
|
||||||
|
for (var i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw new Exception($"Normal Exception {i}");
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
logger.WriteAsync(exception).ConfigureAwait(false);
|
||||||
|
Console.WriteLine($"Normal ExceptionLogged: {i}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.Delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryLeakTester.Start(logger);
|
||||||
|
await Task.Run(RunMemoryReportTask).ConfigureAwait(false);
|
||||||
|
await Task.Run(RunMaskTest).ConfigureAwait(false);
|
||||||
|
await Task.Run(RunWebLoggerTestsAsync).ConfigureAwait(false);
|
||||||
|
await Task.Run(RunWebLoggingTests).ConfigureAwait(false);
|
||||||
|
await Task.Run(RunLoggingTestsAsync).ConfigureAwait(false);
|
||||||
|
await Task.Run(RunLoggingExceptionTests).ConfigureAwait(false);
|
||||||
|
await Task.Run(RunWebLoggingExceptionTests).ConfigureAwait(false);
|
||||||
|
|
||||||
|
async void RunMemoryReportTask()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
await MemoryGuard.PrintReportAsync().ConfigureAwait(false);
|
||||||
|
await Task.Delay(60000).ConfigureAwait(false);
|
||||||
|
Console.ReadKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunWebLoggingExceptionTests()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw new Exception($"WebException {i}");
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
app.Logger.LogCritical(exception, "CRITICAL");
|
||||||
|
app.Logger.LogDebug(exception, "DEBUG");
|
||||||
|
app.Logger.LogError(exception, "ERROR");
|
||||||
|
app.Logger.LogTrace(exception, "TRACE");
|
||||||
|
app.Logger.LogWarning(exception, "WARNING");
|
||||||
|
app.Logger.LogInformation(exception, "INFORMATION");
|
||||||
|
Console.WriteLine($"WebExceptionLogged: {i}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.Delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async void RunWebLoggingTests()
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(logger.LogFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logger.LogFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < 9000000; i++)
|
||||||
|
{
|
||||||
|
app.Logger.LogInformation($"web-test {i}");
|
||||||
|
using (var file = new StreamWriter(Path.Combine(logger.LogFolder, "test.log"), true))
|
||||||
|
{
|
||||||
|
await file.WriteAsync($"WebLogged: {i}{Environment.NewLine}").ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
Console.WriteLine($"WebLogged: {i}");
|
||||||
|
await Task.Delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async void RunMaskTest()
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(logger.LogFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logger.LogFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < 9000000; i++)
|
||||||
|
{
|
||||||
|
var message = $"mask-test {i}";
|
||||||
|
app.Logger.LogInformation("password: test");
|
||||||
|
app.Logger.LogInformation("JWT Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
|
||||||
|
app.Logger.LogInformation("JWT Token2: eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.iOeNU4dAFFeBwNj6qdhdvm-IvDQrTa6R22lQVJVuWJxorJfeQww5Nwsra0PjaOYhAMj9jNMO5YLmud8U7iQ5gJK2zYyepeSuXhfSi8yjFZfRiSkelqSkU19I-Ja8aQBDbqXf2SAWA8mHF8VS3F08rgEaLCyv98fLLH4vSvsJGf6ueZSLKDVXz24rZRXGWtYYk_OYYTVgR1cg0BLCsuCvqZvHleImJKiWmtS0-CymMO4MMjCy_FIl6I56NqLE9C87tUVpo1mT-kbg5cHDD8I7MjCW5Iii5dethB4Vid3mZ6emKjVYgXrtkOQ-JyGMh6fnQxEFN1ft33GX2eRHluK9eg");
|
||||||
|
|
||||||
|
using (var file = new StreamWriter(Path.Combine(logger.LogFolder, "testmask.log"), true))
|
||||||
|
{
|
||||||
|
await file.WriteAsync(message);
|
||||||
|
}
|
||||||
|
Console.WriteLine($"Masked: {i}");
|
||||||
|
await Task.Delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task RunLoggingTestsAsync()
|
||||||
|
{
|
||||||
|
var loggerSettings = new LoggerSettings();
|
||||||
|
loggerSettings.Id = "TEST";
|
||||||
|
loggerSettings.UseLocalTime = true;
|
||||||
|
loggerSettings.FileLoggerOptions.UseLocalTime = true;
|
||||||
|
loggerSettings.TypesToLog.Add(ELogType.INFO);
|
||||||
|
loggerSettings.TypesToLog.Add(ELogType.WARNING);
|
||||||
|
loggerSettings.TypesToLog.Add(ELogType.ERROR);
|
||||||
|
loggerSettings.TypesToLog.Add(ELogType.TRAFFIC);
|
||||||
|
loggerSettings.TypesToLog.Add(ELogType.DEBUG);
|
||||||
|
loggerSettings.LogDebug();
|
||||||
|
loggerSettings.LogInfo();
|
||||||
|
loggerSettings.LogWarning();
|
||||||
|
loggerSettings.LogError();
|
||||||
|
loggerSettings.LogCritical();
|
||||||
|
loggerSettings.LogTrace();
|
||||||
|
loggerSettings.LogTraffic();
|
||||||
|
loggerSettings.FileLoggerOptions.FileSizeLimit = 1024 * 1024 * 1;
|
||||||
|
loggerSettings.FileLoggerOptions.FileNamePrefix = "AllTypes";
|
||||||
|
loggerSettings.FileLoggerOptions.MaxRolloverFiles = 5;
|
||||||
|
var logger = new LogManager(loggerSettings);
|
||||||
|
|
||||||
|
for (var i = 0; i < 9000000; i++)
|
||||||
|
{
|
||||||
|
await logger.WriteAsync($"test to file {i} INFO").ConfigureAwait(false);
|
||||||
|
await logger.WriteAsync($"test to file {i} CRITICAL", ELogType.CRITICAL).ConfigureAwait(false);
|
||||||
|
await logger.WriteAsync($"test to file {i} DEBUG", ELogType.DEBUG).ConfigureAwait(false);
|
||||||
|
await logger.WriteAsync($"test to file {i} ERROR", ELogType.ERROR).ConfigureAwait(false);
|
||||||
|
await logger.WriteAsync($"test to file {i} TRACE", ELogType.TRACE).ConfigureAwait(false);
|
||||||
|
await logger.WriteAsync($"test to file {i} TRAFFIC", ELogType.TRAFFIC).ConfigureAwait(false);
|
||||||
|
await logger.WriteAsync($"test to file {i} WARNING", ELogType.WARNING).ConfigureAwait(false);
|
||||||
|
await logger.WriteAsync($"test to file {i} NONE", ELogType.NONE).ConfigureAwait(false);
|
||||||
|
Console.WriteLine($"Logged: {i}");
|
||||||
|
await Task.Delay(1).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task RunWebLoggerTestsAsync()
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await logger.LogAsync($"test via logger {i}").ConfigureAwait(false);
|
||||||
|
await logger.LogAsync($"test via logger {i}", ELogType.CRITICAL).ConfigureAwait(false);
|
||||||
|
await logger.LogAsync($"test via logger {i}", ELogType.DEBUG).ConfigureAwait(false);
|
||||||
|
await logger.LogAsync($"test via logger {i}", ELogType.ERROR).ConfigureAwait(false);
|
||||||
|
await logger.LogAsync($"test via logger {i}", ELogType.TRAFFIC).ConfigureAwait(false);
|
||||||
|
await logger.LogAsync($"test via logger {i}", ELogType.WARNING).ConfigureAwait(false);
|
||||||
|
await logger.LogAsync($"test via logger {i}", ELogType.NONE).ConfigureAwait(false);
|
||||||
|
}).ConfigureAwait(false);
|
||||||
|
await Task.Delay(1).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.Delay(1);
|
private static void Instance_LeakDetected(object? sender, EonaCat.MemoryGuard.EventArguments.MemoryLeakDetectedEventArgs e)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Run(RunMemoryReportTask).ConfigureAwait(false);
|
|
||||||
await Task.Run(RunMaskTest).ConfigureAwait(false);
|
|
||||||
await Task.Run(RunWebLoggerTestsAsync).ConfigureAwait(false);
|
|
||||||
await Task.Run(RunWebLoggingTests).ConfigureAwait(false);
|
|
||||||
await Task.Run(RunLoggingTestsAsync).ConfigureAwait(false);
|
|
||||||
await Task.Run(RunLoggingExceptionTests).ConfigureAwait(false);
|
|
||||||
await Task.Run(RunWebLoggingExceptionTests).ConfigureAwait(false);
|
|
||||||
|
|
||||||
async void RunMemoryReportTask()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
await MemoryGuard.PrintReportAsync().ConfigureAwait(false);
|
|
||||||
await Task.Delay(60000).ConfigureAwait(false);
|
|
||||||
Console.ReadKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunWebLoggingExceptionTests()
|
|
||||||
{
|
|
||||||
for (var i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
throw new Exception($"WebException {i}");
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
}
|
||||||
|
|
||||||
|
static class MemoryLeakTester
|
||||||
|
{
|
||||||
|
// Rooted forever → GC can never collect
|
||||||
|
private static readonly List<byte[]> _managedLeak = new();
|
||||||
|
private static readonly List<GCHandle> _handles = new();
|
||||||
|
|
||||||
|
public static void Start(Logger logger)
|
||||||
{
|
{
|
||||||
app.Logger.LogCritical(exception, "CRITICAL");
|
// Leak triggered via logging (very realistic)
|
||||||
app.Logger.LogDebug(exception, "DEBUG");
|
logger.LoggerSettings.OnLog += OnLogLeak;
|
||||||
app.Logger.LogError(exception, "ERROR");
|
|
||||||
app.Logger.LogTrace(exception, "TRACE");
|
// Optional background unmanaged leak
|
||||||
app.Logger.LogWarning(exception, "WARNING");
|
StartUnmanagedLeak();
|
||||||
app.Logger.LogInformation(exception, "INFORMATION");
|
|
||||||
Console.WriteLine($"WebExceptionLogged: {i}");
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine("⚠ MEMORY LEAK TEST ENABLED");
|
||||||
|
Console.ResetColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.Delay(1);
|
private static void OnLogLeak(EonaCatLogMessage message)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async void RunWebLoggingTests()
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(logger.LogFolder))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(logger.LogFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < 9000000; i++)
|
|
||||||
{
|
|
||||||
app.Logger.LogInformation($"web-test {i}");
|
|
||||||
using (var file = new StreamWriter(Path.Combine(logger.LogFolder, "test.log"), true))
|
|
||||||
{
|
{
|
||||||
await file.WriteAsync($"WebLogged: {i}{Environment.NewLine}").ConfigureAwait(false);
|
// 5 MB per log
|
||||||
|
var data = new byte[5_000_000];
|
||||||
|
_managedLeak.Add(data);
|
||||||
|
|
||||||
|
// GCHandle leak (advanced / nasty)
|
||||||
|
_handles.Add(GCHandle.Alloc(data, GCHandleType.Normal));
|
||||||
}
|
}
|
||||||
Console.WriteLine($"WebLogged: {i}");
|
|
||||||
await Task.Delay(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async void RunMaskTest()
|
private static void StartUnmanagedLeak()
|
||||||
{
|
|
||||||
if (!Directory.Exists(logger.LogFolder))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(logger.LogFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < 9000000; i++)
|
|
||||||
{
|
|
||||||
var message = $"mask-test {i}";
|
|
||||||
app.Logger.LogInformation("password: test");
|
|
||||||
app.Logger.LogInformation("JWT Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
|
|
||||||
app.Logger.LogInformation("JWT Token2: eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.iOeNU4dAFFeBwNj6qdhdvm-IvDQrTa6R22lQVJVuWJxorJfeQww5Nwsra0PjaOYhAMj9jNMO5YLmud8U7iQ5gJK2zYyepeSuXhfSi8yjFZfRiSkelqSkU19I-Ja8aQBDbqXf2SAWA8mHF8VS3F08rgEaLCyv98fLLH4vSvsJGf6ueZSLKDVXz24rZRXGWtYYk_OYYTVgR1cg0BLCsuCvqZvHleImJKiWmtS0-CymMO4MMjCy_FIl6I56NqLE9C87tUVpo1mT-kbg5cHDD8I7MjCW5Iii5dethB4Vid3mZ6emKjVYgXrtkOQ-JyGMh6fnQxEFN1ft33GX2eRHluK9eg");
|
|
||||||
|
|
||||||
using (var file = new StreamWriter(Path.Combine(logger.LogFolder, "testmask.log"), true))
|
|
||||||
{
|
{
|
||||||
await file.WriteAsync(message);
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Marshal.AllocHGlobal(10_000_000); // 10 MB unmanaged
|
||||||
|
await Task.Delay(500).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Console.WriteLine($"Masked: {i}");
|
|
||||||
await Task.Delay(1);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async Task RunLoggingTestsAsync()
|
}
|
||||||
{
|
|
||||||
var loggerSettings = new LoggerSettings();
|
|
||||||
loggerSettings.Id = "TEST";
|
|
||||||
loggerSettings.UseLocalTime = true;
|
|
||||||
loggerSettings.FileLoggerOptions.UseLocalTime = true;
|
|
||||||
loggerSettings.TypesToLog.Add(ELogType.INFO);
|
|
||||||
loggerSettings.TypesToLog.Add(ELogType.WARNING);
|
|
||||||
loggerSettings.TypesToLog.Add(ELogType.ERROR);
|
|
||||||
loggerSettings.TypesToLog.Add(ELogType.TRAFFIC);
|
|
||||||
loggerSettings.TypesToLog.Add(ELogType.DEBUG);
|
|
||||||
loggerSettings.LogDebug();
|
|
||||||
loggerSettings.LogInfo();
|
|
||||||
loggerSettings.LogWarning();
|
|
||||||
loggerSettings.LogError();
|
|
||||||
loggerSettings.LogCritical();
|
|
||||||
loggerSettings.LogTrace();
|
|
||||||
loggerSettings.LogTraffic();
|
|
||||||
loggerSettings.FileLoggerOptions.FileSizeLimit = 1024 * 1024 * 1;
|
|
||||||
loggerSettings.FileLoggerOptions.FileNamePrefix = "AllTypes";
|
|
||||||
loggerSettings.FileLoggerOptions.MaxRolloverFiles = 5;
|
|
||||||
var logger = new LogManager(loggerSettings);
|
|
||||||
|
|
||||||
for (var i = 0; i < 9000000; i++)
|
|
||||||
{
|
|
||||||
await logger.WriteAsync($"test to file {i} INFO").ConfigureAwait(false);
|
|
||||||
await logger.WriteAsync($"test to file {i} CRITICAL", ELogType.CRITICAL).ConfigureAwait(false);
|
|
||||||
await logger.WriteAsync($"test to file {i} DEBUG", ELogType.DEBUG).ConfigureAwait(false);
|
|
||||||
await logger.WriteAsync($"test to file {i} ERROR", ELogType.ERROR).ConfigureAwait(false);
|
|
||||||
await logger.WriteAsync($"test to file {i} TRACE", ELogType.TRACE).ConfigureAwait(false);
|
|
||||||
await logger.WriteAsync($"test to file {i} TRAFFIC", ELogType.TRAFFIC).ConfigureAwait(false);
|
|
||||||
await logger.WriteAsync($"test to file {i} WARNING", ELogType.WARNING).ConfigureAwait(false);
|
|
||||||
await logger.WriteAsync($"test to file {i} NONE", ELogType.NONE).ConfigureAwait(false);
|
|
||||||
Console.WriteLine($"Logged: {i}");
|
|
||||||
await Task.Delay(1).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task RunWebLoggerTestsAsync()
|
|
||||||
{
|
|
||||||
var i = 0;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
await Task.Run(async () =>
|
|
||||||
{
|
|
||||||
await logger.LogAsync($"test via logger {i}").ConfigureAwait(false);
|
|
||||||
await logger.LogAsync($"test via logger {i}", ELogType.CRITICAL).ConfigureAwait(false);
|
|
||||||
await logger.LogAsync($"test via logger {i}", ELogType.DEBUG).ConfigureAwait(false);
|
|
||||||
await logger.LogAsync($"test via logger {i}", ELogType.ERROR).ConfigureAwait(false);
|
|
||||||
await logger.LogAsync($"test via logger {i}", ELogType.TRAFFIC).ConfigureAwait(false);
|
|
||||||
await logger.LogAsync($"test via logger {i}", ELogType.WARNING).ConfigureAwait(false);
|
|
||||||
await logger.LogAsync($"test via logger {i}", ELogType.NONE).ConfigureAwait(false);
|
|
||||||
}).ConfigureAwait(false);
|
|
||||||
await Task.Delay(1).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run();
|
|
||||||
Reference in New Issue
Block a user