static void Main(string[] args) { string config_file = null; for (int i = 0; i < args.Length; ++i) { if (args[i] == "-i") { if (++i < args.Length) { config_file = args[i]; } } } Database db = new Database(); Console.WriteLine("Initializing Database"); Initializer initializer = new Initializer(new Initializer.EOptions[] { Initializer.EOptions.SkipSystemCreation }); initializer.Initialize(db); SystemConfiguration config = null; using (SQLiteConnection conn = db.Connection) { conn.Open(); if (config_file != null) { try { Console.WriteLine("Reading config file: " + config_file); FileInfo fi = new FileInfo(config_file); string text = File.ReadAllText(fi.FullName); SystemConfiguration c = JsonConvert.DeserializeObject <SystemConfiguration>(text); if (c != null) { // There's no timestamp in the file, so about all we can do is use the timestamp // of the file itself. SetSystemConfiguration(c, fi.CreationTime, db); } } catch (Exception ex) { Console.WriteLine("Error reading config file"); Console.WriteLine(ex.Message); } } // Get the current configuration from the database, then when we read in a new // configuration from the files we'll update the DB. config = GetSystemConfiguration(conn); } Console.WriteLine("Reading Daily Files"); FileInformationResponder responder = new FileInformationResponder(); RequestBus.Instance.Subscribe(responder); string here = AppDomain.CurrentDomain.BaseDirectory; Reader reader = new Reader(here); List <Reader.DailyFileInfo> reports = reader.DoRead(); // Put the reports in order by day so we process the configuration changes properly. reports.Sort((a, b) => a.Day.CompareTo(b.Day)); // If there's nothing to speak of in the database, such as when we just initialized it, // scan through the daily files until we get a SystemConfiguration. That's about the best we can // hope for. if (config == null || config.devices.Count < 2) { config = FindConfigInDailyFiles(reports); } Dictionary <string, DataCollectorContext> collector_id_cache = GetCollectorIDCache(config); DataStorage data_storage = new DataStorage(); BaseInterpreter.AllInterpreters().ForEach(i => data_storage.AddInterpreter(i)); using (SQLiteConnection conn = db.Connection) { conn.Open(); foreach (Reader.DailyFileInfo report in reports) { Console.WriteLine($"Loading {report.Info.Name}"); Stopwatch watch = Stopwatch.StartNew(); int count = 0; using (SQLiteTransaction t = conn.BeginTransaction()) { foreach (DailyReport.Record record in report.Report.records) { if (record.type == ECollectorType.Configuration) { // Deserialize to a SystemConfiguration object, then store that in the DB, and reload the // config from the DB config = JsonConvert.DeserializeObject <SystemConfiguration>(record.value); SetSystemConfiguration(config, record.timestamp, db); collector_id_cache = GetCollectorIDCache(GetSystemConfiguration(conn)); } else { if (collector_id_cache.TryGetValue(record.collector, out DataCollectorContext dc_context)) { DataStorage.DataRecord r = new DataStorage.DataRecord(dc_context, record.value, record.timestamp); r.D.CollectedAt = record.timestamp; data_storage.Insert(r, conn); count++; } else { Console.WriteLine($"Unable to find {record.collector}"); } } } t.Commit(); } long ms = watch.ElapsedMilliseconds; long ms_per_record = count == 0 ? ms : ms / count; Console.WriteLine($"Inserting {count} records took {ms} ms, at {ms_per_record} ms per record"); } } }
protected void ThreadFunc() { try { int max_collections_per_pass = 10; logging.EventLog elog = new ApplicationEventLog(); Database db = new Database(); DataStorage storage = new DataStorage(); m_interpreters.ForEach(i => storage.AddInterpreter(i)); while (GlobalIsRunning.IsRunning) { int collector_count = 0; using (SQLiteConnection conn = db.Connection) { conn.Open(); CheckForConfigurationChanges(storage, conn); // Used to hold which collector was doing its thing if/when an exception occurs. // It's used in the exception handler. string collector_name = string.Empty; try { DBCollectionTimeRetriever retriever = new DBCollectionTimeRetriever(conn); // Gets the list of things that need to be collected right now. They'll // be in the order they should be collected. List <DataCollector> collectors = m_system_device.GetCollectors(retriever); collector_count = collectors.Count; // Limit this to the top 10 or so while (collectors.Count > max_collections_per_pass) { collectors.RemoveAt(collectors.Count - 1); } foreach (DataCollector collector in collectors) { collector_name = collector.Context.Name; //elog.LogInformation($"Collecting {collector_name}"); Stopwatch watch = Stopwatch.StartNew(); // Records that the collector is being collected, updates the next collection // time, and records when the collection attempt was started. When it's destroyed // when exiting the using, it records that it is no longer being collected. // // This was done so even if an exception occurs within Acquire(), the flag // that the collector is being collected will be cleared. using (BeingCollected bc = new BeingCollected(collector.Context.ID.ID, conn)) { collector.Acquire(); } //long elapsed_ms = watch.ElapsedMilliseconds; //if(elapsed_ms > 500) // elog.LogInformation($"Collecting {collector_name} took {elapsed_ms} ms"); if (GlobalIsRunning.IsRunning == false) { break; // out of the foreach loop } } } catch (Exception e) { elog.LogError($"Exception from within {collector_name}"); elog.Log(e); } // Will write the daily file when it's the right time to do so; otherwise, it does nothing. if (GlobalIsRunning.IsRunning) { m_daily_file_writer.DoWrite(conn); } if (GlobalIsRunning.IsRunning) { m_db_cleaner.CleanOldData(m_days_to_keep, conn); } } // Deletes any old daily files if (GlobalIsRunning.IsRunning) { m_daily_file_cleaner.DoClean(); } // Delete any old log files too, if it's time to do so. if (GlobalIsRunning.IsRunning) { LogManager.CleanOldData(); } // And make sure we update our logging if it changed if (GlobalIsRunning.IsRunning) { LogManager.CheckConfiguration(); } // m_shutdown will be reset when the thread starts, and set when it's time to // stop the thread. So this will wait if this event hasn't been // set, but will return immediately if it has been set. // // If there's still more data to collect let's make another run right away if (GlobalIsRunning.IsRunning && collector_count < max_collections_per_pass) { m_shutdown.WaitOne(TimeSpan.FromSeconds(10)); } } m_interpreters.ForEach(i => storage.RemoveInterpreter(i)); } catch (Exception e) { logging.EventLog elog = new ApplicationEventLog(); elog.Log(e); m_shutdown.Reset(); m_thread.Abort(); m_thread = null; } }