Packages
nerves_runtime
0.11.2
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_parser.ex
defmodule Nerves.Runtime.Log.KmsgParser do
@moduledoc """
Functions for parsing kmsg strings
"""
alias Nerves.Runtime.Log.SyslogParser
@doc """
Parse out the kmsg facility, severity, and message (including the timestamp
and host) from a kmsg-formatted string.
See https://elixir.bootlin.com/linux/latest/source/Documentation/ABI/testing/dev-kmsg for full details.
Most messages are of the form:
```text
priority,sequence,timestamp,flag;message
```
`priority` is an integer that when broken apart gives you a facility and severity.
`sequence` is a monotonically increasing counter
`timestamp` is the time in microseconds
`flag` is almost always `-`
`message` is everything else
This parser only supports the minimum kmsg reports. The spec above describes
more functionality, but it appears to be uncommon and I haven't seen any
examples yet in my testing.
"""
@spec parse(String.t()) ::
{:ok,
%{
facility: SyslogParser.facility(),
severity: SyslogParser.severity(),
message: String.t(),
timestamp: integer(),
sequence: integer(),
flags: [atom()]
}}
| {:error, :parse_error}
def parse(line) do
with [metadata, message] <- String.split(line, ";"),
[priority_str, sequence_str, timestamp_str, flag] <-
String.split(metadata, ",", parts: 4),
{priority_int, ""} <- Integer.parse(priority_str),
{sequence, ""} <- Integer.parse(sequence_str),
{timestamp, ""} <- Integer.parse(timestamp_str),
{:ok, facility, severity} <- SyslogParser.decode_priority(priority_int) do
{:ok,
%{
facility: facility,
severity: severity,
message: message,
timestamp: timestamp,
sequence: sequence,
flags: parse_flags(flag)
}}
else
_ -> {:error, :parse_error}
end
end
defp parse_flags("-"), do: []
defp parse_flags("c"), do: [:continue]
defp parse_flags(_), do: []
end