Thursday, June 20, 2019

Get Process and Thread Ids

It is sometimes useful to know the PID or Thread.  For instance if an error occurs and I want to get the specific server OM Log file I can find that file if I knew the Thread and PID.  I am not aware of any way to get these values directly though it is obvious the Siebel application OM has these values internally.  The TraceOn function allows these values to be used while opening and naming the trace file:
TheApplication().TraceOn("TraceFile_$p_$t.log", "Allocation", "All");
results in name like
TraceFile_7382_8188.log
So the trick is to create this file then read the relevant values out of the name.  To do so, I create the file with a unique name that will be known to the script creating it:
var unique = TheApplication().LoginName()+"-"+TimeStamp("DateTimeMilli");
TheApplication().TraceOn(path+"Trace-"+unique+"_$p_$t.log", "Allocation", "All");
To get the values I am interested in, I need to output the directory listing of only this known file to a log I can then open and read, then use format of the name of this file to extract the two values I am interested in:

function SetThreadPID() {
  var pid = TheApplication().GetProfileAttr("XXX OS PID");
  var threadId = TheApplication().GetProfileAttr("PPT OS Thread ID");
  var line, pidThread, path, command, outs;

  try {
    if (threadId == "") {
      if (TheApplication().GetProfileAttr("IsStandaloneWebClient") == "TRUE") {
        path = gsLogPath;
      } else {
        path = TheApplication().GetProfileAttr("Syspref Error Trace Temp Loc");
      }

      if (path != "" && path.toUpperCase() != "FALSE") {
        var unique = TheApplication().LoginName()+"-"+TimeStamp("DateTimeMilli");
        TheApplication().TraceOn(path+"Trace-"+unique+"_$p_$t.log", "Allocation", "All");
        TheApplication().Trace("TEST");
        TheApplication().TraceOff();  
    
        command = "dir "+path+"Trace-"+unique+"_*.log > "+path+"Trace-"+unique+".log";
        outs = Clib.system(command);
        var fp:File = Clib.fopen(path+"Trace-"+unique+".log","r");
        if (fp != null){
          while(Clib.feof(fp) == 0){
            line = Clib.fgets(fp);
            if (line.length > 0){
              if (line.indexOf(unique)>=0) {
                pidThread = line.substring(line.indexOf(unique)+unique.length+1, line.length - 5)
                pid = pidThread.substring(0, pidThread.indexOf("_"));
                threadId = pidThread.substring(pidThread.indexOf("_")+1);
                TheApplication().SetProfileAttr("PPT OS PID", pid);
                TheApplication().SetProfileAttr("PPT OS Thread ID", threadId);
                Clib.fclose(fp);
                outs = Clib.remove(path+"Trace-"+unique+"_"+pid+"_"+threadId+".log")
                outs = Clib.remove(path+"Trace-"+unique+".log")
                break;
              }
            }
          }
        }
      }
    }
  } catch(e) {
    RaiseError(e);
  } finally {
    fp = null;
  }
}

Once the PID and Thread are stored in profile attributes they are available to the business layer to for instance set a PID or thread column on a custom error table.

Note that 'Syspref Error Trace Temp Loc' is a custom field added to the 'Personalization Profile' BC which has the calculation:
SystemPreference("PPT Error Trace Temp Loc")
This is then set to a directory that the Siebel application server has access to (the Siebel temp directory can generally be used safely).

No comments:

Post a Comment