|
@@ -3,6 +3,7 @@ using System.Net.Http.Headers;
|
|
|
using System.Net.Http;
|
|
|
|
|
|
using Vit.Extensions;
|
|
|
+using System.Collections.Concurrent;
|
|
|
|
|
|
namespace Vit.Core.Module.Log.LogCollector.Splunk
|
|
|
{
|
|
@@ -16,6 +17,10 @@ namespace Vit.Core.Module.Log.LogCollector.Splunk
|
|
|
|
|
|
public string authToken;
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 若指定则在指定时间间隔统一推送数据,若不指定则立即推送。单位:ms
|
|
|
+ /// </summary>
|
|
|
+ public int? intervalMs;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 默认 "Splunk"
|
|
@@ -28,22 +33,82 @@ namespace Vit.Core.Module.Log.LogCollector.Splunk
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
public void Init()
|
|
|
{
|
|
|
- httpClient = new System.Net.Http.HttpClient();
|
|
|
+ //信任所有的证书
|
|
|
+ var HttpHandler = new HttpClientHandler
|
|
|
+ {
|
|
|
+ ServerCertificateCustomValidationCallback = (a, b, c, d) => true
|
|
|
+ };
|
|
|
+ httpClient = new System.Net.Http.HttpClient(HttpHandler);
|
|
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AUTH_SCHEME ?? "Splunk", authToken);
|
|
|
if (!httpClient.DefaultRequestHeaders.Contains(SPLUNK_REQUEST_CHANNEL ?? "X-Splunk-Request-Channel"))
|
|
|
{
|
|
|
httpClient.DefaultRequestHeaders.Add(SPLUNK_REQUEST_CHANNEL ?? "X-Splunk-Request-Channel", Guid.NewGuid().ToString());
|
|
|
}
|
|
|
+
|
|
|
+ InitTimer();
|
|
|
}
|
|
|
|
|
|
- private System.Net.Http.HttpClient httpClient = null;
|
|
|
|
|
|
|
|
|
|
|
|
- public void SendAsync(SplunkRecord record)
|
|
|
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
|
|
+ public void SendAsync(SplunkRecord record)
|
|
|
+ {
|
|
|
+ if (recordList == null)
|
|
|
+ SendToServer(record);
|
|
|
+ else
|
|
|
+ recordList.Add(record);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ ~SplunkClient()
|
|
|
+ {
|
|
|
+ if (time != null)
|
|
|
+ {
|
|
|
+ time?.Stop();
|
|
|
+ time = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ #region Timer
|
|
|
+ ConcurrentBag<SplunkRecord> recordList;
|
|
|
+ ConcurrentBag<SplunkRecord> recordList_Swap;
|
|
|
+ Util.Threading.Timer.SersTimer_SingleThread time;
|
|
|
+
|
|
|
+ private void InitTimer()
|
|
|
+ {
|
|
|
+ if (intervalMs.HasValue && intervalMs.Value > 0)
|
|
|
+ {
|
|
|
+ recordList = new ConcurrentBag<SplunkRecord>();
|
|
|
+ recordList_Swap = new ConcurrentBag<SplunkRecord>();
|
|
|
+ time = new Util.Threading.Timer.SersTimer_SingleThread();
|
|
|
+ time.intervalMs = intervalMs.Value;
|
|
|
+ time.timerCallback = (e) =>
|
|
|
+ {
|
|
|
+ (recordList_Swap, recordList) = (recordList, recordList_Swap);
|
|
|
+ if (recordList_Swap.Count > 0)
|
|
|
+ {
|
|
|
+ SendToServer(recordList_Swap);
|
|
|
+ while (recordList_Swap.TryTake(out _)) ;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ time.Start();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private System.Net.Http.HttpClient httpClient = null;
|
|
|
+
|
|
|
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
|
|
+ private void SendToServer(object record)
|
|
|
{
|
|
|
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
|
|
request.Content = new StringContent(record.Serialize(), Vit.Core.Module.Serialization.Serialization_Newtonsoft.defaultEncoding, "application/json");
|
|
@@ -52,7 +117,7 @@ namespace Vit.Core.Module.Log.LogCollector.Splunk
|
|
|
// batch: batchIntervalInSeconds, batchSizeLimit, queueLimit
|
|
|
httpClient.SendAsync(request);
|
|
|
|
|
|
- //var strMsg = msgBody.Serialize();
|
|
|
+ //var strMsg = record.Serialize();
|
|
|
//var response = httpClient.SendAsync(request).Result;
|
|
|
}
|
|
|
}
|