refine global stats

This commit is contained in:
Jicheng Lu 2025-02-04 15:32:26 -06:00
parent 0aa14205cd
commit e208d1d8ff
11 changed files with 31 additions and 38 deletions

View file

@ -200,7 +200,7 @@ public interface IBotSharpRepository : IHaveServiceProvider
#endregion
#region Statistics
BotSharpStats? GetGlobalStats(string metric, string dimension, string value, DateTime recordTime, StatsInterval interval)
BotSharpStats? GetGlobalStats(string metric, string dimension, string dimRefVal, DateTime recordTime, StatsInterval interval)
=> throw new NotImplementedException();
bool SaveGlobalStats(BotSharpStats body)
=> throw new NotImplementedException();

View file

@ -2,8 +2,7 @@ namespace BotSharp.Abstraction.Statistics.Enums;
public enum StatsInterval
{
Hour = 1,
Day = 2,
Week = 3,
Month = 4
Minute = 1,
Hour = 2,
Day = 3
}

View file

@ -1,6 +1,6 @@
namespace BotSharp.Abstraction.Statistics.Enums;
public static class StatsCategory
public static class StatsMetric
{
public static string AgentLlmCost = "agent-llm-cost";
public static string AgentCall = "agent-call";

View file

@ -10,8 +10,8 @@ public class BotSharpStats
[JsonPropertyName("dimension")]
public string Dimension { get; set; } = null!;
[JsonPropertyName("value")]
public string Value { get; set; } = null!;
[JsonPropertyName("dim_ref_val")]
public string DimRefVal { get; set; } = null!;
[JsonPropertyName("data")]
public IDictionary<string, double> Data { get; set; } = new Dictionary<string, double>();
@ -46,7 +46,7 @@ public class BotSharpStats
public override string ToString()
{
return $"{Metric}-{Dimension}-{Value} ({Interval}): {Data?.Count ?? 0}";
return $"{Metric}-{Dimension}-{DimRefVal} ({Interval}): {Data?.Count ?? 0}";
}
public static (DateTime, DateTime) BuildTimeInterval(DateTime recordTime, StatsInterval interval)
@ -56,20 +56,14 @@ public class BotSharpStats
switch (interval)
{
case StatsInterval.Minute:
startTime = new DateTime(recordTime.Year, recordTime.Month, recordTime.Day, recordTime.Hour, recordTime.Minute, 0);
endTime = startTime.AddMinutes(1);
break;
case StatsInterval.Hour:
startTime = new DateTime(recordTime.Year, recordTime.Month, recordTime.Day, recordTime.Hour, 0, 0);
endTime = startTime.AddHours(1);
break;
case StatsInterval.Week:
var dayOfWeek = startTime.DayOfWeek;
var firstDayOfWeek = startTime.AddDays(-(int)dayOfWeek);
startTime = new DateTime(firstDayOfWeek.Year, firstDayOfWeek.Month, firstDayOfWeek.Day, 0, 0, 0);
endTime = startTime.AddDays(7);
break;
case StatsInterval.Month:
startTime = new DateTime(recordTime.Year, recordTime.Month, 1);
endTime = startTime.AddMonths(1);
break;
default:
startTime = new DateTime(recordTime.Year, recordTime.Month, recordTime.Day, 0, 0, 0);
endTime = startTime.AddDays(1);

View file

@ -6,7 +6,7 @@ public class BotSharpStatsInput
{
public string Metric { get; set; }
public string Dimension { get; set; }
public string Value { get; set; }
public string DimRefVal { get; set; }
public List<StatsKeyValuePair> Data { get; set; } = [];
public DateTime RecordTime { get; set; } = DateTime.UtcNow;
public StatsInterval IntervalType { get; set; } = StatsInterval.Day;

View file

@ -63,9 +63,9 @@ public class TokenStatistics : ITokenStatistics
var globalStats = _services.GetRequiredService<IBotSharpStatsService>();
var body = new BotSharpStatsInput
{
Metric = StatsCategory.AgentLlmCost,
Metric = StatsMetric.AgentLlmCost,
Dimension = "agent",
Value = message.CurrentAgentId,
DimRefVal = message.CurrentAgentId,
RecordTime = DateTime.UtcNow,
IntervalType = StatsInterval.Day,
Data = [

View file

@ -4,7 +4,7 @@ namespace BotSharp.Core.Repository;
public partial class FileRepository
{
public BotSharpStats? GetGlobalStats(string metric, string dimension, string value, DateTime recordTime, StatsInterval interval)
public BotSharpStats? GetGlobalStats(string metric, string dimension, string dimRefVal, DateTime recordTime, StatsInterval interval)
{
var baseDir = Path.Combine(_dbSettings.FileRepository, STATS_FOLDER);
var (startTime, endTime) = BotSharpStats.BuildTimeInterval(recordTime, interval);
@ -18,7 +18,7 @@ public partial class FileRepository
var list = JsonSerializer.Deserialize<List<BotSharpStats>>(text, _options);
var found = list?.FirstOrDefault(x => x.Metric.IsEqualTo(metric)
&& x.Dimension.IsEqualTo(dimension)
&& x.Value.IsEqualTo(value)
&& x.DimRefVal.IsEqualTo(dimRefVal)
&& x.StartTime == startTime
&& x.EndTime == endTime);
@ -50,7 +50,7 @@ public partial class FileRepository
var list = JsonSerializer.Deserialize<List<BotSharpStats>>(text, _options);
var found = list?.FirstOrDefault(x => x.Metric.IsEqualTo(body.Metric)
&& x.Dimension.IsEqualTo(body.Dimension)
&& x.Value.IsEqualTo(body.Value)
&& x.DimRefVal.IsEqualTo(body.DimRefVal)
&& x.StartTime == startTime
&& x.EndTime == endTime);
@ -58,7 +58,7 @@ public partial class FileRepository
{
found.Metric = body.Metric;
found.Dimension = body.Dimension;
found.Value = body.Value;
found.DimRefVal = body.DimRefVal;
found.Data = body.Data;
found.RecordTime = body.RecordTime;
found.StartTime = body.StartTime;

View file

@ -31,7 +31,7 @@ public class BotSharpStatsService : IBotSharpStatsService
|| input == null
|| string.IsNullOrEmpty(input.Metric)
|| string.IsNullOrEmpty(input.Dimension)
|| string.IsNullOrEmpty(input.Value)
|| string.IsNullOrEmpty(input.DimRefVal)
|| input.Data.IsNullOrEmpty())
{
return false;
@ -41,14 +41,14 @@ public class BotSharpStatsService : IBotSharpStatsService
var res = locker.Lock(resourceKey, () =>
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var body = db.GetGlobalStats(input.Metric, input.Dimension, input.Value, input.RecordTime, input.IntervalType);
var body = db.GetGlobalStats(input.Metric, input.Dimension, input.DimRefVal, input.RecordTime, input.IntervalType);
if (body == null)
{
var stats = new BotSharpStats
{
Metric = input.Metric,
Dimension = input.Dimension,
Value = input.Value,
DimRefVal = input.DimRefVal,
RecordTime = input.RecordTime,
IntervalType = input.IntervalType,
Data = input.Data.ToDictionary(x => x.Key, x => x.Value)
@ -89,7 +89,7 @@ public class BotSharpStatsService : IBotSharpStatsService
}
catch (Exception ex)
{
_logger.LogError($"Error when updating global stats {input.Metric}-{input.Dimension}-{input.Value}. {ex.Message}\r\n{ex.InnerException}");
_logger.LogError($"Error when updating global stats {input.Metric}-{input.Dimension}-{input.DimRefVal}. {ex.Message}\r\n{ex.InnerException}");
return false;
}
}

View file

@ -31,9 +31,9 @@ public class GlobalStatsConversationHook : ConversationHookBase
var body = new BotSharpStatsInput
{
Metric = StatsCategory.AgentCall,
Metric = StatsMetric.AgentCall,
Dimension = "agent",
Value = message.CurrentAgentId,
DimRefVal = message.CurrentAgentId,
RecordTime = DateTime.UtcNow,
IntervalType = StatsInterval.Day,
Data = [

View file

@ -4,7 +4,7 @@ public class GlobalStatisticsDocument : MongoBase
{
public string Metric { get; set; }
public string Dimension { get; set; }
public string Value { get; set; }
public string DimRefVal { get; set; }
public IDictionary<string, double> Data { get; set; } = new Dictionary<string, double>();
public DateTime RecordTime { get; set; }
public DateTime StartTime { get; set; }

View file

@ -5,7 +5,7 @@ namespace BotSharp.Plugin.MongoStorage.Repository;
public partial class MongoRepository
{
public BotSharpStats? GetGlobalStats(string metric, string dimension, string value, DateTime recordTime, StatsInterval interval)
public BotSharpStats? GetGlobalStats(string metric, string dimension, string dimRefVal, DateTime recordTime, StatsInterval interval)
{
var (startTime, endTime) = BotSharpStats.BuildTimeInterval(recordTime, interval);
@ -14,7 +14,7 @@ public partial class MongoRepository
{
builder.Eq(x => x.Metric, metric),
builder.Eq(x => x.Dimension, dimension),
builder.Eq(x => x.Value, value),
builder.Eq(x => x.DimRefVal, dimRefVal),
builder.Eq(x => x.StartTime, startTime),
builder.Eq(x => x.EndTime, endTime)
};
@ -27,7 +27,7 @@ public partial class MongoRepository
{
Metric = found.Metric,
Dimension = found.Dimension,
Value = found.Value,
DimRefVal = found.DimRefVal,
Data = found.Data,
RecordTime = found.RecordTime,
StartTime = startTime,
@ -48,7 +48,7 @@ public partial class MongoRepository
{
builder.Eq(x => x.Metric, body.Metric),
builder.Eq(x => x.Dimension, body.Dimension),
builder.Eq(x => x.Value, body.Value),
builder.Eq(x => x.DimRefVal, body.DimRefVal),
builder.Eq(x => x.StartTime, startTime),
builder.Eq(x => x.EndTime, endTime)
};
@ -58,7 +58,7 @@ public partial class MongoRepository
.SetOnInsert(x => x.Id, Guid.NewGuid().ToString())
.Set(x => x.Metric, body.Metric)
.Set(x => x.Dimension, body.Dimension)
.Set(x => x.Value, body.Value)
.Set(x => x.DimRefVal, body.DimRefVal)
.Set(x => x.Data, body.Data)
.Set(x => x.StartTime, body.StartTime)
.Set(x => x.EndTime, body.EndTime)