# HG changeset patch # User Jonas Schäfer # Date 1619590914 -7200 # Node ID 025cf93acfe9bc901a556ed3e62dbfca3d2f2075 # Parent 7e5c8186f121ebb17525150dcf67be1a60dfa36b mod_measure_process: Provide metrics about the process itself diff -r 7e5c8186f121 -r 025cf93acfe9 mod_measure_process/README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_measure_process/README.markdown Wed Apr 28 08:21:54 2021 +0200 @@ -0,0 +1,27 @@ +--- +labels: +- Statistics +summary: Measure process resource use metrics (cpu, memory, file descriptors) +--- + +Description +=========== + +This module exposes process resource use metrics similar to those exposed by +default when using a Prometheus client library. Specifically, the following +metrics are exposed: + +- CPU use +- Resident set and virtual memory size +- Number of open file descriptors and their limit + +This module uses the new OpenMetrics API and thus requires a recent version +of Prosody trunk (0.12+). + +Compatibility +============= + + ------- ------------- + trunk Works + 0.11 Does not work + ------- ------------- diff -r 7e5c8186f121 -r 025cf93acfe9 mod_measure_process/mod_measure_process.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_measure_process/mod_measure_process.lua Wed Apr 28 08:21:54 2021 +0200 @@ -0,0 +1,74 @@ +module:set_global() + +local get_cpu_time = os.clock + +local custom_metric = require "core.statsmanager".metric +local cpu_time = custom_metric( + "counter", "process_cpu", "seconds", + "CPU time used by Prosody as reported by clock(3)." +):with_labels() + +local lfs = require "lfs" + +module:hook("stats-update", function () + cpu_time:set(get_cpu_time()) +end); + +if lfs.attributes("/proc/self/statm", "mode") == "file" then + local pagesize = module:get_option_number("memory_pagesize", 4096); -- getconf PAGESIZE + + local vsz = custom_metric( + "gauge", "process_virtual_memory", "bytes", + "Virtual memory size in bytes." + ):with_labels() + local rss = custom_metric( + "gauge", "process_resident_memory", "bytes", + "Resident memory size in bytes." + ):with_labels() + + module:hook("stats-update", function () + local statm, err = io.open("/proc/self/statm"); + if not statm then + module:log("error", tostring(err)); + return; + end + -- virtual memory (caches, opened librarys, everything) + vsz:set(statm:read("*n") * pagesize); + -- resident set size (actually used memory) + rss:set(statm:read("*n") * pagesize); + statm:close(); + end); +end + +if lfs.attributes("/proc/self/fd", "mode") == "directory" then + local open_fds = custom_metric( + "gauge", "process_open_fds", "", + "Number of open file descriptors." + ):with_labels() + + local has_posix, posix = pcall(require, "util.pposix") + local max_fds + if has_posix then + max_fds = custom_metric( + "gauge", "process_max_fds", "", + "Maximum number of open file descriptors" + ):with_labels() + else + module:log("warn", "not reporting maximum number of file descriptors because mod_posix is not available") + end + + module:hook("stats-update", function () + local count = 0 + for _ in lfs.dir("/proc/self/fd") do + count = count + 1 + end + open_fds:set(count) + + if has_posix then + local ok, soft, hard = posix.getrlimit("NOFILE") + if ok then + max_fds:set(hard) + end + end + end); +end