using System; using System.Collections.Generic; using System.Net; using System.Net.Http.Json; using System.Threading.Tasks; using ColdMint.scripts.debug; using HttpClient = System.Net.Http.HttpClient; namespace ColdMint.scripts.openObserve; /// /// LogCollector /// 日志收集器 /// public static class LogCollector { private static readonly List LogDataList = []; /// /// Automatic upload threshold /// 自动上传的阈值 /// /// ///An attempt is made to upload logs when messages reach this number. ///当消息到达此数量后将尝试上传日志。 /// public static int UploadThreshold { get; set; } = 300; private static bool _lockList; /// /// httpClient /// Http客户 /// private static HttpClient? _httpClient; private static string? _orgId; private static string? _streamName; /// /// CanUploadLog /// 是否能上传日志 /// public static bool CanUploadLog => _httpClient != null; /// /// UpdateHttpClient /// 更新Http客户端 /// /// public static void UpdateHttpClient(OpenObserve openObserve) { if (openObserve.Address == null || openObserve.AccessToken == null || openObserve.OrgId == null || openObserve.StreamName == null) { return; } var httpClient = new HttpClient(); httpClient.BaseAddress = new Uri(openObserve.Address); //Add a Cookie to the request header //添加Cookie到请求头 var cookie = new Cookie("auth_tokens", "{\"access_token\":\"Basic " + openObserve.AccessToken + "\",\"refresh_token\":\"\"}"); httpClient.DefaultRequestHeaders.Add("Cookie", cookie.ToString()); _httpClient = httpClient; _orgId = openObserve.OrgId; _streamName = openObserve.StreamName; } /// /// Push log /// 推送日志 /// /// private static async Task PostLog(List logRequestBean) { if (_httpClient == null) { return; } _lockList = true; LogCat.LogWithFormat("start_uploading", label: LogCat.LogLabel.LogCollector, false, logRequestBean.Count); var httpResponseMessage = await _httpClient.PostAsJsonAsync("/api/" + _orgId + "/" + _streamName + "/_json", logRequestBean); _lockList = false; if (httpResponseMessage.IsSuccessStatusCode) { LogDataList.RemoveRange(0, logRequestBean.Count); LogCat.LogWithFormat("upload_successful", label: LogCat.LogLabel.LogCollector, false, logRequestBean.Count, LogDataList.Count); if (LogDataList.Count > UploadThreshold) { //After the upload succeeds, if the threshold is still met, continue uploading. //上传成功后,如果依然满足阈值,那么继续上传。 await PostLog(LogDataList.GetRange(0, UploadThreshold)); } } else { LogCat.LogWithFormat("upload_failed", label: LogCat.LogLabel.LogCollector, false, httpResponseMessage.StatusCode.ToString(), LogDataList.Count); } } /// /// Push log information to the cache /// 推送日志信息到缓存 /// /// ///Log data ///日志信息 /// /// ///When logs reach the upload threshold, logs are automatically uploaded. ///当日志信息到达上传阈值后会自动上传。 /// public static async Task Push(LogData logData) { LogDataList.Add(logData); LogCat.LogWithFormat("upload_status", LogCat.LogLabel.LogCollector, false, LogDataList.Count, UploadThreshold); if (!_lockList && LogDataList.Count > UploadThreshold) { //执行上传 await PostLog(LogDataList.GetRange(0, UploadThreshold)); } } } public class LogData { /// /// The AppId of this application /// 此应用的AppId /// public string? AppId { get; set; } /// /// message /// 消息 /// // ReSharper disable UnusedAutoPropertyAccessor.Global public string? Message { get; set; } // ReSharper restore UnusedAutoPropertyAccessor.Global /// /// level /// 错误等级 /// // ReSharper disable UnusedAutoPropertyAccessor.Global public int Level { get; set; } // ReSharper restore UnusedAutoPropertyAccessor.Global }