2020-05-09 03:56:06 +00:00
|
|
|
|
using System;
|
2020-06-15 04:05:00 +00:00
|
|
|
|
using System.Collections.Generic;
|
2020-05-09 13:04:38 +00:00
|
|
|
|
using System.Globalization;
|
2020-05-09 03:56:06 +00:00
|
|
|
|
using System.Linq;
|
2020-06-15 04:05:00 +00:00
|
|
|
|
using System.Net;
|
2020-05-09 03:56:06 +00:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
2020-06-15 04:05:00 +00:00
|
|
|
|
using Nettle;
|
2020-05-09 03:56:06 +00:00
|
|
|
|
using Wabbajack.Common;
|
2020-07-07 12:29:05 +00:00
|
|
|
|
using Wabbajack.Server;
|
2020-05-09 03:56:06 +00:00
|
|
|
|
using Wabbajack.Server.DataLayer;
|
|
|
|
|
using Wabbajack.Server.DTOs;
|
|
|
|
|
using WebSocketSharp;
|
|
|
|
|
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
|
|
|
|
|
|
|
|
|
namespace Wabbajack.BuildServer.Controllers
|
|
|
|
|
{
|
|
|
|
|
[ApiController]
|
|
|
|
|
[Route("/metrics")]
|
|
|
|
|
public class MetricsController : ControllerBase
|
|
|
|
|
{
|
|
|
|
|
private SqlService _sql;
|
|
|
|
|
private ILogger<MetricsController> _logger;
|
|
|
|
|
|
|
|
|
|
public MetricsController(ILogger<MetricsController> logger, SqlService sql)
|
|
|
|
|
{
|
|
|
|
|
_sql = sql;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
2020-05-09 13:04:38 +00:00
|
|
|
|
[Route("{subject}/{value}")]
|
|
|
|
|
public async Task<Result> LogMetricAsync(string subject, string value)
|
2020-05-09 03:56:06 +00:00
|
|
|
|
{
|
|
|
|
|
var date = DateTime.UtcNow;
|
2020-05-09 13:04:38 +00:00
|
|
|
|
await Log(date, subject, value, Request.Headers[Consts.MetricsKeyHeader].FirstOrDefault());
|
2020-05-09 03:56:06 +00:00
|
|
|
|
return new Result { Timestamp = date};
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-09 13:04:38 +00:00
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("report/{subject}")]
|
|
|
|
|
public async Task<IActionResult> MetricsReport(string subject)
|
|
|
|
|
{
|
|
|
|
|
var results = (await _sql.MetricsReport(subject))
|
|
|
|
|
.GroupBy(m => m.Subject)
|
|
|
|
|
.Select(g => new MetricResult
|
|
|
|
|
{
|
|
|
|
|
SeriesName = g.Key,
|
|
|
|
|
Labels = g.Select(m => m.Date.ToString(CultureInfo.InvariantCulture)).ToList(),
|
|
|
|
|
Values = g.Select(m => m.Count).ToList()
|
|
|
|
|
});
|
|
|
|
|
return Ok(results.ToList());
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-07 12:29:05 +00:00
|
|
|
|
[HttpGet]
|
2020-07-07 20:17:49 +00:00
|
|
|
|
[Route("badge/{name}/total_installs_badge.json")]
|
|
|
|
|
public async Task<IActionResult> TotalInstallsBadge(string name)
|
2020-07-07 12:29:05 +00:00
|
|
|
|
{
|
2020-07-07 20:17:49 +00:00
|
|
|
|
var results = await _sql.TotalInstalls(name);
|
2020-07-07 12:29:05 +00:00
|
|
|
|
|
|
|
|
|
Response.ContentType = "application/json";
|
2020-07-07 20:17:49 +00:00
|
|
|
|
|
|
|
|
|
return Ok(results == 0
|
|
|
|
|
? new Badge($"Modlist {name} not found!", "Error") {color = "red"}
|
|
|
|
|
: new Badge("Installations: ", $"{results}") {color = "green"});
|
2020-07-07 12:29:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-07-07 20:17:49 +00:00
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("badge/{name}/unique_installs_badge.json")]
|
|
|
|
|
public async Task<IActionResult> UniqueInstallsBadge(string name)
|
|
|
|
|
{
|
|
|
|
|
var results = await _sql.UniqueInstalls(name);
|
|
|
|
|
|
|
|
|
|
Response.ContentType = "application/json";
|
|
|
|
|
|
|
|
|
|
return Ok(results == 0
|
|
|
|
|
? new Badge($"Modlist {name} not found!", "Error") {color = "red"}
|
|
|
|
|
: new Badge("Installations: ", $"{results}"){color = "green"}) ;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-15 04:05:00 +00:00
|
|
|
|
private static readonly Func<object, string> ReportTemplate = NettleEngine.GetCompiler().Compile(@"
|
|
|
|
|
<html><body>
|
|
|
|
|
<h2>Tar Report for {{$.key}}</h2>
|
|
|
|
|
<h3>Ban Status: {{$.status}}</h3>
|
|
|
|
|
<table>
|
|
|
|
|
{{each $.log }}
|
|
|
|
|
<tr>
|
|
|
|
|
<td>{{$.Timestamp}}</td>
|
|
|
|
|
<td>{{$.Path}}</td>
|
|
|
|
|
<td>{{$.Key}}</td>
|
|
|
|
|
</tr>
|
|
|
|
|
{{/each}}
|
|
|
|
|
</table>
|
|
|
|
|
</body></html>
|
|
|
|
|
");
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
[Route("tarlog/{key}")]
|
|
|
|
|
public async Task<IActionResult> TarLog(string key)
|
|
|
|
|
{
|
|
|
|
|
var isTarKey = await _sql.IsTarKey(key);
|
|
|
|
|
|
|
|
|
|
List<(DateTime, string, string)> report = new List<(DateTime, string, string)>();
|
|
|
|
|
|
|
|
|
|
if (isTarKey) report = await _sql.FullTarReport(key);
|
|
|
|
|
|
|
|
|
|
var response = ReportTemplate(new
|
|
|
|
|
{
|
|
|
|
|
key = key,
|
|
|
|
|
status = isTarKey ? "BANNED" : "NOT BANNED",
|
|
|
|
|
log = report.Select(entry => new
|
|
|
|
|
{
|
|
|
|
|
Timestamp = entry.Item1,
|
|
|
|
|
Path = entry.Item2,
|
|
|
|
|
Key = entry.Item3
|
|
|
|
|
}).ToList()
|
|
|
|
|
});
|
|
|
|
|
return new ContentResult
|
|
|
|
|
{
|
|
|
|
|
ContentType = "text/html",
|
|
|
|
|
StatusCode = (int) HttpStatusCode.OK,
|
|
|
|
|
Content = response
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-09 03:56:06 +00:00
|
|
|
|
private async Task Log(DateTime timestamp, string action, string subject, string metricsKey = null)
|
|
|
|
|
{
|
|
|
|
|
_logger.Log(LogLevel.Information, $"Log - {timestamp} {action} {subject} {metricsKey}");
|
|
|
|
|
await _sql.IngestMetric(new Metric
|
|
|
|
|
{
|
|
|
|
|
Timestamp = timestamp, Action = action, Subject = subject, MetricsKey = metricsKey
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Result
|
|
|
|
|
{
|
|
|
|
|
public DateTime Timestamp { get; set; }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|