using System; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Alphaleonis.Win32.Filesystem; using MongoDB.Driver; using MongoDB.Driver.Linq; using Nancy; using Wabbajack.CacheServer.DTOs; using Wabbajack.Common; namespace Wabbajack.CacheServer { /// /// Extremely /// public class Metrics : NancyModule { private static SemaphoreSlim _lockObject = new SemaphoreSlim(1); public static async Task Log(DateTime timestamp, string action, string subject) { var msg = new[] {string.Join("\t", new[]{timestamp.ToString(), action, subject})}; Utils.Log(msg.First()); var db = Server.Config.Metrics.Connect(); await db.InsertOneAsync(new Metric {Timestamp = timestamp, Action = action, Subject = subject}); } public static Task Log(string action, string subject) { return Log(DateTime.Now, action, subject); } public Metrics() : base("/") { Get("/metrics/{Action}/{Value}", HandleMetrics); Get("/metrics/chart/", HandleChart); Get("/metrics/chart/{Action}/", HandleChart); Get("/metrics/chart/{Action}/{Value}/", HandleChart); Get("/metrics/ingest/{filename}", HandleBulkIngest); } private async Task HandleBulkIngest(dynamic arg) { Log("Bulk Loading " + arg.filename.ToString()); var lines = File.ReadAllLines(Path.Combine(@"c:\tmp", (string)arg.filename)); var db = Server.Config.Metrics.Connect(); var data = lines.Select(line => line.Split('\t')) .Where(line => line.Length == 3) .Select(line => new Metric{ Timestamp = DateTime.Parse(line[0]), Action = line[1], Subject = line[2] }) .ToList(); foreach (var metric in data) await db.InsertOneAsync(metric); return $"Processed {lines.Length} records"; } private async Task HandleMetrics(dynamic arg) { var date = DateTime.UtcNow; await Log(date, arg.Action, arg.Value); return date.ToString(); } private async Task HandleChart(dynamic arg) { /*var data = (await GetData()).Select(line => line.Split('\t')) .Where(line => line.Length == 3) .Select(line => new {date = DateTime.Parse(line[0]), Action = line[1], Value = line[2]});*/ var q = Server.Config.Metrics.Connect().AsQueryable(); // Remove guids / Default, which come from testing if (arg?.Action != null) { var action = (string)arg.Action; q = q.Where(d => d.Action == action); } if (arg?.Value != null) { var value = (string)arg.Value; q = q.Where(d => d.Subject.StartsWith(value)); } var data = (await q.Take(Int32.MaxValue).ToListAsync()).AsEnumerable(); data = data.Where(d => !Guid.TryParse(d.Subject ?? "", out Guid v) && (d.Subject ?? "") != "Default"); var grouped_and_counted = data.GroupBy(d => d.Timestamp.ToString("yyyy-MM-dd")) .OrderBy(d => d.Key) .Select(d => new {Day = d.Key, Count = d.Count()}) .ToList(); var sb = new StringBuilder(); sb.Append(""); sb.Append(""); sb.Append(""); sb.Append(""); var response = (Response)sb.ToString(); response.ContentType = "text/html"; return response; } public void Log(string l) { Utils.Log("Metrics: " + l); } } }