chore(agent): log /proc reads, log diagnostics enable, comment trap_exit
Addresses final code review: - Host collector's /proc reads now go through Diagnostics.log_read/3, appearing in commands.log formatted as `$ cat /proc/loadavg` - configure/1 logs an info line on successful enable so the operator has a breadcrumb in the journal - Writer.init/1 documents the deliberate trap_exit omission
This commit is contained in:
parent
2bb901873f
commit
3367b95b91
4 changed files with 34 additions and 3 deletions
|
|
@ -51,13 +51,13 @@ defmodule ProxmoxAgent.Collectors.Host do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp read_loadavg(proc_dir) do
|
defp read_loadavg(proc_dir) do
|
||||||
body = File.read!(Path.join(proc_dir, "loadavg"))
|
body = read_and_log(Path.join(proc_dir, "loadavg"))
|
||||||
[l1, l5, l15 | _] = String.split(body, ~r/\s+/, trim: true)
|
[l1, l5, l15 | _] = String.split(body, ~r/\s+/, trim: true)
|
||||||
{to_float(l1), to_float(l5), to_float(l15)}
|
{to_float(l1), to_float(l5), to_float(l15)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp read_meminfo(proc_dir) do
|
defp read_meminfo(proc_dir) do
|
||||||
body = File.read!(Path.join(proc_dir, "meminfo"))
|
body = read_and_log(Path.join(proc_dir, "meminfo"))
|
||||||
|
|
||||||
parsed =
|
parsed =
|
||||||
body
|
body
|
||||||
|
|
@ -76,11 +76,23 @@ defmodule ProxmoxAgent.Collectors.Host do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp read_uptime(proc_dir) do
|
defp read_uptime(proc_dir) do
|
||||||
body = File.read!(Path.join(proc_dir, "uptime"))
|
body = read_and_log(Path.join(proc_dir, "uptime"))
|
||||||
[secs | _] = String.split(body, " ", trim: true)
|
[secs | _] = String.split(body, " ", trim: true)
|
||||||
secs |> to_float() |> trunc()
|
secs |> to_float() |> trunc()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp read_and_log(path) do
|
||||||
|
start = System.monotonic_time(:microsecond)
|
||||||
|
result = File.read(path)
|
||||||
|
duration_us = System.monotonic_time(:microsecond) - start
|
||||||
|
ProxmoxAgent.Diagnostics.log_read(path, result, duration_us)
|
||||||
|
|
||||||
|
case result do
|
||||||
|
{:ok, body} -> body
|
||||||
|
{:error, reason} -> raise File.Error, reason: reason, action: "read file", path: to_string(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp kb_to_bytes(nil), do: nil
|
defp kb_to_bytes(nil), do: nil
|
||||||
|
|
||||||
defp kb_to_bytes(str) do
|
defp kb_to_bytes(str) do
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ defmodule ProxmoxAgent.Diagnostics do
|
||||||
case File.mkdir_p(dir) do
|
case File.mkdir_p(dir) do
|
||||||
:ok ->
|
:ok ->
|
||||||
Application.put_env(:agent, :dump_dir, dir)
|
Application.put_env(:agent, :dump_dir, dir)
|
||||||
|
Logger.info("diagnostics: enabled, writing to #{dir}")
|
||||||
:ok
|
:ok
|
||||||
|
|
||||||
{:error, reason} ->
|
{:error, reason} ->
|
||||||
|
|
@ -46,6 +47,11 @@ defmodule ProxmoxAgent.Diagnostics do
|
||||||
cast({:sample, kind, payload})
|
cast({:sample, kind, payload})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec log_read(Path.t(), command_result(), non_neg_integer()) :: :ok
|
||||||
|
def log_read(path, result, duration_us) do
|
||||||
|
log_command("cat", [to_string(path)], result, duration_us)
|
||||||
|
end
|
||||||
|
|
||||||
defp disable do
|
defp disable do
|
||||||
Application.delete_env(:agent, :dump_dir)
|
Application.delete_env(:agent, :dump_dir)
|
||||||
:ok
|
:ok
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ defmodule ProxmoxAgent.Diagnostics.Writer do
|
||||||
def init(opts) do
|
def init(opts) do
|
||||||
dir = Keyword.fetch!(opts, :dir)
|
dir = Keyword.fetch!(opts, :dir)
|
||||||
|
|
||||||
|
# No trap_exit: the Writer owns no linked processes other than the supervisor.
|
||||||
|
# If you add a linked port/task, restore Process.flag(:trap_exit, true) and
|
||||||
|
# add a matching handle_info({:EXIT, _, _}, state) clause.
|
||||||
with {:ok, commands} <- open(Path.join(dir, "commands.log")),
|
with {:ok, commands} <- open(Path.join(dir, "commands.log")),
|
||||||
{:ok, samples} <- open(Path.join(dir, "samples.log")) do
|
{:ok, samples} <- open(Path.join(dir, "samples.log")) do
|
||||||
{:ok, %{dir: dir, commands: commands, samples: samples}}
|
{:ok, %{dir: dir, commands: commands, samples: samples}}
|
||||||
|
|
|
||||||
|
|
@ -96,5 +96,15 @@ defmodule ProxmoxAgent.DiagnosticsTest do
|
||||||
assert body =~ "kind=fast"
|
assert body =~ "kind=fast"
|
||||||
assert body =~ "\"zfs_pools\""
|
assert body =~ "\"zfs_pools\""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "log_read/3 writes to commands.log formatted as cat", %{dir: dir} do
|
||||||
|
assert :ok = Diagnostics.log_read("/proc/loadavg", {:ok, "0.12 0.34 0.56 1/200 3000"}, 150)
|
||||||
|
:ok = GenServer.call(ProxmoxAgent.Diagnostics.Writer, :flush)
|
||||||
|
|
||||||
|
body = File.read!(Path.join(dir, "commands.log"))
|
||||||
|
assert body =~ "$ cat /proc/loadavg"
|
||||||
|
assert body =~ "0.12 0.34 0.56"
|
||||||
|
assert body =~ "exit=0"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue