Packages
nerves_runtime
0.11.5
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/syslog_tailer.ex
defmodule Nerves.Runtime.Log.SyslogTailer do
use GenServer
require Logger
@moduledoc """
This GenServer routes syslog messages from C-based applications and libraries through
the Elixir Logger for collection.
"""
alias Nerves.Runtime.Log.SyslogParser
@syslog_path "/dev/log"
@doc """
Start the local syslog 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
# Blindly try to remove an old file just in case it exists from a previous run
_ = File.rm(@syslog_path)
{:ok, log_port} =
:gen_udp.open(0, [:local, :binary, {:active, true}, {:ip, {:local, @syslog_path}}])
# All processes should be able to log messages
File.chmod!(@syslog_path, 0o666)
{:ok, log_port}
end
@impl GenServer
def handle_info({:udp, log_port, _, 0, raw_entry}, log_port) do
case SyslogParser.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
)
_ ->
# This is unlikely to ever happen, but if a message was somehow
# malformed and we couldn't parse the syslog priority, we should
# still do a best-effort to pass along the raw data.
Logger.warn("Malformed syslog report: #{inspect(raw_entry)}")
end
{:noreply, log_port}
end
end