static void lcm_logprov_destroy (lcm_logprov_t *lr) { dbg (DBG_LCM, "closing lcm log provider context\n"); if (lr->thread_created) { /* Destroy the timer thread */ int64_t abort_cmd = -1; int status = lcm_internal_pipe_write(lr->timer_pipe[1], &abort_cmd, sizeof(abort_cmd)); if(status < 0) { perror(__FILE__ " - write (abort_cmd)"); } g_thread_join (lr->timer_thread); } if(lr->notify_pipe[0] >= 0) lcm_internal_pipe_close(lr->notify_pipe[0]); if(lr->notify_pipe[1] >= 0) lcm_internal_pipe_close(lr->notify_pipe[1]); if(lr->timer_pipe[0] >= 0) lcm_internal_pipe_close(lr->timer_pipe[0]); if(lr->timer_pipe[1] >= 0) lcm_internal_pipe_close(lr->timer_pipe[1]); if (lr->event) lcm_eventlog_free_event (lr->event); if (lr->log) lcm_eventlog_destroy (lr->log); free (lr->filename); free (lr); }
static int pylog_initobj(PyObject *s, PyObject *args, PyObject *kwds) { PyLogObject *self = (PyLogObject *)s; static char *keywords[] = { "filename", "mode", 0 }; char *filename = NULL; char *mode = "r"; if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", keywords, &filename, &mode)) return -1; if (!strcmp (mode, "r")) { self->mode = 'r'; } else if (!strcmp (mode, "w")) { self->mode = 'w'; } else { PyErr_SetString (PyExc_ValueError, "invalid mode"); return -1; } if (self->eventlog) { lcm_eventlog_destroy (self->eventlog); } self->eventlog = lcm_eventlog_create (filename, mode); if (!self->eventlog) { PyErr_SetFromErrno (PyExc_IOError); return -1; } return 0; }
static void pylog_dealloc(PyLogObject *self) { if (self->eventlog) { lcm_eventlog_destroy (self->eventlog); } Py_TYPE(self)->tp_free((PyObject*)self); }
LogFile::~LogFile() { if(eventlog) lcm_eventlog_destroy(eventlog); eventlog = NULL; if(last_event) lcm_eventlog_free_event(last_event); last_event = NULL; }
static PyObject * pylog_close (PyLogObject *self) { if (self->eventlog) { lcm_eventlog_destroy (self->eventlog); self->eventlog = NULL; } Py_INCREF (Py_None); return Py_None; }
int main(int argc, char **argv) { if(argc < 2) { fprintf(stderr, "usage: example1-poses <logfile>\n"); return 1; } lcm_eventlog_t *log = lcm_eventlog_create(argv[1], "r"); if(!log) { fprintf(stderr, "error opening log file\n"); return 1; } printf("# utime x y z x' y' z'\n"); lcm_eventlog_event_t *event = lcm_eventlog_read_next_event(log); while(event) { if(!strcmp(event->channel, "POSE")) { lcmtypes_pose_t pose; lcmtypes_pose_t_decode(event->data, 0, event->datalen, &pose); printf("%lld %f %f %f %f %f %f\n", (long long)pose.utime, pose.pos[0], pose.pos[1], pose.pos[2], pose.vel[0], pose.vel[1], pose.vel[2]); lcmtypes_pose_t_decode_cleanup(&pose); } lcm_eventlog_free_event(event); event = lcm_eventlog_read_next_event(log); } lcm_eventlog_destroy(log); return 0; }
int main(int argc, char **argv) { if(argc < 2) { fprintf(stderr, "usage: example3-gps <logfile>\n"); return 1; } lcm_eventlog_t *log = lcm_eventlog_create(argv[1], "r"); if(!log) { fprintf(stderr, "error opening log file\n"); return 1; } lcm_eventlog_event_t *event = lcm_eventlog_read_next_event(log); while(event) { if(!strcmp(event->channel, "GPS_TO_LOCAL")) { lcmtypes_gps_to_local_t gps; lcmtypes_gps_to_local_t_decode(event->data, 0, event->datalen, &gps); printf("%lld %.10f %.10f %f %f\n", (long long)gps.utime, gps.lat_lon_el_theta[0], gps.lat_lon_el_theta[1], gps.lat_lon_el_theta[2], gps.lat_lon_el_theta[3]); lcmtypes_gps_to_local_t_decode_cleanup(&gps); } lcm_eventlog_free_event(event); event = lcm_eventlog_read_next_event(log); } lcm_eventlog_destroy(log); return 0; }
int main(int argc, char **argv) { int verbose = 0; int filterChannels =0; char *pattern = strdup(".*"); char *dest_fname = NULL; int64_t start_utime = 0; int64_t end_utime = -1; int have_end_utime = 0; int invert_regex = 0; char *optstring = "hc:vs:e:i"; int c; while ((c = getopt_long(argc, argv, optstring, NULL, 0)) >= 0) { switch (c) { case 'h': usage(); break; case 's': { char *eptr = NULL; double start_time = strtod(optarg, &eptr); if (*eptr != 0) usage(); start_utime = (int64_t) (start_time * 1000000); } break; case 'e': { char *eptr = NULL; double end_time = strtod(optarg, &eptr); if (*eptr != 0) usage(); end_utime = (int64_t) (end_time * 1000000); have_end_utime = 1; } break; case 'i': invert_regex = 1; filterChannels = 1; break; case 'c': free(pattern); pattern = strdup(optarg); filterChannels = 1; break; case 'v': verbose = 1; break; default: usage(); break; }; } if (start_utime < 0 || (have_end_utime && end_utime < start_utime)) usage(); if (optind > argc - 3) usage(); regex_t preg; if (0 != regcomp(&preg, pattern, REG_NOSUB | REG_EXTENDED)) { fprintf(stderr, "bad regex\n"); exit(1); } int num_src_logs = argc - optind - 1; fprintf(stderr, "Splicing together %d logs\n", num_src_logs); lcm_eventlog_t *src_logs[num_src_logs]; for (int i = 0; i < argc - optind - 1; i++) { char * src_fname = argv[optind + i]; src_logs[i] = lcm_eventlog_create(src_fname, "r"); if (!src_logs[i]) { perror("Unable to open source logfile"); for (int j = 0; j < i; j++) lcm_eventlog_destroy(src_logs[j]); regfree(&preg); return 1; } } dest_fname = argv[argc - 1]; lcm_eventlog_t *dst_log = lcm_eventlog_create(dest_fname, "w"); if (!dst_log) { perror("Unable to open destination logfile"); for (int i = 0; i < num_src_logs; i++) lcm_eventlog_destroy(src_logs[i]); regfree(&preg); return 1; } GHashTable *counts = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); int nwritten = 0; int have_first_event_timestamp = 0; int64_t first_event_timestamp = -1; lcm_eventlog_event_t *events[num_src_logs]; for (int i = 0; i < num_src_logs; i++) events[i] = lcm_eventlog_read_next_event(src_logs[i]); while (1) { lcm_eventlog_event_t *event; int mind = -1; int64_t mtime = INT64_MAX; for (int i = 0; i < num_src_logs; i++) { if (events[i] == NULL) continue; else if (events[i]->timestamp < mtime) { mtime = events[i]->timestamp; mind = i; } } if (mind < 0) //all are null break; event = events[mind]; events[mind] = lcm_eventlog_read_next_event(src_logs[mind]); if (!have_first_event_timestamp) { first_event_timestamp = event->timestamp; have_first_event_timestamp = 1; } int64_t elapsed = event->timestamp - first_event_timestamp; if (elapsed < start_utime) { lcm_eventlog_free_event(event); continue; } if (have_end_utime && elapsed > end_utime) { lcm_eventlog_free_event(event); break; } int copy_to_dest = 1; if (filterChannels) { int regmatch = regexec(&preg, event->channel, 0, NULL, 0); copy_to_dest = (regmatch == 0 && !invert_regex) || (regmatch != 0 && invert_regex); } if (copy_to_dest) { lcm_eventlog_write_event(dst_log, event); nwritten++; if (verbose) { int *count = g_hash_table_lookup(counts, event->channel); if (!count) { count = (int*) malloc(sizeof(int)); *count = 1; g_hash_table_insert(counts, strdup(event->channel), count); printf("matched channel %s\n", event->channel); } else { *count += 1; } } } lcm_eventlog_free_event(event); } if (verbose) { g_hash_table_foreach(counts, _verbose_entry_summary, NULL); printf("=====\n"); printf("Events written: %d\n", nwritten); } regfree(&preg); for (int i = 0; i < num_src_logs; i++) lcm_eventlog_destroy(src_logs[i]); lcm_eventlog_destroy(dst_log); g_hash_table_destroy(counts); return 0; }
int main(int argc, char **argv) { int verbose = 0; char *pattern = g_strdup(".*"); char *source_fname = NULL; char *dest_fname = NULL; int64_t start_utime = 0; int64_t end_utime = -1; int have_end_utime = 0; int invert_regex = 0; char *optstring = "hc:vs:e:i"; int c; while ((c = getopt_long(argc, argv, optstring, NULL, 0)) >= 0) { switch (c) { case 'h': usage(); break; case 's': { char *eptr = NULL; double start_time = strtod(optarg, &eptr); if (*eptr != 0) usage(); start_utime = (int64_t)(start_time * 1000000); } break; case 'e': { char *eptr = NULL; double end_time = strtod(optarg, &eptr); if (*eptr != 0) usage(); end_utime = (int64_t)(end_time * 1000000); have_end_utime = 1; } break; case 'i': invert_regex = 1; break; case 'c': g_free(pattern); pattern = g_strdup(optarg); break; case 'v': verbose = 1; break; default: usage(); break; }; } if (start_utime < 0 || (have_end_utime && end_utime < start_utime)) usage(); if (optind != argc - 2) usage(); GRegex *regex; GError *rerr = NULL; regex = g_regex_new(pattern, (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &rerr); if (rerr) { fprintf(stderr, "bad regex\n"); exit(1); } source_fname = argv[argc - 2]; dest_fname = argv[argc - 1]; lcm_eventlog_t *src_log = lcm_eventlog_create(source_fname, "r"); if (!src_log) { perror("Unable to open source logfile"); g_regex_unref(regex); return 1; } lcm_eventlog_t *dst_log = lcm_eventlog_create(dest_fname, "w"); if (!dst_log) { perror("Unable to open destination logfile"); lcm_eventlog_destroy(src_log); g_regex_unref(regex); return 1; } GHashTable *counts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free); int nwritten = 0; int have_first_event_timestamp = 0; int64_t first_event_timestamp = 0; for (lcm_eventlog_event_t *event = lcm_eventlog_read_next_event(src_log); event != NULL; event = lcm_eventlog_read_next_event(src_log)) { if (!have_first_event_timestamp) { first_event_timestamp = event->timestamp; have_first_event_timestamp = 1; } int64_t elapsed = event->timestamp - first_event_timestamp; if (elapsed < start_utime) { lcm_eventlog_free_event(event); continue; } if (have_end_utime && elapsed > end_utime) { lcm_eventlog_free_event(event); break; } int regmatch = g_regex_match(regex, event->channel, (GRegexMatchFlags) 0, NULL); if ((!regmatch && invert_regex) || (regmatch && !invert_regex)) { lcm_eventlog_write_event(dst_log, event); nwritten++; if (verbose) { int *count = (int *) g_hash_table_lookup(counts, event->channel); if (!count) { count = (int *) malloc(sizeof(int)); *count = 1; g_hash_table_insert(counts, g_strdup(event->channel), count); printf("matched channel %s\n", event->channel); } else { *count += 1; } } } lcm_eventlog_free_event(event); } if (verbose) { g_hash_table_foreach(counts, _verbose_entry_summary, NULL); printf("=====\n"); printf("Events written: %d\n", nwritten); } g_regex_unref(regex); lcm_eventlog_destroy(src_log); lcm_eventlog_destroy(dst_log); g_hash_table_destroy(counts); return 0; }
int main(int argc, char *argv[]) { #ifndef WIN32 setlinebuf (stdout); #endif char logpath[PATH_MAX]; memset (logpath, 0, sizeof (logpath)); logger_t logger; memset (&logger, 0, sizeof (logger)); // set some defaults logger.force_overwrite = 0; logger.auto_increment = 0; logger.use_strftime = 0; char *chan_regex = strdup(".*"); double max_write_queue_size_mb = DEFAULT_MAX_WRITE_QUEUE_SIZE_MB; logger.invert_channels = 0; logger.fflush_interval_ms = 100; char *lcmurl = NULL; char *optstring = "a:fic:shm:vu:"; int c; struct option long_opts[] = { { "auto-split-hours", required_argument, 0, 'a' }, { "auto-split-mb", required_argument, 0, 'b' }, { "channel", required_argument, 0, 'c' }, { "force", no_argument, 0, 'f' }, { "increment", required_argument, 0, 'i' }, { "lcm-url", required_argument, 0, 'l' }, { "max-unwritten-mb", required_argument, 0, 'm' }, { "strftime", required_argument, 0, 's' }, { "invert-channels", no_argument, 0, 'v' }, { "flush-interval", required_argument, 0,'u'}, { 0, 0, 0, 0 } }; while ((c = getopt_long (argc, argv, optstring, long_opts, 0)) >= 0) { switch (c) { case 'a': logger.auto_split_hours = strtod(optarg, NULL); logger.auto_increment = 1; if(logger.auto_split_hours <= 0) { usage(); return 1; } break; case 'b': logger.auto_split_mb = strtod(optarg, NULL); logger.auto_increment = 1; if(logger.auto_split_mb <= 0) { usage(); return 1; } break; case 'f': logger.force_overwrite = 1; break; case 'c': free(chan_regex); chan_regex = strdup(optarg); break; case 'i': logger.auto_increment = 1; break; case 's': logger.use_strftime = 1; break; case 'l': free(lcmurl); lcmurl = strdup(optarg); break; case 'v': logger.invert_channels = 1; break; case 'm': max_write_queue_size_mb = strtod(optarg, NULL); if(max_write_queue_size_mb <= 0) { usage(); return 1; } break; case 'u': logger.fflush_interval_ms = atol(optarg); if(logger.fflush_interval_ms <= 0) { usage(); return 1; } break; case 'h': default: usage(); return 1; }; } if (optind == argc) { strcpy (logger.input_fname, "lcmlog-%Y-%m-%d"); logger.auto_increment = 1; logger.use_strftime = 1; } else if (optind == argc - 1) { strncpy (logger.input_fname, argv[optind], sizeof (logger.input_fname)); } else if (optind < argc-1) { usage (); return 1; } // initialize GLib threading g_thread_init(NULL); logger.time0 = timestamp_now(); logger.max_write_queue_size = (int64_t)(max_write_queue_size_mb * (1 << 20)); if(0 != open_logfile(&logger)) return 1; // create write thread logger.write_thread_exit_flag = 0; logger.mutex = g_mutex_new(); logger.write_queue_size = 0; logger.write_queue = g_async_queue_new(); logger.write_thread = g_thread_create(write_thread, &logger, TRUE, NULL); // begin logging logger.lcm = lcm_create (lcmurl); free(lcmurl); if (!logger.lcm) { fprintf (stderr, "Couldn't initialize LCM!"); return 1; } if(logger.invert_channels) { // if inverting the channels, subscribe to everything and invert on the // callback lcm_subscribe(logger.lcm, ".*", message_handler, &logger); char *regexbuf = g_strdup_printf("^%s$", chan_regex); #ifdef USE_GREGEX GError *rerr = NULL; logger.regex = g_regex_new(regexbuf, (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, &rerr); if(rerr) { fprintf(stderr, "%s\n", rerr->message); g_free(regexbuf); return 1; } #else if (0 != regcomp (&logger.preg, regexbuf, REG_NOSUB | REG_EXTENDED)) { fprintf(stderr, "bad regex!\n"); g_free(regexbuf); return 1; } #endif g_free(regexbuf); } else { // otherwise, let LCM handle the regex lcm_subscribe(logger.lcm, chan_regex, message_handler, &logger); } free(chan_regex); _mainloop = g_main_loop_new (NULL, FALSE); signal_pipe_glib_quit_on_kill (); glib_mainloop_attach_lcm (logger.lcm); #ifdef USE_SIGHUP signal(SIGHUP, sighup_handler); #endif // main loop g_main_loop_run (_mainloop); fprintf(stderr, "Logger exiting\n"); // stop the write thread g_mutex_lock(logger.mutex); logger.write_thread_exit_flag = 1; g_mutex_unlock(logger.mutex); g_async_queue_push(logger.write_queue, &logger.write_thread_exit_flag); g_thread_join(logger.write_thread); g_mutex_free(logger.mutex); // cleanup. This isn't strictly necessary, do it to be pedantic and so that // leak checkers don't complain glib_mainloop_detach_lcm (logger.lcm); lcm_destroy (logger.lcm); lcm_eventlog_destroy (logger.log); for(void *msg = g_async_queue_try_pop(logger.write_queue); msg; msg=g_async_queue_try_pop(logger.write_queue)) { if(msg == &logger.write_thread_exit_flag) continue; free(msg); } g_async_queue_unref(logger.write_queue); if(logger.invert_channels) { #ifdef USE_GREGEX g_regex_unref(logger.regex); #else regfree(&logger.preg); #endif } return 0; }
static void* write_thread(void *user_data) { logger_t *logger = (logger_t*) user_data; GTimeVal start_time; g_get_current_time(&start_time); int num_splits = 0; int64_t next_split_sec = start_time.tv_sec + logger->auto_split_hours * SECONDS_PER_HOUR; while(1) { void *msg = g_async_queue_pop(logger->write_queue); // Is it time to start a new logfile? int split_log = 0; if(logger->auto_split_hours) { GTimeVal now; g_get_current_time(&now); split_log = (now.tv_sec > next_split_sec); } else if(logger->auto_split_mb) { double logsize_mb = (double)logger->logsize / (1 << 20); split_log = (logsize_mb > logger->auto_split_mb); } if(_reset_logfile) { split_log = 1; _reset_logfile = 0; } if(split_log) { // Yes. open up a new log file lcm_eventlog_destroy(logger->log); if(0 != open_logfile(logger)) exit(1); num_splits++; int64_t log_duration_sec = logger->auto_split_hours * SECONDS_PER_HOUR; next_split_sec = start_time.tv_sec + (num_splits + 1) * log_duration_sec; logger->logsize = 0; logger->last_report_logsize = 0; } // Should the write thread exit? g_mutex_lock(logger->mutex); if(logger->write_thread_exit_flag) { g_mutex_unlock(logger->mutex); return NULL; } // nope. write the event to disk lcm_eventlog_event_t *le = (lcm_eventlog_event_t*) msg; int64_t sz = sizeof(lcm_eventlog_event_t) + le->channellen + 1 + le->datalen; logger->write_queue_size -= sz; g_mutex_unlock(logger->mutex); if(0 != lcm_eventlog_write_event(logger->log, le)) { static int64_t last_spew_utime = 0; char *reason = strdup(strerror(errno)); int64_t now = timestamp_now(); if(now - last_spew_utime > 500000) { fprintf(stderr, "lcm_eventlog_write_event: %s\n", reason); last_spew_utime = now; } free(reason); free(le); if(errno == ENOSPC) { exit(1); } else { continue; } } if (logger->fflush_interval_ms >= 0 && (le->timestamp - logger->last_fflush_time) > logger->fflush_interval_ms*1000) { fflush(logger->log->f); logger->last_fflush_time = le->timestamp; } // bookkeeping, cleanup int64_t offset_utime = le->timestamp - logger->time0; logger->nevents++; logger->events_since_last_report ++; logger->logsize += 4 + 8 + 8 + 4 + le->channellen + 4 + le->datalen; free(le); if (offset_utime - logger->last_report_time > 1000000) { double dt = (offset_utime - logger->last_report_time)/1000000.0; double tps = logger->events_since_last_report / dt; double kbps = (logger->logsize - logger->last_report_logsize) / dt / 1024.0; printf("Summary: %s ti:%4"PRIi64"sec Events: %-9"PRIi64" ( %4"PRIi64" MB ) TPS: %8.2f KB/s: %8.2f\n", logger->fname, timestamp_seconds(offset_utime), logger->nevents, logger->logsize/1048576, tps, kbps); logger->last_report_time = offset_utime; logger->events_since_last_report = 0; logger->last_report_logsize = logger->logsize; } } }