Source · fairmq/
DeviceRunner.cxxsource
Described in Configuration and properties, Devices, Plugins and control, custom-controller: control from code, Command-line options, Your first device, Logging.
1/********************************************************************************2 * Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *3 * *4 * This software is distributed under the terms of the *5 * GNU Lesser General Public Licence (LGPL) version 3, *6 * copied verbatim in the file "LICENSE" *7 ********************************************************************************/8 9#include "DeviceRunner.h"10 11#include <fairmq/tools/Strings.h>12#include <fairmq/tools/Version.h>13#include <fairmq/Version.h>14 15#include <fairlogger/Logger.h>16 17#include <exception>18 19using namespace std;20using namespace fair::mq;21 22DeviceRunner::DeviceRunner(int argc, char*const* argv, bool printLogo)23 : fRawCmdLineArgs(tools::ToStrVector(argc, argv, false))24 , fDevice(nullptr)25 , fPluginManager(fRawCmdLineArgs)26 , fPrintLogo(printLogo)27{}28 29bool DeviceRunner::HandleGeneralOptions(const fair::mq::ProgOptions& config, bool printLogo)30{31 if (config.Count("help")) {32 config.PrintHelp();33 return false;34 }35 36 if (config.Count("print-options")) {37 config.PrintOptionsRaw();38 return false;39 }40 41 if (config.Count("print-channels") || config.Count("version")) {42 fair::Logger::SetConsoleSeverity("nolog");43 } else {44 string severity = config.GetProperty<string>("severity");45 string logFile = config.GetProperty<string>("log-to-file");46 string logFileSeverity = config.GetProperty<string>("file-severity");47 bool color = config.GetProperty<bool>("color");48 49 string verbosity = config.GetProperty<string>("verbosity");50 fair::Logger::SetVerbosity(verbosity);51 52 if (!logFile.empty()) {53 fair::Logger::InitFileSink(logFileSeverity, logFile);54 fair::Logger::SetConsoleSeverity("nolog");55 } else {56 fair::Logger::SetConsoleColor(color);57 auto envFairMQSeverity = getenv("FAIRMQ_SEVERITY");58 if (envFairMQSeverity) {59 severity = envFairMQSeverity;60 }61 if (!severity.empty()) {62 fair::Logger::SetConsoleSeverity(severity);63 }64 }65 66 if (printLogo) {67 LOG(info) << endl68 << " ______ _ _______ _________ " << endl69 << " / ____/___ _(_)_______ |/ /_ __ \\ version "70 << FAIRMQ_GIT_VERSION << endl71 << " / /_ / __ `/ / ___/__ /|_/ /_ / / / build " << FAIRMQ_BUILD_TYPE72 << endl73 << " / __/ / /_/ / / / _ / / / / /_/ / " << FAIRMQ_REPO_URL << endl74 << R"( /_/ \__,_/_/_/ /_/ /_/ \___\_\ )" << FAIRMQ_LICENSE75 << " © " << FAIRMQ_COPYRIGHT << endl;76 }77 }78 79 return true;80}81 82void DeviceRunner::SubscribeForConfigChange()83{84 fConfig.Subscribe<bool>("device-runner", [](const std::string& key, const bool val) {85 if (key == "color") {86 fair::Logger::SetConsoleColor(val);87 }88 });89 fConfig.Subscribe<string>("device-runner", [&](const std::string& key, const std::string& val) {90 if (key == "severity") {91 fair::Logger::SetConsoleSeverity(val);92 } else if (key == "file-severity") {93 fair::Logger::SetFileSeverity(val);94 } else if (key == "verbosity") {95 fair::Logger::SetVerbosity(val);96 } else if (key == "log-to-file") {97 string fileSeverity = fConfig.GetProperty<string>("file-severity");98 fair::Logger::InitFileSink(fileSeverity, val);99 }100 });101}102void DeviceRunner::UnsubscribeFromConfigChange()103{104 fConfig.Unsubscribe<bool>("device-runner");105 fConfig.Unsubscribe<string>("device-runner");106}107 108auto DeviceRunner::Run() -> int109{110 fPluginManager.LoadPlugin("s:config");111 112 ////// CALL HOOK ///////113 fEvents.Emit<hooks::LoadPlugins>(*this);114 ////////////////////////115 116 // Load builtin plugins last117 fPluginManager.LoadPlugin("s:control");118 119 ////// CALL HOOK ///////120 fEvents.Emit<hooks::SetCustomCmdLineOptions>(*this);121 ////////////////////////122 123 fPluginManager.ForEachPluginProgOptions([&](boost::program_options::options_description options) {124 fConfig.AddToCmdLineOptions(options);125 });126 fConfig.AddToCmdLineOptions(PluginManager::ProgramOptions());127 128 ////// CALL HOOK ///////129 fEvents.Emit<hooks::ModifyRawCmdLineArgs>(*this);130 ////////////////////////131 132 fConfig.ParseAll(fRawCmdLineArgs, true);133 134 if (!HandleGeneralOptions(fConfig, fPrintLogo)) {135 return 0;136 }137 138 fConfig.Notify();139 140 // handle configuration updates (for general options)141 SubscribeForConfigChange();142 143 ////// CALL HOOK ///////144 fEvents.Emit<hooks::InstantiateDevice>(*this);145 ////////////////////////146 147 if (!fDevice) {148 LOG(error) << "getDevice(): no valid device provided. Exiting.";149 return 1;150 }151 152 fDevice->SetRawCmdLineArgs(fRawCmdLineArgs);153 154 // Handle --print-channels155 fDevice->RegisterChannelEndpoints();156 if (fConfig.Count("print-channels")) {157 fDevice->PrintRegisteredChannels();158 fDevice->ChangeStateOrThrow(fair::mq::Transition::End);159 return 0;160 }161 162 // Handle --version163 if (fConfig.Count("version")) {164 LOGV(info, verylow) << "FairMQ version: " << FAIRMQ_GIT_VERSION;165 LOGV(info, verylow) << "User device version: " << fDevice->GetVersion();166 fDevice->ChangeStateOrThrow(fair::mq::Transition::End);167 return 0;168 }169 170 LOG(debug) << "PID: " << getpid();171 172 // Configure device173 fDevice->SetConfig(fConfig);174 175 // Initialize plugin services176 fPluginManager.EmplacePluginServices(fConfig, *fDevice);177 178 // Instantiate and run plugins179 fPluginManager.InstantiatePlugins();180 181 // Log IDLE configuration182 fConfig.PrintOptions();183 184 // Run the device185 fDevice->RunStateMachine();186 187 // Wait for control plugin to release device control188 fPluginManager.WaitForPluginsToReleaseDeviceControl();189 190 // stop handling configuration updates (for general options)191 UnsubscribeFromConfigChange();192 193 return 0;194}195 196auto DeviceRunner::RunWithExceptionHandlers() -> int197{198 try {199 return Run();200 } catch (exception& e) {201 LOG(error) << "Uncaught exception reached the top of DeviceRunner: " << e.what();202 return 1;203 } catch (...) {204 LOG(error) << "Uncaught exception reached the top of DeviceRunner.";205 return 1;206 }207}