<chapter id="ext-acctg-11"><title>Using the C Interface
to Extended Accounting</title><highlights><para>This chapter describes the C interface to extended accounting and covers
the following topics:</para><itemizedlist><listitem><para><olink targetptr="ext-acctg-12" remap="internal">Overview of the C Interface
to Extended Accounting</olink></para>
</listitem><listitem><para><olink targetptr="ext-acctg-16" remap="internal">Extended Accounting API Functions</olink></para>
</listitem><listitem><para><olink targetptr="ext-acctg-15" remap="internal">C Code Examples for Accessing
exacct Files</olink></para>
</listitem>
</itemizedlist>
</highlights><sect1 id="ext-acctg-12"><title>Overview of the C Interface to Extended Accounting</title><para>Projects and tasks are used to label and separate workloads. The extended
accounting subsystem is used to monitor resource consumption by workloads
that are running on the system. Extended accounting produces accounting records
for the workload tasks and processes.</para><para>For an overview of extended accounting and example procedures for administering
extended accounting, see <olink targetdoc="sysadrm" targetptr="rmacct-1" remap="external">Chapter 4, <citetitle remap="chapter">Extended Accounting (Overview),</citetitle> in <citetitle remap="book">System Administration Guide: Solaris Containers-Resource Management and Solaris Zones</citetitle></olink> and <olink targetdoc="sysadrm" targetptr="rmacct.task.sgm" remap="external">Chapter 5, <citetitle remap="chapter">Administering Extended Accounting (Tasks),</citetitle> in <citetitle remap="book">System Administration Guide: Solaris Containers-Resource Management and Solaris Zones</citetitle></olink>.</para><para>The extended accounting framework has been expanded for zones. Each
zone has its own extended accounting files for task and process-based accounting.
The extended accounting files in the global zone contain accounting records
for the global zone and for all non-global zones. The accounting records contain
a zone name tag. The global zone administrator can use the tag during the
extraction of per zone accounting data from the accounting files in the global
zone.</para>
</sect1><sect1 id="ext-acctg-16"><title>Extended Accounting API Functions</title><para>The extended accounting API contains functions that perform the following: </para><itemizedlist><listitem><para><filename>exacct</filename> system calls</para>
</listitem><listitem><para>Operations on the <filename>exacct</filename> file</para>
</listitem><listitem><para>Operations on <filename>exacct</filename> objects</para>
</listitem><listitem><para>Miscellaneous Operations</para>
</listitem>
</itemizedlist><sect2 id="ext-acctg-17"><title><filename>exacct</filename> System Calls</title><simplelist><member></member><member></member><member></member>
</simplelist><para>The following table lists the system calls that interact with the extended
accounting subsystem.</para><table frame="topbot" id="fygec"><title>Extended Accounting System Calls</title><tgroup cols="2" colsep="0" rowsep="0"><colspec colwidth="19.92*"/><colspec colwidth="80.08*"/><thead><row rowsep="1"><entry><para>Function</para>
</entry><entry><para>Description</para>
</entry>
</row>
</thead><tbody><row><entry><para><olink targetdoc="refman2" targetptr="putacct-2" remap="external"><citerefentry><refentrytitle>putacct</refentrytitle><manvolnum>2</manvolnum></citerefentry></olink></para>
</entry><entry><para>Provides privileged processes with the ability to tag accounting records
with additional data that is specific to the process</para>
</entry>
</row><row><entry><para><olink targetdoc="refman2" targetptr="getacct-2" remap="external"><citerefentry><refentrytitle>getacct</refentrytitle><manvolnum>2</manvolnum></citerefentry></olink></para>
</entry><entry><para>Enables privileged processes to request extended accounting buffers
from the kernel for currently executing tasks and processes</para>
</entry>
</row><row><entry><para><olink targetdoc="refman2" targetptr="wracct-2" remap="external"><citerefentry><refentrytitle>wracct</refentrytitle><manvolnum>2</manvolnum></citerefentry></olink></para>
</entry><entry><para>Requests the kernel to write resource usage data for a specified task
or process</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2><sect2 id="ext-acctg-18"><title>Operations on the <literal>exacct</literal> File</title><para>These functions provide access to the <literal>exacct</literal> files:</para><table frame="topbot" id="fygdy"><title><filename>exacct</filename> File Functions</title><tgroup cols="2" colsep="0" rowsep="0"><colspec colwidth="33.47*"/><colspec colwidth="66.53*"/><thead><row rowsep="1"><entry><para>Function</para>
</entry><entry><para>Description</para>
</entry>
</row>
</thead><tbody><row><entry><para><olink targetdoc="refman3e" targetptr="ea-open-3exacct" remap="external"><citerefentry><refentrytitle>ea_open</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Opens an <filename>exacct</filename> file.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-close-3exacct" remap="external"><citerefentry><refentrytitle>ea_close</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Closes an <filename>exacct</filename> file.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-get-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_get_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>First time use on a group of objects reads data into an <structname>ea_object_t</structname> structure. Subsequent use on the group cycles through the objects
in the group.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-write-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_write_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Appends the specified object to the open <filename>exacct</filename> file.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-next-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_next_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Reads the basic fields (<literal>eo_catalog</literal> and <literal>eo_type</literal>)
into an <structname>ea_object_t</structname> structure and rewinds to the
head of the record.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-previous-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_previous_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Skips back one object in the <filename>exacct</filename> file and reads
the basic fields (<literal>eo_catalog</literal> and <literal>eo_type</literal>)
into an <structname>ea_object_t</structname>.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-get-hostname-3exacct" remap="external"><citerefentry><refentrytitle>ea_get_hostname</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Gets the name of the host on which the <filename>exacct</filename> file
was created.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-get-creator-3exacct" remap="external"><citerefentry><refentrytitle>ea_get_creator</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Determines the creator of the <filename>exacct</filename> file.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2><sect2 id="ext-acctg-19"><title>Operations on <literal>exacct</literal> Objects</title><para>These functions are used to access <literal>exacct</literal> objects:</para><table frame="topbot" id="fygjd"><title><literal>exacct</literal> Object Functions</title><tgroup cols="2" colsep="0" rowsep="0"><colspec colwidth="33.19*"/><colspec colwidth="66.81*"/><thead><row rowsep="1"><entry><para>Function</para>
</entry><entry><para>Description</para>
</entry>
</row>
</thead><tbody><row><entry><para><olink targetdoc="refman3e" targetptr="ea-set-item-3exacct" remap="external"><citerefentry><refentrytitle>ea_set_item</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Assigns an <filename>exacct</filename> object and sets the value(s).</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-set-group-3exacct" remap="external"><citerefentry><refentrytitle>ea_set_group</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Sets the values of a group of <filename>exacct</filename> objects.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-match-object-catalog-3exacct" remap="external"><citerefentry><refentrytitle>ea_match_object_catalog</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Checks an <filename>exacct</filename> object's mask to see if that object
has a specific catalog tag.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-attach-to-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_attach_to_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Attaches an <filename>exacct</filename> object to a specified <filename>exacct</filename> object.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-attach-to-group-3exacct" remap="external"><citerefentry><refentrytitle>ea_attach_to_group</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Attaches a chain of <filename>exacct</filename> objects as member items
of a specified group.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-free-item-3exacct" remap="external"><citerefentry><refentrytitle>ea_free_item</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Frees the <literal>value</literal> fields in the specified <filename>exacct</filename> object.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-free-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_free_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Frees the specified <filename>exacct</filename> object and any attached
hierarchies of objects.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2><sect2 id="ext-acctg-20"><title>Memory Management</title><para>The following table lists the functions associated with extended accounting
memory management. The function name is a link to its man page.</para><table frame="topbot" id="ext-acctg-tbl-4"><title>Extended Accounting Memory
Management Functions</title><tgroup cols="2" colsep="0" rowsep="0"><colspec colname="colspec14" colwidth="40.27*"/><colspec colname="colspec15" colwidth="59.73*"/><thead><row rowsep="1"><entry><para>Link to man page</para>
</entry><entry><para>Description</para>
</entry>
</row>
</thead><tbody><row><entry><para><olink targetdoc="refman3e" targetptr="ea-pack-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_pack_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Converts an <literal>exacct</literal> object from unpacked (in-memory)
representation to packed (in-file) representation.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-unpack-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_unpack_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Converts an <literal>exacct</literal> object from packed (in-file) representation
to unpacked (in-memory) representation.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-strdup-3exacct" remap="external"><citerefentry><refentrytitle>ea_strdup</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Duplicates a string that is to be stored inside an <literal>ea_object_t</literal> structure.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-strfree-3exacct" remap="external"><citerefentry><refentrytitle>ea_strfree</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Frees a string previously copied by <function>ea_strdup</function>.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-alloc-3exacct" remap="external"><citerefentry><refentrytitle>ea_alloc</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Allocates a block of memory of the requested size. This block can be
safely passed to <literal>libexacct</literal> functions, and can be safely
freed by any of  the <literal>ea_free</literal> functions.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-free-3exacct" remap="external"><citerefentry><refentrytitle>ea_free</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Frees a block of memory previously allocated by <function>ea_alloc</function>.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-free-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_free_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Frees variable-length data in object hierarchy.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-free-item-3exacct" remap="external"><citerefentry><refentrytitle>ea_free_item</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Frees value fields of designated object, if EUP_ALLOC is specified.
The object  is not freed.  <function>ea_free_object</function> frees the specified
object and any attached hierarchy of objects. If the flag argument is set
to EUP_ALLOC, <function>ea_free_object</function> also frees any variable-length
data in the object hierarchy. If the flag argument is set to EUP_NOALLOC, <function>ea_free_object</function> does not free the variable-length data. In particular,
these flags should correspond to the flags specified in calls to <literal>ea_unpack_object</literal>(3EXACCT).</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-copy-object-3exacct" remap="external"><citerefentry><refentrytitle>ea_copy_object</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para>Copies an <literal>ea_object_t</literal>. If  the source object is part
of a chain, only the current object is copied. If the source object is a group,
only  the group object is copied without its list of members. The group object <literal>eg_nobjs</literal> and <literal>eg_objs fields</literal> are set to 0 and
NULL respectively. Use <function>ea_copy_tree</function> to copy recursively
a group or a list of items.</para>
</entry>
</row><row><entry><para><olink targetdoc="refman3e" targetptr="ea-copy-object-tree-3exacct" remap="external"><citerefentry><refentrytitle>ea_copy_object_tree</refentrytitle><manvolnum>3EXACCT</manvolnum></citerefentry></olink></para>
</entry><entry><para><literal>ea_copy_object_tree</literal> recursively copies an <literal>ea_object_t</literal>. All elements in the <literal>eo_next</literal> list are copied.
Any group objects are recursively copied. The returned object can be completely
freed with <literal>ea_free_object</literal>(3EXACCT) by specifying the EUP_ALLOC
flag. </para>
</entry>
</row><row><entry><para><function>ea_get_object_tree</function></para>
</entry><entry><para>Reads in nobj top-level objects  from the file, returning the same data
structure that would have originally been passed to <function>ea_write_object</function>.
On encountering a group object,<function>ea_get_object</function> reads only
the group header part of the group. <function>ea_get_object_tree</function> reads
 the group and all its member items, recursing into subrecords if necessary.
The returned object data structure can be completely freed with <function>ea_free_object</function> by specifying the EUP_ALLOC flag.</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2><sect2 id="ext-acctg-21"><title>Miscellaneous Operations</title><para>These functions are associated with miscellaneous operations:</para><simplelist><member><olink targetdoc="refman3e" targetptr="ea-error-3exacct" remap="external"><citerefentry><refentrytitle>ea_error</refentrytitle><manvolnum>3EXACCT</manvolnum>
</citerefentry></olink></member><member><olink targetdoc="refman3e" targetptr="ea-match-object-catalog-3exacct" remap="external"><citerefentry><refentrytitle>ea_match_object_catalog</refentrytitle><manvolnum>3EXACCT</manvolnum>
</citerefentry></olink></member>
</simplelist>
</sect2>
</sect1><sect1 id="ext-acctg-15"><title>C Code Examples for Accessing <literal>exacct</literal> Files</title><para>This section provides code examples for accessing <literal>exacct</literal> files.</para><example><title>Displaying <literal>exacct</literal> Data for a Designated <literal>pid</literal></title><para>This example displays a specific <literal>pid</literal>'s <literal>exacct</literal> data snapshot from the kernel.</para><programlisting>...
  ea_object_t *scratch;
  int unpk_flag = EUP_ALLOC;  /* use the same allocation flag */
                              /* for unpack and free */

  /* Omit return value checking, to keep code samples short */

  bsize = getacct(P_PID, pid, NULL, 0);
  buf = malloc(bsize);

  /* Retrieve exacct object and unpack */
  getacct(P_PID, pid, buf, bsize);
  ea_unpack_object(&amp;scratch, unpk_flag, buf, bsize);

  /* Display the exacct record */
  disp_obj(scratch);
  if (scratch->eo_type == EO_GROUP) {
         disp_group(scratch);
  }
  ea_free_object(scratch, unpk_flag);
		...	</programlisting>
</example><example><title>Identifying Individual Tasks During a Kernel Build</title><para>This example evaluates kernel builds and displays a string that
describes the portion of the source tree being built by this task make. Display
the portion of the source being built to aid in the per-source-directory analysis.</para><para>The key points for this example include the following:</para><itemizedlist><listitem><para>To aggregate the time for a <literal>make</literal>, which
could include many processes, each <literal>make</literal> is initiated as
a task. Child <literal>make</literal> processes are created as different tasks.
To aggregate across the makefile tree, the parent-child task relationship
must be identified.</para>
</listitem><listitem><para>Add a tag with this information to the task's <literal>exacct</literal> file.
Add a current working directory string that describes the portion of the source
tree being built by this task make.</para><programlisting>ea_set_item(&amp;cwd, EXT_STRING | EXC_LOCAL | MY_CWD, 
                               cwdbuf, strlen(cwdbuf));</programlisting>
</listitem>
</itemizedlist><programlisting>  ...
/* Omit return value checking and error processing */
/* to keep code sample short */
ptid = gettaskid();	/* Save "parent" task-id */
tid = settaskid(getprojid(), TASK_NORMAL);	/* Create new task */

/* Set data for item objects ptskid and cwd */
ea_set_item(&amp;ptskid, EXT_UINT32 | EXC_LOCAL | MY_PTID, &amp;ptid, 0);
ea_set_item(&amp;cwd, EXT_STRING | EXC_LOCAL | MY_CWD, cwdbuf, strlen(cwdbuf));

/* Set grp object and attach ptskid and cwd to grp */
ea_set_group(&amp;grp, EXT_GROUP | EXC_LOCAL |  EXD_GROUP_HEADER);
ea_attach_to_group(&amp;grp, &amp;ptskid);
ea_attach_to_group(&amp;grp, &amp;cwd);

/* Pack the object and put it back into the accounting stream */
ea_buflen = ea_pack_object(&amp;grp, ea_buf, sizeof(ea_buf));
putacct(P_TASKID, tid, ea_buf, ea_buflen, EP_EXACCT_OBJECT);

/* Memory management: free memory allocate in ea_set_item */
ea_free_item(&amp;cwd, EUP_ALLOC);
  ...</programlisting>
</example><example><title>Reading and Displaying the Contents of a System <literal>exacct</literal> File</title><para>This example shows how to read and display a system <literal>exacct</literal> file
for a process or a task. </para><para>The key points for this example include the following:</para><itemizedlist><listitem><para>Call <function>ea_get_object</function> to get the next object
in the file. Call <function>ea_get_object</function> in a loop until EOF enables
a complete traversal of the <literal>exacct</literal> file.</para>
</listitem><listitem><para><function>catalog_name</function> uses the <structname>catalog_item</structname> structure to convert a Solaris catalog's type ID to a meaningful
string that describes the content of the object's data. The type ID is obtained
by masking the lowest 24 bits, or 3 bytes.</para><programlisting>switch(o->eo_catalog &amp; EXT_TYPE_MASK) {
  case EXT_UINT8:
      printf(" 8: %u", o->eo_item.ei_uint8);
      break;
  case EXT_UINT16:
  ...
}</programlisting>
</listitem><listitem><para>The upper 4 bits of <literal>TYPE_MASK</literal> are used
to find out the data type to print the object's actual data.</para>
</listitem><listitem><para><function>disp_group</function> takes a pointer to a group
object and the number of objects in the group. For each object in the group, <function>disp_group</function> calls <function>disp_obj</function> and recursively
calls <function>disp_group</function> if the object is a group object.</para>
</listitem>
</itemizedlist><programlisting>/* Omit return value checking and error processing */
/* to keep code sample short */
main(int argc, char *argv)
{
  ea_file_t ef;
  ea_object_t scratch;
  char *fname;
		
  fname = argv[1];
  ea_open(&amp;ef, fname, NULL,  EO_NO_VALID_HDR, O_RDONLY, 0);
  bzero(&amp;scratch, sizeof (ea_object_t));
  while (ea_get_object(&amp;ef, &amp;scratch)  != -1) {
	     disp_obj(&amp;scratch);
	     if (scratch.eo_type == EO_GROUP)
	         disp_group(&amp;ef, scratch.eo_group.eg_nobjs);
	     bzero(&amp;scratch, sizeof (ea_object_t));
  }
  ea_close(&amp;ef);
}

struct catalog_item {   /* convert Solaris catalog's type ID */
                        /* to a meaningful string */
	 int	type;
	 char *name;
 } catalog[] = {
	 { EXD_VERSION, 	"version\t" },
	 ...
	 { EXD_PROC_PID,	"  pid\t" },
	 ...
   };

 static char *
 catalog_name(int type)
 {
	 int i = 0;
	 while (catalog[i].type != EXD_NONE) {
		 if (catalog[i].type == type)
			 return (catalog[i].name);	
		 else
			 i++;
	 }
	 return ("unknown\t");
 }

 static void disp_obj(ea_object_t *o)
 {
	 printf("%s\t", catalog_name(o->eo_catalog &amp; 0xffffff));
	 switch(o->eo_catalog &amp; EXT_TYPE_MASK) {
	 case EXT_UINT8:
		 printf(" 8: %u", o->eo_item.ei_uint8);
		 break;
	 case EXT_UINT16:
	 ...
 }
 static void disp_group(ea_file_t *ef, uint_t nobjs)
 {
	 for (i = 0; i &lt; nobjs; i++) {
		 ea_get_object(ef, &amp;scratch));
             	 disp_obj(&amp;scratch);
		 if (scratch.eo_type == EO_GROUP)
                disp_group(ef, scratch.eo_group.eg_nobjs);
        }
 }</programlisting>
</example>
</sect1><sect1 id="ext-acctg-1"><title>Programming Issues With <literal>exacct</literal> Files</title><itemizedlist><listitem><para>Memory management </para><itemizedlist><listitem><para>Use the same allocation flags for <function>ea_free_object</function> and <function>ea_unpack_object</function>.</para>
</listitem><listitem><para>For string objects, an <function>ea_set_item</function> results
in allocation, and should be followed by <literal>ea_free_item</literal>(<replaceable>obj</replaceable>, <literal>EUP_ALLOC</literal>) to free internal storage.</para>
</listitem><listitem><para><function>ea_pack_object</function> and <function>getacct</function> use
zero size. To get size. <function>getacct</function> should be called twice:
first time with NULL buffer to size buffer to be passed in the second call.
See Example 3-1 in <olink targetptr="ext-acctg-15" remap="internal">C Code Examples for Accessing
exacct Files</olink>.</para>
</listitem>
</itemizedlist>
</listitem><listitem><para>Applications should skip unknown <literal>exacct</literal> records
in <literal>exacct</literal> files produced by the system, to be robust in
the face of changes to <literal>exacct</literal> file content.</para>
</listitem><listitem><para>Use <literal>EXC_LOCAL</literal> for customized accounting.
Application-specific records can be created using <literal>EXC_LOCAL</literal>.
Use <literal>libexacct</literal> as general tracing or debugging facility.</para><itemizedlist><listitem><para>See <filename>&lt;sys/exacct_catalog.h></filename>.</para>
</listitem><listitem><para>Data id field of <literal>ea_catalog_t</literal> can be customized.</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</sect1>
</chapter>