Exemple #1
0
        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");
                }
            }
        }
Exemple #2
0
        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;
            }
        }