系统管理指南:Oracle Solaris Containers-资源管理和 Oracle Solaris Zones

第 5 章 管理扩展记帐(任务)

本章介绍如何管理扩展记帐子系统。

有关扩展记帐子系统的概述,请参见第 4 章

管理扩展记帐功能(任务图)

任务 

说明 

参考 

激活扩展记帐功能。 

使用扩展记帐监视系统上运行的每个项目的资源消耗情况。可以使用扩展记帐子系统捕获任务、进程和流的历史数据。

如何激活进程、任务和流的扩展记帐如何使用启动脚本激活扩展记帐

显示扩展记帐状态。 

确定扩展记帐功能的状态。 

如何显示扩展记帐状态

查看可用的记帐资源。 

查看系统上的可用记帐资源。 

如何查看可用的记帐资源

取消激活进程、任务和流的记帐功能。 

禁用扩展记帐功能。 

如何取消激活进程记帐、任务记帐和流记帐

将 Perl 接口用于扩展记帐功能。 

使用 Perl 接口开发自定义报告脚本和提取脚本。 

使用 libexacct 的 Perl 接口

使用扩展记帐功能

如果用户拥有要管理的扩展记帐类型的相应权限配置文件,则可以管理扩展记帐(启动记帐、停止记帐和更改记帐配置参数):

Procedure如何激活进程、任务和流的扩展记帐

要激活任务、进程和流的扩展记帐功能,请使用 acctadm 命令。acctadm 的可选最终参数表示此命令是应该针对扩展记帐功能的进程记帐组件、系统任务记帐组件还是流记帐组件执行。

  1. 成为超级用户或承担等效角色。

    角色包含授权和具有一定权限的命令。有关角色的更多信息,请参见《系统管理指南:基本管理》中的“使用 RBAC 和 Solaris 管理工具(任务图)”

  2. 激活进程的扩展记帐。


    # acctadm -e extended -f /var/adm/exacct/proc process
    
  3. 激活任务的扩展记帐。


    # acctadm -e extended,mstate -f /var/adm/exacct/task task
    
  4. 激活流的扩展记帐。


    # acctadm -e extended -f /var/adm/exacct/flow flow
    
另请参见

有关更多信息,请参见 acctadm(1M)

如何使用启动脚本激活扩展记帐

通过将 /etc/init.d/acctadm 脚本链接到 /etc/rc2.d,可以在运行时激活扩展记帐。


# ln -s /etc/init.d/acctadm /etc/rc2.d/Snacctadm
# ln -s /etc/init.d/acctadm /etc/rc2.d/Knacctadm

n 变量以数字替换。

必须至少手动激活一次扩展记帐以设置配置。

有关记帐配置的信息,请参见扩展记帐配置

如何显示扩展记帐状态

键入不带参数的 acctadm 可以显示扩展记帐功能的当前状态。


# acctadm
                 Task accounting: active
            Task accounting file: /var/adm/exacct/task
          Tracked task resources: extended
        Untracked task resources: none
              Process accounting: active
         Process accounting file: /var/adm/exacct/proc
       Tracked process resources: extended
     Untracked process resources: host
                 Flow accounting: active
            Flow accounting file: /var/adm/exacct/flow
          Tracked flow resources: extended
        Untracked flow resources: none

在前一示例中,系统任务记帐在扩展模式和 mstate 模式下激活。进程记帐和流记帐在扩展模式下激活。


注 –

在扩展记帐的上下文中,微状态 (mstate) 是指与微状态进程转换关联的扩展数据,可从进程使用情况文件(请参见 proc(4))中获取此数据。与基本记录或扩展记录相比,此数据可提供有关进程活动的更多详细信息。


如何查看可用的记帐资源

可用的资源随系统和平台的不同而有所不同。使用带有 -r 选项的 acctadm 命令可以查看系统上的可用记帐资源组。


# acctadm -r
process:
extended pid,uid,gid,cpu,time,command,tty,projid,taskid,ancpid,wait-status,zone,flag,
memory,mstatedisplays as one line
basic    pid,uid,gid,cpu,time,command,tty,flag
task:
extended taskid,projid,cpu,time,host,mstate,anctaskid,zone
basic    taskid,projid,cpu,time
flow:
extended 
saddr,daddr,sport,dport,proto,dsfield,nbytes,npkts,action,ctime,lseen,projid,uid
basic    saddr,daddr,sport,dport,proto,nbytes,npkts,action

Procedure如何取消激活进程记帐、任务记帐和流记帐

要取消激活进程记帐、任务记帐和流记帐,请使用带有 -x 选项的 acctadm 命令分别禁用每个记帐。

  1. 成为超级用户或承担等效角色。

    角色包含授权和具有一定权限的命令。有关角色的更多信息,请参见《系统管理指南:基本管理》中的“使用 RBAC 和 Solaris 管理工具(任务图)”

  2. 禁用进程记帐。


    # acctadm -x process 
    
  3. 禁用任务记帐。


    # acctadm -x task
    
  4. 禁用流记帐。


    # acctadm -x flow
    
  5. 检验是否已禁用任务记帐、进程记帐和流记帐。


    	# acctadm
                Task accounting: inactive
           Task accounting file: none
         Tracked task resources: extended
       Untracked task resources: none
             Process accounting: inactive
        Process accounting file: none
      Tracked process resources: extended
    Untracked process resources: host
                Flow accounting: inactive
           Flow accounting file: none
         Tracked flow resources: extended
       Untracked flow resources: none

使用 libexacct 的 Perl 接口

如何递归列显 exacct 对象的内容

使用以下代码可以递归列显 exacct 对象的内容。请注意,此功能作为 Sun::Solaris::Exacct::Object::dump() 函数由库提供。此功能还可以通过 ea_dump_object() 公用函数提供。


sub dump_object
     {
             my ($obj, $indent) = @_;
             my $istr = '  ' x $indent;

             #
             # Retrieve the catalog tag.  Because we are 
             # doing this in an array context, the
             # catalog tag will be returned as a (type, catalog, id) 
             # triplet, where each member of the triplet will behave as 
             # an integer or a string, depending on context.
             # If instead this next line provided a scalar context, e.g.
             #    my $cat  = $obj->catalog()->value();
             # then $cat would be set to the integer value of the 
             # catalog tag.
             #
             my @cat = $obj->catalog()->value();

             #
             # If the object is a plain item
             #
             if ($obj->type() == &EO_ITEM) {
                     #
                     # Note: The '%s' formats provide s string context, so
                     # the components of the catalog tag will be displayed
                     # as the symbolic values. If we changed the '%s'
                     # formats to '%d', the numeric value of the components
                     # would be displayed.
                     #
                     printf("%sITEM\n%s  Catalog = %s|%s|%s\n", 
                        $istr, $istr, @cat);
                     $indent++;

                     #
                     # Retrieve the value of the item.  If the item contains
                     # in turn a nested exacct object (i.e., an item or
                     # group),then the value method will return a reference
                     # to the appropriate sort of perl object
                     # (Exacct::Object::Item or Exacct::Object::Group).
                     # We could of course figure out that the item contained
                     # a nested item orgroup by examining the catalog tag in
                     # @cat and looking for a type of EXT_EXACCT_OBJECT or
                     # EXT_GROUP.
                     #
                     my $val = $obj->value();
                     if (ref($val)) {
                             # If it is a nested object, recurse to dump it.
                             dump_object($val, $indent);
                     } else {
                             # Otherwise it is just a 'plain' value, so
                             # display it.
                             printf("%s  Value = %s\n", $istr, $val);
                     }

             #
             # Otherwise we know we are dealing with a group.  Groups
             # represent contents as a perl list or array (depending on
             # context), so we can process the contents of the group
             # with a 'foreach' loop, which provides a list context.
             # In a list context the value method returns the content
             # of the group as a perl list, which is the quickest
             # mechanism, but doesn't allow the group to be modified.
             # If we wanted to modify the contents of the group we could
             # do so like this:
             #    my $grp = $obj->value();   # Returns an array reference
             #    $grp->[0] = $newitem;
             # but accessing the group elements this way is much slower.
             #
             } else {
                     printf("%sGROUP\n%s  Catalog = %s|%s|%s\n",
                         $istr, $istr, @cat);
                     $indent++;
                     # 'foreach' provides a list context.
                     foreach my $val ($obj->value()) {
                             dump_object($val, $indent);
                     }
                     printf("%sENDGROUP\n", $istr);
             }
     }

如何创建新的组记录并将其写入文件

使用以下脚本可以创建新的组记录并将其写入名为 /tmp/exacct 的文件。


#!/usr/bin/perl

use strict;
use warnings;
use Sun::Solaris::Exacct qw(:EXACCT_ALL);
# Prototype list of catalog tags and values.
     my @items = (
             [ &EXT_STRING | &EXC_DEFAULT | &EXD_CREATOR      => "me"       ],
             [ &EXT_UINT32 | &EXC_DEFAULT | &EXD_PROC_PID     => $$         ],
             [ &EXT_UINT32 | &EXC_DEFAULT | &EXD_PROC_UID     => $<         ],
             [ &EXT_UINT32 | &EXC_DEFAULT | &EXD_PROC_GID     => $(         ],
             [ &EXT_STRING | &EXC_DEFAULT | &EXD_PROC_COMMAND => "/bin/rec" ],
     );

     # Create a new group catalog object.
     my $cat = ea_new_catalog(&EXT_GROUP | &EXC_DEFAULT | &EXD_NONE)

     # Create a new Group object and retrieve its data array.
     my $group = ea_new_group($cat);
     my $ary = $group->value();

     # Push the new Items onto the Group array.
     foreach my $v (@items) {
             push(@$ary, ea_new_item(ea_new_catalog($v->[0]), $v->[1]));
     }

     # Open the exacct file, write the record & close.
     my $f = ea_new_file('/tmp/exacct', &O_RDWR | &O_CREAT | &O_TRUNC)
        || die("create /tmp/exacct failed: ", ea_error_str(), "\n");
     $f->write($group);
     $f = undef;

如何列显 exacct 文件的内容

使用以下 Perl 脚本可以列显 exacct 文件的内容。


#!/usr/bin/perl

     use strict;
     use warnings;
     use Sun::Solaris::Exacct qw(:EXACCT_ALL);

     die("Usage is dumpexacct <exacct file>\n") unless (@ARGV == 1);

     # Open the exact file and display the header information.
     my $ef = ea_new_file($ARGV[0], &O_RDONLY) || die(error_str());
     printf("Creator:  %s\n", $ef->creator());
     printf("Hostname: %s\n\n", $ef->hostname());

     # Dump the file contents
     while (my $obj = $ef->get()) {
             ea_dump_object($obj);
     }

     # Report any errors
     if (ea_error() != EXR_OK && ea_error() != EXR_EOF)  {
             printf("\nERROR: %s\n", ea_error_str());
             exit(1);
     }
     exit(0);

Sun::Solaris::Exacct::Object->dump() 的输出示例

以下是对在如何创建新的组记录并将其写入文件中创建的文件运行 Sun::Solaris::Exacct::Object->dump() 时生成的输出示例。


Creator:  root
Hostname: localhost
GROUP
       Catalog = EXT_GROUP|EXC_DEFAULT|EXD_NONE
       ITEM
         Catalog = EXT_STRING|EXC_DEFAULT|EXD_CREATOR
         Value = me
       ITEM
         Catalog = EXT_UINT32|EXC_DEFAULT|EXD_PROC_PID
         Value = 845523
       ITEM
         Catalog = EXT_UINT32|EXC_DEFAULT|EXD_PROC_UID
         Value = 37845
       ITEM
         Catalog = EXT_UINT32|EXC_DEFAULT|EXD_PROC_GID
         Value = 10
       ITEM
         Catalog = EXT_STRING|EXC_DEFAULT|EXD_PROC_COMMAND
         Value = /bin/rec
ENDGROUP