From: hyperguy <sig...@hy...> - 2010-05-13 22:52:04
|
Hi, I'm having an issue monitoring a process in java from mac os x 10.5. On 10.6, this seems to work fairly good, though, maybe not 100%, but close. However, on 10.5 it works 0%. I use process builder to create a java process. In this case it's actually a make command that's invoked that is causing the problem similar to the following: make -f <path to makefile>/Makefile ARG1=VAL1 ARG2=VAL2 ARG3+=VAL3 <other args...> SRC_ROOT=<somepath> OUTPUTDIR=<anotherpath> all I use PTLQ to look for this process and I create a query string something like: String query = "Exe.Name.ct=make,Args.1.ct=-f,Args.2.ct=Makefile,Args.2.ct=ARG1=VAL1 .". Basically, to simplify the query, I take the basename of arch arg, and then use "ct' with each arg to try to match it. I didn't seem to have much luck using "eq" with unmodified args when I tried this weeks (if not months) ago. On Mac OS X 10.6 this seems to work great. On Mac OS X 10.5, it doesn't match anything. I once tried some query strings (like the PTQL page examples) such as "State.Name.eq=make,Args.-1.eq=all" (then also trying ct, then eventually changing State to Exe); however, if another make was running (and this does happen frequently), then it wouldn't match (I error out if there is more than one match). Using Exe instead of State seemed to make the following code work (at least on 10.6): Here are some code fragments. This one creates the query: public String makePTQLQueryString (String _command) { String [] cmdLineArray = _command.split("\\s+"); String queryString = null; // turn every argument into a basename for use with contains "ct" query for (int i = 0; i < cmdLineArray.length; i++) { cmdLineArray [i] = basename (cmdLineArray [i]); } // every query should have the exe name queryString = "Exe.Name.ct="+cmdLineArray[0]; // the rest of the command line, if any, should be args if (cmdLineArray.length > 1) { for (int i = 1; i < cmdLineArray.length; i++) { queryString += ",Args."+i+".ct="+cmdLineArray[i]; } } return queryString; } Here I use a global sigar object (I also tried creating a new sigar obj for each query), and I search for processes that match the query above: int pid = 0; // process query logic moved to makeQueryString String query = makePTQLQueryString (appName); LOG(this, LOG_SEV_TRACE, "isRunning(" + appName + ", " + guiApp + "): query:\n '" + query + "'"); try { pQuery = processQuery.getQuery(query); } catch (MalformedQueryException e) { LOG(this, LOG_SEV_ERROR, "IsRunning: malformedquery exception: " + e.getMessage()); return 0; } try { long[] pids = pQuery.find(sigar); LOG(this, LOG_SEV_TRACE, "isRunning(" + appName + "): num of matching pids for '" + appName + "': " + pids.length); if (pids.length == 1) { pid = (int) pids[0]; LOG(this, LOG_SEV_TRACE, "isRunning(" + appName + ", " + guiApp + "): found matching pid '" + pid + "' for '" + appName + "'"); } else if (pids.length < 1) { LOG(this, LOG_SEV_TRACE, "isRunning(" + appName + ", " + guiApp + "): no matching pid found for '" + appName + "'"); } else if (pids.length > 1) { // we have more than one pid available, but randomly choosing // one is prob not the right answer here // a better solution is notify the user, and let him/her make a // better appName query LOG(this, LOG_SEV_TRACE, "isRunning(" + appName + ", " + appName + ", " + guiApp + "): warning: found '" + pids.length + "' matching pids for '" + appName + "'"); } } catch (SigarException e) { LOG(this, LOG_SEV_ERROR, "IsRunning: sigar exception: " + e.getMessage()); return 0; } LOG(this, LOG_SEV_INFO, "isRunning(" + appName + ", " + guiApp + ") returns: " + pid); return pid; Does this seem like the right approach to take with my queries? I am trying to make the code generic so that I can invoke arbitrary processes and still match them exactly. Are there any known problems or limitations that might cause this to work on 10.6 but fail on 10.5? Eventually, I want to make the same code work on mac, linux, windows, etc. Thanks, hyperguy |
From: hyperguy <sig...@hy...> - 2010-05-17 19:21:39
|
Found out the reason. On 10.5 there is at least a 16ms window before the process actually starts. So it looks like sigar wasn't finding the process because it didn't yet exist. I added a wait loop to check for the expected process, and that did the trick. |
From: hyperguy <sig...@hy...> - 2010-05-17 19:21:39
|
The cut-and-paste munged things up in my original post (copy from mac's textedit), sorry about that. Anyways, I was able to confirm that at the sigar command line, that my original query string works on both 10.6 and 10.5, i.e. all args are turned into basenames. Here is the query on 10.5: sigar> ps Exe.Name.ct=make,Args.1.ct=-f,Args.2.ct=Makefile,Args.3.ct=timer,Args.4.ct=test_timeout,Args.5.ct=all 24881 build 14:13 74M 564K - R 0:0 /Developer/usr/bin/make It seems that something is not right when I'm doing the query programmatically. Given the above query string, what is the correct way to run the query programmatically? It seems that if ps works on both 10.5 and 10.6, then I must be doing something wrong. TIA -hyperguy |