mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Metrics bug fixes
This commit is contained in:
parent
ad5c8b83e6
commit
94b01a0454
@ -4,10 +4,11 @@ using Wabbajack.BuildServer.Models;
|
|||||||
|
|
||||||
namespace Wabbajack.BuildServer.Controllers
|
namespace Wabbajack.BuildServer.Controllers
|
||||||
{
|
{
|
||||||
|
[ApiController]
|
||||||
public abstract class AControllerBase<T> : ControllerBase
|
public abstract class AControllerBase<T> : ControllerBase
|
||||||
{
|
{
|
||||||
protected readonly ILogger<T> Logger;
|
|
||||||
protected readonly DBContext Db;
|
protected readonly DBContext Db;
|
||||||
|
protected readonly ILogger<T> Logger;
|
||||||
|
|
||||||
protected AControllerBase(ILogger<T> logger, DBContext db)
|
protected AControllerBase(ILogger<T> logger, DBContext db)
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Threading.Tasks;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using GraphQL;
|
using GraphQL;
|
||||||
using GraphQL.Language.AST;
|
|
||||||
using GraphQL.Types;
|
using GraphQL.Types;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Wabbajack.BuildServer.GraphQL;
|
using Wabbajack.BuildServer.GraphQL;
|
||||||
using Wabbajack.BuildServer.Models;
|
using Wabbajack.BuildServer.Models;
|
||||||
|
|
||||||
@ -24,12 +20,8 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
public async Task<IActionResult> Post([FromBody] GraphQLQuery query)
|
public async Task<IActionResult> Post([FromBody] GraphQLQuery query)
|
||||||
{
|
{
|
||||||
var inputs = query.Variables.ToInputs();
|
var inputs = query.Variables.ToInputs();
|
||||||
var schema = new Schema
|
var schema = new Schema {Query = new Query(Db), Mutation = new Mutation(Db)};
|
||||||
{
|
|
||||||
Query = new Query(Db),
|
|
||||||
Mutation = new Mutation(Db)
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = await new DocumentExecuter().ExecuteAsync(_ =>
|
var result = await new DocumentExecuter().ExecuteAsync(_ =>
|
||||||
{
|
{
|
||||||
_.Schema = schema;
|
_.Schema = schema;
|
||||||
@ -37,14 +29,13 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
_.OperationName = query.OperationName;
|
_.OperationName = query.OperationName;
|
||||||
_.Inputs = inputs;
|
_.Inputs = inputs;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(result.Errors?.Count > 0)
|
if (result.Errors?.Count > 0)
|
||||||
{
|
{
|
||||||
return BadRequest();
|
return BadRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
Wabbajack.BuildServer/Controllers/Heartbeat.cs
Normal file
31
Wabbajack.BuildServer/Controllers/Heartbeat.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Wabbajack.BuildServer.Models;
|
||||||
|
using Wabbajack.Common;
|
||||||
|
|
||||||
|
namespace Wabbajack.BuildServer.Controllers
|
||||||
|
{
|
||||||
|
[Route("/heartbeat")]
|
||||||
|
public class Heartbeat : AControllerBase<Heartbeat>
|
||||||
|
{
|
||||||
|
static Heartbeat()
|
||||||
|
{
|
||||||
|
_startTime = DateTime.Now;
|
||||||
|
|
||||||
|
}
|
||||||
|
private static DateTime _startTime;
|
||||||
|
|
||||||
|
public Heartbeat(ILogger<Heartbeat> logger, DBContext db) : base(logger, db)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<TimeSpan> GetHeartbeat()
|
||||||
|
{
|
||||||
|
return DateTime.Now - _startTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,7 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
[Route("{xxHashAsBase64}")]
|
[Route("{xxHashAsBase64}")]
|
||||||
public async Task<IndexedVirtualFile> GetFile(string xxHashAsBase64)
|
public async Task<IndexedVirtualFile> GetFile(string xxHashAsBase64)
|
||||||
{
|
{
|
||||||
var id = xxHashAsBase64;//.FromHex().ToBase64();
|
var id = xxHashAsBase64.FromHex().ToBase64();
|
||||||
var query = new[]
|
var query = new[]
|
||||||
{
|
{
|
||||||
new BsonDocument("$match",
|
new BsonDocument("$match",
|
||||||
@ -47,16 +47,18 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
if (t == null)
|
if (t == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Dictionary<string, TreeResult> indexed_children= new Dictionary<string, TreeResult>();
|
Dictionary<string, TreeResult> indexed_children = new Dictionary<string, TreeResult>();
|
||||||
if (t.IsArchive)
|
if (t.IsArchive)
|
||||||
indexed_children = t.ChildFiles.ToDictionary(t => t.Hash);
|
indexed_children = t.ChildFiles.ToDictionary(t => t.Hash);
|
||||||
|
|
||||||
var file = new IndexedVirtualFile
|
var file = new IndexedVirtualFile
|
||||||
{
|
{
|
||||||
Name = Name,
|
Name = Name,
|
||||||
Size = t.Size,
|
Size = t.Size,
|
||||||
Hash = t.Hash,
|
Hash = t.Hash,
|
||||||
Children = t.IsArchive ? t.Children.Select(child => Convert(indexed_children[child.Hash], child.Name)).ToList() : new List<IndexedVirtualFile>()
|
Children = t.IsArchive
|
||||||
|
? t.Children.Select(child => Convert(indexed_children[child.Hash], child.Name)).ToList()
|
||||||
|
: new List<IndexedVirtualFile>()
|
||||||
};
|
};
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@ -68,7 +70,5 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
{
|
{
|
||||||
public List<TreeResult> ChildFiles { get; set; }
|
public List<TreeResult> ChildFiles { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,5 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
.OrderByDescending(j => j.Priority)
|
.OrderByDescending(j => j.Priority)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,12 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("/lists")]
|
[Route("/lists")]
|
||||||
|
|
||||||
public class ListValidation : AControllerBase<ListValidation>
|
public class ListValidation : AControllerBase<ListValidation>
|
||||||
{
|
{
|
||||||
public ListValidation(ILogger<ListValidation> logger, DBContext db) : base(logger, db)
|
public ListValidation(ILogger<ListValidation> logger, DBContext db) : base(logger, db)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("status.json")]
|
[Route("status.json")]
|
||||||
public async Task<IList<ModlistSummary>> HandleGetLists()
|
public async Task<IList<ModlistSummary>> HandleGetLists()
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Wabbajack.BuildServer.Models;
|
|
||||||
using Wabbajack.Common;
|
|
||||||
|
|
||||||
namespace Wabbajack.BuildServer.Controllers
|
|
||||||
{
|
|
||||||
[Route("/metrics")]
|
|
||||||
public class Metrics : AControllerBase<Metrics>
|
|
||||||
{
|
|
||||||
[HttpGet]
|
|
||||||
[Route("{Action}/Value")]
|
|
||||||
public async Task<string> NewMetric(string Action, string Value)
|
|
||||||
{
|
|
||||||
|
|
||||||
var date = DateTime.UtcNow;
|
|
||||||
await Log(date, Action, Value, Request.Headers[Consts.MetricsKeyHeader].FirstOrDefault());
|
|
||||||
return date.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Metrics(ILogger<Metrics> logger, DBContext db) : base(logger, db)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task Log(DateTime timestamp, string action, string subject, string metricsKey = null)
|
|
||||||
{
|
|
||||||
var msg = new[] {string.Join("\t", new[]{timestamp.ToString(), metricsKey, action, subject})};
|
|
||||||
Utils.Log(msg.First());
|
|
||||||
await Db.Metrics.InsertOneAsync(new Metric {Timestamp = timestamp, Action = action, Subject = subject, MetricsKey = metricsKey});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
46
Wabbajack.BuildServer/Controllers/MetricsController.cs
Normal file
46
Wabbajack.BuildServer/Controllers/MetricsController.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
using MongoDB.Driver.Linq;
|
||||||
|
using Wabbajack.BuildServer.Models;
|
||||||
|
using Wabbajack.Common;
|
||||||
|
using Wabbajack.Lib.ModListRegistry;
|
||||||
|
|
||||||
|
namespace Wabbajack.BuildServer.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("/metrics")]
|
||||||
|
public class MetricsController : AControllerBase<MetricsController>
|
||||||
|
{
|
||||||
|
public MetricsController(ILogger<MetricsController> logger, DBContext db) : base(logger, db)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[Route("{Subject}/{Value}")]
|
||||||
|
public async Task<Result> LogMetricAsync(string Subject, string Value)
|
||||||
|
{
|
||||||
|
var date = DateTime.UtcNow;
|
||||||
|
await Log(date, Subject, Value, Request.Headers[Consts.MetricsKeyHeader].FirstOrDefault());
|
||||||
|
return new Result { Timestamp = date};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Log(DateTime timestamp, string action, string subject, string metricsKey = null)
|
||||||
|
{
|
||||||
|
Logger.Log(LogLevel.Information, $"Log - {timestamp} {action} {subject} {metricsKey}");
|
||||||
|
await Db.Metrics.InsertOneAsync(new Metric
|
||||||
|
{
|
||||||
|
Timestamp = timestamp, Action = action, Subject = subject, MetricsKey = metricsKey
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Result
|
||||||
|
{
|
||||||
|
public DateTime Timestamp { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,14 +13,13 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
[Route("/v1/games/")]
|
[Route("/v1/games/")]
|
||||||
public class NexusCache : AControllerBase<NexusCache>
|
public class NexusCache : AControllerBase<NexusCache>
|
||||||
{
|
{
|
||||||
|
|
||||||
public NexusCache(ILogger<NexusCache> logger, DBContext db) : base(logger, db)
|
public NexusCache(ILogger<NexusCache> logger, DBContext db) : base(logger, db)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up the mod details for a given Gamename/ModId pair. If the entry is not found in the cache it will
|
/// Looks up the mod details for a given Gamename/ModId pair. If the entry is not found in the cache it will
|
||||||
/// be requested from the server (using the caller's Nexus API key if provided).
|
/// be requested from the server (using the caller's Nexus API key if provided).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="db"></param>
|
/// <param name="db"></param>
|
||||||
/// <param name="GameName">The Nexus game name</param>
|
/// <param name="GameName">The Nexus game name</param>
|
||||||
@ -38,13 +37,7 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
var api = await NexusApiClient.Get(Request.Headers["apikey"].FirstOrDefault());
|
var api = await NexusApiClient.Get(Request.Headers["apikey"].FirstOrDefault());
|
||||||
var path = $"/v1/games/{GameName}/mods/{ModId}.json";
|
var path = $"/v1/games/{GameName}/mods/{ModId}.json";
|
||||||
var body = await api.Get<ModInfo>(path);
|
var body = await api.Get<ModInfo>(path);
|
||||||
result = new NexusCacheData<ModInfo>
|
result = new NexusCacheData<ModInfo> {Data = body, Path = path, Game = GameName, ModId = ModId};
|
||||||
{
|
|
||||||
Data = body,
|
|
||||||
Path = path,
|
|
||||||
Game = GameName,
|
|
||||||
ModId = ModId
|
|
||||||
};
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Db.NexusModInfos.InsertOneAsync(result);
|
await Db.NexusModInfos.InsertOneAsync(result);
|
||||||
@ -74,10 +67,7 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
var body = await api.Get<NexusApiClient.GetModFilesResponse>(path);
|
var body = await api.Get<NexusApiClient.GetModFilesResponse>(path);
|
||||||
result = new NexusCacheData<NexusApiClient.GetModFilesResponse>
|
result = new NexusCacheData<NexusApiClient.GetModFilesResponse>
|
||||||
{
|
{
|
||||||
Data = body,
|
Data = body, Path = path, Game = GameName, ModId = ModId
|
||||||
Path = path,
|
|
||||||
Game = GameName,
|
|
||||||
ModId = ModId
|
|
||||||
};
|
};
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -85,7 +75,6 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
}
|
}
|
||||||
catch (MongoWriteException)
|
catch (MongoWriteException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
method = "NOT_CACHED";
|
method = "NOT_CACHED";
|
||||||
@ -96,10 +85,11 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{GameName}/mods/{ModId}/files/{FileId}.json")]
|
[Route("{GameName}/mods/{ModId}/files/{FileId}.json")]
|
||||||
public async Task<object> GetFileInfo(string GameName, string ModId, string FileId)
|
public async Task<object> GetFileInfo(string GameName, string ModId, string FileId)
|
||||||
{
|
{
|
||||||
var result = await Db.NexusFileInfos.FindOneAsync(info => info.Game == GameName && info.ModId == ModId && info.FileId == FileId);
|
var result = await Db.NexusFileInfos.FindOneAsync(info =>
|
||||||
|
info.Game == GameName && info.ModId == ModId && info.FileId == FileId);
|
||||||
|
|
||||||
string method = "CACHED";
|
string method = "CACHED";
|
||||||
if (result == null)
|
if (result == null)
|
||||||
@ -109,9 +99,9 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
var body = await api.Get<NexusFileInfo>(path);
|
var body = await api.Get<NexusFileInfo>(path);
|
||||||
result = new NexusCacheData<NexusFileInfo>
|
result = new NexusCacheData<NexusFileInfo>
|
||||||
{
|
{
|
||||||
Data = body,
|
Data = body,
|
||||||
Path = path,
|
Path = path,
|
||||||
Game = GameName,
|
Game = GameName,
|
||||||
ModId = ModId,
|
ModId = ModId,
|
||||||
FileId = FileId
|
FileId = FileId
|
||||||
};
|
};
|
||||||
@ -121,7 +111,6 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
}
|
}
|
||||||
catch (MongoWriteException)
|
catch (MongoWriteException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
method = "NOT_CACHED";
|
method = "NOT_CACHED";
|
||||||
@ -130,7 +119,5 @@ namespace Wabbajack.BuildServer.Controllers
|
|||||||
Response.Headers.Add("x-cache-method", method);
|
Response.Headers.Add("x-cache-method", method);
|
||||||
return result.Data;
|
return result.Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,12 @@ namespace Wabbajack.BuildServer
|
|||||||
{
|
{
|
||||||
CreateHostBuilder(args).Build().Run();
|
CreateHostBuilder(args).Build().Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
Host.CreateDefaultBuilder(args)
|
Host.CreateDefaultBuilder(args)
|
||||||
.ConfigureWebHostDefaults(webBuilder =>
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
{
|
{
|
||||||
webBuilder.UseUrls("http://*:5000", "https://*:5001");
|
webBuilder.UseUrls("http://*:5000");
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ using Swashbuckle.AspNetCore.Swagger;
|
|||||||
using Wabbajack.BuildServer.Controllers;
|
using Wabbajack.BuildServer.Controllers;
|
||||||
using Wabbajack.BuildServer.Models;
|
using Wabbajack.BuildServer.Models;
|
||||||
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
|
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
|
||||||
|
using Wabbajack.BuildServer.Controllers;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Directory = System.IO.Directory;
|
using Directory = System.IO.Directory;
|
||||||
|
|
||||||
@ -44,15 +45,15 @@ namespace Wabbajack.BuildServer
|
|||||||
{
|
{
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo {Title = "Wabbajack Build API", Version = "v1"});
|
c.SwaggerDoc("v1", new OpenApiInfo {Title = "Wabbajack Build API", Version = "v1"});
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddSingleton<DBContext>();
|
services.AddSingleton<DBContext>();
|
||||||
services.AddSingleton<JobManager>();
|
services.AddSingleton<JobManager>();
|
||||||
services.AddSingleton<AppSettings>();
|
services.AddSingleton<AppSettings>();
|
||||||
services.AddControllers(o =>
|
services.AddMvc();
|
||||||
|
services.AddControllers()
|
||||||
|
.AddNewtonsoftJson(o =>
|
||||||
{
|
{
|
||||||
|
|
||||||
}).AddNewtonsoftJson(o =>
|
|
||||||
{
|
|
||||||
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,11 +2,8 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<UserSecretsId>aspnet-Wabbajack.BuildServer-6E798B30-DB04-4436-BE65-F043AF37B314</UserSecretsId>
|
<UserSecretsId>aspnet-Wabbajack.BuildServer-6E798B30-DB04-4436-BE65-F043AF37B314</UserSecretsId>
|
||||||
<WebProject_DirectoryAccessLevelKey>0</WebProject_DirectoryAccessLevelKey>
|
<WebProject_DirectoryAccessLevelKey>0</WebProject_DirectoryAccessLevelKey>
|
||||||
<PublishTrimmed>true</PublishTrimmed>
|
|
||||||
<PublishSingleFile>true</PublishSingleFile>
|
|
||||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user