Log Formatting Standards
This project assumes Lmod log messages are written to disk using the following format.
Log entries must follow this format to be parsable by the lmod-ingest
application.
[SYSLOG PREFIX] user=[USERNAME] jobid=[JOBID] module=[PACKAGE]/[VERSION] path=[MODULEPATH] host=[HOSTNAME] time=[UTC]
Individual field values are defined as follows:
Field | Description |
---|---|
SYSLOG PREFIX |
A system specific message prefix added by syslog. This value is ignored. |
USERNAME |
The name of the user who loaded the module. |
JOBID |
The nullable (nil ) ID of the slurm job the module was loaded from. |
PACKAGE |
The name of the package loaded via lmod. |
VERSION |
The version of the pacakge loaded via lmod. |
MODULEPATH |
The path of the loaded module file. |
HOSTNAME |
The machine hostname where the module was loaded. |
UTC |
The UTC time the module was loaded. |
Setting the Log Format
If your format differs from the above, you must change it by editing the SitePackage.lua
file.
The specific location of this file will vary depending on your Slurm cluster setup.
Appending the following code to the bottom of your SitePackage.lua
file will send lmod messages to syslog using the required format.
Note the slurm Job ID is determined using the nullable environmental variable SLURM_JOB_ID
(and not the older, deprecated variable SLURM_JOBID
).
--------------------------------------------------------------------------
require("lmod_system_execute")
local hook = require("Hook")
local uname = require("posix").uname
-- Cosmic class not available in the CRC current default lmod (6.6.3), introduced in 7.1.8
-- allows fetching of globals and defaults, see 'host' assignment in load_hook()
-- local cosmic = require("Cosmic"):singleton()
-- local syshost = cosmic:value("LMOD_SYSHOST")
-- By using the hook.register function, this function "load_hook" is called
-- ever time a module is loaded with the file name and the module name.
local s_msgA = {}
function load_hook(t)
-- the arg t is a table:
-- t.modFullName: the module full name: (i.e: gcc/4.7.2)
-- t.fn: The file name: (i.e /apps/modulefiles/Core/gcc/4.7.2.lua)
if (mode() ~= "load") then return end
local user = os.getenv("USER")
local jobid = os.getenv("SLURM_JOB_ID") or "nil"
local host = uname("%n")
local currentTime = epoch()
local msg = string.format("'user=%s jobid=%s module=%s path=%s host=%s time=%f'",
user, jobid, t.modFullName, t.fn, host, currentTime)
local a = s_msgA
a[#a+1] = msg
end
hook.register("load",load_hook)
function report_loads()
local sys = os.getenv("LMOD_sys") or "Linux"
if (sys == "Linux") then
local a = s_msgA
for i = 1,#a do
local msg = a[i]
lmod_system_execute("logger -t ModuleUsageTracking -p local0.info " .. msg)
end
end
end
ExitHookA.register(report_loads)