void BaseShadow::initUserLog() { MyString logfilename,dagmanLogFile; int use_xml; // we expect job_updater to already be initialized, in case we // need to put the job on hold as a result of failure to open // the log ASSERT( job_updater ); std::vector<const char*> logfiles; if ( getPathToUserLog(jobAd, logfilename) ) { logfiles.push_back(logfilename.Value()); dprintf(D_FULLDEBUG, "%s = %s\n", ATTR_ULOG_FILE, logfilename.Value()); } if ( getPathToUserLog(jobAd, dagmanLogFile, ATTR_DAGMAN_WORKFLOW_LOG) ) { logfiles.push_back(dagmanLogFile.Value()); dprintf(D_FULLDEBUG, "%s = %s\n", ATTR_DAGMAN_WORKFLOW_LOG, dagmanLogFile.Value()); } if( !logfiles.empty()) { if( !uLog.initialize (logfiles, cluster, proc, 0, gjid)) { MyString hold_reason; hold_reason.formatstr("Failed to initialize user log to %s%s%s", logfilename.Value(), logfiles.size() == 1 ? "" : " or ", dagmanLogFile.Value()); dprintf( D_ALWAYS, "%s\n",hold_reason.Value()); holdJobAndExit(hold_reason.Value(), CONDOR_HOLD_CODE_UnableToInitUserLog,0); // holdJobAndExit() should not return, but just in case it does // EXCEPT EXCEPT("Failed to initialize user log: %s",hold_reason.Value()); } uLog.setUseXML(jobAd->LookupBool(ATTR_ULOG_USE_XML, use_xml) && use_xml); if(logfiles.size() > 1) { MyString msk; jobAd->LookupString(ATTR_DAGMAN_WORKFLOW_MASK, msk); Tokenize(msk.Value()); dprintf(D_FULLDEBUG, "Mask is \"%s\"\n", msk.Value()); while(const char* mask = GetNextToken(",",true)) { dprintf(D_FULLDEBUG, "Adding \"%s\" to mask\n",mask); uLog.AddToMask(ULogEventNumber(atoi(mask))); } } } else { dprintf(D_FULLDEBUG, "no %s found\n", ATTR_ULOG_FILE); dprintf(D_FULLDEBUG, "and no %s found\n", ATTR_DAGMAN_WORKFLOW_LOG); } }
bool LocalUserLog::initFromJobAd( ClassAd* ad, const char* path_attr, const char* xml_attr, bool write_event_log ) { MyString tmp, dagmanLogFilename, logfilename; bool use_xml = false; const char* iwd = jic->jobIWD(); int cluster = jic->jobCluster(); int proc = jic->jobProc(); int subproc = jic->jobSubproc(); std::vector<const char*> logfiles; dprintf( D_FULLDEBUG, "LocalUserLog::initFromJobAd: path_attr = %s\n", path_attr); dprintf( D_FULLDEBUG, "LocalUserLog::initFromJobAd: xml_attr = %s\n", xml_attr); // Look for the "regular" user log file (e.g., UserLog or // StarterUserLog). if( ! ad->LookupString(path_attr, tmp) ) { // The fact that this attribute is not found in the ClassAd // indicates we do not want logging to a log file specified // in the submit file. // These semantics are defined in JICShadow::init. // We still need to check below for a DAGMan-specified // workflow log file for local universe!! dprintf( D_FULLDEBUG, "No %s found in job ClassAd\n", path_attr ); } else { dprintf( D_FULLDEBUG, "LocalUserLog::initFromJobAd: tmp = %s\n", tmp.Value()); if( fullpath (tmp.Value() ) ) { // we have a full pathname in the job ad. however, if the // job is using a different iwd (namely, filetransfer is // being used), we want to just stick it in the local iwd // for the job, instead. if( jic->iwdIsChanged() ) { const char* base = condor_basename(tmp.Value()); logfilename.formatstr( "%s/%s", iwd, base); } else { logfilename = tmp; } } else { // no full path, so, use the job's iwd... logfilename.formatstr( "%s/%s", iwd, tmp.Value()); } logfiles.push_back( logfilename.Value()); } // Look for the special workflow log file for DAGMan (local // universe only -- for other universes, the schedd or the // shadow will log to that file and trying to write it in // the starter will cause the starter to crash -- see // gittrac #5299). std::vector<ULogEventNumber> mask_vec; if ( jic->jobUniverse() == CONDOR_UNIVERSE_LOCAL && ad->LookupString(ATTR_DAGMAN_WORKFLOW_LOG, tmp) ) { dprintf( D_FULLDEBUG, "LocalUserLog::initFromJobAd: %s is defined\n", ATTR_DAGMAN_WORKFLOW_LOG); dprintf( D_FULLDEBUG, "LocalUserLog::initFromJobAd: tmp = %s\n", tmp.Value()); if( fullpath (tmp.Value() ) ) { // we have a full pathname in the job ad. however, if the // job is using a different iwd (namely, filetransfer is // being used), we want to just stick it in the local iwd // for the job, instead. if( jic->iwdIsChanged() ) { const char* base = condor_basename(tmp.Value()); dagmanLogFilename.formatstr( "%s/%s", iwd, base); } else { dagmanLogFilename = tmp; } } else { // no full path, so, use the job's iwd... dagmanLogFilename.formatstr( "%s/%s", iwd, tmp.Value()); } logfiles.push_back( dagmanLogFilename.Value()); MyString msk; if( ad->LookupString(ATTR_DAGMAN_WORKFLOW_MASK, msk) ) { // Check the mask of the DAGMan log dprintf( D_FULLDEBUG, "LocalUserLog::initFromJobAd: msk = %s\n", msk.Value()); Tokenize(msk.Value()); while(const char* mask = GetNextToken(",",true)) { dprintf( D_FULLDEBUG, "Adding \"%s\" to the mask\n",mask); mask_vec.push_back(ULogEventNumber(atoi(mask))); } } } if ( logfiles.empty() && write_event_log ) { char *global_log = param( "EVENT_LOG" ); if ( global_log ) { logfiles.push_back( UNIX_NULL_FILE ); free( global_log ); } } if ( logfiles.empty() ) { return initNoLogging(); } ad->LookupBool( xml_attr, use_xml ); for(std::vector<const char*>::iterator p = logfiles.begin(); p != logfiles.end(); ++p) { dprintf( D_FULLDEBUG, "LocalUserLog::initFromJobAd: UserLog " "file %s\n",*p); } bool ret = init( logfiles, use_xml, cluster, proc, subproc ); if(ret) { for(std::vector<ULogEventNumber>::iterator m = mask_vec.begin(); m != mask_vec.end(); ++m) { u_log.AddToMask(*m); } } dprintf( D_FULLDEBUG, "LocalUserLog::initFromJobAd: returning %s\n", ret?"True":"False"); return ret; }