#include "comboaddress.hh" #include "sclasses.hh" #include #include #include "navmon.pb.h" #include "fmt/format.h" #include "fmt/printf.h" #include #include #include #include #include #include #include #include "storage.hh" #include #include #include "navmon.hh" #include "CLI/CLI.hpp" #include "version.hh" static char program[]="navcat"; using namespace std; extern const char* g_gitHash; // get all stations (numerical) from a directory vector getSources(string_view dirname) { DIR *dir = opendir(&dirname[0]); if(!dir) unixDie("Listing metrics from statistics storage "+(string)dirname); struct dirent *result=0; vector ret; for(;;) { errno=0; if(!(result = readdir(dir))) { closedir(dir); if(errno) unixDie("Reading directory entry "+(string)dirname); else break; } if(result->d_name[0] != '.') { uint64_t src; if(sscanf(result->d_name, "%08" PRIx64, &src)==1) ret.push_back(src); } } sort(ret.begin(), ret.end()); return ret; } static bool operator==(const timespec& a, const timespec& b) { return a.tv_sec == b.tv_sec && a.tv_nsec && b.tv_nsec; } // send protobuf data from the named directories and stations, between start and stoptime void sendProtobuf(const vector& dirs, vector stations, time_t startTime, time_t stopTime=0) { timespec start; start.tv_sec = startTime; start.tv_nsec = 0; // so we have a ton of files, and internally these are not ordered map fpos; vector > rnmms; for(;;) { rnmms.clear(); for(const auto& dir : dirs) { cerr<<"Gathering data from "< srcs = stations.empty() ? getSources(dir) : stations; int count=0; for(const auto& src: srcs) { string fname = getPath(dir, start.tv_sec, src); FILE* fp = fopen(fname.c_str(), "r"); if(!fp) continue; uint32_t offset= fpos[fname]; if(fseek(fp, offset, SEEK_SET) < 0) { cerr<<"Error seeking: "<= make_pair(start.tv_sec, start.tv_nsec)) { rnmms.push_back({ts, msg}); ++count; } } // cerr<<"Harvested "< stopTime) break; std::string buf="bert"; uint16_t len = htons(nmm.second.size()); buf.append((char*)(&len), 2); buf += nmm.second; //fwrite(buf.c_str(), 1, buf.size(), stdout); writen2(1, buf.c_str(), buf.size()); ++count; } cerr<<"Done sending " << count<<" messages"< storages; int galwn{-1}; app.add_option("--storage,-s", storages, "Locations of storage files"); vector stations; app.add_flag("--version", doVERSION, "show program version and copyright"); app.add_option("--begin,-b", beginarg, "Begin time (2020-01-01 00:00, or 12:30)"); app.add_option("--end,-e", endarg, "End time. Now if omitted"); app.add_option("--stations", stations, "only send data from listed stations"); app.add_option("--gal-wn", galwn, "Galileo week number to report on"); CLI11_PARSE(app, argc, argv); if(doVERSION) { showVersion(program, g_gitHash); exit(0); } time_t startTime, stopTime; if(galwn >=0) { startTime=utcFromGST(galwn, 0); stopTime=startTime + 7*86400; } else if(!beginarg.empty()) { startTime = parseTime(beginarg); stopTime = endarg.empty() ? time(0) : parseTime(endarg); } else { cerr<<"No time range specified, use -b or --gal-wn"<