diff --git a/.vscode/launch.json b/.vscode/launch.json index 95c9b301..6b9a0d68 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -50,7 +50,7 @@ "AYANOVA_FOLDER_USER_FILES": "c:\\temp\\RavenTestData\\userfiles", "AYANOVA_FOLDER_BACKUP_FILES": "c:\\temp\\RavenTestData\\backupfiles", "AYANOVA_METRICS_USE_INFLUXDB": "false", - "AYANOVA_SERVER_TEST_MODE":"false", + "AYANOVA_SERVER_TEST_MODE":"true", "AYANOVA_SERVER_TEST_MODE_SEEDLEVEL":"small", "AYANOVA_SERVER_TEST_MODE_TZ_OFFSET":"-7", "AYANOVA_BACKUP_PG_DUMP_PATH":"C:\\data\\code\\PostgreSQLPortable_12.0\\App\\PgSQL\\bin\\" diff --git a/devdocs/tools.txt b/devdocs/tools.txt index 3f0919ba..7a8032f3 100644 --- a/devdocs/tools.txt +++ b/devdocs/tools.txt @@ -690,4 +690,8 @@ JAVASCRIPT DOWNSAMPLING TOOL return sampled; } - //============================================= \ No newline at end of file + //============================================= + + + COlors colours for charts + http://perceptualedge.com/articles/b-eye/choosing_colors.pdf \ No newline at end of file diff --git a/server/AyaNova/Controllers/ServerMetricsController.cs b/server/AyaNova/Controllers/ServerMetricsController.cs index 9454aab8..0b221f14 100644 --- a/server/AyaNova/Controllers/ServerMetricsController.cs +++ b/server/AyaNova/Controllers/ServerMetricsController.cs @@ -31,7 +31,7 @@ namespace AyaNova.Api.Controllers private readonly AyContext ct; private readonly ILogger log; private readonly ApiServerState serverState; - private const int MAX_RECORDS_BEFORE_DOWNSAMPLING = 400; + private const int DEFAULT_MAX_RECORDS = 400; private const long MB = (1024 * 1024); /// @@ -49,7 +49,6 @@ namespace AyaNova.Api.Controllers } - /// /// Get all server metrics for time period specified /// @@ -61,7 +60,6 @@ namespace AyaNova.Api.Controllers public async Task GetMetrics([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)) @@ -69,87 +67,53 @@ namespace AyaNova.Api.Controllers if (!ModelState.IsValid) return BadRequest(new ApiErrorResponse(ModelState)); - //use specified values or just return all - maxRecords ??= MAX_RECORDS_BEFORE_DOWNSAMPLING; + 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 + //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(); - //Log - await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); + 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>; - //Downsample - // if (maxRecords < MinuteMetrics.Count) - // { - var dsCPU = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.CPU)).ToList(); - dsCPU = Util.DataUtil.LargestTriangleThreeBuckets(dsCPU, (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 dsAllocated = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Allocated)).ToList(); - dsAllocated = Util.DataUtil.LargestTriangleThreeBuckets(dsAllocated, (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 dsWorkingSet = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.WorkingSet)).ToList(); - dsWorkingSet = Util.DataUtil.LargestTriangleThreeBuckets(dsWorkingSet, (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 dsPrivateBytes = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.PrivateBytes)).ToList(); - dsPrivateBytes = Util.DataUtil.LargestTriangleThreeBuckets(dsPrivateBytes, (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 dsGen0 = MinuteMetrics.Select(z => new Tuple(z.t.ToOADate(), z.Gen0)).ToList(); - dsGen0 = Util.DataUtil.LargestTriangleThreeBuckets(dsGen0, (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 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 ret = new + var ret = new + { + MetricMM = new { - DownSampled = true, - 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() + 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() - } + } - }; - return Ok(ApiOkResponse.Response(ret)); - - // } - // else - // { - // var tsOffset = new TimeSpan(0); - // var ret = new - // { - // DownSampled = false, - // MetricMM = new - // { - // labels = MinuteMetrics.Select(z => z.t).ToArray(), - // cpu = MinuteMetrics.Select(z => z.CPU).ToArray(), - // gen0 = MinuteMetrics.Select(z => z.Gen0).ToArray(), - // gen1 = MinuteMetrics.Select(z => z.Gen1).ToArray(), - // gen2 = MinuteMetrics.Select(z => z.Gen2).ToArray(), - // allocated = MinuteMetrics.Select(z => z.Allocated / MB).ToArray(), - // workingSet = MinuteMetrics.Select(z => z.WorkingSet / MB).ToArray(), - // privateBytes = MinuteMetrics.Select(z => z.PrivateBytes / MB).ToArray() - - // } - - // }; - // return Ok(ApiOkResponse.Response(ret)); - // } + }; + + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); + return Ok(ApiOkResponse.Response(ret)); } @@ -178,7 +142,7 @@ namespace AyaNova.Api.Controllers } } - public class MetricDouble + public class MetricDouble { public DateTime x { get; set; } public double y { get; set; }