draios / sysdig

Linux system exploration and troubleshooting tool with first class support for containers
http://www.sysdig.com/
Other
7.68k stars 728 forks source link

Ask about evt.type=procinfo #2074

Open DullJZ opened 3 months ago

DullJZ commented 3 months ago

I want to use sysdig to list the CPU usage of all container processes, so I wrote a script imitating topproc_cpu.lua:

-- Chisel description
description = "Show the top process defined by the highest CPU utilization in containers."
short_description = "Top processes by CPU usage"
category = "CPU Usage"

-- Chisel argument list
args = {}

require "common"
terminal = require "ansiterminal"

grtable = {}
fkeys = {}
TOP_NUMBER = 999999
local print_container = true

vizinfo =
{
    key_fld = {"proc.name","proc.pid"},
    key_desc = {"Process", "PID"},
    value_fld = "thread.exectime",
    value_desc = "CPU%",
    value_units = "timepct",
    top_number = TOP_NUMBER,
    output_format = "json"
}

-- Initialization callback
function on_init()
    -- Print container info as well
    if print_container then
        -- Modify host pid column name and add container information
        vizinfo.key_fld = {"proc.name", "proc.pid", "proc.vpid", "container.name"}
        vizinfo.key_desc = {"Process", "Host_pid", "Container_pid", "container.name"}
    end

    -- Request the fields we need
    for i, name in ipairs(vizinfo.key_fld) do
        fkeys[i] = chisel.request_field(name)
    end

    -- Request the fields we need
    fvalue = chisel.request_field(vizinfo.value_fld)
    fcpu = chisel.request_field("thread.cpu")

    chisel.set_filter("evt.type=procinfo and container.name!=host")
    return true
end

-- Event parsing callback
function on_event()
    local key = nil
    local kv = nil

    for i, fld in ipairs(fkeys) do
        kv = evt.field(fld)
        if kv == nil then
            return
        end

        if key == nil then
            key = kv
        else
            key = key .. "\001\001" .. evt.field(fld)
        end
    end

    local cpu = evt.field(fcpu)

    if grtable[key] == nil then
        grtable[key] = cpu * 10000000
    else
        grtable[key] = grtable[key] + (cpu * 10000000)
    end
    print_sorted_table(grtable, ts_s, 0, delta, vizinfo)
    return true
end

But this seems to only provide one process information when an event occurs, outputting:

{
  "data":[["s6-svscan","2492","1","docker-tc",0]],
  "info":[{
      "desc":"Process",
      "is_key":true,
      "name":"proc.name"
    },{
      "desc":"Host_pid",
      "is_key":true,
      "name":"proc.pid"
    },{
      "desc":"CPU%",
      "is_key":false,
      "name":"thread.exectime"
    },{
      "desc":"container.name",
      "is_key":true,
      "name":"container.name"
    }],
  "ts":"0"
}

Therefore, I want to know how the built-in evt.type=procinfo works. In other words, how can I achieve my goal, like viewing all process information in csysdig?

jasondellaluce commented 3 months ago

Hey @DullJZ. The evt.type=procinfo event, and the on_event callback, are both only relative to one process/thread per time, so as you already do it would be appropriate to use a combination of a table and print it with an interval. Can you expand on why topproc_cpu.lua is not enough for your use case? Also I think the filter evt.type=procinfo and container.name!=host is not necessary, and evt.type=procinfo should be enough.

DullJZ commented 3 months ago

Thanks for your reply!

Actually I want to make a command-line way to get all the infomation about processes in a container, including cpu, memory and io usage, like csysdig does:

image