From 2221f53136c615df6bc496c2fd0e89d2b4a072b3 Mon Sep 17 00:00:00 2001 From: Oleg Babin Date: Wed, 8 Oct 2025 17:52:24 +0400 Subject: [PATCH] process: handle possible `fio.read` errors Once I catched an error during tests: ``` tarantool/override/metrics/psutils/psutils_linux.lua:49: bad argument #1 to 'string.split' (string expected, got nil) ``` That shows that in some rare cases fio.read can return `nil, err` but before this patch this case was unhandled. This patch fixes it. Also it was pretty strange to print a message via "print" function. It was changed to "log" module that is more native for tarantool. This patch doesn't contain tests because it's pretty hard to reproduce such error (file was opened but `file:read()` returned an errors for some reasons). Closes #526 --- CHANGELOG.md | 2 ++ metrics/psutils/psutils_linux.lua | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20c86f13..ed6491a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed a potential `process` metrics error when `fio.read` returns an empty string or an error. + # [1.5.0] - 2025-08-13 ### Added diff --git a/metrics/psutils/psutils_linux.lua b/metrics/psutils/psutils_linux.lua index c514dbbe..443a6d89 100644 --- a/metrics/psutils/psutils_linux.lua +++ b/metrics/psutils/psutils_linux.lua @@ -1,6 +1,7 @@ local fio = require('fio') local string = require('string') local ffi = require('ffi') +local log = require('log') local get_nprocs_conf = function() end if jit.os == 'Linux' then @@ -19,7 +20,7 @@ local function get_cpu_time() local stats_raw = cpu_stat_file:read(512) cpu_stat_file:close() - if #stats_raw == 0 then + if stats_raw == nil or #stats_raw == 0 then return nil end @@ -37,14 +38,22 @@ local function get_cpu_time() end local function parse_process_stat(path) - local stat = fio.open(path, 'O_RDONLY') - if stat == nil then - print('stat open error') + local stat, err = fio.open(path, 'O_RDONLY') + if err ~= nil then + log.error('stat open error: %s', tostring(err)) return nil end - local s = stat:read(512) + local s + s, err = stat:read(512) stat:close() + if err ~= nil then + log.error('stat read error: %s', tostring(err)) + return nil + end + if s == nil or #s == 0 then + return nil + end local stats = string.split(s) return {