Files
raven/server/AyaNova/generator/CoreJobMetricsSnapshot.cs
2020-01-27 22:52:21 +00:00

133 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using App.Metrics;
using AyaNova.Util;
using AyaNova.Models;
namespace AyaNova.Biz
{
/// <summary>
/// called by Generator to gather server metrics and check on things
/// See MetricsRegistry for defined metrics
///
/// </summary>
internal static class CoreJobMetricsSnapshot
{
private static ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("CoreJobMetricsSnapshot");
#if (DEBUG)
private static TimeSpan DO_EVERY_INTERVAL = new TimeSpan(0, 1, 0);//DEBUG do a check every 60 seconds
#else
private static TimeSpan DO_EVERY_INTERVAL = new TimeSpan(0, 15, 0);//RELEASE do a check every 15 minutes
#endif
private static DateTime lastServerCheckDone = DateTime.MinValue;
private static DateTime lastRecordCountCheck = DateTime.MinValue;
private static DateTime lastFileCountCheck = DateTime.MinValue;
////////////////////////////////////////////////////////////////////////////////////////////////
// DoAsync
//
public static async Task DoJobAsync(AyContext ct)
{
//https://www.app-metrics.io/
IMetrics metrics = (IMetrics)ServiceProviderProvider.Provider.GetService(typeof(IMetrics));
//This will get triggered roughly every minute (10 seconds in debug), but we don't want to healthcheck that frequently
if (!DateUtil.IsAfterDuration(lastServerCheckDone, DO_EVERY_INTERVAL))
return;
log.LogTrace("Starting metrics snapshot");
//Gather core metrics here
var process = Process.GetCurrentProcess();
//PHYSICAL MEMORY
metrics.Measure.Gauge.SetValue(MetricsRegistry.PhysicalMemoryGauge, process.WorkingSet64);
//PRIVATE BYTES
metrics.Measure.Gauge.SetValue(MetricsRegistry.PrivateBytesGauge, process.PrivateMemorySize64);
//RECORDS IN TABLE
//Only do this once per hour
if (DateUtil.IsAfterDuration(lastRecordCountCheck, 1))
{
lastRecordCountCheck = DateTime.UtcNow;
log.LogTrace("Counting table records");
//Get a count of important tables in db
List<string> allTableNames = await DbUtil.GetAllTablenamesAsync();
//Skip some tables as they are internal and / or only ever have one record
List<string> skipTableNames = new List<string>();
skipTableNames.Add("alicense");
skipTableNames.Add("aschemaversion");
foreach (string table in allTableNames)
{
if (!skipTableNames.Contains(table))
{
var tags = new MetricTags("TableTagKey", table);
metrics.Measure.Gauge.SetValue(MetricsRegistry.DBRecordsGauge, tags, await DbUtil.CountOfRecordsAsync(table));
}
}
}
//JOB COUNTS (DEAD, RUNNING, COMPLETED, SLEEPING)
foreach (JobStatus stat in Enum.GetValues(typeof(JobStatus)))
{
var jobtag = new MetricTags("JobStatus", stat.ToString());
metrics.Measure.Gauge.SetValue(MetricsRegistry.JobsGauge, jobtag, await JobsBiz.GetCountForJobStatusAsync(ct, stat));
}
//FILES ON DISK
//Only do this once per hour
if (DateUtil.IsAfterDuration(lastFileCountCheck, 1))
{
lastFileCountCheck = DateTime.UtcNow;
log.LogTrace("Files on disk information");
var UtilFilesInfo = FileUtil.GetUtilityFolderSizeInfo();
var UserFilesInfo = FileUtil.GetAttachmentFolderSizeInfo();
var mtag = new MetricTags("File type", "Business object files");
metrics.Measure.Gauge.SetValue(MetricsRegistry.FileCountGauge, mtag, UserFilesInfo.FileCountWithChildren);
metrics.Measure.Gauge.SetValue(MetricsRegistry.FileSizeGauge, mtag, UserFilesInfo.SizeWithChildren);
mtag = new MetricTags("File type", "OPS files");
metrics.Measure.Gauge.SetValue(MetricsRegistry.FileCountGauge, mtag, UtilFilesInfo.FileCountWithChildren);
metrics.Measure.Gauge.SetValue(MetricsRegistry.FileSizeGauge, mtag, UtilFilesInfo.SizeWithChildren);
}
lastServerCheckDone = DateTime.UtcNow;
//just to hide compiler warning for now
await Task.CompletedTask;
}
/////////////////////////////////////////////////////////////////////
}//eoc
}//eons