// Read the history from the specified history file, or from all the history files. // There are multiple history files because we do rotation. static void readHistoryFromFiles(bool fileisuserlog, const char *JobHistoryFileName, const char* constraint, ExprTree *constraintExpr) { printHeader(); if (JobHistoryFileName) { if (fileisuserlog) { ClassAdList jobs; if ( ! userlog_to_classads(JobHistoryFileName, jobs, NULL, 0, constraint)) { fprintf(stderr, "Error: Can't open userlog %s\n", JobHistoryFileName); exit(1); } printJobAds(jobs); jobs.Clear(); } else { // If the user specified the name of the file to read, we read that file only. readHistoryFromFileEx(JobHistoryFileName, constraint, constraintExpr, backwards); } } else { // The user didn't specify the name of the file to read, so we read // the history file, and any backups (rotated versions). int numHistoryFiles; const char **historyFiles; historyFiles = findHistoryFiles("HISTORY", &numHistoryFiles); if (!historyFiles) { fprintf( stderr, "Error: No history file is defined\n"); fprintf(stderr, "\n"); print_wrapped_text("Extra Info: " "The variable HISTORY is not defined in " "your config file. If you want Condor to " "keep a history of past jobs, you must " "define HISTORY in your config file", stderr ); exit(1); } if (historyFiles && numHistoryFiles > 0) { int fileIndex; if (backwards) { // Reverse reading of history files array for(fileIndex = numHistoryFiles - 1; fileIndex >= 0; fileIndex--) { readHistoryFromFileEx(historyFiles[fileIndex], constraint, constraintExpr, backwards); } } else { for (fileIndex = 0; fileIndex < numHistoryFiles; fileIndex++) { readHistoryFromFileEx(historyFiles[fileIndex], constraint, constraintExpr, backwards); } } freeHistoryFilesList(historyFiles); } } return; }
void shortlog_output(struct shortlog *log) { int i, j; if (log->sort_by_number) qsort(log->list.items, log->list.nr, sizeof(struct path_list_item), compare_by_number); for (i = 0; i < log->list.nr; i++) { struct path_list *onelines = log->list.items[i].util; if (log->summary) { printf("%6d\t%s\n", onelines->nr, log->list.items[i].path); } else { printf("%s (%d):\n", log->list.items[i].path, onelines->nr); for (j = onelines->nr - 1; j >= 0; j--) { const char *msg = onelines->items[j].path; if (log->wrap_lines) { int col = print_wrapped_text(msg, log->in1, log->in2, log->wrap); if (col != log->wrap) putchar('\n'); } else printf(" %s\n", msg); } putchar('\n'); } onelines->strdup_paths = 1; path_list_clear(onelines, 1); free(onelines); log->list.items[i].util = NULL; } log->list.strdup_paths = 1; path_list_clear(&log->list, 1); log->mailmap.strdup_paths = 1; path_list_clear(&log->mailmap, 1); }
int main(int argc, char* argv[]) { Collectors = NULL; HistorySnapshot *historySnapshot; SQLQuery queryhor; SQLQuery queryver; QuillErrCode st; void **parameters; char *dbconn=NULL; bool readfromfile = false,remotequill=false; char *dbIpAddr=NULL, *dbName=NULL,*queryPassword=NULL,*quillName=NULL; AttrList *ad=0; int flag = 1; MyString tmp; int i; parameters = (void **) malloc(NUM_PARAMETERS * sizeof(void *)); myDistro->Init( argc, argv ); queryhor.setQuery(HISTORY_ALL_HOR, NULL); queryver.setQuery(HISTORY_ALL_VER, NULL); longformat=TRUE; for(i=1; i<argc; i++) { if(strcmp(argv[i], "-name")==0) { i++; if (argc <= i) { fprintf( stderr, "Error: Argument -name requires the name of a quilld as a parameter\n" ); exit(1); } if( !(quillName = get_daemon_name(argv[i])) ) { fprintf( stderr, "Error: unknown host %s\n", get_host_part(argv[i]) ); printf("\n"); print_wrapped_text("Extra Info: The name given with the -name " "should be the name of a condor_quilld process. " "Normally it is either a hostname, or " "\"name@hostname\". " "In either case, the hostname should be the " "Internet host name, but it appears that it " "wasn't.", stderr); exit(1); } tmp.sprintf ("%s == \"%s\"", ATTR_NAME, quillName); quillQuery.addORConstraint (tmp.Value()); tmp.sprintf ("%s == \"%s\"", ATTR_SCHEDD_NAME, quillName); quillQuery.addORConstraint (tmp.Value()); remotequill = true; readfromfile = false; } else if (strcmp(argv[i],"-help")==0) { Usage(argv[0],0); } } if (i<argc) Usage(argv[0]); config(); /* This call must happen AFTER config() is called */ if (checkDBconfig() == true && !readfromfile) { readfromfile = false; } else { /* couldn't get DB configuration, so bail out */ printf("Error: Cannot use DB to get history information\n"); exit(1); } if(readfromfile == false) { if(remotequill) { if (Collectors == NULL) { Collectors = CollectorList::create(); if(Collectors == NULL ) { printf("Error: Unable to get list of known collectors\n"); exit(1); } } result = Collectors->query ( quillQuery, quillList ); if(result != Q_OK) { printf("Fatal Error querying collectors\n"); exit(1); } if(quillList.MyLength() == 0) { printf("Error: Unknown quill server %s\n", quillName); exit(1); } quillList.Open(); while ((ad = quillList.Next())) { // get the address of the database dbIpAddr = dbName = queryPassword = NULL; if (!ad->LookupString(ATTR_QUILL_DB_IP_ADDR, &dbIpAddr) || !ad->LookupString(ATTR_QUILL_DB_NAME, &dbName) || !ad->LookupString(ATTR_QUILL_DB_QUERY_PASSWORD, &queryPassword) || (ad->LookupBool(ATTR_QUILL_IS_REMOTELY_QUERYABLE,flag) && !flag)) { printf("Error: The quill daemon \"%s\" is not set up " "for database queries\n", quillName); exit(1); } } } dbconn = getDBConnStr(quillName,dbIpAddr,dbName,queryPassword); historySnapshot = new HistorySnapshot(dbconn); //printf ("\n\n-- Quill: %s : %s : %s\n", quillName, dbIpAddr, dbName); st = historySnapshot->sendQuery(&queryhor, &queryver, longformat, true); //if there's a failure here and if we're not posing a query on a //remote quill daemon, we should instead query the local file if(st == QUILL_FAILURE) { printf( "-- Database at %s not reachable\n", dbIpAddr); } // query history table if (historySnapshot->isHistoryEmpty()) { printf("No historical jobs in the database\n"); } historySnapshot->release(); delete(historySnapshot); } if(parameters) free(parameters); if(dbIpAddr) free(dbIpAddr); if(dbName) free(dbName); if(queryPassword) free(queryPassword); if(quillName) free(quillName); if(dbconn) free(dbconn); return 0; }
static char * getDBConnStr(char *&quillName, char *&databaseIp, char *&databaseName, char *&queryPassword) { char *host, *port, *dbconn, *ptr_colon; char *tmpquillname, *tmpdatabaseip, *tmpdatabasename, *tmpquerypassword; int len, tmp1, tmp2, tmp3; if((!quillName && !(tmpquillname = param("QUILL_NAME"))) || (!databaseIp && !(tmpdatabaseip = param("QUILL_DB_IP_ADDR"))) || (!databaseName && !(tmpdatabasename = param("QUILL_DB_NAME"))) || (!queryPassword && !(tmpquerypassword = param("QUILL_DB_QUERY_PASSWORD")))) { fprintf( stderr, "Error: Could not find database related parameter\n"); fprintf(stderr, "\n"); print_wrapped_text("Extra Info: " "The most likely cause for this error " "is that you have not defined " "QUILL_NAME/QUILL_DB_IP_ADDR/" "QUILL_DB_NAME/QUILL_DB_QUERY_PASSWORD " "in the condor_config file. You must " "define this variable in the config file", stderr); exit( 1 ); } if(!quillName) { quillName = tmpquillname; } if(!databaseIp) { if(tmpdatabaseip[0] != '<') { //2 for the two brackets and 1 for the null terminator databaseIp = (char *) malloc(strlen(tmpdatabaseip)+3); sprintf(databaseIp, "<%s>", tmpdatabaseip); free(tmpdatabaseip); } else { databaseIp = tmpdatabaseip; } } if(!databaseName) { databaseName = tmpdatabasename; } if(!queryPassword) { queryPassword = tmpquerypassword; } tmp1 = strlen(databaseName); tmp2 = strlen(queryPassword); len = strlen(databaseIp); //the 6 is for the string "host= " or "port= " //the rest is a subset of databaseIp so a size of //databaseIp is more than enough host = (char *) malloc((len+6) * sizeof(char)); port = (char *) malloc((len+6) * sizeof(char)); //here we break up the ipaddress:port string and assign the //individual parts to separate string variables host and port ptr_colon = strchr(databaseIp, ':'); strcpy(host, "host= "); strncat(host, databaseIp+1, ptr_colon - databaseIp-1); strcpy(port, "port= "); strcat(port, ptr_colon+1); port[strlen(port)-1] = '\0'; //tmp3 is the size of dbconn - its size is estimated to be //(2 * len) for the host/port part, tmp1 + tmp2 for the //password and dbname part and 1024 as a cautiously //overestimated sized buffer tmp3 = (2 * len) + tmp1 + tmp2 + 1024; dbconn = (char *) malloc(tmp3 * sizeof(char)); sprintf(dbconn, "%s %s user=quillreader password=%s dbname=%s", host, port, queryPassword, databaseName); free(host); free(port); return dbconn; }