Packages
nerves_runtime
0.11.8
0.13.13
0.13.12
0.13.11
retired
0.13.10
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.10
0.11.9
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
retired
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.1
0.3.0
0.2.0
0.1.2
0.1.1
0.1.0
Small, general runtime utilities for Nerves devices
Current section
Files
Jump to
Current section
Files
lib/nerves_runtime/log/kmsg_tailer.ex
defmodule Nerves.Runtime.Log.KmsgTailer do
@moduledoc """
Collects operating system-level messages from `/proc/kmsg`,
forwarding them to `Logger` with an appropriate level to match the syslog
priority parsed out of the message.
"""
use GenServer
require Logger
alias Nerves.Runtime.Log.{KmsgParser, SyslogParser}
@doc """
Start the kmsg monitoring GenServer.
"""
@spec start_link(any()) :: GenServer.on_start()
def start_link(_args) do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
@impl GenServer
def init(_args), do: {:ok, %{port: open_port(), buffer: ""}}
@impl GenServer
def handle_info({port, {:data, {:noeol, fragment}}}, %{port: port, buffer: buffer} = state) do
{:noreply, %{state | buffer: buffer <> fragment}}
end
def handle_info(
{port, {:data, {:eol, fragment}}},
%{port: port, buffer: buffer} = state
) do
_ = handle_message(buffer <> fragment)
{:noreply, %{state | buffer: ""}}
end
defp open_port() do
Port.open({:spawn_executable, executable()}, [
{:arg0, "kmsg_tailer"},
{:line, 1024},
:use_stdio,
:binary,
:exit_status
])
end
defp executable() do
:code.priv_dir(:nerves_runtime) ++ '/nerves_runtime'
end
defp handle_message(raw_entry) do
case KmsgParser.parse(raw_entry) do
{:ok, %{facility: facility, severity: severity, message: message}} ->
level = SyslogParser.severity_to_logger(severity)
Logger.bare_log(
level,
message,
module: __MODULE__,
facility: facility,
severity: severity
)
_ ->
# We don't handle continuations and multi-line kmsg logs.
# It's painful to ignore log messages, but these don't seem
# to be reported by dmesg and the ones I've seen so far contain
# redundant information that's primary value is that it's
# machine parsable (i.e. key=value listings)
:ok
end
end
end