189 lines
5.7 KiB
C#
189 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using EonaCat.Json;
|
|
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.
|
|
|
|
namespace EonaCat.Logger.Servers.Splunk
|
|
{
|
|
/// <summary>
|
|
/// Splunk Server.
|
|
/// </summary>
|
|
public class Splunk : IDisposable
|
|
{
|
|
private string _splunkHecUrl = "https://127.0.0.1:8088/services/collector/event";
|
|
private HttpClient _httpClient;
|
|
private HttpClientHandler _httpClientHandler;
|
|
private bool _disposed;
|
|
|
|
public event EventHandler<Exception> OnException;
|
|
|
|
public string SplunkHecToken { get; set; } = "splunk-hec-token";
|
|
public string Nickname { get; set; }
|
|
public List<ELogType> TypesToLog { get; set; }
|
|
|
|
public string SplunkHecUrl
|
|
{
|
|
get => _splunkHecUrl;
|
|
set
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
throw new ArgumentNullException(nameof(SplunkHecUrl));
|
|
}
|
|
|
|
_splunkHecUrl = value.StartsWith("http", StringComparison.OrdinalIgnoreCase)
|
|
? value
|
|
: $"http://{value}";
|
|
|
|
RecreateHttpClient();
|
|
}
|
|
}
|
|
|
|
public bool HasHecToken => !string.IsNullOrWhiteSpace(SplunkHecToken) && SplunkHecToken != "splunk-hec-token";
|
|
public bool HasHecUrl => !string.IsNullOrWhiteSpace(_splunkHecUrl);
|
|
public bool IsHttpsHecUrl => _splunkHecUrl.StartsWith("https", StringComparison.OrdinalIgnoreCase);
|
|
public bool IsLocalHost => _splunkHecUrl.Contains("127.0.0.1") || _splunkHecUrl.Contains("localhost");
|
|
|
|
public Splunk(string splunkHecUrl, string splunkHecToken, HttpClientHandler handler = null, string nickName = null, List<ELogType> typesToLog = null)
|
|
{
|
|
SplunkHecToken = splunkHecToken ?? throw new ArgumentNullException(nameof(splunkHecToken));
|
|
SplunkHecUrl = splunkHecUrl ?? throw new ArgumentNullException(nameof(splunkHecUrl));
|
|
Nickname = nickName ?? $"{splunkHecUrl}_{splunkHecToken}";
|
|
TypesToLog = typesToLog;
|
|
|
|
_httpClientHandler = handler ?? new HttpClientHandler();
|
|
CreateHttpClient();
|
|
}
|
|
|
|
private void CreateHttpClient()
|
|
{
|
|
DisposeHttpClient();
|
|
|
|
_httpClientHandler ??= new HttpClientHandler();
|
|
_httpClient = new HttpClient(_httpClientHandler)
|
|
{
|
|
BaseAddress = new Uri(SplunkHecUrl)
|
|
};
|
|
|
|
if (!_httpClient.DefaultRequestHeaders.Contains("Authorization"))
|
|
{
|
|
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Splunk {SplunkHecToken}");
|
|
}
|
|
}
|
|
|
|
private void RecreateHttpClient()
|
|
{
|
|
DisposeHttpClient();
|
|
_httpClientHandler = new HttpClientHandler();
|
|
CreateHttpClient();
|
|
}
|
|
|
|
public void DisableSSLValidation()
|
|
{
|
|
DisposeHttpClient();
|
|
_httpClientHandler = new HttpClientHandler
|
|
{
|
|
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
|
};
|
|
CreateHttpClient();
|
|
}
|
|
|
|
public async Task<HttpResponseMessage> SendAsync(SplunkPayload payload, bool disableSplunkSSL = false)
|
|
{
|
|
if (_disposed)
|
|
{
|
|
throw new ObjectDisposedException(nameof(Splunk));
|
|
}
|
|
|
|
try
|
|
{
|
|
if (payload == null || !HasHecToken || !HasHecUrl)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (disableSplunkSSL)
|
|
{
|
|
DisableSSLValidation();
|
|
}
|
|
|
|
_httpClient ??= new HttpClient(_httpClientHandler ?? new HttpClientHandler())
|
|
{
|
|
BaseAddress = new Uri(SplunkHecUrl)
|
|
};
|
|
|
|
var eventObject = new
|
|
{
|
|
@event = payload.EventData,
|
|
sourcetype = payload.SourceType,
|
|
host = payload.Host
|
|
};
|
|
|
|
var json = JsonHelper.ToJson(eventObject);
|
|
|
|
using var request = new HttpRequestMessage(HttpMethod.Post, "services/collector/event")
|
|
{
|
|
Content = new StringContent(json, Encoding.UTF8, "application/json")
|
|
};
|
|
|
|
return await _httpClient.SendAsync(request).ConfigureAwait(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
OnException?.Invoke(this, ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal void DisposeHttpClient()
|
|
{
|
|
try
|
|
{
|
|
_httpClient?.Dispose();
|
|
_httpClientHandler?.Dispose();
|
|
}
|
|
catch
|
|
{
|
|
// Silent fail
|
|
}
|
|
finally
|
|
{
|
|
_httpClient = null;
|
|
_httpClientHandler = null;
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (_disposed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_disposed = true;
|
|
|
|
if (disposing)
|
|
{
|
|
DisposeHttpClient();
|
|
}
|
|
}
|
|
|
|
~Splunk()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
}
|
|
}
|