From 7184046ebf948a07c337692f3fa300e79cdd49b6 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Fri, 29 May 2020 14:15:25 +0000 Subject: [PATCH] --- .../Controllers/ServerMetricsController.cs | 147 +++++++++++++++++- 1 file changed, 143 insertions(+), 4 deletions(-) diff --git a/server/AyaNova/Controllers/ServerMetricsController.cs b/server/AyaNova/Controllers/ServerMetricsController.cs index 65683161..815ffbe7 100644 --- a/server/AyaNova/Controllers/ServerMetricsController.cs +++ b/server/AyaNova/Controllers/ServerMetricsController.cs @@ -50,14 +50,152 @@ namespace AyaNova.Api.Controllers /// - /// Get all server metrics for time period specified + /// Get minute frequency server metrics for time period specified /// /// Start timestamp UTC /// End timestamp UTC - /// Optional maximum records to return. If there are more records for the time period selected than this value the result will be downsampled. There is a 400 record maximum fixed default + /// Optional maximum records to return (downsampled). There is a 400 record maximum fixed default /// Snapshot of metrics - [HttpGet] - public async Task GetMetrics([FromQuery, Required] DateTime? tsStart, [FromQuery, Required] DateTime? tsEnd, [FromQuery] int? maxRecords) + [HttpGet("mm")] + public async Task GetMMMetrics([FromQuery, Required] DateTime? tsStart, [FromQuery, Required] DateTime? tsEnd, [FromQuery] int? maxRecords) + { + //Note: the date and times are nullable and required so that the regular modelstate code kicks in to ensure they are present + if (serverState.IsClosed) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.Metrics)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + + maxRecords ??= DEFAULT_MAX_RECORDS; + + List MinuteMetrics = new List(); + //touniversal is because the parameters are converted to local time here + //but then sent to the query as local time as well and not universal time which is what it should be + MinuteMetrics = await ct.MetricMM.AsNoTracking().Where(z => z.t >= ((DateTime)tsStart).ToUniversalTime() && z.t <= ((DateTime)tsEnd).ToUniversalTime()).OrderBy(z => z.t).ToListAsync(); + + + var dsCPU = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.CPU)).ToList(); + dsCPU = Util.DataUtil.LargestTriangleThreeBuckets(dsCPU, (int)maxRecords) as List>; + + var dsAllocated = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Allocated)).ToList(); + dsAllocated = Util.DataUtil.LargestTriangleThreeBuckets(dsAllocated, (int)maxRecords) as List>; + + var dsWorkingSet = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.WorkingSet)).ToList(); + dsWorkingSet = Util.DataUtil.LargestTriangleThreeBuckets(dsWorkingSet, (int)maxRecords) as List>; + + var dsPrivateBytes = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.PrivateBytes)).ToList(); + dsPrivateBytes = Util.DataUtil.LargestTriangleThreeBuckets(dsPrivateBytes, (int)maxRecords) as List>; + + var dsGen0 = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Gen0)).ToList(); + dsGen0 = Util.DataUtil.LargestTriangleThreeBuckets(dsGen0, (int)maxRecords) as List>; + + var dsGen1 = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Gen1)).ToList(); + dsGen1 = Util.DataUtil.LargestTriangleThreeBuckets(dsGen1, (int)maxRecords) as List>; + + var dsGen2 = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Gen2)).ToList(); + dsGen2 = Util.DataUtil.LargestTriangleThreeBuckets(dsGen2, (int)maxRecords) as List>; + + var MetricMM = new + { + cpu = dsCPU.Select(z => new MetricDouble(DateTime.FromOADate(z.Item1), z.Item2)).ToArray(), + gen0 = dsGen0.Select(z => new MetricInt(DateTime.FromOADate(z.Item1), z.Item2)).ToArray(), + gen1 = dsGen1.Select(z => new MetricInt(DateTime.FromOADate(z.Item1), z.Item2)).ToArray(), + gen2 = dsGen2.Select(z => new MetricInt(DateTime.FromOADate(z.Item1), z.Item2)).ToArray(), + allocated = dsAllocated.Select(z => new MetricLong(DateTime.FromOADate(z.Item1), z.Item2 / MB)).ToArray(), + workingSet = dsWorkingSet.Select(z => new MetricLong(DateTime.FromOADate(z.Item1), z.Item2 / MB)).ToArray(), + privateBytes = dsPrivateBytes.Select(z => new MetricLong(DateTime.FromOADate(z.Item1), z.Item2 / MB)).ToArray() + }; + + + var ret = new + { + MetricMM = MetricMM + + }; + + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); + return Ok(ApiOkResponse.Response(ret)); + } + + /// + /// Get hourly server metrics for time period specified + /// + /// Start timestamp UTC + /// End timestamp UTC + /// Optional maximum records to return (downsampled). There is a 400 record maximum fixed default + /// Snapshot of metrics + [HttpGet("hh")] + public async Task GetHHMetrics([FromQuery, Required] DateTime? tsStart, [FromQuery, Required] DateTime? tsEnd, [FromQuery] int? maxRecords) + { + //Note: the date and times are nullable and required so that the regular modelstate code kicks in to ensure they are present + if (serverState.IsClosed) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + if (!Authorized.HasReadFullRole(HttpContext.Items, AyaType.Metrics)) + return StatusCode(403, new ApiNotAuthorizedResponse()); + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + + maxRecords ??= DEFAULT_MAX_RECORDS; + + List MinuteMetrics = new List(); + //touniversal is because the parameters are converted to local time here + //but then sent to the query as local time as well and not universal time which is what it should be + MinuteMetrics = await ct.MetricMM.AsNoTracking().Where(z => z.t >= ((DateTime)tsStart).ToUniversalTime() && z.t <= ((DateTime)tsEnd).ToUniversalTime()).OrderBy(z => z.t).ToListAsync(); + + + var dsCPU = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.CPU)).ToList(); + dsCPU = Util.DataUtil.LargestTriangleThreeBuckets(dsCPU, (int)maxRecords) as List>; + + var dsAllocated = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Allocated)).ToList(); + dsAllocated = Util.DataUtil.LargestTriangleThreeBuckets(dsAllocated, (int)maxRecords) as List>; + + var dsWorkingSet = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.WorkingSet)).ToList(); + dsWorkingSet = Util.DataUtil.LargestTriangleThreeBuckets(dsWorkingSet, (int)maxRecords) as List>; + + var dsPrivateBytes = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.PrivateBytes)).ToList(); + dsPrivateBytes = Util.DataUtil.LargestTriangleThreeBuckets(dsPrivateBytes, (int)maxRecords) as List>; + + var dsGen0 = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Gen0)).ToList(); + dsGen0 = Util.DataUtil.LargestTriangleThreeBuckets(dsGen0, (int)maxRecords) as List>; + + var dsGen1 = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Gen1)).ToList(); + dsGen1 = Util.DataUtil.LargestTriangleThreeBuckets(dsGen1, (int)maxRecords) as List>; + + var dsGen2 = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Gen2)).ToList(); + dsGen2 = Util.DataUtil.LargestTriangleThreeBuckets(dsGen2, (int)maxRecords) as List>; + + var MetricMM = new + { + cpu = dsCPU.Select(z => new MetricDouble(DateTime.FromOADate(z.Item1), z.Item2)).ToArray(), + gen0 = dsGen0.Select(z => new MetricInt(DateTime.FromOADate(z.Item1), z.Item2)).ToArray(), + gen1 = dsGen1.Select(z => new MetricInt(DateTime.FromOADate(z.Item1), z.Item2)).ToArray(), + gen2 = dsGen2.Select(z => new MetricInt(DateTime.FromOADate(z.Item1), z.Item2)).ToArray(), + allocated = dsAllocated.Select(z => new MetricLong(DateTime.FromOADate(z.Item1), z.Item2 / MB)).ToArray(), + workingSet = dsWorkingSet.Select(z => new MetricLong(DateTime.FromOADate(z.Item1), z.Item2 / MB)).ToArray(), + privateBytes = dsPrivateBytes.Select(z => new MetricLong(DateTime.FromOADate(z.Item1), z.Item2 / MB)).ToArray() + }; + + + var ret = new + { + MetricMM = MetricMM + + }; + + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); + return Ok(ApiOkResponse.Response(ret)); + } + + /// + /// Get daily server metrics for time period specified + /// + /// Start timestamp UTC + /// End timestamp UTC + /// Optional maximum records to return (downsampled). There is a 400 record maximum fixed default + /// Snapshot of metrics + [HttpGet("dd")] + public async Task GetDDMetrics([FromQuery, Required] DateTime? tsStart, [FromQuery, Required] DateTime? tsEnd, [FromQuery] int? maxRecords) { //Note: the date and times are nullable and required so that the regular modelstate code kicks in to ensure they are present if (serverState.IsClosed) @@ -119,6 +257,7 @@ namespace AyaNova.Api.Controllers } + //------------ public class MetricLong {