diff --git a/EonaCat.Logger/EonaCat.Logger.csproj b/EonaCat.Logger/EonaCat.Logger.csproj
index 8f17c31..fbb483c 100644
--- a/EonaCat.Logger/EonaCat.Logger.csproj
+++ b/EonaCat.Logger/EonaCat.Logger.csproj
@@ -3,7 +3,7 @@
.netstandard2.1; net6.0; net7.0; net8.0; net4.8;
icon.ico
latest
- 1.3.5
+ 1.3.6
EonaCat (Jeroen Saey)
true
EonaCat (Jeroen Saey)
@@ -24,7 +24,7 @@
- 1.3.5+{chash:10}.{c:ymd}
+ 1.3.6+{chash:10}.{c:ymd}
true
true
v[0-9]*
@@ -52,10 +52,11 @@
-
- runtime; build; native; contentfiles; analyzers; buildtransitive; compile
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
-
+
diff --git a/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs b/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs
index 4364cab..ff16ab4 100644
--- a/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs
+++ b/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs
@@ -310,12 +310,6 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
return message;
}
- private async Task WriteStopMessage()
- {
- var message = LogHelper.GetStopMessage();
- await WriteMessagesAsync(new List { CreateLoggerMessage(message, CurrentDateTimeOffset) }, _cancellationTokenSource.Token).ConfigureAwait(false);
- }
-
internal string AddMessage(DateTimeOffset timestamp, string message)
{
var result = CreateLoggerMessage(message, timestamp);
diff --git a/EonaCat.Logger/Managers/ILogManager.cs b/EonaCat.Logger/Managers/ILogManager.cs
index b3576d9..0260478 100644
--- a/EonaCat.Logger/Managers/ILogManager.cs
+++ b/EonaCat.Logger/Managers/ILogManager.cs
@@ -8,12 +8,10 @@ namespace EonaCat.Logger.Managers;
public interface ILogManager
{
Task WriteAsync(string message, ELogType logType = ELogType.INFO, bool? writeToConsole = null,
- bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string customSplunkSourceType = null,
- bool? sendToGrayLogServers = null, string grayLogFacility = null, string grayLogSource = null,
+ string customSplunkSourceType = null, string grayLogFacility = null, string grayLogSource = null,
string grayLogVersion = "1.1");
Task WriteAsync(Exception exception, string module = null, string method = null, bool criticalException = false,
- bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null,
- string customSplunkSourceType = null, bool? sendToGrayLogServers = null, string grayLogFacility = null,
+ bool? writeToConsole = null, string customSplunkSourceType = null, string grayLogFacility = null,
string grayLogSource = null, string grayLogVersion = "1.1");
}
\ No newline at end of file
diff --git a/EonaCat.Logger/Managers/LogHelper.cs b/EonaCat.Logger/Managers/LogHelper.cs
index fa23b5d..8d8e374 100644
--- a/EonaCat.Logger/Managers/LogHelper.cs
+++ b/EonaCat.Logger/Managers/LogHelper.cs
@@ -2,14 +2,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
-using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using EonaCat.Json;
using EonaCat.Logger.Extensions;
-using EonaCat.Logger.GrayLog;
-using EonaCat.Logger.Splunk.Models;
-using EonaCat.Logger.Syslog;
+using EonaCat.Logger.Servers.GrayLog;
+using EonaCat.Logger.Servers.Splunk.Models;
using Microsoft.Extensions.Logging;
// This file is part of the EonaCat project(s) which is released under the Apache License.
@@ -35,7 +33,10 @@ internal static class LogHelper
internal static string FormatMessageWithHeader(LoggerSettings settings, ELogType logType, string currentMessage,
DateTime dateTime, string category = null)
{
- if (string.IsNullOrWhiteSpace(currentMessage)) return currentMessage;
+ if (string.IsNullOrWhiteSpace(currentMessage))
+ {
+ return currentMessage;
+ }
category ??= "General";
var sb = new StringBuilder(settings?.HeaderFormat ?? "[EonaCatLogger]");
@@ -143,9 +144,9 @@ internal static class LogHelper
logger.Log(logLevel, message);
}
- public static async Task SendToSplunkServersAsync(LoggerSettings settings, SplunkPayload splunkPayload, bool sendToSplunkServer)
+ public static async Task SendToSplunkServersAsync(LoggerSettings settings, SplunkPayload splunkPayload)
{
- if (settings == null || !sendToSplunkServer || splunkPayload == null)
+ if (settings == null || splunkPayload == null)
{
return;
}
@@ -174,9 +175,14 @@ internal static class LogHelper
///
/// Overload for sending a simple log message to Splunk.
///
- public static async Task SendToSplunkServersAsync(LoggerSettings settings, string logType, string message, bool sendToSplunkServer)
+ public static async Task SendToSplunkServersAsync(LoggerSettings settings, string logType, string message)
{
- if (settings == null || !sendToSplunkServer || string.IsNullOrWhiteSpace(message))
+ if (settings == null || string.IsNullOrWhiteSpace(message))
+ {
+ return;
+ }
+
+ if (settings.SplunkServers == null || settings.SplunkServers.Count() == 0)
{
return;
}
@@ -188,7 +194,7 @@ internal static class LogHelper
SourceType = logType
};
- await SendToSplunkServersAsync(settings, splunkPayload, sendToSplunkServer);
+ await SendToSplunkServersAsync(settings, splunkPayload);
}
///
@@ -201,9 +207,14 @@ internal static class LogHelper
internal static async Task SendToGrayLogServersAsync(LoggerSettings settings, string message, ELogType logLevel,
- string facility, string source, bool sendToGrayLogServer, string version = "1.1")
+ string facility, string source, string version = "1.1")
{
- if (settings == null || !sendToGrayLogServer || string.IsNullOrWhiteSpace(message))
+ if (settings == null || string.IsNullOrWhiteSpace(message))
+ {
+ return;
+ }
+
+ if (settings.GrayLogServers == null || settings.GrayLogServers.Count() == 0)
{
return;
}
@@ -258,13 +269,12 @@ internal static class LogHelper
await Task.WhenAll(tasks);
}
-
///
/// Sends a message via TCP to a GrayLog server.
///
- private static async Task SendViaTcpAsync(GrayLogServer server, byte[] data)
+ private static async Task SendViaTcpAsync(Graylog server, byte[] data)
{
- using var tcpClient = new TcpClient();
+ using var tcpClient = new System.Net.Sockets.TcpClient();
await tcpClient.ConnectAsync(server.Hostname, server.Port);
using var stream = tcpClient.GetStream();
await stream.WriteAsync(data, 0, data.Length);
@@ -274,7 +284,7 @@ internal static class LogHelper
///
/// Sends large messages in chunks over UDP.
///
- private static async Task SendUdpInChunksAsync(GrayLogServer server, byte[] data, int chunkSize)
+ private static async Task SendUdpInChunksAsync(Graylog server, byte[] data, int chunkSize)
{
for (int i = 0; i < data.Length; i += chunkSize)
{
@@ -283,9 +293,14 @@ internal static class LogHelper
}
}
- internal static async Task SendToSysLogServersAsync(LoggerSettings settings, string message, bool sendToSyslogServers)
+ internal static async Task SendToSysLogServersAsync(LoggerSettings settings, string message)
{
- if (settings == null || !sendToSyslogServers || string.IsNullOrWhiteSpace(message))
+ if (settings == null || string.IsNullOrWhiteSpace(message))
+ {
+ return;
+ }
+
+ if (settings.SysLogServers == null || settings.SysLogServers.Count() == 0)
{
return;
}
@@ -329,12 +344,84 @@ internal static class LogHelper
await Task.WhenAll(tasks);
}
+ internal static async Task SendToTcpLogServersAsync(LoggerSettings settings, string message)
+ {
+ if (settings == null || string.IsNullOrWhiteSpace(message))
+ {
+ return;
+ }
+
+ if (settings.TcpServers == null || settings.TcpServers.Count() == 0)
+ {
+ return;
+ }
+
+ var tasks = settings.TcpServers?
+ .Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
+ .Select(async server =>
+ {
+ try
+ {
+ var data = Encoding.UTF8.GetBytes(message);
+ server.DisposeTcp();
+ server.SetTcp();
+ await server.WriteAsync(data).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ OnException?.Invoke(null, new ErrorMessage
+ {
+ Exception = ex,
+ Message = $"Error logging to Tcp Server '{server.Hostname}': {ex.Message}"
+ });
+ }
+ }) ?? new List();
+
+ await Task.WhenAll(tasks);
+ }
+
+ internal static async Task SendToUdpLogServersAsync(LoggerSettings settings, string message)
+ {
+ if (settings == null || string.IsNullOrWhiteSpace(message))
+ {
+ return;
+ }
+
+ if (settings.UdpServers == null || settings.UdpServers.Count() == 0)
+ {
+ return;
+ }
+
+ var tasks = settings.UdpServers?
+ .Where(server => !string.IsNullOrWhiteSpace(server.Hostname) && server.Port >= 0)
+ .Select(async server =>
+ {
+ try
+ {
+ var data = Encoding.UTF8.GetBytes(message);
+ server.DisposeUdp();
+ server.SetUdp();
+ await server.WriteAsync(data).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ OnException?.Invoke(null, new ErrorMessage
+ {
+ Exception = ex,
+ Message = $"Error logging to Udp Server '{server.Hostname}': {ex.Message}"
+ });
+ }
+ }) ?? new List();
+
+ await Task.WhenAll(tasks);
+ }
+
///
/// Sends a message via TCP to a syslog server.
///
- private static async Task SendViaTcpAsync(SyslogServer server, byte[] data)
+ private static async Task SendViaTcpAsync(Servers.Syslog.Syslog server, byte[] data)
{
- using var tcpClient = new TcpClient();
+ using var tcpClient = new System.Net.Sockets.TcpClient();
await tcpClient.ConnectAsync(server.Hostname, server.Port);
using var stream = tcpClient.GetStream();
await stream.WriteAsync(data, 0, data.Length);
@@ -344,7 +431,7 @@ internal static class LogHelper
///
/// Sends large messages in chunks over UDP.
///
- private static async Task SendUdpInChunksAsync(SyslogServer server, byte[] data, int chunkSize)
+ private static async Task SendUdpInChunksAsync(Servers.Syslog.Syslog server, byte[] data, int chunkSize)
{
for (int i = 0; i < data.Length; i += chunkSize)
{
diff --git a/EonaCat.Logger/Managers/LogManager.cs b/EonaCat.Logger/Managers/LogManager.cs
index b953922..e59f418 100644
--- a/EonaCat.Logger/Managers/LogManager.cs
+++ b/EonaCat.Logger/Managers/LogManager.cs
@@ -1,13 +1,19 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using EonaCat.Logger.EonaCatCoreLogger;
using EonaCat.Logger.EonaCatCoreLogger.Extensions;
using EonaCat.Logger.EonaCatCoreLogger.Models;
using EonaCat.Logger.Extensions;
-using EonaCat.Logger.Syslog;
+using EonaCat.Logger.Servers.GrayLog;
+using EonaCat.Logger.Servers.Splunk;
+using EonaCat.Logger.Servers.Syslog;
+using EonaCat.Logger.Servers.Tcp;
+using EonaCat.Logger.Servers.Udp;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -24,23 +30,8 @@ namespace EonaCat.Logger.Managers
private bool _isDisposing;
private string _category;
- public LogManager(LoggerSettings settings, string serverIp, int serverPort)
+ public LogManager(LoggerSettings settings)
{
- if (string.IsNullOrEmpty(serverIp))
- {
- throw new ArgumentNullException(nameof(serverIp));
- }
-
- if (serverPort < 0)
- {
- throw new ArgumentException("Server port must be zero or greater.");
- }
-
- settings.SysLogServers = new List
- {
- new(serverIp, serverPort)
- };
-
Settings = settings;
SetupLogManager();
}
@@ -87,8 +78,7 @@ namespace EonaCat.Logger.Managers
public async Task WriteAsync(Exception exception, string module = null, string method = null,
bool criticalException = false,
- bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null,
- string customSplunkSourceType = null, bool? sendToGrayLogServers = null, string grayLogFacility = null,
+ bool? writeToConsole = null, string customSplunkSourceType = null, string grayLogFacility = null,
string grayLogSource = null, string grayLogVersion = "1.1")
{
if (exception == null)
@@ -97,14 +87,14 @@ namespace EonaCat.Logger.Managers
}
await WriteAsync(exception.FormatExceptionToMessage(module, method),
- criticalException ? ELogType.CRITICAL : ELogType.ERROR, writeToConsole, sendToSysLogServers,
- sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogFacility, grayLogSource,
+ criticalException ? ELogType.CRITICAL : ELogType.ERROR, writeToConsole,
+ customSplunkSourceType, grayLogFacility, grayLogSource,
grayLogVersion);
}
public async Task WriteAsync(string message, ELogType logType = ELogType.INFO, bool? writeToConsole = null,
- bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string customSplunkSourceType = null,
- bool? sendToGrayLogServers = null, string grayLogFacility = null, string grayLogSource = null,
+ string customSplunkSourceType = null,
+ string grayLogFacility = null, string grayLogSource = null,
string grayLogVersion = "1.1")
{
if (logType == ELogType.NONE)
@@ -112,8 +102,8 @@ namespace EonaCat.Logger.Managers
return;
}
- await InternalWriteAsync(CurrentDateTime, message, logType, writeToConsole, sendToSysLogServers, sendToSplunkServers,
- customSplunkSourceType, sendToGrayLogServers, grayLogFacility, grayLogSource, grayLogVersion);
+ await InternalWriteAsync(CurrentDateTime, message, logType, writeToConsole,
+ customSplunkSourceType, grayLogFacility, grayLogSource, grayLogVersion);
}
///
@@ -202,8 +192,7 @@ namespace EonaCat.Logger.Managers
}
private async Task InternalWriteAsync(DateTime dateTime, string message, ELogType logType = ELogType.INFO,
- bool? writeToConsole = null, bool? sendToSyslogServers = null, bool? sendToSplunkServers = null,
- string customSplunkSourceType = null, bool? sendToGrayLogServers = null, string grayLogFacility = null,
+ bool? writeToConsole = null, string customSplunkSourceType = null, string grayLogFacility = null,
string grayLogSource = null, string grayLogVersion = "1.1")
{
if (string.IsNullOrWhiteSpace(message) || logType == ELogType.NONE || !IsLogLevelEnabled(logType) || _isDisposing)
@@ -218,9 +207,6 @@ namespace EonaCat.Logger.Managers
var messageWithHeader = LogHelper.FormatMessageWithHeader(Settings, logType, message, dateTime, _category);
var writeToConsoleValue = writeToConsole.GetValueOrDefault(Settings.EnableConsole);
- var sendToSyslogServersValue = sendToSyslogServers.GetValueOrDefault(Settings.SendToSyslogServers);
- var sendToSplunkServersValue = sendToSplunkServers.GetValueOrDefault(Settings.SendToSplunkServers);
- var sendToGrayLogServersValue = sendToGrayLogServers.GetValueOrDefault(Settings.SendToGrayLogServers);
LogHelper.SendToFile(Logger, Settings, logType, message);
@@ -229,21 +215,14 @@ namespace EonaCat.Logger.Managers
LogHelper.SendToConsole(Settings, logType, messageWithHeader, true);
}
- var tasks = new List(3);
- if (sendToSyslogServersValue)
+ var tasks = new List(5)
{
- tasks.Add(LogHelper.SendToSysLogServersAsync(Settings, messageWithHeader, true));
- }
- if (sendToSplunkServersValue)
- {
- tasks.Add(LogHelper.SendToSplunkServersAsync(Settings, customSplunkSourceType ?? logType.ToString(),
- messageWithHeader, true));
- }
- if (sendToGrayLogServersValue)
- {
- tasks.Add(LogHelper.SendToGrayLogServersAsync(Settings, messageWithHeader, logType, grayLogFacility,
- grayLogSource, true, grayLogVersion));
- }
+ LogHelper.SendToSysLogServersAsync(Settings, messageWithHeader),
+ LogHelper.SendToSplunkServersAsync(Settings, customSplunkSourceType ?? logType.ToString(), messageWithHeader),
+ LogHelper.SendToGrayLogServersAsync(Settings, messageWithHeader, logType, grayLogFacility, grayLogSource, grayLogVersion),
+ LogHelper.SendToTcpLogServersAsync(Settings, messageWithHeader),
+ LogHelper.SendToUdpLogServersAsync(Settings, messageWithHeader),
+ };
if (tasks.Count > 0)
{
@@ -340,5 +319,326 @@ namespace EonaCat.Logger.Managers
File.Delete(CurrentLogFile);
}
}
+
+ ///
+ /// Add sysLog server
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool AddSyslogServer(string address, int port, string nickName = null)
+ {
+ if (Settings.SysLogServers == null)
+ {
+ Settings.SysLogServers = new List();
+ }
+
+ if (Settings.SysLogServers.Any(x => (nickName != null && x.Nickname == nickName) || nickName == null && x.Hostname == address && x.Port == port))
+ {
+ return false;
+ }
+
+ Settings.SysLogServers.Add(new Syslog(address, port));
+ return true;
+ }
+
+ ///
+ /// Remove the sysLog server
+ ///
+ ///
+ ///
+ ///
+ public bool RemoveSyslogServer(string address, int port)
+ {
+ if (Settings.SysLogServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.SysLogServers.FirstOrDefault(x => x.Hostname == address && x.Port == port);
+ if (delete != null)
+ {
+ Settings.SysLogServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Remove the sysLog server
+ ///
+ ///
+ ///
+ public bool RemoveSyslogServer(string nickName)
+ {
+ if (Settings.SysLogServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.SysLogServers.FirstOrDefault(x => x.Nickname == nickName);
+ if (delete != null)
+ {
+ Settings.SysLogServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Add Splunk server
+ ///
+ ///
+ ///
+ /// (optional)
+ /// (optional)
+ ///
+ public bool AddSplunkServer(string splunkHecUrl, string splunkHecToken, HttpClientHandler httpClientHandler = null, string nickName = null)
+ {
+ if (Settings.SplunkServers == null)
+ {
+ Settings.SplunkServers = new List();
+ }
+
+ if (Settings.SplunkServers.Any(x => (nickName != null && x.Nickname == nickName) || nickName == null && x.SplunkHecUrl == splunkHecUrl && x.SplunkHecToken == splunkHecToken))
+ {
+ return false;
+ }
+
+ Settings.SplunkServers.Add(new Splunk(splunkHecUrl, splunkHecToken, httpClientHandler, nickName));
+ return true;
+ }
+
+ ///
+ /// Remove the Splunk server
+ ///
+ ///
+ ///
+ ///
+ public bool RemoveSplunkServer(string splunkHecUrl, string splunkHecToken)
+ {
+ if (Settings.SplunkServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.SplunkServers.FirstOrDefault(x => x.SplunkHecUrl == splunkHecUrl && x.SplunkHecToken == splunkHecToken);
+ if (delete != null)
+ {
+ Settings.SplunkServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Remove the Splunk server
+ ///
+ ///
+ ///
+ public bool RemoveSplunkServer(string nickName)
+ {
+ if (Settings.SplunkServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.SplunkServers.FirstOrDefault(x => x.Nickname == nickName);
+ if (delete != null)
+ {
+ Settings.SplunkServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Add GrayLog server
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool AddGrayLogServer(string address, int port, string nickName = null)
+ {
+ if (Settings.GrayLogServers == null)
+ {
+ Settings.GrayLogServers = new List();
+ }
+
+ if (Settings.GrayLogServers.Any(x => (nickName != null && x.Nickname == nickName) || nickName == null && x.Hostname == address && x.Port == port))
+ {
+ return false;
+ }
+
+ Settings.GrayLogServers.Add(new Graylog(address, port));
+ return true;
+ }
+
+ ///
+ /// Remove the GrayLog server
+ ///
+ ///
+ ///
+ ///
+ public bool RemoveGrayLogServer(string address, int port)
+ {
+ if (Settings.GrayLogServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.GrayLogServers.FirstOrDefault(x => x.Hostname == address && x.Port == port);
+ if (delete != null)
+ {
+ Settings.GrayLogServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Remove the GrayLog server
+ ///
+ ///
+ ///
+ public bool RemoveGrayLogServer(string nickName)
+ {
+ if (Settings.GrayLogServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.GrayLogServers.FirstOrDefault(x => x.Nickname == nickName);
+ if (delete != null)
+ {
+ Settings.GrayLogServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Add Tcp server
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool AddTcpLogServer(string address, int port, string nickName = null)
+ {
+ if (Settings.TcpServers == null)
+ {
+ Settings.TcpServers = new List();
+ }
+
+ if (Settings.TcpServers.Any(x => (nickName != null && x.Nickname == nickName) || (nickName == null && x.Hostname == address && x.Port == port)))
+ {
+ return false;
+ }
+
+ Settings.TcpServers.Add(new Tcp(address, port));
+ return true;
+ }
+
+ ///
+ /// Remove the Tcp server
+ ///
+ ///
+ ///
+ ///
+ public bool RemoveTcpLogServer(string address, int port)
+ {
+ if (Settings.TcpServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.TcpServers.FirstOrDefault(x => x.Hostname == address && x.Port == port);
+ if (delete != null)
+ {
+ Settings.TcpServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Remove the Tcp server
+ ///
+ ///
+ ///
+ public bool RemoveTcpLogServer(string nickName)
+ {
+ if (Settings.TcpServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.TcpServers.FirstOrDefault(x => x.Nickname == nickName);
+ if (delete != null)
+ {
+ Settings.TcpServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Add Udp server
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool AddUdpLogServer(string address, int port, string nickName = null)
+ {
+ if (Settings.UdpServers == null)
+ {
+ Settings.UdpServers = new List();
+ }
+
+ if (Settings.UdpServers.Any(x => (nickName != null && x.Nickname == nickName) || nickName == null && x.Hostname == address && x.Port == port))
+ {
+ return false;
+ }
+
+ Settings.UdpServers.Add(new Udp(address, port));
+ return true;
+ }
+
+ ///
+ /// Remove the Udp server
+ ///
+ ///
+ ///
+ ///
+ public bool RemoveUdpLogServer(string address, int port)
+ {
+ if (Settings.UdpServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.UdpServers.FirstOrDefault(x => x.Hostname == address && x.Port == port);
+ if (delete != null)
+ {
+ Settings.UdpServers.Remove(delete);
+ }
+ return true;
+ }
+
+ ///
+ /// Remove the Udp server
+ ///
+ ///
+ ///
+ public bool RemoveUdpLogServer(string nickName)
+ {
+ if (Settings.UdpServers == null)
+ {
+ return false;
+ }
+
+ var delete = Settings.UdpServers.FirstOrDefault(x => x.Nickname == nickName);
+ if (delete != null)
+ {
+ Settings.UdpServers.Remove(delete);
+ }
+ return true;
+ }
}
}
\ No newline at end of file
diff --git a/EonaCat.Logger/Managers/LoggerSettings.cs b/EonaCat.Logger/Managers/LoggerSettings.cs
index 3b2a8cc..e500570 100644
--- a/EonaCat.Logger/Managers/LoggerSettings.cs
+++ b/EonaCat.Logger/Managers/LoggerSettings.cs
@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
+using System.Net.Sockets;
using System.Text.RegularExpressions;
using EonaCat.Logger.EonaCatCoreLogger;
using EonaCat.Logger.EonaCatCoreLogger.Models;
-using EonaCat.Logger.GrayLog;
-using EonaCat.Logger.Syslog;
+using EonaCat.Logger.Servers.GrayLog;
namespace EonaCat.Logger.Managers;
// This file is part of the EonaCat project(s) which is released under the Apache License.
@@ -127,18 +127,13 @@ public class LoggerSettings
}
public ELogType MaxLogType { get; set; } = ELogType.INFO;
+ public List SysLogServers { get; internal set; }
+ public List SplunkServers { get; internal set; }
- public bool SendToSyslogServers { get; set; }
+ public List GrayLogServers { get; internal set; }
+ public List TcpServers { get; internal set; }
- public List SysLogServers { get; set; }
-
- public bool SendToSplunkServers { get; set; }
-
- public bool SendToGrayLogServers { get; set; }
-
- public List SplunkServers { get; set; }
-
- public List GrayLogServers { get; set; }
+ public List UdpServers { get; internal set; }
///
/// Determines if the fileLogging is enabled
diff --git a/EonaCat.Logger/GrayLog/GrayLogServer.cs b/EonaCat.Logger/Servers/GrayLog/Graylog.cs
similarity index 58%
rename from EonaCat.Logger/GrayLog/GrayLogServer.cs
rename to EonaCat.Logger/Servers/GrayLog/Graylog.cs
index 3f134ce..c08a103 100644
--- a/EonaCat.Logger/GrayLog/GrayLogServer.cs
+++ b/EonaCat.Logger/Servers/GrayLog/Graylog.cs
@@ -1,87 +1,84 @@
using System;
using System.Net.Sockets;
-namespace EonaCat.Logger.GrayLog;
+namespace EonaCat.Logger.Servers.GrayLog;
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
///
-/// Syslog server.
+/// GrayLog client
///
-public class GrayLogServer
+public class Graylog : IDisposable
{
internal readonly object SendLock = new();
private string _Hostname = "127.0.0.1";
private int _Port = 12201;
internal UdpClient Udp;
- ///
- /// Instantiate the object.
- ///
- public GrayLogServer()
+ public bool SupportsTcp { get; set; }
+ public string Nickname { get; set; }
+ public string IpPort => _Hostname + ":" + _Port;
+
+ public Graylog() { }
+
+ public Graylog(string hostname = "127.0.0.1", int port = 12201, string nickName = null)
{
+ _Hostname = hostname ?? throw new ArgumentNullException(nameof(hostname));
+ _Port = port >= 0 ? port : throw new ArgumentException("Port must be zero or greater.");
+
+ Nickname = nickName ?? IpPort;
+ SetUdp();
}
- ///
- /// Instantiate the object.
- ///
- /// Hostname.
- /// Port.
- public GrayLogServer(string hostname = "127.0.0.1", int port = 12201)
- {
- Hostname = hostname;
- Port = port;
- }
-
- ///
- /// Hostname.
- ///
public string Hostname
{
get => _Hostname;
-
set
{
if (string.IsNullOrEmpty(value))
- {
throw new ArgumentNullException(nameof(Hostname));
- }
_Hostname = value;
-
SetUdp();
}
}
- ///
- /// UDP port.
- ///
public int Port
{
get => _Port;
set
{
if (value < 0)
- {
throw new ArgumentException("Port must be zero or greater.");
- }
_Port = value;
-
SetUdp();
}
}
- ///
- /// IP:port of the server.
- ///
- public string IpPort => _Hostname + ":" + _Port;
-
- public bool SupportsTcp { get; set; }
-
private void SetUdp()
{
- Udp = null;
+ DisposeUdp();
Udp = new UdpClient(_Hostname, _Port);
}
+
+ private void DisposeUdp()
+ {
+ if (Udp != null)
+ {
+ Udp.Dispose();
+ Udp = null;
+ }
+ }
+
+ public void Dispose()
+ {
+ DisposeUdp();
+ GC.SuppressFinalize(this);
+ }
+
+ ~Graylog()
+ {
+ Dispose();
+ }
}
\ No newline at end of file
diff --git a/EonaCat.Logger/Splunk/Models/SplunkPayload.cs b/EonaCat.Logger/Servers/Splunk/Models/SplunkPayload.cs
similarity index 87%
rename from EonaCat.Logger/Splunk/Models/SplunkPayload.cs
rename to EonaCat.Logger/Servers/Splunk/Models/SplunkPayload.cs
index 73a2db9..4fa59d9 100644
--- a/EonaCat.Logger/Splunk/Models/SplunkPayload.cs
+++ b/EonaCat.Logger/Servers/Splunk/Models/SplunkPayload.cs
@@ -1,4 +1,4 @@
-namespace EonaCat.Logger.Splunk.Models;
+namespace EonaCat.Logger.Servers.Splunk.Models;
public class SplunkPayload
{
diff --git a/EonaCat.Logger/Servers/Splunk/Splunk.cs b/EonaCat.Logger/Servers/Splunk/Splunk.cs
new file mode 100644
index 0000000..2308fe3
--- /dev/null
+++ b/EonaCat.Logger/Servers/Splunk/Splunk.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using EonaCat.Json;
+
+namespace EonaCat.Logger.Servers.Splunk;
+
+using EonaCat.Logger.Servers.Splunk.Models;
+// This file is part of the EonaCat project(s) which is released under the Apache License.
+// See the LICENSE file or go to https://EonaCat.com/License for full license details.
+
+///
+/// Splunk Server.
+///
+using System;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+public class Splunk : IDisposable
+{
+ internal readonly object SendLock = new();
+ private string _splunkHecUrl = "https://127.0.0.1:8088/services/collector/event";
+
+ public string SplunkHecToken { get; set; } = "splunk-hec-token";
+ public HttpClientHandler SplunkClientHandler { get; private set; }
+ public HttpClient HttpClient { get; private set; }
+ public string Nickname { get; set; }
+
+ public bool HasHecToken => !string.IsNullOrWhiteSpace(SplunkHecToken) && SplunkHecToken != "splunk-hec-token";
+ public bool HasHecUrl => !string.IsNullOrWhiteSpace(SplunkHecUrl);
+ public bool IsHttpsHecUrl => HasHecUrl && _splunkHecUrl.ToLower().StartsWith("https");
+ public bool IsLocalHost => HasHecUrl && (_splunkHecUrl.ToLower().Contains("127.0.0.1") || _splunkHecUrl.ToLower().Contains("localhost"));
+
+ public Splunk(string splunkHecUrl, string splunkHecToken, HttpClientHandler httpClientHandler = null, string nickName = null)
+ {
+ SplunkHecUrl = splunkHecUrl ?? throw new ArgumentNullException(nameof(splunkHecUrl));
+ SplunkHecToken = splunkHecToken ?? throw new ArgumentNullException(nameof(splunkHecToken));
+
+ Nickname = nickName ?? $"{splunkHecUrl}_{splunkHecToken}";
+ SplunkClientHandler = httpClientHandler ?? new HttpClientHandler();
+
+ CreateHttpClient();
+ }
+
+ public string SplunkHecUrl
+ {
+ get => _splunkHecUrl;
+ set
+ {
+ if (!string.IsNullOrWhiteSpace(value) && !value.ToLower().Contains("http"))
+ {
+ value = $"http://{value}";
+ }
+
+ _splunkHecUrl = value;
+ CreateHttpClient();
+ }
+ }
+
+ private void CreateHttpClient()
+ {
+ DisposeHttpClient();
+
+ SplunkClientHandler ??= new HttpClientHandler();
+ HttpClient = new HttpClient(SplunkClientHandler)
+ {
+ BaseAddress = new Uri(SplunkHecUrl)
+ };
+
+ HttpClient.DefaultRequestHeaders.Add("Authorization", $"Splunk {SplunkHecToken}");
+ }
+
+ public void DisableSSLValidation()
+ {
+ DisposeHttpClient();
+
+ SplunkClientHandler = new HttpClientHandler
+ {
+ ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
+ };
+
+ CreateHttpClient();
+ }
+
+ public async Task SendAsync(SplunkPayload splunkPayload)
+ {
+ if (splunkPayload == null) return null;
+
+ var eventObject = new
+ {
+ @event = splunkPayload.EventData,
+ sourcetype = splunkPayload.SourceType,
+ host = splunkPayload.Host
+ };
+
+ var eventJson = JsonHelper.ToJson(eventObject);
+ if (!HasHecToken) CreateHttpClient();
+
+ using var content = new StringContent(eventJson, Encoding.UTF8, "application/json");
+ return await HttpClient.PostAsync("/services/collector/event", content);
+ }
+
+ private void DisposeHttpClient()
+ {
+ if (HttpClient != null)
+ {
+ HttpClient.Dispose();
+ HttpClient = null;
+ }
+
+ if (SplunkClientHandler != null)
+ {
+ SplunkClientHandler.Dispose();
+ SplunkClientHandler = null;
+ }
+ }
+
+ public void Dispose()
+ {
+ DisposeHttpClient();
+ GC.SuppressFinalize(this);
+ }
+
+ ~Splunk()
+ {
+ Dispose();
+ }
+}
\ No newline at end of file
diff --git a/EonaCat.Logger/Syslog/SyslogServer.cs b/EonaCat.Logger/Servers/Syslog/Syslog.cs
similarity index 63%
rename from EonaCat.Logger/Syslog/SyslogServer.cs
rename to EonaCat.Logger/Servers/Syslog/Syslog.cs
index 824ff1b..c54a9ca 100644
--- a/EonaCat.Logger/Syslog/SyslogServer.cs
+++ b/EonaCat.Logger/Servers/Syslog/Syslog.cs
@@ -1,87 +1,82 @@
using System;
using System.Net.Sockets;
-namespace EonaCat.Logger.Syslog;
+namespace EonaCat.Logger.Servers.Syslog;
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
///
/// Syslog server.
///
-public class SyslogServer
+public class Syslog : IDisposable
{
private string _Hostname = "127.0.0.1";
private int _Port = 514;
internal UdpClient Udp;
- ///
- /// Instantiate the object.
- ///
- public SyslogServer()
- {
- }
+ public Syslog() { }
- ///
- /// Instantiate the object.
- ///
- /// Hostname.
- /// Port.
- public SyslogServer(string hostname = "127.0.0.1", int port = 514)
+ public Syslog(string hostname = "127.0.0.1", int port = 514, string nickName = null)
{
Hostname = hostname;
Port = port;
+ Nickname = nickName ?? IpPort;
}
- ///
- /// Hostname.
- ///
public string Hostname
{
get => _Hostname;
-
set
{
if (string.IsNullOrEmpty(value))
- {
throw new ArgumentNullException(nameof(Hostname));
- }
_Hostname = value;
-
SetUdp();
}
}
- ///
- /// UDP port.
- ///
public int Port
{
get => _Port;
set
{
if (value < 0)
- {
throw new ArgumentException("Port must be zero or greater.");
- }
_Port = value;
-
SetUdp();
}
}
- ///
- /// IP:port of the server.
- ///
- public string IpPort => _Hostname + ":" + _Port;
-
- public bool SupportsTcp { get; set; }
-
+ public string IpPort => _Hostname + ":" + _Port;
+ public bool SupportsTcp { get; set; }
+ public string Nickname { get; set; }
+
private void SetUdp()
{
- Udp = null;
+ DisposeUdp();
Udp = new UdpClient(_Hostname, _Port);
}
+
+ private void DisposeUdp()
+ {
+ if (Udp != null)
+ {
+ Udp.Dispose();
+ Udp = null;
+ }
+ }
+
+ public void Dispose()
+ {
+ DisposeUdp();
+ GC.SuppressFinalize(this);
+ }
+
+ ~Syslog()
+ {
+ Dispose();
+ }
}
\ No newline at end of file
diff --git a/EonaCat.Logger/Servers/Tcp/Tcp.cs b/EonaCat.Logger/Servers/Tcp/Tcp.cs
new file mode 100644
index 0000000..07f30e4
--- /dev/null
+++ b/EonaCat.Logger/Servers/Tcp/Tcp.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+namespace EonaCat.Logger.Servers.Tcp
+{
+ // This file is part of the EonaCat project(s) which is released under the Apache License.
+ // See the LICENSE file or go to https://EonaCat.com/License for full license details.
+ public class Tcp : IDisposable
+ {
+ private string _Hostname = "127.0.0.1";
+ private int _Port = 514;
+ internal TcpClient _tcp;
+
+ public string Nickname { get; set; }
+ public string IpPort => _Hostname + ":" + _Port;
+
+ public Tcp(string hostname, int port, string nickname = null)
+ {
+ _Hostname = hostname ?? throw new ArgumentNullException(nameof(hostname));
+ _Port = port >= 0 ? port : throw new ArgumentException("Port must be zero or greater.");
+
+ Nickname = nickname ?? IpPort;
+ SetTcp();
+ }
+
+ public string Hostname
+ {
+ get => _Hostname;
+ set
+ {
+ if (string.IsNullOrEmpty(value))
+ throw new ArgumentNullException(nameof(Hostname));
+
+ _Hostname = value;
+ SetTcp();
+ }
+ }
+
+ public int Port
+ {
+ get => _Port;
+ set
+ {
+ if (value < 0)
+ throw new ArgumentException("Port must be zero or greater.");
+
+ _Port = value;
+ SetTcp();
+ }
+ }
+
+ internal void SetTcp()
+ {
+ DisposeTcp();
+ _tcp = new TcpClient(_Hostname, _Port);
+ }
+
+ internal void DisposeTcp()
+ {
+ if (_tcp != null)
+ {
+ _tcp.Close();
+ _tcp.Dispose();
+ _tcp = null;
+ }
+ }
+
+ public void Dispose()
+ {
+ DisposeTcp();
+ GC.SuppressFinalize(this);
+ }
+
+ internal async Task WriteAsync(byte[] data)
+ {
+ if (_tcp == null)
+ {
+ return;
+ }
+
+ if (data == null)
+ {
+ return;
+ }
+
+ using var stream = _tcp.GetStream();
+ await stream.WriteAsync(data, 0, data.Length);
+ await stream.FlushAsync();
+ }
+
+ internal async Task WriteAsync(string data)
+ {
+ if (_tcp == null)
+ {
+ return;
+ }
+
+ if (string.IsNullOrEmpty(data))
+ {
+ return;
+ }
+
+ var sendData = Encoding.UTF8.GetBytes(data);
+ using var stream = _tcp.GetStream();
+ await stream.WriteAsync(sendData, 0, sendData.Length);
+ await stream.FlushAsync();
+ }
+
+ ~Tcp()
+ {
+ Dispose();
+ }
+ }
+}
diff --git a/EonaCat.Logger/Servers/Udp/Udp.cs b/EonaCat.Logger/Servers/Udp/Udp.cs
new file mode 100644
index 0000000..c99dc12
--- /dev/null
+++ b/EonaCat.Logger/Servers/Udp/Udp.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+namespace EonaCat.Logger.Servers.Udp
+{
+ // This file is part of the EonaCat project(s) which is released under the Apache License.
+ // See the LICENSE file or go to https://EonaCat.com/License for full license details.
+ public class Udp : IDisposable
+ {
+ const int MaxUdpPacketSize = 4096;
+ private string _Hostname = "127.0.0.1";
+ private int _Port = 514;
+ internal UdpClient _udp;
+
+ public string Nickname { get; set; }
+ public string IpPort => _Hostname + ":" + _Port;
+
+ public Udp(string hostname, int port, string nickname = null)
+ {
+ _Hostname = hostname ?? throw new ArgumentNullException(nameof(hostname));
+ _Port = port >= 0 ? port : throw new ArgumentException("Port must be zero or greater.");
+
+ Nickname = nickname ?? IpPort;
+ SetUdp();
+ }
+
+ public string Hostname
+ {
+ get => _Hostname;
+ set
+ {
+ if (string.IsNullOrEmpty(value))
+ throw new ArgumentNullException(nameof(Hostname));
+
+ _Hostname = value;
+ SetUdp();
+ }
+ }
+
+ public int Port
+ {
+ get => _Port;
+ set
+ {
+ if (value < 0)
+ throw new ArgumentException("Port must be zero or greater.");
+
+ _Port = value;
+ SetUdp();
+ }
+ }
+
+ internal void SetUdp()
+ {
+ DisposeUdp();
+ _udp = new UdpClient(_Hostname, _Port);
+ }
+
+ internal void DisposeUdp()
+ {
+ if (_udp != null)
+ {
+ _udp.Dispose();
+ _udp = null;
+ }
+ }
+
+ public void Dispose()
+ {
+ DisposeUdp();
+ GC.SuppressFinalize(this);
+ }
+
+ internal async Task WriteAsync(byte[] data, bool dontFragment = false)
+ {
+ if (_udp == null || data == null)
+ {
+ return;
+ }
+
+ _udp.DontFragment = dontFragment;
+
+ int maxChunkSize = MaxUdpPacketSize;
+ int offset = 0;
+
+ while (offset < data.Length)
+ {
+ int chunkSize = Math.Min(maxChunkSize, data.Length - offset);
+ byte[] chunk = new byte[chunkSize];
+ Array.Copy(data, offset, chunk, 0, chunkSize);
+
+ await _udp.SendAsync(chunk, chunk.Length);
+ offset += chunkSize;
+ }
+ }
+
+ internal async Task WriteAsync(string data, bool dontFragment = false)
+ {
+ if (_udp == null || string.IsNullOrEmpty(data))
+ {
+ return;
+ }
+
+ var sendData = Encoding.UTF8.GetBytes(data);
+ _udp.DontFragment = dontFragment;
+
+ int maxChunkSize = MaxUdpPacketSize;
+ int offset = 0;
+
+ while (offset < sendData.Length)
+ {
+ int chunkSize = Math.Min(maxChunkSize, sendData.Length - offset);
+ byte[] chunk = new byte[chunkSize];
+ Array.Copy(sendData, offset, chunk, 0, chunkSize);
+
+ await _udp.SendAsync(chunk, chunk.Length);
+ offset += chunkSize;
+ }
+ }
+
+ ~Udp()
+ {
+ Dispose();
+ }
+ }
+}
diff --git a/EonaCat.Logger/Zabbix/API/ZabbixApi.cs b/EonaCat.Logger/Servers/Zabbix/API/ZabbixApi.cs
similarity index 98%
rename from EonaCat.Logger/Zabbix/API/ZabbixApi.cs
rename to EonaCat.Logger/Servers/Zabbix/API/ZabbixApi.cs
index 1ff6966..fdb64e3 100644
--- a/EonaCat.Logger/Zabbix/API/ZabbixApi.cs
+++ b/EonaCat.Logger/Servers/Zabbix/API/ZabbixApi.cs
@@ -5,7 +5,7 @@ using System.IO;
using System.Net;
using System.Text;
-namespace EonaCat.Logger.Zabbix.API;
+namespace EonaCat.Logger.Servers.Zabbix.API;
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
@@ -26,8 +26,8 @@ public class ZabbixApi
}
public ZabbixApi(string user, string password, string zabbixURL) : this(user, password, zabbixURL, false)
- {
-
+ {
+
}
private readonly string _user;
@@ -112,7 +112,7 @@ public class ZabbixApi
private string SendRequest(string jsonParams)
{
WebRequest request = WebRequest.Create(_zabbixURL);
-
+
if (_basicAuth != null)
{
request.Headers.Add("Authorization", "Basic " + _basicAuth);
diff --git a/EonaCat.Logger/Zabbix/API/ZabbixApiRequest.cs b/EonaCat.Logger/Servers/Zabbix/API/ZabbixApiRequest.cs
similarity index 95%
rename from EonaCat.Logger/Zabbix/API/ZabbixApiRequest.cs
rename to EonaCat.Logger/Servers/Zabbix/API/ZabbixApiRequest.cs
index 650d832..ac40e98 100644
--- a/EonaCat.Logger/Zabbix/API/ZabbixApiRequest.cs
+++ b/EonaCat.Logger/Servers/Zabbix/API/ZabbixApiRequest.cs
@@ -1,4 +1,4 @@
-namespace EonaCat.Logger.Zabbix.API
+namespace EonaCat.Logger.Servers.Zabbix.API
{
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
diff --git a/EonaCat.Logger/Zabbix/API/ZabbixApiResponse.cs b/EonaCat.Logger/Servers/Zabbix/API/ZabbixApiResponse.cs
similarity index 93%
rename from EonaCat.Logger/Zabbix/API/ZabbixApiResponse.cs
rename to EonaCat.Logger/Servers/Zabbix/API/ZabbixApiResponse.cs
index 6a838a7..14a01c5 100644
--- a/EonaCat.Logger/Zabbix/API/ZabbixApiResponse.cs
+++ b/EonaCat.Logger/Servers/Zabbix/API/ZabbixApiResponse.cs
@@ -1,6 +1,6 @@
using System.Dynamic;
-namespace EonaCat.Logger.Zabbix.API
+namespace EonaCat.Logger.Servers.Zabbix.API
{
// This file is part of the EonaCat project(s) which is released under the Apache License.
// See the LICENSE file or go to https://EonaCat.com/License for full license details.
diff --git a/EonaCat.Logger/Servers/Zabbix/ZabbixData.cs b/EonaCat.Logger/Servers/Zabbix/ZabbixData.cs
new file mode 100644
index 0000000..5e4c715
--- /dev/null
+++ b/EonaCat.Logger/Servers/Zabbix/ZabbixData.cs
@@ -0,0 +1,22 @@
+
+namespace EonaCat.Logger.Servers.Zabbix
+{
+ // This file is part of the EonaCat project(s) which is released under the Apache License.
+ // See the LICENSE file or go to https://EonaCat.com/License for full license details.
+ ///
+ /// Zabbix server.
+ ///
+ public class ZabbixData
+ {
+ public string Host { get; set; }
+ public string Key { get; set; }
+ public string Value { get; set; }
+
+ public ZabbixData(string host, string key, string value)
+ {
+ Host = host;
+ Key = key;
+ Value = value;
+ }
+ }
+}
diff --git a/EonaCat.Logger/Servers/Zabbix/ZabbixRequest.cs b/EonaCat.Logger/Servers/Zabbix/ZabbixRequest.cs
new file mode 100644
index 0000000..0b13e48
--- /dev/null
+++ b/EonaCat.Logger/Servers/Zabbix/ZabbixRequest.cs
@@ -0,0 +1,79 @@
+using EonaCat.Json;
+using System;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EonaCat.Logger.Servers.Zabbix
+{
+ // This file is part of the EonaCat project(s) which is released under the Apache License.
+ // See the LICENSE file or go to https://EonaCat.com/License for full license details.
+ public class ZabbixRequest
+ {
+ private const int BUFFER_SIZE = 1024;
+
+ ///
+ /// The request to send to the Zabbix server
+ ///
+ public string Request { get; set; }
+
+ ///
+ /// The data to send to the Zabbix server
+ ///
+ public ZabbixData[] Data { get; set; }
+
+ public ZabbixRequest(string host, string key, string value)
+ {
+ Request = "sender data";
+ Data = [new ZabbixData(host, key, value)];
+ }
+
+ ///
+ /// Sends the request to the Zabbix server
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendAsync(string server, int port = 10051, int timeout = 500)
+ {
+ string json = JsonHelper.ToJson(new ZabbixRequest(Data[0].Host, Data[0].Key, Data[0].Value));
+ using (TcpClient tcpClient = new TcpClient(server, port))
+ using (NetworkStream stream = tcpClient.GetStream())
+ {
+ byte[] header = Encoding.ASCII.GetBytes("ZBXD\x01");
+ byte[] dataLength = BitConverter.GetBytes((long)json.Length);
+ byte[] content = Encoding.ASCII.GetBytes(json);
+ byte[] message = new byte[header.Length + dataLength.Length + content.Length];
+
+ Buffer.BlockCopy(header, 0, message, 0, header.Length);
+ Buffer.BlockCopy(dataLength, 0, message, header.Length, dataLength.Length);
+ Buffer.BlockCopy(content, 0, message, header.Length + dataLength.Length, content.Length);
+
+ stream.Write(message, 0, message.Length);
+ stream.Flush();
+
+ int counter = 0;
+ while (!stream.DataAvailable)
+ {
+ if (counter < timeout / 50)
+ {
+ counter++;
+ await Task.Delay(50).ConfigureAwait(false);
+ }
+ else
+ {
+ throw new TimeoutException();
+ }
+ }
+
+ byte[] responseBytes = new byte[BUFFER_SIZE];
+ stream.Read(responseBytes, 0, responseBytes.Length);
+ string responseAsString = Encoding.UTF8.GetString(responseBytes);
+ string jsonResult = responseAsString.Substring(responseAsString.IndexOf('{'));
+ return JsonHelper.ToObject(jsonResult);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/EonaCat.Logger/Servers/Zabbix/ZabbixResponse.cs b/EonaCat.Logger/Servers/Zabbix/ZabbixResponse.cs
new file mode 100644
index 0000000..ce56f9e
--- /dev/null
+++ b/EonaCat.Logger/Servers/Zabbix/ZabbixResponse.cs
@@ -0,0 +1,11 @@
+namespace EonaCat.Logger.Servers.Zabbix
+{
+ // This file is part of the EonaCat project(s) which is released under the Apache License.
+ // See the LICENSE file or go to https://EonaCat.com/License for full license details.
+ public class ZabbixResponse
+ {
+ public string Response { get; set; }
+ public string Info { get; set; }
+
+ }
+}
diff --git a/EonaCat.Logger/Splunk/SplunkServer.cs b/EonaCat.Logger/Splunk/SplunkServer.cs
deleted file mode 100644
index dbc4cad..0000000
--- a/EonaCat.Logger/Splunk/SplunkServer.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using System;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using EonaCat.Json;
-using EonaCat.Logger.Splunk.Models;
-
-namespace EonaCat.Logger.SplunkServer;
-// This file is part of the EonaCat project(s) which is released under the Apache License.
-// See the LICENSE file or go to https://EonaCat.com/License for full license details.
-
-///
-/// Splunk Server.
-///
-public class SplunkServer
-{
- internal readonly object SendLock = new();
- private string _splunkHecUrl = "https://127.0.0.1:8088/services/collector/event";
-
-
- ///
- /// Instantiate the object.
- ///
- /// splunkHecUrl.
- /// splunkHecToken.
- /// httpClientHandler. (optional)
- public SplunkServer(string splunkHecUrl, string splunkHecToken, HttpClientHandler httpClientHandler = null)
- {
- SplunkHecUrl = splunkHecUrl;
- SplunkHecToken = splunkHecToken;
-
- if (httpClientHandler == null)
- {
- httpClientHandler = new HttpClientHandler();
- }
-
- SplunkClientHandler = httpClientHandler;
- CreateHttpClient();
- }
-
- ///
- /// SplunkHecUrl
- ///
- public string SplunkHecUrl
- {
- get => _splunkHecUrl;
-
- set
- {
- if (!string.IsNullOrWhiteSpace(_splunkHecUrl) && !_splunkHecUrl.ToLower().Contains("http"))
- {
- value = $"http://{value}";
- }
-
- _splunkHecUrl = value;
- }
- }
-
- public bool IsHttpsHecUrl => HasHecUrl && _splunkHecUrl.ToLower().StartsWith("https");
-
- ///
- /// SplunkHecToken
- ///
- public string SplunkHecToken { get; set; } = "splunk-hec-token";
-
- public HttpClientHandler SplunkClientHandler { get; internal set; }
- public HttpClient HttpClient { get; private set; }
-
- ///
- /// Determines if a HEC token is available
- ///
- public bool HasHecToken => !string.IsNullOrWhiteSpace(SplunkHecToken) && SplunkHecToken != "splunk-hec-token";
-
- ///
- /// Determines if a HEC url is available
- ///
- public bool HasHecUrl => !string.IsNullOrWhiteSpace(SplunkHecUrl);
-
- ///
- /// Determines if the splunk URL is local
- ///
- public bool IsLocalHost => HasHecUrl &&
- (SplunkHecUrl.ToLower().Contains("127.0.0.1") ||
- SplunkHecUrl.ToLower().Contains("localhost"));
-
- private void CreateHttpClient()
- {
- HttpClient = new HttpClient(SplunkClientHandler);
- HttpClient.BaseAddress = new Uri(SplunkHecUrl);
-
- // Add the HEC token to the request headers for authorization
- HttpClient.DefaultRequestHeaders.Add("Authorization", $"Splunk {SplunkHecToken}");
- }
-
- ///
- /// Disables SSL validation (can be used for insecure https urls)
- /// This overwrites your own httpClientHandler
- ///
- public void DisableSSLValidation()
- {
- var clientHandler = new HttpClientHandler
- {
- ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
- };
-
- SplunkClientHandler = clientHandler;
- CreateHttpClient();
- }
-
- public async Task SendAsync(SplunkPayload splunkPayload)
- {
- if (splunkPayload == null)
- {
- return null;
- }
-
- // Create an event object with the required fields
- var eventObject = new
- {
- @event = splunkPayload.EventData,
- sourcetype = splunkPayload.SourceType,
- host = splunkPayload.Host
- };
-
- // Serialize the event object to JSON
- var eventJson = JsonHelper.ToJson(eventObject);
-
- if (!HasHecToken)
- {
- CreateHttpClient();
- }
-
- // Create an HTTP content with the event data
- var content = new StringContent(eventJson, Encoding.UTF8, "application/json");
-
- // Send the event to Splunk
- var response = await HttpClient.PostAsync("/services/collector/event", content);
-
- return response;
- }
-}
\ No newline at end of file
diff --git a/EonaCat.Logger/Zabbix/ZabbixData.cs b/EonaCat.Logger/Zabbix/ZabbixData.cs
deleted file mode 100644
index 0bfcead..0000000
--- a/EonaCat.Logger/Zabbix/ZabbixData.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-
-///
-/// Zabbix server.
-///
-public class ZabbixData
-{
- public string Host { get; set; }
- public string Key { get; set; }
- public string Value { get; set; }
-
- public ZabbixData(string host, string key, string value)
- {
- Host = host;
- Key = key;
- Value = value;
- }
-}
diff --git a/EonaCat.Logger/Zabbix/ZabbixRequest.cs b/EonaCat.Logger/Zabbix/ZabbixRequest.cs
deleted file mode 100644
index 5c376eb..0000000
--- a/EonaCat.Logger/Zabbix/ZabbixRequest.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using EonaCat.Json;
-using System;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading.Tasks;
-
-public class ZabbixRequest
-{
- private const int BUFFER_SIZE = 1024;
-
- ///
- /// The request to send to the Zabbix server
- ///
- public string Request { get; set; }
-
- ///
- /// The data to send to the Zabbix server
- ///
- public ZabbixData[] Data { get; set; }
-
- public ZabbixRequest(string host, string key, string value)
- {
- Request = "sender data";
- Data = [new ZabbixData(host, key, value)];
- }
-
- ///
- /// Sends the request to the Zabbix server
- ///
- ///
- ///
- ///
- ///
- ///
- public async Task SendAsync(string server, int port = 10051, int timeout = 500)
- {
- string json = JsonHelper.ToJson(new ZabbixRequest(Data[0].Host, Data[0].Key, Data[0].Value));
- using (TcpClient tcpClient = new TcpClient(server, port))
- using (NetworkStream stream = tcpClient.GetStream())
- {
- byte[] header = Encoding.ASCII.GetBytes("ZBXD\x01");
- byte[] dataLength = BitConverter.GetBytes((long)json.Length);
- byte[] content = Encoding.ASCII.GetBytes(json);
- byte[] message = new byte[header.Length + dataLength.Length + content.Length];
-
- Buffer.BlockCopy(header, 0, message, 0, header.Length);
- Buffer.BlockCopy(dataLength, 0, message, header.Length, dataLength.Length);
- Buffer.BlockCopy(content, 0, message, header.Length + dataLength.Length, content.Length);
-
- stream.Write(message, 0, message.Length);
- stream.Flush();
-
- int counter = 0;
- while (!stream.DataAvailable)
- {
- if (counter < timeout / 50)
- {
- counter++;
- await Task.Delay(50).ConfigureAwait(false);
- }
- else
- {
- throw new TimeoutException();
- }
- }
-
- byte[] responseBytes = new byte[BUFFER_SIZE];
- stream.Read(responseBytes, 0, responseBytes.Length);
- string responseAsString = Encoding.UTF8.GetString(responseBytes);
- string jsonResult = responseAsString.Substring(responseAsString.IndexOf('{'));
- return JsonHelper.ToObject(jsonResult);
- }
- }
-}
\ No newline at end of file
diff --git a/EonaCat.Logger/Zabbix/ZabbixResponse.cs b/EonaCat.Logger/Zabbix/ZabbixResponse.cs
deleted file mode 100644
index 2f46c16..0000000
--- a/EonaCat.Logger/Zabbix/ZabbixResponse.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-public class ZabbixResponse
-{
- public string Response { get; set; }
- public string Info { get; set; }
-
-}
diff --git a/Testers/EonaCat.Logger.Test.Web/Program.cs b/Testers/EonaCat.Logger.Test.Web/Program.cs
index 5d8129b..ba8b999 100644
--- a/Testers/EonaCat.Logger.Test.Web/Program.cs
+++ b/Testers/EonaCat.Logger.Test.Web/Program.cs
@@ -183,7 +183,7 @@ async void RunWebLoggingTests()
await file.WriteAsync($"WebLogged: {i}{Environment.NewLine}").ConfigureAwait(false);
}
Console.WriteLine($"WebLogged: {i}");
- Task.Delay(1);
+ await Task.Delay(1);
}
}
@@ -203,10 +203,10 @@ async void RunMaskTest()
using (var file = new StreamWriter(Path.Combine(logger.LogFolder, "testmask.log"), true))
{
- file.WriteAsync(message);
+ await file.WriteAsync(message);
}
Console.WriteLine($"Masked: {i}");
- Task.Delay(1);
+ await Task.Delay(1);
}
}