diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs
index a2dba27..d6bc593 100644
--- a/ConsoleApp1/Program.cs
+++ b/ConsoleApp1/Program.cs
@@ -7,28 +7,43 @@ using EonaCat.LogStack.Core;
var logger = new LogBuilder("MyApp")
.WithMinimumLevel(LogLevel.Information)
.WriteToConsole()
- .WriteToFile("C:\\tesss", maxFileSize: 50 * 1024 * 1024)
- //.WriteToJsonFile("./logs", maxFileSize: 50 * 1024 * 1024)
- //.WriteToHttp("https://127.0.0.1")
- //.WriteToUdp("127.0.0.1", 514)
- //.WriteToTcp("127.0.0.1", 514)
- //.WriteToDatabase(null)
- //.WriteToDiscord("https://discord.com/api/webhooks/...")
- //.WriteToMicrosoftTeams("https://outlook.office.com/webhook/...")
- //.WriteToElasticSearch("http://localhost:9200/logs")
- //.WriteToGraylogFlow(null)
- //.WriteToZabbixFlow(null)
+ .WriteToFile("./testlogs", maxFileSize: 50 * 1024 * 1024)
.BoostWithCorrelationId()
.BoostWithProcessId()
.Build();
+Console.WriteLine("Logger created successfully");
+Console.WriteLine("Writing log entries...");
-
-while (true)
+// Test: Write a few log entries and then dispose
+for (int i = 0; i < 10; i++)
{
- logger.Information("Application started");
- logger.Error(new Exception("Nerd!"), "Something went wrong");
- await Task.Delay(1);
-}
+ logger.Information("Application started - iteration " + i);
+ logger.Error(new Exception("Nerd!"), "Something went wrong - iteration " + i);
+}
-await logger.DisposeAsync(); // Flushes all logs
\ No newline at end of file
+Console.WriteLine("Wrote 10 log entries");
+
+// Wait a bit for the flush to happen
+await Task.Delay(3000);
+
+Console.WriteLine("Disposing logger...");
+await logger.DisposeAsync(); // Flushes all logs
+
+Console.WriteLine("Logging complete. Check ./testlogs for log files.");
+
+// List files that were created
+var logdir = new System.IO.DirectoryInfo("./testlogs");
+if (logdir.Exists)
+{
+ var files = logdir.GetFiles();
+ Console.WriteLine($"Found {files.Length} log files:");
+ foreach (var file in files)
+ {
+ Console.WriteLine($" - {file.Name} ({file.Length} bytes)");
+ }
+}
+else
+{
+ Console.WriteLine("./testlogs directory does not exist!");
+}
diff --git a/EonaCat.LogStack/EonaCat.LogStack.csproj b/EonaCat.LogStack/EonaCat.LogStack.csproj
index 97c76d9..d57307e 100644
--- a/EonaCat.LogStack/EonaCat.LogStack.csproj
+++ b/EonaCat.LogStack/EonaCat.LogStack.csproj
@@ -14,7 +14,7 @@ It features a rich fluent API for routing log events to dozens of destinations f
EonaCat (Jeroen Saey)
EonaCat;Logger;EonaCatLogStack;Log;Writer;Flows;LogStack;Memory;Speed;Jeroen;Saey
- 0.1.4
+ 0.1.6
README.md
True
LICENSE
@@ -25,7 +25,7 @@ It features a rich fluent API for routing log events to dozens of destinations f
- 0.1.4+{chash:10}.{c:ymd}
+ 0.1.6+{chash:10}.{c:ymd}
true
true
v[0-9]*
@@ -36,7 +36,7 @@ It features a rich fluent API for routing log events to dozens of destinations f
- 0.1.4
+ 0.1.6
EonaCat.LogStack
EonaCat.LogStack
https://git.saey.me/EonaCat/EonaCat.LogStack
diff --git a/EonaCat.LogStack/EonaCatLoggerCore/Flows/FileFlow.cs b/EonaCat.LogStack/EonaCatLoggerCore/Flows/FileFlow.cs
index fe0e59e..078826e 100644
--- a/EonaCat.LogStack/EonaCatLoggerCore/Flows/FileFlow.cs
+++ b/EonaCat.LogStack/EonaCatLoggerCore/Flows/FileFlow.cs
@@ -9,6 +9,7 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -198,7 +199,19 @@ namespace EonaCat.LogStack.Flows
_maxMemoryBytes = maxMemoryBytes;
_flushInterval = TimeSpan.FromMilliseconds(flushIntervalMs);
_outputFormat = outputFormat;
- _compressionFormat = compression;
+ _compressionFormat = compression;
+
+ // Use the cascading fallback strategy to resolve the final logging directory
+ try
+ {
+ _directory = ResolveLoggingDirectory(_directory);
+ }
+ catch (Exception ex)
+ {
+ WriteToConsoleError($"[FileFlow] Critical error in directory resolution: {ex.Message}");
+ _directory = Path.GetTempPath();
+ OnDirectoryException?.Invoke(this, $"FileFlow: Critical failure in directory resolution: {ex.Message}. Falling back to temp: '{_directory}'");
+ }
_logLevelsForSeparateFiles = logLevelsForSeparateFiles != null
? new HashSet(logLevelsForSeparateFiles)
@@ -207,58 +220,13 @@ namespace EonaCat.LogStack.Flows
SetFileExtension(outputFormat);
CompileTemplate(template);
- // Resolve relative path
- if (_directory.StartsWith("./", StringComparison.Ordinal))
- {
- _directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _directory.Substring(2));
- }
-
- // Never allow logging initialization to crash the host because of a bad
- // directory (ACLs, antivirus locks, read-only locations, etc.).
- // Fall back to a per-user temp directory.
- try
- {
- // Use DirectoryPermissionHelper to ensure directory with proper permissions
- if (!Helpers.DirectoryPermissionHelper.EnsureDirectoryHierarchy(_directory))
- {
- throw new UnauthorizedAccessException($"Cannot write to directory: {Helpers.DirectoryPermissionHelper.GetAccessIssueDiagnosis(_directory)}");
- }
- }
- catch (Exception ex)
- {
- try
- {
- var processId = Process.GetCurrentProcess().Id;
- var newDirectory = Path.Combine(Path.GetTempPath(), "EonaCat.LogStack", processId.ToString());
-
- if (Helpers.DirectoryPermissionHelper.EnsureDirectoryHierarchy(newDirectory))
- {
- OnDirectoryException?.Invoke(this, $"FileFlow: Could not create directory: '{_directory}' ({ex.Message}), using directory '{newDirectory}' instead");
- _directory = newDirectory;
- }
- else
- {
- throw new InvalidOperationException($"Failed to create fallback directory: {newDirectory}");
- }
- }
- catch
- {
- var newDirectory = Path.GetTempPath();
- OnDirectoryException?.Invoke(this, $"FileFlow: Could not create any writable directory, falling back to temp: '{newDirectory}'. Original error: {ex.Message}");
- _directory = newDirectory;
-
- // Last resort: disable file output by pointing to temp path.
- // The writer thread still runs and swallows failures.
- }
- }
-
// BlockingCollection with bounded capacity
_queue = new BlockingCollection(new ConcurrentQueue(), QueueCapacity);
// Dedicated writer thread
_writerThread = new Thread(WriterThreadBody)
{
- IsBackground = true,
+ IsBackground = false,
Name = "FileFlow.Writer[" + filePrefix + "]",
Priority = ThreadPriority.AboveNormal,
};
@@ -830,6 +798,14 @@ namespace EonaCat.LogStack.Flows
_isDisposing = true; // Signal all threads that disposal is in progress
_queue.CompleteAdding();
+
+ // Give the writer thread time to drain the queue before canceling
+ Stopwatch sw = Stopwatch.StartNew();
+ while (_queue.Count > 0 && sw.Elapsed < TimeSpan.FromSeconds(5))
+ {
+ Thread.Sleep(10);
+ }
+
_cts.Cancel();
// Give threads more time to gracefully exit (increased from 2000ms to 5000ms)
@@ -873,6 +849,7 @@ namespace EonaCat.LogStack.Flows
}
private void WriterThreadBody()
{
+ WriteToConsoleError("[FileFlow] Writer thread started");
try
{
while (!_queue.IsCompleted)
@@ -940,6 +917,8 @@ namespace EonaCat.LogStack.Flows
try
{
+ // Write to both stdout and stderr to ensure visibility
+ Console.WriteLine(text);
Console.Error.WriteLine(text);
}
catch
@@ -950,7 +929,7 @@ namespace EonaCat.LogStack.Flows
private void WriteLogEvent(LogEvent log)
{
- long size = 0;
+ long size =0;
try
{
size = EstimateSize(log);
@@ -1015,28 +994,52 @@ namespace EonaCat.LogStack.Flows
{
try
{
- EnsureFileOpen(path, log);
-
- if (ShouldRotate(path, line.Length))
+ if (!EnsureFileOpen(path, log))
{
- string archived = RotateFile(path);
- EnsureFileOpen(path, log);
- if (archived != null)
+ // File open failed; skip write operation but continue with other processing
+ }
+ else
+ {
+ if (ShouldRotate(path, line.Length))
{
- Action onRotate = _onRotate;
- if (onRotate != null)
+ string archived = RotateFile(path);
+ if (!EnsureFileOpen(path, log))
{
- try { onRotate(archived); }
- catch { /* Do nothing */ }
+ // File reopen after rotation failed; skip this write
+ }
+ else
+ {
+ OpenFile of;
+ if (_openFiles.TryGetValue(path, out of))
+ {
+ of.Writer.WriteLine(line);
+ of.Size += line.Length + Environment.NewLine.Length;
+ }
+ }
+ if (archived != null)
+ {
+ Action onRotate = _onRotate;
+ if (onRotate != null)
+ {
+ try { onRotate(archived); }
+ catch { /* Do nothing */ }
+ }
+ }
+ }
+ else
+ {
+ OpenFile of;
+ if (_openFiles.TryGetValue(path, out of))
+ {
+ of.Writer.WriteLine(line);
+ of.Size += line.Length + Environment.NewLine.Length;
+ }
+ else
+ {
+ // File handle disappeared between EnsureFileOpen and write attempt
+ WriteToConsoleError("[FileFlow] File handle for '" + path + "' missing after EnsureFileOpen");
}
}
- }
-
- OpenFile of;
- if (_openFiles.TryGetValue(path, out of))
- {
- of.Writer.WriteLine(line);
- of.Size += line.Length + Environment.NewLine.Length;
}
}
catch (Exception ex)
@@ -1522,7 +1525,7 @@ namespace EonaCat.LogStack.Flows
}
}
- private void EnsureFileOpen(string path, LogEvent logEvent)
+ private bool EnsureFileOpen(string path, LogEvent logEvent)
{
try
{
@@ -1533,7 +1536,7 @@ namespace EonaCat.LogStack.Flows
{
if (File.Exists(path))
{
- return;
+ return true;
}
}
catch
@@ -1584,6 +1587,7 @@ namespace EonaCat.LogStack.Flows
try
{
of.Writer.Write(CsvHeader);
+ of.Writer.Flush();
of.HasCsvHeader = true;
}
catch (Exception ex)
@@ -1600,6 +1604,7 @@ namespace EonaCat.LogStack.Flows
{
of.Writer.WriteLine("");
of.Writer.WriteLine("");
+ of.Writer.Flush();
of.HasXmlHeader = true;
}
else
@@ -1614,6 +1619,8 @@ namespace EonaCat.LogStack.Flows
WriteToConsoleError("[FileFlow] XML header write error for '" + path + "': " + ex.Message);
}
}
+
+ return true;
}
catch (Exception ex)
{
@@ -1640,6 +1647,7 @@ namespace EonaCat.LogStack.Flows
}
}
WriteToConsoleError("[FileFlow] Failed to open '" + path + "': " + ex.Message + diagnosis);
+ return false;
}
}
catch (Exception ex)
@@ -1650,6 +1658,7 @@ namespace EonaCat.LogStack.Flows
WriteToConsoleError("[FileFlow] EnsureFileOpen unhandled error: " + ex.Message);
}
catch { /* ignore */ }
+ return false;
}
}
@@ -1870,6 +1879,7 @@ namespace EonaCat.LogStack.Flows
private void PeriodicFlushLoop()
{
+ WriteToConsoleError("[FileFlow] Periodic flush loop started");
try
{
while (!_isDisposing && !_cts.Token.IsCancellationRequested)
@@ -2032,6 +2042,141 @@ namespace EonaCat.LogStack.Flows
string.Concat(prefix, "_", CachedMachineName, "_", date.ToString(_dateFormat), _fileExtension));
}
+ ///
+ /// Resolves the logging directory with a cascading fallback strategy:
+ /// 1. Try the requested directory
+ /// 2. Try to fix permissions on the requested directory
+ /// 3. Fall back to %appdata%/EonaCat.LogStack/
+ /// 4. Fall back to TEMP directory
+ ///
+ private string ResolveLoggingDirectory(string requestedDirectory)
+ {
+ // Resolve relative paths first
+ string workingDirectory = requestedDirectory;
+ if (workingDirectory.StartsWith("./", StringComparison.Ordinal))
+ {
+ workingDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, workingDirectory.Substring(2));
+ }
+
+ // Attempt 1: Use the requested directory
+ WriteToConsoleError($"[FileFlow] Attempting to use log directory: {workingDirectory}");
+ if (Helpers.DirectoryPermissionHelper.EnsureDirectoryHierarchy(workingDirectory))
+ {
+ WriteToConsoleError($"[FileFlow] Successfully using log directory: {workingDirectory}");
+ return workingDirectory;
+ }
+
+ WriteToConsoleError($"[FileFlow] Failed to use log directory: {workingDirectory}. Diagnosis: {Helpers.DirectoryPermissionHelper.GetAccessIssueDiagnosis(workingDirectory)}");
+
+ // Attempt 2: Try to fix permissions on the requested directory
+ WriteToConsoleError($"[FileFlow] Attempting to fix permissions on: {workingDirectory}");
+ if (TryFixDirectoryPermissions(workingDirectory) && Helpers.DirectoryPermissionHelper.EnsureDirectoryHierarchy(workingDirectory))
+ {
+ WriteToConsoleError($"[FileFlow] Successfully fixed permissions and using log directory: {workingDirectory}");
+ return workingDirectory;
+ }
+
+ WriteToConsoleError($"[FileFlow] Failed to fix permissions on: {workingDirectory}");
+
+ // Attempt 3: Fall back to AppData directory
+ string appDataDirectory = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
+ "EonaCat.LogStack");
+
+ WriteToConsoleError($"[FileFlow] Attempting to use AppData log directory: {appDataDirectory}");
+ if (Helpers.DirectoryPermissionHelper.EnsureDirectoryHierarchy(appDataDirectory))
+ {
+ WriteToConsoleError($"[FileFlow] Successfully using AppData log directory: {appDataDirectory}");
+ OnDirectoryException?.Invoke(this, $"FileFlow: Could not use requested directory '{requestedDirectory}', fell back to '{appDataDirectory}'");
+ return appDataDirectory;
+ }
+
+ WriteToConsoleError($"[FileFlow] Failed to use AppData log directory: {appDataDirectory}. Diagnosis: {Helpers.DirectoryPermissionHelper.GetAccessIssueDiagnosis(appDataDirectory)}");
+
+ // Attempt 4: Fall back to TEMP directory
+ string tempDirectory = Path.GetTempPath();
+ WriteToConsoleError($"[FileFlow] Attempting to use TEMP log directory: {tempDirectory}");
+
+ try
+ {
+ if (Helpers.DirectoryPermissionHelper.CanWrite(tempDirectory))
+ {
+ WriteToConsoleError($"[FileFlow] Successfully using TEMP log directory: {tempDirectory}");
+ OnDirectoryException?.Invoke(this, $"FileFlow: Could not use requested directory '{requestedDirectory}' or AppData, fell back to TEMP directory '{tempDirectory}'");
+ return tempDirectory;
+ }
+ }
+ catch
+ {
+ // Temp directory check failed
+ }
+
+ WriteToConsoleError($"[FileFlow] Failed to use TEMP log directory: {tempDirectory}. This is a critical error - logging may not work.");
+
+ // Final fallback: return the temp path anyway, even if it might not work
+ OnDirectoryException?.Invoke(this, $"FileFlow: Critical - could not find any writable directory. Attempting to use TEMP: '{tempDirectory}'");
+ return tempDirectory;
+ }
+
+ ///
+ /// Attempts to fix directory permissions across all platforms (Windows, Linux, Mac).
+ /// On Windows: Clears read-only attributes.
+ /// On Linux/Mac: Uses chmod to set full permissions.
+ /// Returns true if fix was successful or attempted, false if it failed or is not applicable.
+ ///
+ private bool TryFixDirectoryPermissions(string dirPath)
+ {
+ try
+ {
+ if (!Directory.Exists(dirPath))
+ {
+ // Try to create it first
+ try
+ {
+ Directory.CreateDirectory(dirPath);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ // Attempt to set everyone permissions (handles all platforms)
+ if (Helpers.DirectoryPermissionHelper.TrySetEveryonePermissions(dirPath))
+ {
+ WriteToConsoleError($"[FileFlow] Set permissions on: {dirPath}");
+ return true;
+ }
+
+ // Fallback: On Windows, try clearing the read-only attribute directly
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ try
+ {
+ var dirInfo = new DirectoryInfo(dirPath);
+ if ((dirInfo.Attributes & FileAttributes.ReadOnly) != 0)
+ {
+ dirInfo.Attributes &= ~FileAttributes.ReadOnly;
+ WriteToConsoleError($"[FileFlow] Cleared read-only attribute on: {dirPath}");
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ WriteToConsoleError($"[FileFlow] Failed to fix permissions: {ex.Message}");
+ return false;
+ }
+ }
+
+ // On Unix-like systems, we've already attempted chmod via TrySetEveryonePermissions
+ return false;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
private void SetFileExtension(FileOutputFormat fmt)
{
switch (fmt)
diff --git a/EonaCat.LogStack/Helpers/DirectoryPermissionHelper.cs b/EonaCat.LogStack/Helpers/DirectoryPermissionHelper.cs
index 0bccec8..1674e59 100644
--- a/EonaCat.LogStack/Helpers/DirectoryPermissionHelper.cs
+++ b/EonaCat.LogStack/Helpers/DirectoryPermissionHelper.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
@@ -35,7 +36,7 @@ namespace EonaCat.LogStack.Helpers
}
// Try to create a temporary file to verify write access
- var testFile = Path.Combine(dirPath, ".permission_test_" + Guid.NewGuid().ToString("."));
+ var testFile = Path.Combine(dirPath, ".permission_test_" + Guid.NewGuid().ToString("N"));
try
{
using (var fs = File.Create(testFile, 1, FileOptions.DeleteOnClose))
@@ -150,6 +151,115 @@ namespace EonaCat.LogStack.Helpers
}
}
+ ///
+ /// Attempts to set full permissions for everyone on the directory.
+ /// Falls back to clearing the read-only attribute if needed on Windows.
+ /// Uses chmod on Linux/Mac and Windows permission APIs on Windows.
+ /// This is a best-effort operation for all platforms.
+ ///
+ public static bool TrySetEveryonePermissions(string dirPath)
+ {
+ if (string.IsNullOrEmpty(dirPath) || !Directory.Exists(dirPath))
+ {
+ return false;
+ }
+
+ try
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return TrySetWindowsPermissions(dirPath);
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ return TrySetUnixPermissions(dirPath);
+ }
+
+ // Unknown platform - try whatever we can
+ return CanWrite(dirPath);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to set Windows directory permissions by clearing the read-only attribute.
+ ///
+ private static bool TrySetWindowsPermissions(string dirPath)
+ {
+ try
+ {
+ var dirInfo = new DirectoryInfo(dirPath);
+
+ // Clear read-only attribute if set
+ if ((dirInfo.Attributes & FileAttributes.ReadOnly) != 0)
+ {
+ try
+ {
+ dirInfo.Attributes &= ~FileAttributes.ReadOnly;
+ }
+ catch
+ {
+ // Continue even if attribute clearing fails
+ }
+ }
+
+ // Verify the directory is now writable
+ return CanWrite(dirPath);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ ///
+ /// Attempts to set Unix (Linux/Mac) directory permissions using chmod.
+ /// Sets full permissions (777) for the directory.
+ ///
+ private static bool TrySetUnixPermissions(string dirPath)
+ {
+ if (string.IsNullOrEmpty(dirPath))
+ {
+ return false;
+ }
+
+ try
+ {
+ // Use chmod to set full permissions (777)
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "chmod",
+ Arguments = $"777 \"{dirPath}\"",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ CreateNoWindow = true
+ }
+ };
+
+ process.Start();
+ process.WaitForExit(5000); // Wait up to 5 seconds
+
+ if (process.ExitCode == 0)
+ {
+ // Verify the directory is now writable
+ return CanWrite(dirPath);
+ }
+
+ return false;
+ }
+ catch
+ {
+ // chmod not available or failed
+ return false;
+ }
+ }
+
///
/// Attempts to grant write permissions on Windows by clearing the read-only attribute.
/// This is a best-effort operation and may fail on restricted systems.
diff --git a/Testers/EonaCat.LogStack.Test.Web/Program.cs b/Testers/EonaCat.LogStack.Test.Web/Program.cs
index 9945fac..6138a59 100644
--- a/Testers/EonaCat.LogStack.Test.Web/Program.cs
+++ b/Testers/EonaCat.LogStack.Test.Web/Program.cs
@@ -51,21 +51,24 @@ namespace EonaCat.LogStack.Test.Web
var logBuilder = new LogBuilder();
logBuilder.WithTimestampMode(TimestampMode.Local);
logBuilder.WriteToConsole();
- logBuilder.WriteToFile("./logs", outputFormat: FileOutputFormat.Csv);
- logBuilder.WriteToFile("./logs", outputFormat: FileOutputFormat.StructuredJson);
- logBuilder.WriteToFile("./logs", outputFormat: FileOutputFormat.Text);
- logBuilder.WriteToFile("./logs", outputFormat: FileOutputFormat.Json);
- logBuilder.WriteToFile("./logs", outputFormat: FileOutputFormat.Xml);
+
+ // Use absolute path to ensure directory creation works
+ var logDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "EonaCat.LogStack", "Logs");
+ Directory.CreateDirectory(logDirectory);
+
+ logBuilder.WriteToFile(logDirectory, outputFormat: FileOutputFormat.Csv);
+ logBuilder.WriteToFile(logDirectory, outputFormat: FileOutputFormat.StructuredJson);
+ logBuilder.WriteToFile(logDirectory, outputFormat: FileOutputFormat.Text);
+ logBuilder.WriteToFile(logDirectory, outputFormat: FileOutputFormat.Json);
+ logBuilder.WriteToFile(logDirectory, outputFormat: FileOutputFormat.Xml);
logBuilder.WriteToTcp("127.0.0.1", 514);
//logBuilder.WriteToEncryptedFile("./logs");
//logBuilder.WriteDiagnostics();
logBuilder.WriteToAudit(
- directory: "./audit",
+ directory: Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "EonaCat.LogStack", "Audit"),
auditLevel: AuditLevel.WarningAndAbove, // only Warn+ go to audit trail
includeProperties: true);
//logBuilder.WriteToRollingBuffer();
- var consoleFlow = logBuilder.GetFlow(typeof(ConsoleFlow));
- logBuilder.WriteToThrottled(consoleFlow);
logBuilder.WriteToStatusFlow(new List { new ServiceMonitoring.ServiceStatus { Host = "google.com", Port = 443, ServiceType = ServiceMonitoring.ServiceType.HTTPS } }, checkInterval: TimeSpan.FromSeconds(5));
//logBuilder.WriteToSignalR();
//logBuilder.WriteToEmailFlow();