Added extra web logger test
This commit is contained in:
163
Testers/EonaCat.Logger.Test.Web/Logger.cs
Normal file
163
Testers/EonaCat.Logger.Test.Web/Logger.cs
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
using EonaCat.Logger.Managers;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace EonaCat.Logger.Test.Web
|
||||||
|
{
|
||||||
|
public static class Logger
|
||||||
|
{
|
||||||
|
private static readonly LogManager LogManager = new LogManager(new LoggerSettings
|
||||||
|
{
|
||||||
|
Id = "EonaCatDnsLogger",
|
||||||
|
MaxLogType = ELogType.TRACE,
|
||||||
|
FileLoggerOptions =
|
||||||
|
{
|
||||||
|
LogDirectory = "Logs",
|
||||||
|
FileSizeLimit = 20_000_000, // 20 MB
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public static string LogFolder => "Logs";
|
||||||
|
public static string CurrentLogFile => LogManager.CurrentLogFile;
|
||||||
|
public static bool IsDisabled { get; set; }
|
||||||
|
|
||||||
|
public static void DeleteCurrentLogFile()
|
||||||
|
{
|
||||||
|
if (IsDisabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LogManager.DeleteCurrentLogFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static IActionResult DownloadLogAsync(HttpResponse response, string logFile)
|
||||||
|
{
|
||||||
|
if (IsDisabled)
|
||||||
|
{
|
||||||
|
response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the file exists
|
||||||
|
if (!File.Exists(logFile))
|
||||||
|
{
|
||||||
|
response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a cancellation token source to handle cancellation
|
||||||
|
var cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
// Start streaming the file content to the response
|
||||||
|
Task.Run(() => StreamFileContentAsync(response, logFile, response.Body, cancellationTokenSource.Token), cancellationTokenSource.Token);
|
||||||
|
|
||||||
|
// Return an empty result to indicate that streaming has started
|
||||||
|
return new EmptyResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DisableResponseBuffering(HttpResponse response)
|
||||||
|
{
|
||||||
|
var httpContext = response.HttpContext;
|
||||||
|
var responseBodyFeature = httpContext.Features.Get<IHttpResponseBodyFeature>();
|
||||||
|
if (responseBodyFeature != null)
|
||||||
|
{
|
||||||
|
responseBodyFeature.DisableBuffering();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task StreamFileContentAsync(HttpResponse response, string filePath, Stream outputStream, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Clear the response first
|
||||||
|
response.Clear();
|
||||||
|
|
||||||
|
// Disable response buffering
|
||||||
|
DisableResponseBuffering(response);
|
||||||
|
|
||||||
|
// Set the response headers
|
||||||
|
response.Headers.Add("Content-Disposition", $"attachment; filename={Path.GetFileName(filePath)}");
|
||||||
|
response.Headers.Add("Content-Type", "application/octet-stream");
|
||||||
|
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0)
|
||||||
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the response is completed
|
||||||
|
if (response.HasStarted)
|
||||||
|
{
|
||||||
|
// The response is already completed, so we can't write further
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await outputStream.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Do nothing, handle any specific error if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the file has been modified
|
||||||
|
if (File.GetLastWriteTimeUtc(filePath) > File.GetLastWriteTimeUtc(fileStream.Name))
|
||||||
|
{
|
||||||
|
// Close the existing stream and reopen the file with updated contents
|
||||||
|
fileStream.Close();
|
||||||
|
await StreamFileContentAsync(response, filePath, outputStream, cancellationToken).ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// The operation was canceled, clean up if necessary
|
||||||
|
fileStream.Close();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Flush and close the output stream
|
||||||
|
await outputStream.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException e)
|
||||||
|
{
|
||||||
|
Log(e, "StreamFileContentAsync");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
outputStream?.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void Log(string message, ELogType logType = ELogType.INFO, bool writeToConsole = true)
|
||||||
|
{
|
||||||
|
if (IsDisabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LogManager.Write(message, logType, writeToConsole);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Log(Exception exception, string message = "", bool writeToConsole = true)
|
||||||
|
{
|
||||||
|
if (IsDisabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LogManager.Write(exception, module: message, writeToConsole: writeToConsole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using EonaCat.Logger;
|
|||||||
using EonaCat.Logger.EonaCatCoreLogger;
|
using EonaCat.Logger.EonaCatCoreLogger;
|
||||||
using EonaCat.Logger.EonaCatCoreLogger.Extensions;
|
using EonaCat.Logger.EonaCatCoreLogger.Extensions;
|
||||||
using EonaCat.Logger.Managers;
|
using EonaCat.Logger.Managers;
|
||||||
|
using EonaCat.Logger.Test.Web;
|
||||||
using EonaCat.Web.RateLimiter;
|
using EonaCat.Web.RateLimiter;
|
||||||
using EonaCat.Web.RateLimiter.Endpoints.Extensions;
|
using EonaCat.Web.RateLimiter.Endpoints.Extensions;
|
||||||
using EonaCat.Web.Tracer.Extensions;
|
using EonaCat.Web.Tracer.Extensions;
|
||||||
@@ -112,6 +113,7 @@ void RunLoggingExceptionTests()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task.Run(RunWebLoggerTests);
|
||||||
Task.Run(RunWebLoggingTests);
|
Task.Run(RunWebLoggingTests);
|
||||||
Task.Run(RunLoggingTests);
|
Task.Run(RunLoggingTests);
|
||||||
Task.Run(RunLoggingExceptionTests);
|
Task.Run(RunLoggingExceptionTests);
|
||||||
@@ -174,4 +176,21 @@ void RunLoggingTests()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RunWebLoggerTests()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 9000000; i++)
|
||||||
|
{
|
||||||
|
Logger.Log($"test via logger {i} INFO", ELogType.INFO);
|
||||||
|
Logger.Log($"test via logger {i} CRITICAL", ELogType.CRITICAL);
|
||||||
|
Logger.Log($"test via logger {i} DEBUG", ELogType.DEBUG);
|
||||||
|
Logger.Log($"test via logger {i} ERROR", ELogType.ERROR);
|
||||||
|
Logger.Log($"test via logger {i} TRACE", ELogType.TRACE);
|
||||||
|
Logger.Log($"test via logger {i} TRAFFIC", ELogType.TRAFFIC);
|
||||||
|
Logger.Log($"test via logger {i} WARNING", ELogType.WARNING);
|
||||||
|
Logger.Log($"test via logger {i} NONE", ELogType.NONE);
|
||||||
|
Console.WriteLine($"Logger: {i}");
|
||||||
|
Task.Delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
Reference in New Issue
Block a user