static int process_jlog(const char *file, const char *sub) { jlog_ctx *log = jlog_new(file); if (add_subscriber) { if (jlog_ctx_add_subscriber(log, add_subscriber, JLOG_BEGIN)) { fprintf(stderr, "Could not add subscriber '%s': %s\n", add_subscriber, jlog_ctx_err_string(log)); } else { OUT("Added subscriber '%s'\n", add_subscriber); } } if (remove_subscriber) { if (jlog_ctx_remove_subscriber(log, remove_subscriber) <= 0) { fprintf(stderr, "Could not erase subscriber '%s': %s\n", remove_subscriber, jlog_ctx_err_string(log)); } else { OUT("Erased subscriber '%s'\n", remove_subscriber); } } if (!sub) { if (jlog_ctx_open_writer(log)) { fprintf(stderr, "error opening '%s'\n", file); return 0; } } else { if (jlog_ctx_open_reader(log, sub)) { fprintf(stderr, "error opening '%s'\n", file); return 0; } } if (show_progress) { char buff[20], buff2[20], buff3[20]; jlog_id id, id2, id3; jlog_get_checkpoint(log, sub, &id); if (jlog_ctx_last_log_id(log, &id3)) { fprintf(stderr, "jlog_error: %s\n", jlog_ctx_err_string(log)); fprintf(stderr, "error calling jlog_ctx_last_log_id\n"); } jlog_snprint_logid(buff, sizeof(buff), &id); jlog_snprint_logid(buff3, sizeof(buff3), &id3); OUT("--------------------\n" " Perspective of the '%s' subscriber\n" " current checkpoint: %s\n" " Last write: %s\n", sub, buff, buff3); if (jlog_ctx_read_interval(log, &id, &id2) < 0) { fprintf(stderr, "jlog_error: %s\n", jlog_ctx_err_string(log)); } jlog_snprint_logid(buff, sizeof(buff), &id); jlog_snprint_logid(buff2, sizeof(buff2), &id2); OUT(" next interval: [%s, %s]\n" "--------------------\n\n", buff, buff2); } if (show_subscribers) { char **list; int i; jlog_ctx_list_subscribers(log, &list); for (i = 0; list[i]; i++) { char buff[20]; jlog_id id; jlog_get_checkpoint(log, list[i], &id); jlog_snprint_logid(buff, sizeof(buff), &id); OUT("\t%32s @ %s\n", list[i], buff); } jlog_ctx_list_subscribers_dispose(log, list); } if (show_files) { struct dirent *de; DIR *dir; dir = opendir(file); if (!dir) { fprintf(stderr, "error opening '%s'\n", file); return 0; } while ((de = readdir(dir)) != NULL) { uint32_t logid; if (is_datafile(de->d_name, &logid)) { char fullfile[MAXPATHLEN]; char fullidx[MAXPATHLEN]; struct stat sb; int readers; snprintf(fullfile, sizeof(fullfile), "%s/%s", file, de->d_name); snprintf(fullidx, sizeof(fullidx), "%s/%s" INDEX_EXT, file, de->d_name); if (stat(fullfile, &sb)) { OUT("\t%8s [error stat(2)ing file: %s\n", de->d_name, strerror(errno)); } else { readers = __jlog_pending_readers(log, logid); OUT("\t%8s [%ju bytes] %d pending readers\n", de->d_name, sb.st_size, readers); if (show_index_info) { if (stat(fullidx, &sb)) { OUT("\t\t idx: none\n"); } else { uint32_t marker; int closed; if (jlog_idx_details(log, logid, &marker, &closed)) { OUT("\t\t idx: error\n"); } else { OUT("\t\t idx: %u messages (%08x), %s\n", marker, marker, closed ? "closed" : "open"); } } } if (analyze_datafiles) { analyze_datafile(log, logid); } if (readers == 0 && cleanup) { unlink(fullfile); unlink(fullidx); } } } } closedir(dir); } jlog_ctx_close(log); }
void *reader(void *unused) { jlog_ctx *ctx; char subname[32]; int tcount = 0, fcount = 0; int prev_err = 0; int subno = (int)(uintptr_t)unused; snprintf(subname, sizeof(subname), "sub-%02d", subno); reader_retry: ctx = jlog_new(LOGNAME); if(jlog_ctx_open_reader(ctx, subname) != 0) { if(prev_err == 0) { prev_err = jlog_ctx_err(ctx); jlog_ctx_close(ctx); ctx = jlog_new(LOGNAME); if(prev_err == JLOG_ERR_INVALID_SUBSCRIBER) { fprintf(stderr, "[%02d] invalid subscriber, init...\n", subno); if(jlog_ctx_open_writer(ctx) != 0) { fprintf(stderr, "[%02d] jlog_ctx_open_writer failed: %d %s\n", subno, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx)); } else { if(jlog_ctx_add_subscriber(ctx, subname, JLOG_BEGIN) != 0) { fprintf(stderr, "[%02d] jlog_ctx_add_subscriber failed: %d %s\n", subno, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx)); } else { jlog_ctx_close(ctx); goto reader_retry; } } } } fprintf(stderr, "[%02d] jlog_ctx_open_reader failed: %d %s\n", subno, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx)); croak(); } fprintf(stderr, "[%02d] reader started\n", subno); while(1) { char begins[20], ends[20]; jlog_id begin, end; int count; jlog_message message; if((count = jlog_ctx_read_interval(ctx, &begin, &end)) == -1) { fprintf(stderr, "jlog_ctx_read_interval failed: %d %s\n", jlog_ctx_err(ctx), jlog_ctx_err_string(ctx)); croak(); } jlog_snprint_logid(begins, sizeof(begins), &begin); jlog_snprint_logid(ends, sizeof(ends), &end); if(count > 0) { int i; //fprintf(stderr, "[%02d] reader (%s, %s] count: %d\n", subno, begins, ends, count); for(i=0; i<count; i++, JLOG_ID_ADVANCE(&begin)) { end = begin; if(jlog_ctx_read_message(ctx, &begin, &message) != 0) { if(jlog_ctx_err(ctx) == JLOG_ERR_CLOSE_LOGID) { /* fine */ } else { fcount++; jlog_snprint_logid(begins, sizeof(begins), &begin); fprintf(stderr, "[%02d] read failed @ %s: %d %s\n", subno, begins, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx)); } } else { tcount++; jlog_snprint_logid(begins, sizeof(begins), &begin); /* fprintf(stderr, "[%02d] read: [%s]\n\t'%.*s'\n", subno, begins, message.mess_len, (char *)message.mess); */ } } if(jlog_ctx_read_checkpoint(ctx, &end) != 0) { fprintf(stderr, "[%02d] checkpoint failed: %d %s\n", subno, jlog_ctx_err(ctx), jlog_ctx_err_string(ctx)); } else { fprintf(stderr, "[%02d] \tcheckpointed...\n", subno); } } else { if(writer_done == 1) break; } } fprintf(stderr, "[%02d] reader read %d, failed %d\n", subno, tcount, fcount); jlog_ctx_close(ctx); return (void *)(uintptr_t)tcount; }