1235368Sgnn#!/usr/bin/sh 2235368Sgnn# 3235368Sgnn# dnlcstat - DNLC statistics. 4235368Sgnn# Written in DTrace (Solaris 10 3/05). 5235368Sgnn# 6235368Sgnn# The DNLC is the Directory Name Lookup Cache. Filename lookups often 7235368Sgnn# return a hit from here, before needing to traverse the regular file 8235368Sgnn# system cache or go to disk. 9235368Sgnn# 10235368Sgnn# $Id: dnlcstat 3 2007-08-01 10:50:08Z brendan $ 11235368Sgnn# 12235368Sgnn# USAGE: dnlcstat [interval [count]] 13235368Sgnn# 14235368Sgnn# FIELDS: 15235368Sgnn# 16235368Sgnn# %hit hit percentage for this sample 17235368Sgnn# hit number of DNLC hits in this sample 18235368Sgnn# miss number of DNLC misses in this sample 19235368Sgnn# 20235368Sgnn# SEE ALSO: CacheKit, http://www.brendangregg.com/cachekit.html 21235368Sgnn# (contains a dnlcstat written in Perl, which uses less CPU) 22235368Sgnn# 23235368Sgnn# COPYRIGHT: Copyright (c) 2005 Brendan Gregg. 24235368Sgnn# 25235368Sgnn# CDDL HEADER START 26235368Sgnn# 27235368Sgnn# The contents of this file are subject to the terms of the 28235368Sgnn# Common Development and Distribution License, Version 1.0 only 29235368Sgnn# (the "License"). You may not use this file except in compliance 30235368Sgnn# with the License. 31235368Sgnn# 32235368Sgnn# You can obtain a copy of the license at Docs/cddl1.txt 33235368Sgnn# or http://www.opensolaris.org/os/licensing. 34235368Sgnn# See the License for the specific language governing permissions 35235368Sgnn# and limitations under the License. 36235368Sgnn# 37235368Sgnn# CDDL HEADER END 38235368Sgnn# 39235368Sgnn# 27-Mar-2004 Brendan Gregg Created this. 40235368Sgnn# 14-Jun-2005 " " Updated style. 41235368Sgnn# 14-Jun-2005 " " Last update. 42235368Sgnn# 43235368Sgnn 44235368Sgnn############################## 45235368Sgnn# --- Process Arguments --- 46235368Sgnn# 47235368Sgnn 48235368Sgnn### default values 49235368Sgnninterval=1; count=-1 50235368Sgnn 51235368Sgnn### check arguments 52235368Sgnnif [ "$1" = "-h" -o "$1" = "--help" ]; then 53235368Sgnn cat <<-END >&2 54235368Sgnn USAGE: dnlcstat [interval [count]] 55235368Sgnn dnlcstat # 1 second samples, infinite 56235368Sgnn eg, 57235368Sgnn dnlcstat 1 # print every 1 second 58235368Sgnn dnlcstat 5 6 # print every 5 seconds, 6 times 59235368Sgnn END 60235368Sgnn exit 1 61235368Sgnnfi 62235368Sgnn 63235368Sgnn### argument logic 64235368Sgnnif [ "$1" -gt 0 ]; then 65235368Sgnn interval=$1; count=-1; shift 66235368Sgnnfi 67235368Sgnnif [ "$1" -gt 0 ]; then 68235368Sgnn count=$1; shift 69235368Sgnnfi 70235368Sgnnif [ $interval -eq 0 ]; then 71235368Sgnn interval=1 72235368Sgnnfi 73235368Sgnn 74235368Sgnn 75235368Sgnn################################# 76235368Sgnn# --- Main Program, DTrace --- 77235368Sgnn# 78235368Sgnn/usr/sbin/dtrace -n ' 79235368Sgnn #pragma D option quiet 80235368Sgnn 81235368Sgnn /* 82235368Sgnn * Command line arguments 83235368Sgnn */ 84235368Sgnn inline int INTERVAL = '$interval'; 85235368Sgnn inline int COUNTER = '$count'; 86235368Sgnn inline int SCREEN = 21; 87235368Sgnn 88235368Sgnn int hits; /* hits */ 89235368Sgnn int misses; /* misses */ 90235368Sgnn 91235368Sgnn /* 92235368Sgnn * Initialise variables 93235368Sgnn */ 94235368Sgnn dtrace:::BEGIN 95235368Sgnn { 96235368Sgnn lines = SCREEN + 1; 97235368Sgnn counts = COUNTER; 98235368Sgnn secs = INTERVAL; 99235368Sgnn first = 1; 100235368Sgnn } 101235368Sgnn 102235368Sgnn /* 103235368Sgnn * Print header 104235368Sgnn */ 105235368Sgnn dtrace:::BEGIN, 106235368Sgnn tick-1sec 107235368Sgnn /first || (secs == 0 && lines > SCREEN)/ 108235368Sgnn { 109235368Sgnn printf("%10s %8s %8s\n","dnlc %hit","hit","miss"); 110235368Sgnn lines = 0; 111235368Sgnn first = 0; 112235368Sgnn } 113235368Sgnn 114235368Sgnn /* 115235368Sgnn * Probe DNLC lookups 116235368Sgnn */ 117235368Sgnn fbt:genunix:dnlc_lookup:return 118235368Sgnn { 119235368Sgnn hits += arg1 == 0 ? 0 : 1; 120235368Sgnn misses += arg1 == 0 ? 1 : 0; 121235368Sgnn } 122235368Sgnn 123235368Sgnn profile:::tick-1sec 124235368Sgnn { 125235368Sgnn secs--; 126235368Sgnn } 127235368Sgnn 128235368Sgnn 129235368Sgnn /* 130235368Sgnn * Print output line 131235368Sgnn */ 132235368Sgnn profile:::tick-1sec 133235368Sgnn /secs == 0/ 134235368Sgnn { 135235368Sgnn /* calculate hit percent */ 136235368Sgnn this->divide = misses + hits == 0 ? 1 : misses + hits; 137235368Sgnn ratio = hits * 100 / this->divide; 138235368Sgnn 139235368Sgnn /* print output */ 140235368Sgnn printf("%10d %8d %8d\n",ratio,hits,misses); 141235368Sgnn 142235368Sgnn /* clear counters */ 143235368Sgnn hits = 0; 144235368Sgnn misses = 0; 145235368Sgnn 146235368Sgnn /* process counts */ 147235368Sgnn secs = INTERVAL; 148235368Sgnn counts--; 149235368Sgnn lines++; 150235368Sgnn 151235368Sgnn } 152235368Sgnn 153235368Sgnn /* 154235368Sgnn * End 155235368Sgnn */ 156235368Sgnn profile:::tick-1sec 157235368Sgnn /counts == 0/ 158235368Sgnn { 159235368Sgnn exit(0); 160235368Sgnn } 161235368Sgnn' 162235368Sgnn 163