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
}