We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now


How to access PID in Process accounting on HP-UX?

kslzzg asked
Medium Priority
Last Modified: 2013-12-06
On HP-UX 10.x,can I access historical process ID(not current ones)in process accounting and how? Because we want already past information,specially PID to match with other applications for the purpose of accounting. But as far as I know, the command "acctcom" in HP-UX 10.x can not provide information like PID or PPID. If I am in badly need of PID, how can I do that? Of course, I can't use "ps" to get PID,Because I need those PIDs which corresponding process finished already. Will there be future version of HP-UX or special accounting software  that will  or can provide such functionality in accounting?
On the other hand, I know HP MeasureWare and PerfView can provide past info like PID,PPID as well as other resource utilization, but it can only provide sampling data every minute,which is not so accurate as "acct" functionality provided by HP-UX itself.
Can you give me any solutions or recommendations on that?


Watch Question

I'm not sure what you are looking for.

1.  Process ID is not historically significant.  PID
numbers are reused as needed.  So process 23412 right
now may be Smith running ls -lR /usr/local but two hours
ago it was /usr/lib/sendmail ...

2.  Accounting does NOT write a record for a job until
the job finishes.

3.  Much of the information you want can be found with the
ps command.  More can be found with the dmon command, avail-
able from the HPUX public archives.


I think I need to describe my question in more detail.
What I mean in my question is,of course the past resource utilization comsumed by end-users and their applications.
But besides that, I also need the Process ID that corresponding
to the process that has been finished already in order to relate
this process ID with other sources of accounting utilities plus
the information of the time when the process was finished,so that
I can find out which process belongs to which particular application. Now the problem is there is no process ID information provided within the accounting utilities of HP-UX,
If I do need it, what can I do?


Edited text of question


Edited text of question

You may want to run a cron job that will ps into a tmp file, then do a diff with the master list of stored pids, ending with an update to the master list.

ps -ef | grep -v root > my_temp_ps  # ps list, drop root tasks.
# if you have other tasks that you want to ignore, just extend
# the above pipe
diff master_ps my_temp_ps > change_list

# Now, you would need a cute little awk script, with a bit
# of cut, to give you the clean info.  This could then be
# appended to your master_ps file.

Good luck, Alan.


Of course this is one of simplest ways of doing things like that.
But it is not good to use cron to "ps" every minute only to get PID info of all processes. Because what you will get from doing
this way are still sampling data instead of all actual processes especially for those that only run for less than one minute. In
other words,this method may miss those short-term processes of which lapse time are less than one minute. Not to mention the
overhead caused by a lot of "ps" and "grep",am I right?

You are correct in the question of overhead.
What you seem to require is a shell that will wrap every user command with a 'time', and output that information to a log file.

If you only require this for a limited number of commands, you may want to use the 'alias' function of c-shell.
If you require individual numbers for forked sub-tasks, then you may require a kernel modification.
How much time versus task versus user info do you require?


I think you're stuck.  The system accounting is the only way to go (overhead and granularity of sampling rule that out) but the system doesn't store PID/PPID.  If you knew the signature of the kernel function that makes account log entries, you *might* be able to extract the standard function from the kernel library, insert your own function (one that did save PID/PPID), and build a new kernel.  This is messy & difficult, and (unless you write the PID info to a separate file) breaks all the standard system accounting utilities.

Hmmm...actually, there is an alternative (at least for system programs).  You could write a simple wrapper program that logs its PID, PPID, and a little other info, then exec()s the real program.  You should be able to correlate the normal accounting logs with the PID log if you store the process start time, UID, command name, etc.  This won't work for any program that's not started by the wrapper (e.g. programs that your users write themselves, or if the users figure out where the real programs live and just start them directly).  The wrapper adds some overhead, but if it's being executed constantly (so it is usually in memory), it probably won't be *that* bad.  It's certainly better than running ps every minute.


Dhm's answer seems better than run 'ps' every minute and
keeps logs of 'ps' output and use a program to correlate PID info
with normal process accounting log file by id,stime,end-time,etc.
But what I want to know more about that is:
1.How to write such program? Can you give me a sample?
2.Does each wrapper program exec()s only one real program? If
this is true,I have to run as many such programs as the amount
of application processes and system processes,not to mention some
particular user run his own program someday. In addtion,this will
also adds quite a lot of overhead to the system.
3. The reason to keep process accounting is mainly for the purpose of charging end-users of application softwares for the resource utilization. Therefore, we must focus on these application processes instead of a few system processes.
The reason why I need PID info is that we can't tell who is actual user of certain Oracle processes from HP-UX,and the normal system accounting utilities like 'acctcom' don't provide PID info,this makes it very difficult to correlate accounting processes with accounting logs provided within Oracle.

1. The wrapper program is quite simple.  I'll append the skeleton of one; you'll want to add the actual logging to the area I've only indicated with a comment.

2. The wrapper only exec's one real program, so you have to run the wrapper once for each program you start.  It's true that this adds overhead, but the wrapper is small, so the actual overhead is mainly in doing two execs() instead of just one.  I don't think you'll find this excessive, unless your users normally run *many*, *many* programs that only process for a brief time before exiting.  Again, this scheme won't work if your users write their own programs.

3. Ah, now I see what you're up to.  This limits the scope of the problem nicely: you only have to put the wrapper on the programs a user runs to interact with the database.  (Do your users write C programs that connect to the database?  Or do they mostly just use pre-built applications?)

Anyway, here's the wrapper.  It'll be close, but probably not "compile & go," since I'm just typing it into my browser :-)  How familiar are you with C and Unix programming?

#include <stdio.h>
#include <malloc.h>

#define      REAL_DIR      "/where/you/keep/the/real/programs"

main( int argc, char **argv, char **envp )
      FILE      *pidlog = fopen( "/var/log/acct-pids", "a" );
      char      *realprog;
      char      **copyargs;
      int       i;

      /* save whatever info you like */
      fprintf( pidlog,"PID %d PPID %d UID %d GID %d START %d\n",
            getpid( ), getppid( ), getuid( ), getgid( ),
            time( 0 ) );
      fclose( pidlog );

      /* Now, exec the real program */
      realprog = malloc( strlen(REAL_DIR) + strlen(argv[0]) + 2 );
      strcpy( realprog, REAL_DIR );
      strcat( realprog, "/" );
      strcat( realprog, argv[0] );

      copyargs = (char **)malloc( (argc + 1) * sizeof(char *) );
      for (i = 0; i < argc; i++) copyargs[i] = argv[i];
      copyargs[argc] = 0;

      exit( execve( realprog, copyargs, envp ) );

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.