internal static void Initialize() { Database.SetInitializer(new MigrateDatabaseToLatestVersion <MetricDbContext, Configuration>()); using (var db = new MetricDbContext()) { // Register pre-defined applications foreach ( var metricAppField in typeof(CommonApps).GetFields() .Where( field => field.IsStatic && typeof(MetricAppId).IsAssignableFrom(field.FieldType))) { var metricAppId = (MetricAppId)metricAppField.GetValue(null); if (db.Apps.Any(x => x.AppGuid == metricAppId.Guid)) { continue; } db.Apps.Add(new MetricApp(metricAppId.Guid, metricAppId.Name)); } db.SaveChanges(); // Register pre-defined metrics foreach ( var metricField in typeof(CommonMetrics).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Where( field => typeof(MetricKey).IsAssignableFrom(field.FieldType))) { var metricKey = (MetricKey)metricField.GetValue(null); if (db.MetricDefinitions.Any(x => x.MetricGuid == metricKey.Guid)) { continue; } db.MetricDefinitions.Add(new MetricEventDefinition(metricKey.Guid, metricKey.Name)); } db.SaveChanges(); AppEditorId = db.GetApplicationId(CommonApps.StrideEditorAppId.Guid); AppLauncherId = db.GetApplicationId(CommonApps.StrideLauncherAppId.Guid); // TODO: comment this for production, only valid for testing the metrics, just run once. Note this is VERY SLOW // MetricDbTest.Fill(db); } }
public static void Fill(MetricDbContext db) { var fromTime = new DateTime(2015, 01, 3); var toTime = DateTime.Now; var installGenerators = new List <PseudoInstallGenerator>() { new PseudoInstallGenerator(new DateTime(2015, 01, 20), 1, 3, "1.0.0") { new PseudoMetricEventGenerator(0.7, 1, -1, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(3)), new PseudoMetricEventGenerator(0.9, 1, -0.2, TimeSpan.FromMinutes(50), TimeSpan.FromMinutes(20)), new PseudoMetricEventGenerator(1.0, 2, -0.05, TimeSpan.FromHours(2), TimeSpan.FromHours(1)), }, new PseudoInstallGenerator(new DateTime(2015, 03, 20), 1, 5, "1.1.0") { new PseudoMetricEventGenerator(0.5, 1, -1, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(3)), new PseudoMetricEventGenerator(0.7, 1, -0.2, TimeSpan.FromMinutes(50), TimeSpan.FromMinutes(20)), new PseudoMetricEventGenerator(0.9, 1, -0.01, TimeSpan.FromMinutes(50), TimeSpan.FromMinutes(20)), new PseudoMetricEventGenerator(1.0, 2, -0.005, TimeSpan.FromHours(3), TimeSpan.FromHours(1)), }, new PseudoInstallGenerator(toTime, 1, 10, "1.2.0") { new PseudoMetricEventGenerator(0.3, 1, -1, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(3)), new PseudoMetricEventGenerator(0.5, 1, -0.1, TimeSpan.FromMinutes(50), TimeSpan.FromMinutes(20)), new PseudoMetricEventGenerator(0.7, 1, -0.01, TimeSpan.FromMinutes(50), TimeSpan.FromMinutes(20)), new PseudoMetricEventGenerator(1.0, 2, -0.005, TimeSpan.FromHours(3), TimeSpan.FromHours(1)), }, }; var currentTime = fromTime; var random = new Random(0); var userInstalls = new List <PseudoInstall>(); while (currentTime < toTime) { var generator = installGenerators.FirstOrDefault(t => currentTime < t.Until); if (generator == null) { break; } var installCount = random.Next(generator.InstallCountMin, generator.InstallCountMax); for (int i = 0; i < installCount; i++) { var p = random.NextDouble(); foreach (var eventGenerators in generator.MetricEventGenerators) { if (p <= eventGenerators.Percentage) { eventGenerators.InstallGenerator = generator; var pseudoInstall = new PseudoInstall( new MetricInstall(Guid.NewGuid()) { Created = currentTime + TimeSpan.FromHours(6 + i * 10 / installCount) }, eventGenerators) { NumberPerDay = eventGenerators.NumberPerDay, }; // Save the install to the database db.Installs.Add(pseudoInstall.MetricInstall); // Add our new pseudo install userInstalls.Add(pseudoInstall); break; } } } db.SaveChanges(); int eventCount = 0; // Generate user events for (int i = 0; i < userInstalls.Count; i++) { var pseudoInstall = userInstalls[i]; // Saving and storing metrics per user install every day. This is not correct as we should ideally save them ordered by timestamp between all users // but for this test, we simplify this. for (int eventId = 0; eventId < pseudoInstall.NumberPerDay; eventId++) { var metricEvent = new NewMetricMessage() { ApplicationId = CommonApps.StrideEditorAppId.Guid, InstallId = pseudoInstall.MetricInstall.InstallGuid, SessionId = eventId, EventId = eventId, MetricId = CommonMetrics.OpenApplication.Guid, Value = pseudoInstall.EventGenerator.InstallGenerator.Version }; var time = currentTime + TimeSpan.FromHours(7 + eventId * 10 / pseudoInstall.NumberPerDay); db.SaveNewMetric(metricEvent, pseudoInstall.IPAddress, time, true); metricEvent = new NewMetricMessage() { ApplicationId = CommonApps.StrideEditorAppId.Guid, InstallId = pseudoInstall.MetricInstall.InstallGuid, SessionId = eventId, EventId = eventId, MetricId = CommonMetrics.CloseApplication.Guid, Value = string.Empty }; time += pseudoInstall.EventGenerator.Duration + TimeSpan.FromSeconds(random.NextDouble() * pseudoInstall.EventGenerator.DurationAddDelta.TotalSeconds); db.SaveNewMetric(metricEvent, pseudoInstall.IPAddress, time, true); eventCount += 2; } // Decrease the installs pseudoInstall.NumberPerDay += pseudoInstall.EventGenerator.DecreaseNumberPerDay; if (pseudoInstall.NumberPerDay <= 0.0) { userInstalls.RemoveAt(i); i--; } } db.SaveChanges(); Debug.WriteLine("{0}: Users: {1} Events {2}", currentTime, userInstalls.Count, eventCount); // Add one day currentTime += TimeSpan.FromDays(1); } }