Merge pull request #158 from Moonlight-Panel/ImproveStatistics
Added better statistics calculation and active user messurement
This commit is contained in:
commit
0a1b93b8fb
|
@ -43,6 +43,7 @@ public class User
|
|||
// Date stuff
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
|
||||
public DateTime LastVisitedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Subscriptions
|
||||
|
||||
|
|
1059
Moonlight/App/Database/Migrations/20230611152138_AddLastVisitedTimestamp.Designer.cs
generated
Normal file
1059
Moonlight/App/Database/Migrations/20230611152138_AddLastVisitedTimestamp.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.App.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddLastVisitedTimestamp : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "LastVisitedAt",
|
||||
table: "Users",
|
||||
type: "datetime(6)",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LastVisitedAt",
|
||||
table: "Users");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -762,6 +762,9 @@ namespace Moonlight.App.Database.Migrations
|
|||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("LastVisitedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
|
39
Moonlight/App/Helpers/AvgHelper.cs
Normal file
39
Moonlight/App/Helpers/AvgHelper.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Helpers;
|
||||
|
||||
public static class AvgHelper
|
||||
{
|
||||
public static StatisticsData[] Calculate(StatisticsData[] data, int splitSize = 40)
|
||||
{
|
||||
if (data.Length <= splitSize)
|
||||
return data;
|
||||
|
||||
var result = new List<StatisticsData>();
|
||||
|
||||
var i = data.Length / (float)splitSize;
|
||||
var pc = (int)Math.Round(i);
|
||||
|
||||
foreach (var part in data.Chunk(pc))
|
||||
{
|
||||
double d = 0;
|
||||
var res = new StatisticsData();
|
||||
|
||||
foreach (var entry in part)
|
||||
{
|
||||
d += entry.Value;
|
||||
}
|
||||
|
||||
res.Chart = part.First().Chart;
|
||||
res.Date = part.First().Date;
|
||||
|
||||
if (d == 0)
|
||||
res.Value = 0;
|
||||
|
||||
res.Value = d / part.Length;
|
||||
result.Add(res);
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ namespace Moonlight.App.Services.Sessions;
|
|||
public class SessionService
|
||||
{
|
||||
private readonly SessionRepository SessionRepository;
|
||||
private Repository<User> UserRepository;
|
||||
private readonly IdentityService IdentityService;
|
||||
private readonly NavigationManager NavigationManager;
|
||||
private readonly AlertService AlertService;
|
||||
|
@ -21,13 +22,15 @@ public class SessionService
|
|||
IdentityService identityService,
|
||||
NavigationManager navigationManager,
|
||||
AlertService alertService,
|
||||
DateTimeService dateTimeService)
|
||||
DateTimeService dateTimeService,
|
||||
Repository<User> userRepository)
|
||||
{
|
||||
SessionRepository = sessionRepository;
|
||||
IdentityService = identityService;
|
||||
NavigationManager = navigationManager;
|
||||
AlertService = alertService;
|
||||
DateTimeService = dateTimeService;
|
||||
UserRepository = userRepository;
|
||||
}
|
||||
|
||||
public async Task Register()
|
||||
|
@ -46,6 +49,12 @@ public class SessionService
|
|||
};
|
||||
|
||||
SessionRepository.Add(OwnSession);
|
||||
|
||||
if (user != null) // Track last session init of user as last visited timestamp
|
||||
{
|
||||
user.LastVisitedAt = DateTimeService.GetCurrent();
|
||||
UserRepository.Update(user);
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
|
|
|
@ -7,20 +7,33 @@ namespace Moonlight.App.Services.Statistics;
|
|||
public class StatisticsViewService
|
||||
{
|
||||
private readonly StatisticsRepository StatisticsRepository;
|
||||
private readonly Repository<User> UserRepository;
|
||||
private readonly DateTimeService DateTimeService;
|
||||
|
||||
public StatisticsViewService(StatisticsRepository statisticsRepository, DateTimeService dateTimeService)
|
||||
public StatisticsViewService(StatisticsRepository statisticsRepository, DateTimeService dateTimeService, Repository<User> userRepository)
|
||||
{
|
||||
StatisticsRepository = statisticsRepository;
|
||||
DateTimeService = dateTimeService;
|
||||
UserRepository = userRepository;
|
||||
}
|
||||
|
||||
public StatisticsData[] GetData(string chart, StatisticsTimeSpan timeSpan)
|
||||
{
|
||||
var startDate = DateTimeService.GetCurrent() - TimeSpan.FromHours((int)timeSpan);
|
||||
|
||||
var objs = StatisticsRepository.Get().Where(x => x.Date > startDate && x.Chart == chart);
|
||||
var objs = StatisticsRepository
|
||||
.Get()
|
||||
.Where(x => x.Date > startDate && x.Chart == chart);
|
||||
|
||||
return objs.ToArray();
|
||||
}
|
||||
|
||||
public int GetActiveUsers(StatisticsTimeSpan timeSpan)
|
||||
{
|
||||
var startDate = DateTimeService.GetCurrent() - TimeSpan.FromHours((int)timeSpan);
|
||||
|
||||
return UserRepository
|
||||
.Get()
|
||||
.Count(x => x.LastVisitedAt > startDate);
|
||||
}
|
||||
}
|
|
@ -66,6 +66,20 @@
|
|||
}
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="card mt-4">
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<TL>Active users</TL>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<span class="fs-2">@(ActiveUsers)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</LazyLoader>
|
||||
</OnlyAdmin>
|
||||
|
||||
|
@ -73,7 +87,9 @@
|
|||
{
|
||||
private StatisticsTimeSpan StatisticsTimeSpan = StatisticsTimeSpan.Day;
|
||||
private LazyLoader Loader;
|
||||
|
||||
private Dictionary<string, StatisticsData[]> Charts = new();
|
||||
private int ActiveUsers = 0;
|
||||
|
||||
private int TimeSpanBind
|
||||
{
|
||||
|
@ -91,34 +107,48 @@
|
|||
|
||||
Charts.Add(
|
||||
SmartTranslateService.Translate("Servers"),
|
||||
StatisticsViewService.GetData("serversCount", StatisticsTimeSpan)
|
||||
AvgHelper.Calculate(
|
||||
StatisticsViewService.GetData("serversCount", StatisticsTimeSpan)
|
||||
)
|
||||
);
|
||||
|
||||
Charts.Add(
|
||||
SmartTranslateService.Translate("Users"),
|
||||
StatisticsViewService.GetData("usersCount", StatisticsTimeSpan)
|
||||
AvgHelper.Calculate(
|
||||
StatisticsViewService.GetData("usersCount", StatisticsTimeSpan)
|
||||
)
|
||||
);
|
||||
|
||||
Charts.Add(
|
||||
SmartTranslateService.Translate("Domains"),
|
||||
StatisticsViewService.GetData("domainsCount", StatisticsTimeSpan)
|
||||
AvgHelper.Calculate(
|
||||
StatisticsViewService.GetData("domainsCount", StatisticsTimeSpan)
|
||||
)
|
||||
);
|
||||
|
||||
Charts.Add(
|
||||
SmartTranslateService.Translate("Databases"),
|
||||
StatisticsViewService.GetData("databasesCount", StatisticsTimeSpan)
|
||||
AvgHelper.Calculate(
|
||||
StatisticsViewService.GetData("databasesCount", StatisticsTimeSpan)
|
||||
)
|
||||
);
|
||||
|
||||
Charts.Add(
|
||||
SmartTranslateService.Translate("Webspaces"),
|
||||
StatisticsViewService.GetData("webspacesCount", StatisticsTimeSpan)
|
||||
AvgHelper.Calculate(
|
||||
StatisticsViewService.GetData("webspacesCount", StatisticsTimeSpan)
|
||||
)
|
||||
);
|
||||
|
||||
Charts.Add(
|
||||
SmartTranslateService.Translate("Sessions"),
|
||||
StatisticsViewService.GetData("sessionsCount", StatisticsTimeSpan)
|
||||
AvgHelper.Calculate(
|
||||
StatisticsViewService.GetData("sessionsCount", StatisticsTimeSpan)
|
||||
)
|
||||
);
|
||||
|
||||
ActiveUsers = StatisticsViewService.GetActiveUsers(StatisticsTimeSpan);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue