7 #include "TRACE/tracemf.h"
8 #define TRACE_NAME (app_name_ + "_file_metric").c_str()
10 #include "artdaq-utilities/Plugins/MetricMacros.hh"
11 #include "fhiclcpp/ParameterSet.h"
14 #include <sys/types.h>
16 #include <boost/filesystem.hpp>
21 namespace BFS = boost::filesystem;
30 std::string outputFile_;
31 bool file_name_is_absolute_path_;
32 std::string relative_env_var_;
33 bool uniquify_file_name_;
34 std::ofstream outputStream_;
35 std::ios_base::openmode mode_;
36 std::string timeformat_;
39 std::ostream& getTime_(std::ostream& stream,
const std::chrono::system_clock::time_point& time)
41 std::time_t tt = std::chrono::system_clock::to_time_t(time);
43 struct std::tm* ptm = std::localtime(&tt);
44 if (!timeformat_.empty())
46 return stream << std::put_time(ptm, timeformat_.c_str()) <<
": ";
73 explicit FileMetric(fhicl::ParameterSet
const& config, std::string
const& app_name, std::string
const& metric_name)
75 , outputFile_(
pset.get<std::string>(
"fileName",
"FileMetric.out"))
76 , file_name_is_absolute_path_(
pset.get<bool>(
"absolute_file_path", true))
77 , relative_env_var_(
pset.get<std::string>(
"relative_directory_env_var",
"ARTDAQ_LOG_ROOT"))
78 , uniquify_file_name_(
pset.get<bool>(
"uniquify", false))
79 , timeformat_(
pset.get<std::string>(
"time_format",
"%c"))
82 auto modeString =
pset.get<std::string>(
"fileMode",
"append");
84 mode_ = std::ofstream::out | std::ofstream::app;
85 if (modeString ==
"Overwrite" || modeString ==
"Create" || modeString ==
"Write")
87 mode_ = std::ofstream::out | std::ofstream::trunc;
90 METLOG(TLVL_DEBUG + 32) <<
"FileMetric ctor";
92 if (uniquify_file_name_)
95 clock_gettime(CLOCK_REALTIME, &ts);
96 std::string unique_id = std::to_string(ts.tv_sec) +
"_" + std::to_string(getpid());
97 if (outputFile_.find(
"%UID%") != std::string::npos)
99 outputFile_ = outputFile_.replace(outputFile_.find(
"%UID%"), 5, unique_id);
103 if (outputFile_.rfind(
'.') != std::string::npos)
105 outputFile_ = outputFile_.insert(outputFile_.rfind(
'.'),
"_" + unique_id);
109 outputFile_ = outputFile_.append(
"_" + unique_id);
140 void sendMetric_(
const std::string& name,
const std::string& value,
const std::string& unit,
const std::chrono::system_clock::time_point& time)
override
144 getTime_(outputStream_, time) <<
"FileMetric: " << name <<
": " << value <<
" " << unit <<
"." << std::endl;
155 void sendMetric_(
const std::string& name,
const int& value,
const std::string& unit,
const std::chrono::system_clock::time_point& time)
override
157 sendMetric_(name, std::to_string(value), unit, time);
167 void sendMetric_(
const std::string& name,
const double& value,
const std::string& unit,
const std::chrono::system_clock::time_point& time)
override
169 sendMetric_(name, std::to_string(value), unit, time);
179 void sendMetric_(
const std::string& name,
const float& value,
const std::string& unit,
const std::chrono::system_clock::time_point& time)
override
181 sendMetric_(name, std::to_string(value), unit, time);
191 void sendMetric_(
const std::string& name,
const uint64_t& value,
const std::string& unit,
const std::chrono::system_clock::time_point& time)
override
193 sendMetric_(name, std::to_string(value), unit, time);
202 getTime_(outputStream_, std::chrono::system_clock::now()) <<
"FileMetric plugin started." << std::endl;
211 getTime_(outputStream_, std::chrono::system_clock::now()) <<
"FileMetric plugin has been stopped!" << std::endl;
217 if (!file_name_is_absolute_path_)
219 METLOG(TLVL_DEBUG + 32) <<
"Reading relative directory evironment variable " << relative_env_var_;
220 std::string logPathProblem;
221 std::string logfileName;
222 char* logRootString = getenv(relative_env_var_.c_str());
224 std::string logfileDir;
225 if (logRootString !=
nullptr)
227 if (!BFS::exists(logRootString))
229 METLOG(TLVL_WARNING) <<
"Relative directory environment variable " << relative_env_var_ <<
" points to a non-existant directory! Using /tmp/!";
230 outputFile_ =
"/tmp/" + outputFile_;
231 METLOG(TLVL_INFO) <<
"FileMetric Opening file " << outputFile_;
232 outputStream_.open(outputFile_, mode_);
236 logfileDir = logRootString;
237 logfileDir.append(
"/metrics/");
239 while (outputFile_.find(
'/') != std::string::npos)
241 METLOG(TLVL_DEBUG + 32) <<
"Extracting subdirectories from relative file path " << outputFile_ <<
" (logfileDir = " << logfileDir <<
")";
242 logfileDir.append(outputFile_.substr(0, outputFile_.find(
'/') + 1));
243 outputFile_.erase(0, outputFile_.find(
'/') + 1);
248 METLOG(TLVL_DEBUG + 32) <<
"Creating log file directory " << logfileDir;
249 if (!BFS::exists(logfileDir))
251 BFS::create_directories(logfileDir);
254 logfileName.append(logfileDir);
255 logfileName.append(outputFile_);
257 METLOG(TLVL_INFO) <<
"FileMetric Opening file " << logfileName;
258 outputStream_.open(logfileName, mode_);
263 METLOG(TLVL_WARNING) <<
"Relative directory environment variable " << relative_env_var_ <<
" is null! Using /tmp/!";
264 outputFile_ =
"/tmp/" + outputFile_;
265 METLOG(TLVL_INFO) <<
"FileMetric Opening file " << outputFile_;
266 outputStream_.open(outputFile_, mode_);
271 METLOG(TLVL_INFO) <<
"FileMetric Opening file " << outputFile_;
272 outputStream_.open(outputFile_, mode_);
274 if (outputStream_.is_open())
276 getTime_(outputStream_, std::chrono::system_clock::now()) <<
"FileMetric plugin file opened." << std::endl;
280 METLOG(TLVL_ERROR) <<
"Error opening metric file " << outputFile_;
286 getTime_(outputStream_, std::chrono::system_clock::now()) <<
"FileMetric closing file stream." << std::endl;
290 outputStream_.flush();
291 outputStream_.close();
The MetricPlugin class defines the interface that MetricManager uses to send metric data to the vario...
void startMetrics()
Perform startup actions. Simply calls the virtual startMetrics_ function.
~FileMetric() override
FileMetric Destructor. Calls stopMetrics and then closes the file.
fhicl::ParameterSet pset
The ParameterSet used to configure the MetricPlugin.
void stopMetrics_() override
Perform shutdown actions. Writes stop message to output file.
void sendMetric_(const std::string &name, const int &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
void stopMetrics()
Perform shutdown actions. Zeroes out all accumulators, and sends zeros for each metric. Calls stopMetrics_() for any plugin-defined shutdown actions.
void sendMetric_(const std::string &name, const float &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
void sendMetric_(const std::string &name, const std::string &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
void sendMetric_(const std::string &name, const double &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
void startMetrics_() override
Perform startup actions. Writes start message to output file.
void sendMetric_(const std::string &name, const uint64_t &value, const std::string &unit, const std::chrono::system_clock::time_point &time) override
Write metric data to a file.
FileMetric writes metric data to a file on disk.
FileMetric(fhicl::ParameterSet const &config, std::string const &app_name, std::string const &metric_name)
FileMetric Constructor. Opens the file and starts the metric.
std::string getLibName() const override
Get the library name for the File metric.
bool inhibit_
Flag to indicate that the MetricPlugin is being stopped, and any metric back-ends which do not have a...