// This script tracks time between packet queue and xmit. // The information is provided to userspace using Memory Mapped Values (mmv) // which are updated every second and are readable by a PCP pmda. global net_device probe procfs("schema").read.maxsize(8192) { # Note: This is the "pretty-printed" version of the schema, intended # to be read by humans. We could remove the whitespace and newlines # if we wanted to make the output shorter (but less readable). # # Note 2: Note that we have to break this long string into more than # 1 assignment since we're bumping up against MAXSTRINGLEN. Procfs # $value can hold more than MAXSTRINGLEN because of the # '.maxsize(N)' parameter above. $value = "{\n" " \"type\": \"object\",\n" " \"title\": \"root\",\n" " \"additionalProperties\": false,\n" " \"properties\": {\n" " \"generation\": {\n" " \"type\": \"integer\",\n" " \"additionalProperties\": false\n" " },\n" $value .= " \"data\": {\n" " \"type\": \"object\",\n" " \"additionalProperties\": false,\n" " \"properties\": {\n" " \"interface\": {\n" " \"type\": \"string\",\n" " \"description\": \"network xmit device\",\n" " \"minLength\": 0,\n" " \"additionalProperties\": false\n" " },\n" $value .= " \"xmit_count\": {\n" " \"type\": \"integer\",\n" " \"description\": \"number of packets for xmit device\",\n" " \"minimum\": 0,\n" " \"default\": 0,\n" " \"additionalProperties\": false\n" " },\n" " \"xmit_latency\": {\n" " \"type\": \"integer\",\n" " \"description\": \"sum of latency for xmit device\",\n" " \"minimum\": 0,\n" " \"default\": 0,\n" " \"additionalProperties\": false\n" " }\n" " },\n" $value .= " \"required\": [\n" " \"interface\",\n" " \"xmit_count\",\n" " \"xmit_latency\"\n" " ]\n" " }\n" " }\n" "}\n" } probe procfs("data").read.maxsize(8192) { # NOTE: This is the "pretty-printed" version of the data, intended # to be read by humans. We could remove the whitespace and newlines # if we wanted to make the output shorter (but less readable). $value = "{\n" " \"generation\": 1,\n" " \"data\": {\n" if (@count(skb_queue_t[net_device])) { $value .= sprintf(" \"interface\": \"%s\",\n \"xmit_count\": %d,\n \"xmit_latency\": %d\n", net_device, @sum(skb_queue_t[net_device]), @count(skb_queue_t[net_device])) } else { $value .= sprintf(" \"interface\": \"%s\",\n \"xmit_count\": %d,\n \"xmit_latency\": %d\n", net_device, 0, 0) } $value .= " }\n" "}\n" } // Set up the mmv and make it available probe begin { // fallback instance device "eth0" if none specified if (argc == 0) { argv[1] = "eth0" } // remember the network device net_device = argv[1] } // probes to track the information global skb_queue_start_t, skb_queue_t probe kernel.trace("net_dev_queue") { skb_queue_start_t[$skb] = gettimeofday_ns(); } probe kernel.trace("net_dev_start_xmit"), kernel.trace("net_dev_xmit") { t = gettimeofday_ns(); st = skb_queue_start_t[$skb] if (st){ skb_queue_t[kernel_string($dev->name)] <<< t - st delete skb_queue_start_t[$skb] } }