This commit is contained in:
2020-07-29 23:13:20 +00:00
parent b30a911351
commit 90052f1000
7 changed files with 40 additions and 28 deletions

4
.vscode/launch.json vendored
View File

@@ -42,8 +42,8 @@
"AYANOVA_JWT_SECRET": "UNLICENSED5G*QQJ8#bQ7$Xr_@sXfHq4", "AYANOVA_JWT_SECRET": "UNLICENSED5G*QQJ8#bQ7$Xr_@sXfHq4",
//"AYANOVA_SET_SUPERUSER_PW": "l3tm3in", //"AYANOVA_SET_SUPERUSER_PW": "l3tm3in",
"AYANOVA_LOG_LEVEL": "Info", "AYANOVA_LOG_LEVEL": "Info",
//"AYANOVA_LOG_LEVEL": "Debug", // "AYANOVA_LOG_LEVEL": "Debug",
//"AYANOVA_LOG_LEVEL": "Trace", // "AYANOVA_LOG_LEVEL": "Trace",
"AYANOVA_DEFAULT_TRANSLATION": "en", "AYANOVA_DEFAULT_TRANSLATION": "en",
//TRANSLATION MUST BE en for Integration TESTING //TRANSLATION MUST BE en for Integration TESTING
//"AYANOVA_PERMANENTLY_ERASE_DATABASE": "true", //"AYANOVA_PERMANENTLY_ERASE_DATABASE": "true",

View File

@@ -23,7 +23,7 @@ namespace AyaNova
//Boot lock for generator //Boot lock for generator
ServerGlobalOpsSettingsCache.BOOTING = true; ServerGlobalOpsSettingsCache.BOOTING = true;
//Get config //Get config
var config = new ConfigurationBuilder().AddEnvironmentVariables().AddCommandLine(args).Build(); var config = new ConfigurationBuilder().AddEnvironmentVariables().AddCommandLine(args).Build();
ServerBootConfig.SetConfiguration(config); ServerBootConfig.SetConfiguration(config);
@@ -39,7 +39,7 @@ namespace AyaNova
//default log level //default log level
NLog.LogLevel NLogLevel = NLog.LogLevel.Info; NLog.LogLevel NLogLevel = NLog.LogLevel.Info;
bool logLevelIsInfoOrHigher = true; bool FilterOutMicrosoftLogItems = true;
switch (ServerBootConfig.AYANOVA_LOG_LEVEL.ToLowerInvariant()) switch (ServerBootConfig.AYANOVA_LOG_LEVEL.ToLowerInvariant())
{ {
@@ -57,11 +57,10 @@ namespace AyaNova
break; break;
case "debug": case "debug":
NLogLevel = NLog.LogLevel.Debug; NLogLevel = NLog.LogLevel.Debug;
logLevelIsInfoOrHigher = false;
break; break;
case "trace": case "trace":
NLogLevel = NLog.LogLevel.Trace; NLogLevel = NLog.LogLevel.Trace;
logLevelIsInfoOrHigher = false; FilterOutMicrosoftLogItems = false;//Only at TRACE level do we want to see all the Microsoft logging stuff
break; break;
default: default:
NLogLevel = NLog.LogLevel.Info; NLogLevel = NLog.LogLevel.Info;
@@ -134,7 +133,7 @@ namespace AyaNova
logConfig.LoggingRules.Add(logRuleForConsole); logConfig.LoggingRules.Add(logRuleForConsole);
//only log microsoft stuff it log is debug level or lower //only log microsoft stuff it log is debug level or lower
if (logLevelIsInfoOrHigher) if (FilterOutMicrosoftLogItems)
{ {
//filter OUT microsoft stuff //filter OUT microsoft stuff
logConfig.LoggingRules.Add(logRuleFilterOutMicrosoft); logConfig.LoggingRules.Add(logRuleFilterOutMicrosoft);
@@ -165,7 +164,7 @@ namespace AyaNova
//log configuration //log configuration
try try
{ {
var AyaNovaConfig = config.AsEnumerable().Where(z => z.Key.StartsWith("AYANOVA") && z.Key != "AYANOVA_JWT_SECRET"&& z.Key != "AYANOVA_SET_SUPERUSER_PW").Select(z => z.Key + "=" + z.Value).ToList(); var AyaNovaConfig = config.AsEnumerable().Where(z => z.Key.StartsWith("AYANOVA") && z.Key != "AYANOVA_JWT_SECRET" && z.Key != "AYANOVA_SET_SUPERUSER_PW").Select(z => z.Key + "=" + z.Value).ToList();
var DiagConfig = string.Join(",", AyaNovaConfig); var DiagConfig = string.Join(",", AyaNovaConfig);
DiagConfig = DbUtil.PasswordRedactedConnectionString(DiagConfig); DiagConfig = DbUtil.PasswordRedactedConnectionString(DiagConfig);
logger.Info($"Config {DiagConfig}"); logger.Info($"Config {DiagConfig}");

View File

@@ -182,14 +182,16 @@ namespace AyaNova.Biz
//system lock (no license) is a complete deal breaker for continuation beyond here //system lock (no license) is a complete deal breaker for continuation beyond here
if (serverState.IsSystemLocked) return; if (serverState.IsSystemLocked) return;
//Moved the following user count checker to within JOB SWEEPER so that it only checks on every half hour so it's less obvious in logs with full trace on and
//also so someone fucking with the system won't get locked out right away.
//"SHENANIGAN" CHECK, note, must be here after systemlock because it relies on there being a license //"SHENANIGAN" CHECK, note, must be here after systemlock because it relies on there being a license
if (await UserBiz.ActiveCountAsync() > AyaNova.Core.License.ActiveKey.ActiveNumber) // if (await UserBiz.ActiveCountAsync() > AyaNova.Core.License.ActiveKey.ActiveNumber)
{ // {
var msg = $"E1020 - Active count exceeded capacity"; // var msg = $"E1020 - Active count exceeded capacity";
ServiceProviderProvider.ServerState.SetSystemLock(msg); // ServiceProviderProvider.ServerState.SetSystemLock(msg);
log.LogCritical(msg); // log.LogCritical(msg);
return; // return;
} // }
//BACKUP //BACKUP
@@ -199,7 +201,7 @@ namespace AyaNova.Biz
await CoreJobNotify.DoWorkAsync(); await CoreJobNotify.DoWorkAsync();
await CoreNotificationSweeper.DoWorkAsync(); await CoreNotificationSweeper.DoWorkAsync();
//JOB SWEEPER //JOB SWEEPER / AND USER COUNT CHECK
await CoreJobSweeper.DoWorkAsync(); await CoreJobSweeper.DoWorkAsync();
//### API Open only jobs //### API Open only jobs

View File

@@ -34,6 +34,8 @@ namespace AyaNova.Biz
{ {
using (AyContext ct = ServiceProviderProvider.DBContext) using (AyContext ct = ServiceProviderProvider.DBContext)
{ {
// var ret = await ct.Database.ExecuteSqlRawAsync($"SELECT COUNT(*) FROM auser AS a WHERE (a.active = TRUE) AND ((a.usertype = 2) OR (a.usertype = 7))");
var ret = await ct.User.AsNoTracking().Where(z => z.Active == true && ( var ret = await ct.User.AsNoTracking().Where(z => z.Active == true && (
z.UserType == UserType.Service || z.UserType == UserType.Service ||
z.UserType == UserType.ServiceContractor)).LongCountAsync(); z.UserType == UserType.ServiceContractor)).LongCountAsync();
@@ -299,8 +301,8 @@ namespace AyaNova.Biz
await SearchIndexAsync(dbObject, false); await SearchIndexAsync(dbObject, false);
await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags); await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, dbObject.Tags, SnapshotOfOriginalDBObj.Tags);
await NotifyEventProcessor.HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj); await NotifyEventProcessor.HandlePotentialNotificationEvent(AyaEvent.Modified, dbObject, SnapshotOfOriginalDBObj);
return dbObject; return dbObject;
} }

View File

@@ -107,7 +107,7 @@ namespace AyaNova.Biz
//All items have an event date, for non time delayed events it's just the moment it was created //All items have an event date, for non time delayed events it's just the moment it was created
//which will predate this moment now if it's pre-existing //which will predate this moment now if it's pre-existing
var events = await ct.NotifyEvent.Include(z => z.NotifySubscription).ToListAsync(); var events = await ct.NotifyEvent.Include(z => z.NotifySubscription).ToListAsync();
log.LogDebug($"Found {events.Count} NotifyEvents to examine for potential delivery"); log.LogTrace($"Found {events.Count} NotifyEvents to examine for potential delivery");
//cache translations //cache translations
//Get all subscription unique userId's that aren't inapp deliveries //Get all subscription unique userId's that aren't inapp deliveries

View File

@@ -17,7 +17,7 @@ namespace AyaNova.Biz
{ {
private static ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("CoreJobSweeper"); private static ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("CoreJobSweeper");
private static DateTime lastSweep = DateTime.MinValue; private static DateTime lastSweep = DateTime.MinValue;
private static TimeSpan SWEEP_EVERY_INTERVAL = new TimeSpan(0, 30, 0); private static TimeSpan SWEEP_EVERY_INTERVAL = new TimeSpan(0, 0, 10);
private static TimeSpan SUCCEEDED_JOBS_DELETE_AFTER_THIS_TIMESPAN = new TimeSpan(14, 0, 0, 0);//14 days private static TimeSpan SUCCEEDED_JOBS_DELETE_AFTER_THIS_TIMESPAN = new TimeSpan(14, 0, 0, 0);//14 days
private static TimeSpan FAILED_JOBS_DELETE_AFTER_THIS_TIMESPAN = new TimeSpan(14, 0, 0, 0);//14 days (gives people time to notice and look into it) private static TimeSpan FAILED_JOBS_DELETE_AFTER_THIS_TIMESPAN = new TimeSpan(14, 0, 0, 0);//14 days (gives people time to notice and look into it)
private static TimeSpan INTERNAL_JOBS_LOGS_DELETE_AFTER_THIS_TIMESPAN = new TimeSpan(14, 0, 0, 0);//14 days private static TimeSpan INTERNAL_JOBS_LOGS_DELETE_AFTER_THIS_TIMESPAN = new TimeSpan(14, 0, 0, 0);//14 days
@@ -28,7 +28,7 @@ namespace AyaNova.Biz
// DoSweep // DoSweep
// //
public static async Task DoWorkAsync() public static async Task DoWorkAsync()
{ {
//This will get triggered roughly every minute, but we don't want to sweep that frequently //This will get triggered roughly every minute, but we don't want to sweep that frequently
if (DateTime.UtcNow - lastSweep < SWEEP_EVERY_INTERVAL) if (DateTime.UtcNow - lastSweep < SWEEP_EVERY_INTERVAL)
return; return;
@@ -40,22 +40,31 @@ namespace AyaNova.Biz
//calculate cutoff to delete //calculate cutoff to delete
DateTime dtDeleteCutoff = DateTime.UtcNow - SUCCEEDED_JOBS_DELETE_AFTER_THIS_TIMESPAN; DateTime dtDeleteCutoff = DateTime.UtcNow - SUCCEEDED_JOBS_DELETE_AFTER_THIS_TIMESPAN;
await sweepAsync(ct, dtDeleteCutoff, JobStatus.Completed); await sweepAsync(ct, dtDeleteCutoff, JobStatus.Completed);
//SWEEP FAILED JOBS //SWEEP FAILED JOBS
//calculate cutoff to delete //calculate cutoff to delete
dtDeleteCutoff = DateTime.UtcNow - FAILED_JOBS_DELETE_AFTER_THIS_TIMESPAN; dtDeleteCutoff = DateTime.UtcNow - FAILED_JOBS_DELETE_AFTER_THIS_TIMESPAN;
await sweepAsync(ct, dtDeleteCutoff, JobStatus.Failed); await sweepAsync(ct, dtDeleteCutoff, JobStatus.Failed);
//KILL STUCK JOBS //KILL STUCK JOBS
//calculate cutoff to delete //calculate cutoff to delete
DateTime dtRunningDeadline = DateTime.UtcNow - RUNNING_JOBS_BECOME_FAILED_AFTER_THIS_TIMESPAN; DateTime dtRunningDeadline = DateTime.UtcNow - RUNNING_JOBS_BECOME_FAILED_AFTER_THIS_TIMESPAN;
await killStuckJobsAsync(ct, dtRunningDeadline); await killStuckJobsAsync(ct, dtRunningDeadline);
//SWEEP INTERNAL JOB LOG //SWEEP INTERNAL JOB LOG
//calculate cutoff to delete //calculate cutoff to delete
dtDeleteCutoff = DateTime.UtcNow - INTERNAL_JOBS_LOGS_DELETE_AFTER_THIS_TIMESPAN; dtDeleteCutoff = DateTime.UtcNow - INTERNAL_JOBS_LOGS_DELETE_AFTER_THIS_TIMESPAN;
await SweepInternalJobsLogsAsync(ct, dtDeleteCutoff); await SweepInternalJobsLogsAsync(ct, dtDeleteCutoff);
//Stealthy check of user count exceeded
if (await UserBiz.ActiveCountAsync() > AyaNova.Core.License.ActiveKey.ActiveNumber)
{
var msg = $"E1020 - Active count exceeded capacity";
AyaNova.Util.ServiceProviderProvider.ServerState.SetSystemLock(msg);
log.LogCritical(msg);
return;
}
} }
lastSweep = DateTime.UtcNow; lastSweep = DateTime.UtcNow;
} }
@@ -76,7 +85,7 @@ namespace AyaNova.Biz
{ {
try try
{ {
await JobsBiz.RemoveJobAndLogsAsync(j.GId); await JobsBiz.RemoveJobAndLogsAsync(j.GId);
} }
catch (Exception ex) catch (Exception ex)
@@ -114,7 +123,7 @@ namespace AyaNova.Biz
private static async Task SweepInternalJobsLogsAsync(AyContext ct, DateTime dtDeleteCutoff) private static async Task SweepInternalJobsLogsAsync(AyContext ct, DateTime dtDeleteCutoff)
{ {
//Get the deleteable list (this is for reporting, could easily just do it in one go) //Get the deleteable list (this is for reporting, could easily just do it in one go)
var logs = await ct.OpsJobLog var logs = await ct.OpsJobLog
.AsNoTracking() .AsNoTracking()

View File

@@ -53,7 +53,7 @@ namespace AyaNova.Generator
{ {
if (!ServerGlobalOpsSettingsCache.BOOTING) if (!ServerGlobalOpsSettingsCache.BOOTING)
{ {
log.LogDebug($"GeneratorService running jobs"); log.LogTrace($"GeneratorService running jobs");
//================================================================= //=================================================================
try try