meminfo からの情報取得

okkyの銀河制圧奇譚: 解答を書いておく -1- 課題からです。 okky さんは awker としても知られていますが、Linux の Project Doubt などのプロジェクトを手がけていた方です。

課題はリンク先をご覧ください。

/proc/meminfo や /proc/slabinfo などから情報を取得していくわけですが、ここでは大いに gawk の機能を使って awk だけでやってみます。

#! /usr/bin/gawk -f
# meminfo.awk

BEGIN {
    meminfo_file  = "/proc/meminfo";
    slabinfo_file = "/proc/slabinfo";
    yellow_limit  = 358809;
    red_limit     = 627916;
    sleep_cmd     = "/bin/sleep";

    for (;;) {
        # request 1 -------------------------------------------------
        now         = strftime("%Y/%m/%d %H:%M:%S");
        output_file = output_file ? output_file : \
                      "meminfo_" strftime("%Y%m%d") ".log";

        while (getline < meminfo_file > 0) {
            sub(/:$/, "", $1);
            i++;
            mem_label[i] = $1;
            mem_info[i]  = $2;
            mem[$1] = $2;
        }
        close(meminfo_file);

        if (getline < output_file <= 0) {
            for (i = 1; i <= length(mem_info); i++) {
                label = label sprintf("\"%s\"\t", mem_label[i]);
            }
            print gensub(/(.*)\t/, "\"date\"\t\\1", 1, label)   >> output_file;
            close(output_file);
        } else {
            for (i = 1; i <= length(mem_info); i++) {
                info = info   sprintf("\"%s\"\t", mem_info[i]);
            }
            print gensub(/(.*)\t/, "\"" now "\"\t\\1", 1, info) >> output_file;
            close(output_file);

            # request 3 ---------------------------------------------
            while (getline < slabinfo_file > 0) {
                print "# " $0                                   >> output_file;
            }
            close(slabinfo_file);
            #--------------------------------------------------------
        }
        #------------------------------------------------------------

        # request 2 -------------------------------------------------
        if (mem["Slab"] >= red_limit || red_flag == 1) {
            red_flag    = 1;
            interval    = 30;
        } else if (mem["Slab"] >= yellow_limit || yellow_flag == 1) {
            yellow_flag = 1;
            interval    = 60;
        } else {
            green_flag  = 1;
            interval    = 300;
        }

        system(sleep_cmd " " interval);
        #------------------------------------------------------------

    }
}

gawk 特有の機能としては length() 関数で配列の数をカウントできることや gensub() 関数で置換後の文字列を返していたりしているところです。 また、日付も strftime() から取得しています。 xgawk の機能を使えば sleep コマンドも awk だけで実装できます。

実行すると、output_file を指定しない場合には日付付きのログに記録します。

$ vi meminfo.awk

別のターミナルから実行結果を見てみます。

$ less meminfo_20090513.log
"date"	"MemTotal"	"MemFree"	"Buffers"	"Cached"	"SwapCached"	"Active"	"Inactive"	"HighTotal"	"HighFree"	"LowTotal"	"LowFree"	"SwapTotal"	"SwapFree"	"Dirty"	"Writeback"	"AnonPages"	"Mapped"	"Slab"	"SReclaimable"	"SUnreclaim"	"PageTables"	"NFS_Unstable"	"Bounce"	"WritebackTmp"	"CommitLimit"	"Committed_AS"	"VmallocTotal"	"VmallocUsed"	"VmallocChunk"	"HugePages_Total"	"HugePages_Free"	"HugePages_Rsvd"	"HugePages_Surp"	"Hugepagesize"	"DirectMap4k"	"DirectMap4M"
"2009/05/13 22:02:46"	"2032236"	"68700"	"48688"	"996600"	"40"	"1369228"	"477064"	"1137344"	"8136"	"894892"	"60564"	"2031608"	"2031568"	"4116"	"0"	"800984"	"294108"	"75496"	"59628"	"15868"	"9944"	"0"	"0"	"0"	"4043520"	"1963904"	"110584"	"14356"	"95220"	"0"	"0"	"0"	"0"	"4096"	"12288"	"905216"	""	"2032236"	"65516"	"27820"	"973840"	"40"	"1372284"	"480948"	"1137344"	"5740"	"894892"	"59776"	"2031608"	"2031568"	"57032"	"0"	"851736"	"299860"	"71488"	"55304"	"16184"	"10124"	"0"	"0"	"0"	"4043520"	"2056712"	"110584"	"14356"	"95220"	"0"	"0"	"0"	"0"	"4096"	"12288"	"905216"
# slabinfo - version: 2.1
# # name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
# fuse_request          42     42    376   21    2 : tunables    0    0    0 : slabdata      2      2      0
# fuse_inode            18     18    448   18    2 : tunables    0    0    0 : slabdata      1      1      0
# fat_inode_cache       40     40    400   20    2 : tunables    0    0    0 : slabdata      2      2      0
# fat_cache            340    340     24  170    1 : tunables    0    0    0 : slabdata      2      2      0
# rpc_inode_cache       16     16    512   16    2 : tunables    0    0    0 : slabdata      1      1      0
# RAWv6                 23     23    704   23    4 : tunables    0    0    0 : slabdata      1      1      0
# TCPv6                 30     36   1344   12    4 : tunables    0    0    0 : slabdata      3      3      0
# nf_conntrack_expect     48     48    168   24    1 : tunables    0    0    0 : slabdata      2      2      0
# nf_conntrack         555    561    232   17    1 : tunables    0    0    0 : slabdata     33     33      0
# kcopyd_job             0      0    264   15    1 : tunables    0    0    0 : slabdata      0      0      0
# dm_uevent              0      0   2464   13    8 : tunables    0    0    0 : slabdata      0      0      0
# kmalloc_dma-512       16     16    512   16    2 : tunables    0    0    0 : slabdata      1      1      0
# bsg_cmd                0      0    288   14    1 : tunables    0    0    0 : slabdata      0      0      0
# mqueue_inode_cache     14     14    576   14    2 : tunables    0    0    0 : slabdata      1      1      0
# isofs_inode_cache      0      0    376   21    2 : tunables    0    0    0 : slabdata      0      0      0
# hugetlbfs_inode_cache     23     23    344   23    2 : tunables    0    0    0 : slabdata      1      1      0
# journal_handle       340    340     24  170    1 : tunables    0    0    0 : slabdata      2      2      0
# journal_head        1165   1168     56   73    1 : tunables    0    0    0 : slabdata     16     16      0
# revoke_record        512    512     16  256    1 : tunables    0    0    0 : slabdata      2      2      0
# ext3_inode_cache   68892  69888    496   16    2 : tunables    0    0    0 : slabdata   4368   4368      0
# ext3_xattr           425    425     48   85    1 : tunables    0    0    0 : slabdata      5      5      0
# dquot                  0      0    128   32    1 : tunables    0    0    0 : slabdata      0      0      0
# shmem_inode_cache   2628   2628    448   18    2 : tunables    0    0    0 : slabdata    146    146      0
# TCP                  165    169   1216   13    4 : tunables    0    0    0 : slabdata     13     13      0
# sgpool-128            24     24   2560   12    8 : tunables    0    0    0 : slabdata      2      2      0
# sgpool-64             24     24   1280   12    4 : tunables    0    0    0 : slabdata      2      2      0
# sgpool-32             31     36    640   12    2 : tunables    0    0    0 : slabdata      3      3      0
# sgpool-16             24     24    320   12    1 : tunables    0    0    0 : slabdata      2      2      0
# scsi_io_context        0      0    104   39    1 : tunables    0    0    0 : slabdata      0      0      0
# blkdev_queue          52     52   1224   13    4 : tunables    0    0    0 : slabdata      4      4      0
# blkdev_requests       48     60    200   20    1 : tunables    0    0    0 : slabdata      3      3      0
# biovec-256            50     50   3072   10    8 : tunables    0    0    0 : slabdata      5      5      0
# biovec-128            63     63   1536   21    8 : tunables    0    0    0 : slabdata      3      3      0
# biovec-64             74     84    768   21    4 : tunables    0    0    0 : slabdata      4      4      0
# sock_inode_cache     973    987    384   21    2 : tunables    0    0    0 : slabdata     47     47      0
# file_lock_cache       78     78    104   39    1 : tunables    0    0    0 : slabdata      2      2      0
# Acpi-Namespace      2720   2720     24  170    1 : tunables    0    0    0 : slabdata     16     16      0
# task_delay_info      421    459     80   51    1 : tunables    0    0    0 : slabdata      9      9      0
# taskstats             24     24    328   12    1 : tunables    0    0    0 : slabdata      2      2      0
# proc_inode_cache    1098   1298    368   22    2 : tunables    0    0    0 : slabdata     59     59      0
# sigqueue              56     56    144   28    1 : tunables    0    0    0 : slabdata      2      2      0
# radix_tree_node    13113  22386    296   13    1 : tunables    0    0    0 : slabdata   1722   1722      0
# bdev_cache            48     48    512   16    2 : tunables    0    0    0 : slabdata      3      3      0
# sysfs_dir_cache    11845  12155     48   85    1 : tunables    0    0    0 : slabdata    143    143      0
# inode_cache          498    966    344   23    2 : tunables    0    0    0 : slabdata     42     42      0
# dentry             36159  39210    136   30    1 : tunables    0    0    0 : slabdata   1307   1307      0
# avc_node             146    146     56   73    1 : tunables    0    0    0 : slabdata      2      2      0
# selinux_inode_security   7111   7140     40  102    1 : tunables    0    0    0 : slabdata     70     70      0
# buffer_head        43283 109568     64   64    1 : tunables    0    0    0 : slabdata   1712   1712      0
# mm_struct            908    936    448   18    2 : tunables    0    0    0 : slabdata     52     52      0
# vm_area_struct     20957  21390     88   46    1 : tunables    0    0    0 : slabdata    465    465      0
# files_cache          210    231    384   21    2 : tunables    0    0    0 : slabdata     11     11      0
# signal_cache         263    280    576   14    2 : tunables    0    0    0 : slabdata     20     20      0
# sighand_cache        237    264   1344   12    4 : tunables    0    0    0 : slabdata     22     22      0
# task_struct          348    369   3280    9    8 : tunables    0    0    0 : slabdata     41     41      0
# anon_vma            6653   7168     16  256    1 : tunables    0    0    0 : slabdata     28     28      0
# idr_layer_cache     1092   1092    152   26    1 : tunables    0    0    0 : slabdata     42     42      0
# kmalloc-4096         334    360   4096    8    8 : tunables    0    0    0 : slabdata     45     45      0
# kmalloc-2048         189    192   2048   16    8 : tunables    0    0    0 : slabdata     12     12      0
# kmalloc-1024         616    640   1024   16    4 : tunables    0    0    0 : slabdata     40     40      0
# kmalloc-512         4912   4944    512   16    2 : tunables    0    0    0 : slabdata    309    309      0
# kmalloc-256          528    528    256   16    1 : tunables    0    0    0 : slabdata     33     33      0
# kmalloc-128         1221   1472    128   32    1 : tunables    0    0    0 : slabdata     46     46      0
# kmalloc-64         14116  14144     64   64    1 : tunables    0    0    0 : slabdata    221    221      0
# kmalloc-32          2142   2432     32  128    1 : tunables    0    0    0 : slabdata     19     19      0
# kmalloc-16          4148   5632     16  256    1 : tunables    0    0    0 : slabdata     22     22      0
# kmalloc-8           6110   6144      8  512    1 : tunables    0    0    0 : slabdata     12     12      0
# kmalloc-192        10506  10710    192   21    1 : tunables    0    0    0 : slabdata    510    510      0
# kmalloc-96          2253   2268     96   42    1 : tunables    0    0    0 : slabdata     54     54      0

Linux の場合には proc システムからいろいろな情報を得ることができたり、これを利用して様々な設定を行うことができます。 また、ほとんどの Linux では標準で gawk は動作しますので、gawk の機能を使った自分用のログ整理を行うことも可能です。

tag_gawk.pngtag_gawk.png