diff --git a/server/AyaNova/Controllers/ServerMetricsController.cs b/server/AyaNova/Controllers/ServerMetricsController.cs index e7c666b3..2cb062c3 100644 --- a/server/AyaNova/Controllers/ServerMetricsController.cs +++ b/server/AyaNova/Controllers/ServerMetricsController.cs @@ -178,6 +178,49 @@ namespace AyaNova.Api.Controllers + /// + /// Get database related 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("db")] + public async Task GetDBMetrics([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 DBMetrics = 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 + DBMetrics = await ct.MetricDD.AsNoTracking().Where(z => z.t >= ((DateTime)tsStart).ToUniversalTime() && z.t <= ((DateTime)tsEnd).ToUniversalTime()).OrderBy(z => z.t).ToListAsync(); + var dsDBTotalSize = DBMetrics.Select(z => new Tuple(z.t.ToOADate(), z.DBTotalSize)).ToList(); + dsDBTotalSize = Util.DataUtil.LargestTriangleThreeBuckets(dsDBTotalSize, (int)maxRecords) as List>; + + //table distribution, top 10 + + + var ret = new + { + + totalSize = dsDBTotalSize.Select(z => new MetricLong(DateTime.FromOADate(z.Item1), z.Item2 / MB)).ToArray() + + }; + + + + await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct); + return Ok(ApiOkResponse.Response(ret)); + } + //------------ diff --git a/server/AyaNova/generator/CoreJobMetricsSnapshot.cs b/server/AyaNova/generator/CoreJobMetricsSnapshot.cs index ca4aaf64..1a19b979 100644 --- a/server/AyaNova/generator/CoreJobMetricsSnapshot.cs +++ b/server/AyaNova/generator/CoreJobMetricsSnapshot.cs @@ -96,7 +96,7 @@ namespace AyaNova.Biz _lastMMSnapshot = now; - + } ///////////////////////////////////////////// @@ -157,8 +157,25 @@ namespace AyaNova.Biz var UtilityFilesAvailableSpace = FileUtil.UtilityFilesDriveAvailableSpace(); var AttachmentFilesAvailableSpace = FileUtil.AttachmentFilesDriveAvailableSpace(); + + using (AyContext ct = ServiceProviderProvider.DBContext) { + //DB total size + long DBTotalSize = 0; + using (var command = ct.Database.GetDbConnection().CreateCommand()) + { + command.CommandText = "select pg_database_size(current_database());"; + ct.Database.OpenConnection(); + using (var dr = command.ExecuteReader()) + { + if (dr.HasRows) + { + DBTotalSize = dr.Read() ? dr.GetInt64(0) : 0; + } + ct.Database.CloseConnection(); + } + } //write to db MetricDD dd = new MetricDD() { @@ -167,7 +184,8 @@ namespace AyaNova.Biz AttachmentFilesAvailableSpace = AttachmentFilesAvailableSpace, UtilityFileSize = UtilFilesInfo.SizeWithChildren, UtilityFileCount = UtilFilesInfo.FileCountWithChildren, - UtilityFilesAvailableSpace = UtilityFilesAvailableSpace + UtilityFilesAvailableSpace = UtilityFilesAvailableSpace, + DBTotalSize = DBTotalSize }; ct.MetricDD.Add(dd); ct.SaveChanges(); diff --git a/server/AyaNova/models/MetricDD.cs b/server/AyaNova/models/MetricDD.cs index bea48144..4a13aaaa 100644 --- a/server/AyaNova/models/MetricDD.cs +++ b/server/AyaNova/models/MetricDD.cs @@ -20,6 +20,8 @@ namespace AyaNova.Models public long UtilityFileCount { get; set; } public long UtilityFilesAvailableSpace { get; set; } + public long DBTotalSize { get; set; } + diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index 10388941..9cd13c62 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -22,7 +22,7 @@ namespace AyaNova.Util //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!! private const int DESIRED_SCHEMA_LEVEL = 11; - internal const long EXPECTED_COLUMN_COUNT = 327; + internal const long EXPECTED_COLUMN_COUNT = 328; internal const long EXPECTED_INDEX_COUNT = 134; //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!! @@ -252,7 +252,7 @@ namespace AyaNova.Util //One hour metrics await ExecQueryAsync("CREATE TABLE ametrichh (t timestamp not null, test bigint)"); //One day metrics - await ExecQueryAsync("CREATE TABLE ametricdd (t timestamp not null, attachmentfilesize bigint, attachmentfilecount bigint, attachmentfilesavailablespace bigint, utilityfilesize bigint, utilityfilecount bigint, utilityfilesavailablespace bigint)"); + await ExecQueryAsync("CREATE TABLE ametricdd (t timestamp not null, dbtotalsize bigint, attachmentfilesize bigint, attachmentfilecount bigint, attachmentfilesavailablespace bigint, utilityfilesize bigint, utilityfilecount bigint, utilityfilesavailablespace bigint)"); //SEARCH TABLES