wabbajack/Wabbajack.Server/DataLayer/Metrics.cs

189 lines
7.4 KiB
C#
Raw Normal View History

2020-06-14 13:13:29 +00:00
using System;
using System.Collections.Generic;
2020-05-09 13:04:38 +00:00
using System.Linq;
using System.Threading.Tasks;
using Dapper;
using Wabbajack.Server.DTOs;
2021-10-23 16:51:17 +00:00
namespace Wabbajack.Server.DataLayer;
public partial class SqlService
{
2021-10-23 16:51:17 +00:00
public async Task IngestMetric(Metric metric)
{
2021-10-23 16:51:17 +00:00
await using var conn = await Open();
await conn.ExecuteAsync(
@"INSERT INTO dbo.Metrics (Timestamp, Action, Subject, MetricsKey) VALUES (@Timestamp, @Action, @Subject, @MetricsKey)",
metric);
}
public async Task IngestAccess(string ip, string log)
{
await using var conn = await Open();
await conn.ExecuteAsync(@"INSERT INTO dbo.AccessLog (Timestamp, Action, Ip) VALUES (@Timestamp, @Action, @Ip)",
new
2020-06-14 13:13:29 +00:00
{
Timestamp = DateTime.UtcNow,
Ip = ip,
Action = log
});
2021-10-23 16:51:17 +00:00
}
public async Task<IEnumerable<AggregateMetric>> MetricsReport(string action)
{
await using var conn = await Open();
return (await conn.QueryAsync<AggregateMetric>(@"
select
datefromparts(datepart(YEAR,Timestamp), datepart(MONTH,Timestamp), datepart(DAY,Timestamp)) as Date,
GroupingSubject as Subject,
count(*) as Count
from dbo.metrics where
Action = @Action
AND GroupingSubject in (select DISTINCT GroupingSubject from dbo.Metrics
WHERE action = @Action
AND MetricsKey is not null
AND Subject != 'Default'
AND Subject != 'untitled'
AND TRY_CONVERT(uniqueidentifier, Subject) is null
AND Timestamp >= DATEADD(DAY, -1, GETUTCDATE()))
group by
datefromparts(datepart(YEAR,Timestamp), datepart(MONTH,Timestamp), datepart(DAY,Timestamp)),
GroupingSubject
2021-10-23 16:51:17 +00:00
Order by datefromparts(datepart(YEAR,Timestamp), datepart(MONTH,Timestamp), datepart(DAY,Timestamp)) asc",
new {Action = action}))
.ToList();
}
2020-06-15 04:05:00 +00:00
2021-10-23 16:51:17 +00:00
public async Task<List<(DateTime, string, string)>> FullTarReport(string key)
{
await using var conn = await Open();
return (await conn.QueryAsync<(DateTime, string, string)>(@"
2020-06-15 04:05:00 +00:00
SELECT u.Timestamp, u.Path, u.MetricsKey FROM
(SELECT al.Timestamp, JSON_VALUE(al.Action, '$.Path') as Path, al.MetricsKey FROM dbo.AccessLog al
2020-06-16 22:21:01 +00:00
WHERE al.MetricsKey = @MetricsKey
2020-06-15 04:05:00 +00:00
UNION ALL
SELECT m.Timestamp, m.Action + ' ' + m.Subject as Path, m.MetricsKey FROM dbo.Metrics m
2020-06-16 22:21:01 +00:00
WHERE m.MetricsKey = @MetricsKey
AND m.Action != 'TarKey') u
2020-06-15 04:05:00 +00:00
ORDER BY u.Timestamp Desc",
2021-10-23 16:51:17 +00:00
new {MetricsKey = key})).ToList();
}
2020-06-16 22:21:01 +00:00
2021-10-23 16:51:17 +00:00
public async Task<bool> ValidMetricsKey(string metricsKey)
{
await using var conn = await Open();
return await conn.QuerySingleOrDefaultAsync<string>(
"SELECT TOP(1) MetricsKey from dbo.MetricsKeys Where MetricsKey = @MetricsKey",
new {MetricsKey = metricsKey}) != default;
}
2021-02-18 05:44:54 +00:00
2021-10-23 16:51:17 +00:00
public async Task AddMetricsKey(string metricsKey)
{
await using var conn = await Open();
await using var trans = conn.BeginTransaction();
2021-02-18 05:44:54 +00:00
2021-10-23 16:51:17 +00:00
if (await conn.QuerySingleOrDefaultAsync<string>(
2021-02-18 05:44:54 +00:00
"SELECT TOP(1) MetricsKey from dbo.MetricsKeys Where MetricsKey = @MetricsKey",
2021-10-23 16:51:17 +00:00
new {MetricsKey = metricsKey}, trans) != default)
return;
2021-02-18 05:44:54 +00:00
2021-10-23 16:51:17 +00:00
await conn.ExecuteAsync("INSERT INTO dbo.MetricsKeys (MetricsKey) VALUES (@MetricsKey)",
new {MetricsKey = metricsKey}, trans);
}
2020-07-07 20:17:49 +00:00
2021-10-23 16:51:17 +00:00
public async Task<string[]> AllKeys()
{
await using var conn = await Open();
return (await conn.QueryAsync<string>("SELECT MetricsKey from dbo.MetricsKeys")).ToArray();
}
2020-07-07 20:17:49 +00:00
2021-10-23 16:51:17 +00:00
public async Task<long> UniqueInstalls(string machineUrl)
{
await using var conn = await Open();
return await conn.QueryFirstAsync<long>(
@"SELECT COUNT(*) FROM (
2020-07-07 20:17:49 +00:00
SELECT DISTINCT MetricsKey from dbo.Metrics where Action = 'finish_install' and GroupingSubject in (
SELECT JSON_VALUE(Metadata, '$.title') FROM dbo.ModLists
WHERE JSON_VALUE(Metadata, '$.links.machineURL') = @MachineURL)) s",
2021-10-23 16:51:17 +00:00
new {MachineURL = machineUrl});
}
public async Task<long> TotalInstalls(string machineUrl)
{
await using var conn = await Open();
return await conn.QueryFirstAsync<long>(
@"SELECT COUNT(*) from dbo.Metrics where Action = 'finish_install' and GroupingSubject in (
2020-07-07 20:17:49 +00:00
SELECT JSON_VALUE(Metadata, '$.title') FROM dbo.ModLists
WHERE JSON_VALUE(Metadata, '$.links.machineURL') = @MachineURL)",
2021-10-23 16:51:17 +00:00
new {MachineURL = machineUrl});
}
2021-02-17 05:46:05 +00:00
2021-10-23 16:51:17 +00:00
public async Task<IEnumerable<(string, long)>> GetTotalInstalls()
{
await using var conn = await Open();
return await conn.QueryAsync<(string, long)>(
@"SELECT GroupingSubject, Count(*) as Count
2021-02-17 05:46:05 +00:00
From dbo.Metrics
WHERE
GroupingSubject in (select DISTINCT GroupingSubject from dbo.Metrics
WHERE action = 'finish_install'
AND MetricsKey is not null)
group by GroupingSubject
order by Count(*) desc");
2021-10-23 16:51:17 +00:00
}
public async Task<IEnumerable<(string, long)>> GetTotalUniqueInstalls()
{
await using var conn = await Open();
return await conn.QueryAsync<(string, long)>(
@"Select GroupingSubject, Count(*) as Count
2021-02-17 05:46:05 +00:00
FROM
(select DISTINCT MetricsKey, GroupingSubject
From dbo.Metrics
WHERE
GroupingSubject in (select DISTINCT GroupingSubject from dbo.Metrics
WHERE action = 'finish_install'
AND MetricsKey is not null)) m
GROUP BY GroupingSubject
Order by Count(*) desc
");
2021-10-23 16:51:17 +00:00
}
public async IAsyncEnumerable<MetricRow> MetricsDump()
{
var keys = new Dictionary<string, long>();
2021-02-17 05:46:05 +00:00
2021-10-23 16:51:17 +00:00
await using var conn = await Open();
foreach (var row in await conn.QueryAsync<(long, DateTime, string, string, string, string)>(
@"select Id, Timestamp, Action, Subject, MetricsKey, GroupingSubject from dbo.metrics WHERE MetricsKey is not null"))
2021-02-17 05:46:05 +00:00
{
2021-10-23 16:51:17 +00:00
if (!keys.TryGetValue(row.Item5, out var keyid))
2021-02-17 05:46:05 +00:00
{
2021-10-23 16:51:17 +00:00
keyid = keys.Count;
keys[row.Item5] = keyid;
2021-02-17 05:46:05 +00:00
}
2021-10-23 16:51:17 +00:00
yield return new MetricRow
{
Id = row.Item1,
Timestamp = row.Item2,
Action = row.Item3,
Subject = row.Item4,
MetricsKey = keyid,
GroupingSubject = row.Item6
};
2021-02-17 05:46:05 +00:00
}
}
2021-10-23 16:51:17 +00:00
public class MetricRow
{
public string Action;
public string GroupingSubject;
public long Id;
public long MetricsKey;
public string Subject;
public DateTime Timestamp;
}
}