Beispiel #1
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;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    g_type_init ();

    dbg_init ();

    // initialize application state and zero out memory
    g_self = (state_t*) calloc( 1, sizeof(state_t) );
    state_t *self = g_self;



    // run the main loop
    self->loop = g_main_loop_new(NULL, FALSE);

    getopt_t *gopt = getopt_create();

    getopt_add_bool  (gopt, 'h',   "help",    0,        "Show this help");
    getopt_add_bool  (gopt, 'v',   "verbose",    0,     "Be verbose");

    if (!getopt_parse(gopt, argc, argv, 1) || getopt_get_bool(gopt,"help")) {
        printf("Usage: %s [options]\n\n", argv[0]);
        getopt_do_usage(gopt);
        return 0;
    }

    self->verbose = getopt_get_bool(gopt, "verbose");

    self->lcm = lcm_create(NULL);
    if (!self->lcm)
        return 1;

    // read config file
    if (!(self->config = read_config_file ())) {
        dbg (DBG_ERROR, "[viewer] failed to read config file.");
        return -1;
    }


    // attach lcm to main loop
    glib_mainloop_attach_lcm (self->lcm);

    // publish cam settings every now and then
    // g_timeout_add_seconds (2, &publish_log_info_data, self);
    // g_timeout_add_seconds (2, &dump_to_index_file, self);

    // listen to tablet event
    navlcm_log_info_t_subscribe (self->lcm, "LOG_INFO", on_log_info_set_event, self);

    list_files (self);

    publish_log_info_data (self);

    // connect to kill signal
    signal_pipe_glib_quit_on_kill (self->loop);

    // run main loop
    g_main_loop_run (self->loop);

    // cleanup
    g_main_loop_unref (self->loop);

    return 0;
}