23 #include "../bblogfile.h"
25 #include <arpa/inet.h>
26 #include <blackboard/internal/instance_factory.h>
27 #include <blackboard/remote.h>
28 #include <interfaces/SwitchInterface.h>
31 #include <sys/types.h>
32 #include <utils/system/argparser.h>
33 #include <utils/system/fam.h>
34 #include <utils/system/signal.h>
35 #include <utils/time/time.h>
46 print_usage(
const char *program_name)
48 printf(
"Usage: %s [-h] [-r host:port] <COMMAND> <logfile>\n"
49 " %s print <logfile> <index> [index ...]\n"
50 " %s convert <infile> <outfile> <format>\n"
52 " -h Print this usage information\n"
54 " watch Continuously watch a log file (like tail)\n"
55 " info Print meta information of log file\n"
56 " print Print specific data index\n"
57 " <index> [index ...] is a list of indices to print\n"
58 " replay Replay log file in real-time to console\n"
59 " repair Repair file, i.e. properly set number of entries\n"
60 " enable Enable logging on a remotely running bblogger\n"
61 " disable Disable logging on a remotely running bblogger\n"
62 " convert Convert logfile to different format\n"
63 " <infile> input log file\n"
64 " <outfile> converted output file\n"
65 " <format> format to convert to, currently supported:\n"
66 " - csv Comma-separated values\n",
73 print_info(std::string &filename)
80 printf(
"Failed to print info, exception follows\n");
87 repair_file(std::string &filename)
91 printf(
"Nothing to repair, files are fine\n");
94 if (strcmp(e.
type_id(),
"repair-success") == 0) {
95 printf(
"Repair successful, actions done follow.\n");
99 printf(
"Repair failed, exception follows.\n");
107 print_indexes(std::string &filename, std::vector<unsigned int> &indexes)
111 for (
unsigned int i = 0; i < indexes.size(); ++i) {
112 bf.read_index(indexes[i]);
117 printf(
"Failed to print info, exception follows\n");
126 replay_file(std::string &filename)
131 Time last_offset((
long)0);
133 if (!bf.has_next()) {
134 printf(
"File does not have any entries, aborting.\n");
142 last_offset = bf.entry_offset();
145 while (bf.has_next()) {
147 diff = bf.entry_offset() - last_offset;
149 last_offset = bf.entry_offset();
154 printf(
"Failed to print info, exception follows\n");
166 BBLogWatcher(
const char *filename,
BBLogFile &file) : file_(file)
170 fam_->add_listener(
this);
171 fam_->watch_file(filename);
178 fam_->remove_listener(
this);
183 fam_event(
const char *filename,
unsigned int mask)
185 if (mask & FAM_DELETE) {
189 unsigned int remaining = file_.remaining_entries();
190 for (
unsigned int i = 0; i < remaining; ++i) {
198 handle_signal(
int signal)
208 fam_->process_events(-1);
219 watch_file(std::string &filename)
221 BBLogFile file(filename.c_str(), NULL,
false);
226 BBLogWatcher watcher(filename.c_str(), file);
233 set_enabled(
const char *hostname,
unsigned short int port,
bool enabled)
240 printf(
"No writer exists, BBLogger not loaded?\n");
258 convert_file_csv(
BBLogFile &bf, FILE *outf)
263 fprintf(outf,
"# Time relative to beginning (in sec)");
283 convert_file(std::string &infile, std::string &outfile, std::string &format)
285 if (format !=
"csv") {
286 printf(
"Unsupported output format '%s'\n", format.c_str());
290 FILE *outf = fopen(outfile.c_str(),
"wx");
292 perror(
"Failed to open output file");
300 if (format ==
"csv") {
301 convert_file_csv(bf, outf);
305 printf(
"Failed to convert log file: %s\n", e.
what());
321 main(
int argc,
char **argv)
325 if (argp.has_arg(
"h")) {
326 print_usage(argv[0]);
330 std::string command, file;
331 if (argp.num_items() < 1) {
332 printf(
"Invalid number of arguments\n");
333 print_usage(argv[0]);
335 }
else if (argp.num_items() >= 2) {
336 file = argp.items()[1];
339 command = argp.items()[0];
341 if (command ==
"watch") {
342 return watch_file(file);
344 }
else if (command ==
"info") {
345 return print_info(file);
347 }
else if (command ==
"print") {
348 std::vector<const char *> index_strings = argp.items();
349 index_strings.erase(index_strings.begin(), index_strings.begin() + 2);
351 std::vector<unsigned int> indexes(index_strings.size());
352 for (
unsigned int i = 0; i < index_strings.size(); ++i) {
353 long l = atol(index_strings[i]);
360 if (indexes.size() == 0) {
361 printf(
"No indexes given.\n\n");
362 print_usage(argv[0]);
366 return print_indexes(file, indexes);
368 }
else if (command ==
"replay") {
369 return replay_file(file);
371 }
else if (command ==
"repair") {
372 return repair_file(file);
374 }
else if ((command ==
"enable") || (command ==
"disable")) {
375 char * host = strdup(
"localhost");
376 unsigned short int port = 1910;
377 if (argp.has_arg(
"r")) {
378 argp.parse_hostport(
"r", &host, &port);
380 int rv = set_enabled(host, port, (command ==
"enable"));
384 }
else if (command ==
"convert") {
385 if (argp.num_items() != 4) {
386 printf(
"Invalid number of arguments\n");
387 print_usage(argv[0]);
390 std::string outfile = argp.items()[2];
391 std::string format = argp.items()[3];
392 return convert_file(file, outfile, format);
395 printf(
"Invalid command '%s'\n", command.c_str());
396 print_usage(argv[0]);
Class to easily access bblogger log files.
bool has_next()
Check if another entry is available.
void read_next()
Read next entry.
const fawkes::Time & entry_offset() const
Get current entry offset.
static void repair_file(const char *filename)
Repair file.
fawkes::Interface * interface()
Get interface instance.
void read_index(unsigned int index)
Read entry at particular index.
unsigned int remaining_entries()
Get number of remaining entries.
Parse command line arguments.
The BlackBoard abstract class.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
virtual void close(Interface *interface)=0
Close interface.
Base class for exceptions in Fawkes.
void print_trace()
Prints trace to stderr.
virtual const char * what() const
Get primary string.
const char * type_id() const
Get type ID.
File Alteration Monitor Listener.
Monitors files for changes.
Interface field iterator.
size_t get_length() const
Get length of current field.
const char * get_name() const
Get name of current field.
const char * get_value_string(const char *array_sep=", ")
Get value of current field as string.
const char * get_typename() const
Get type of current field as string.
Base class for all Fawkes BlackBoard interfaces.
InterfaceFieldIterator fields_end()
Invalid iterator.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
bool has_writer() const
Check if there is a writer for the interface.
unsigned int msgq_enqueue(Message *message)
Enqueue message at end of queue.
Interface for signal handling.
static void unregister_handler(int signum)
Unregister a SignalHandler for a signal.
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
DisableSwitchMessage Fawkes BlackBoard Interface Message.
EnableSwitchMessage Fawkes BlackBoard Interface Message.
SwitchInterface Fawkes BlackBoard Interface.
A class for handling time.
void wait()
Wait (sleep) for this time.
double in_sec() const
Convet time to seconds.
Fawkes library namespace.