Expand description
Parser for FreeSWITCH log files.
Handles the full complexity of mod_logfile output: five distinct line
formats, multi-line CHANNEL_DATA and SDP dumps, truncated buffer collisions,
and per-session state tracking — no regex, a single dependency
(freeswitch-types).
§Architecture
The parser is organized in three composable layers, each wrapping the previous:
- Layer 1 (
parse_line) — stateless, zero-allocation single-line classifier - Layer 2 (
LogStream) — structural state machine that groups continuations, classifies messages, and detects multi-line blocks - Layer 3 (
SessionTracker) — per-UUID state machine that propagates dialplan context, channel state, and variables across entries; extensible viaSessionTracker::with_pre_hookandSessionTracker::with_post_hookfor custom leg detection
See docs/design-rationale.md in the repository for the parsing strategy
and why each layer exists; the line-format anatomy lives in the repository’s
CLAUDE.md.
§Examples
Read lines from stdin, process through all three layers, and print enriched entries:
use std::io;
use freeswitch_log_parser::{read_log_lines, LogStream, SessionTracker};
// read_log_lines tolerates mod_logfile's truncated codepoints; the strict
// BufRead::lines() reader would panic on them.
let lines = read_log_lines(io::stdin().lock()).map(|d| d.expect("read error").text);
let stream = LogStream::new(lines);
let mut tracker = SessionTracker::new(stream);
for enriched in tracker.by_ref() {
let e = &enriched.entry;
println!("{} [{}] {}", e.timestamp, e.message_kind, e.message);
}
let stats = tracker.stats();
eprintln!("{} lines, {} unclassified",
stats.lines_processed, stats.lines_unclassified);§Feature flags
cli— enables thefslogbinary with clap, xz decompression, and regex filtering
Structs§
- Attached
Lines - Compact storage for the raw continuation lines of a log entry.
- Attached
Lines Iter - Iterator over the lines of an
AttachedLines. - Attached
Overflow - One entry’s attached lines outgrew the
u32offsets addressing them. - Bridge
Info - What a
bridge()argument list says about the leg it is about to create. - Codec
Impl - A codec implementation the engine reports it is running, as distinct from a
CodecOfferread off the wire. - Codec
Offer - One codec as FreeSWITCH spells it inside a negotiation trace’s brackets.
- Conference
Membership - A session’s membership in one conference.
- Decoded
Line - A decoded log line plus the UTF-8 verdict for its bytes.
- Enriched
Entry - A
LogEntrypaired with the session’s state snapshot at that point in time. - Field
- A located byte range and what it holds.
- Find
Uuids - Iterator returned by
find_uuids. - LogEntry
- A complete parsed log entry with all context resolved.
- LogStream
- Layer 2 structural state machine — groups continuation lines, classifies messages, and detects multi-line blocks (CHANNEL_DATA, SDP, codec negotiation).
- Media
Codecs - What one media type’s negotiation produced for a session.
- Parse
Level Error - Returned when a string doesn’t match any known log level.
- Parse
Stats - Cumulative parsing statistics, updated as lines flow through the stream.
- RawLine
- Zero-copy result of parsing a single log line.
- Rendered
Entry - An entry’s text after a rewrite, one string per render unit.
- Segment
Tracker - Handle for looking up which segment a line number belongs to.
- Session
Media - Codecs a session negotiated, by media type and by direction.
- Session
Snapshot - Immutable point-in-time copy of a session’s state, attached to each [
EnrichedEntry]. - Session
State - Mutable per-UUID state accumulator, updated as entries are processed.
- Session
Tracker - Layer 3 per-session state machine — tracks per-UUID state (dialplan context,
channel state, variables) across entries and yields
EnrichedEntryvalues. - Tracked
Chain - Iterator that concatenates named segments and tracks which line number
each segment starts at. Pair with
SegmentTrackerto look up which segment a given line belongs to. - Unclassified
Line - Record of a single unclassified line, captured when tracking is enabled.
Enums§
- Block
- Structured data extracted from a multi-line dump that follows a primary log entry.
- Call
Direction - Call direction from the
Call-Directionheader. Wire format is lowercase. - Call
State - Call state from
switch_channel_callstate_t– carried in theChannel-Call-Stateheader. - Channel
State - Channel state from
switch_channel_state_t– carried in theChannel-Stateheader as a string (CS_ROUTING) and inChannel-State-Numberas an integer. - Channel
Variable - Core FreeSWITCH channel variable names (the part after the
variable_prefix). - Codec
Media - Which negotiation trace a codec token came from.
- Codec
Parse Error - Why a codec token could not be read.
- Conference
Variable - mod_conference channel variable names (the part after the
variable_prefix). - Dtmf
Source - Source of a DTMF event log line.
- Field
Kind - What a located span holds.
- Field
Location - Which of an entry’s texts a range indexes.
- Hangup
Cause - Hangup cause from
switch_cause_t(Q.850 + FreeSWITCH extensions). - Line
Kind - Classification of a single log line’s structural format.
- LogLevel
- FreeSWITCH log severity level.
- Message
Kind - Semantic classification of a log message’s content.
- Parse
Warning - A parsing anomaly, attached to the entry whose lines produced it.
- Render
Error - Why a rewrite could not be applied.
- SdpDirection
- Which end of a call an SDP body belongs to.
- Session
Reading - A per-session reading whose value its vocabulary did not know.
- SipInvite
Direction - Direction of a sofia SIP INVITE log line.
- Sofia
Variable - mod_sofia / SIP channel variable names (the part after the
variable_prefix). - Unclassified
Reason - Why a line was marked as unclassified.
- Unclassified
Tracking - Controls how much detail is recorded for lines that couldn’t be fully classified.
- Utf8
Decode - Outcome of classifying a line’s bytes as UTF-8.
Constants§
- LOOPBACK_
PEER_ UUID_ VARS - mod_loopback variables whose value is another leg’s UUID. Separate from
PEER_UUID_VARSonly becausefreeswitch-typesgives them their own enum. - PEER_
UUID_ VARS - Channel variables whose value is, or contains, a peer leg’s UUID.
Traits§
- Variable
Name - Trait for typed channel variable name enums.
Functions§
- apply_
fields - Rewrite the spans of one text, returning the result.
- classify_
message - Classify a log message’s text into a
MessageKind. - classify_
utf8 - Classify a line’s bytes as UTF-8, distinguishing a truncated codepoint (benign) from a genuinely invalid byte (corruption). Pure; no I/O.
- decode_
log_ line - Decode one raw log line: strip the terminator, classify, lossy-recover.
- find_
uuids - Iterate the UUIDs embedded anywhere in
text, yielding each match’s byte offset and slice. Matches never overlap. - for_
each_ peer_ uuid - Call
fwith every peer-leg UUIDentrymentions. - for_
each_ peer_ uuid_ with - Call
fwith every peer-leg UUIDentrymentions, treating a variable as peer-bearing when it is inPEER_UUID_VARSorextra_varaccepts its name. - is_
peer_ uuid_ var - Whether
nameis one ofPEER_UUID_VARSorLOOPBACK_PEER_UUID_VARS. Accepts the bare variable name; strip anyvariable_prefix first. - is_uuid
- Whether
sis exactly one canonical UUID: 8-4-4-4-12 hex digits, either case. - log_
rotation_ stamp - The rotation stamp encoded in a
freeswitch.log.*filename, orNonefor the active log and for any name that does not carry one. - message_
fields - Locate the fields a message carries, as ranges into
msg. - normalize_
entry_ timestamp - Rewrite a log entry’s
YYYY-MM-DD HH:MM:SS.fffffftimestamp into the stamp form, dropping the sub-second part so it compares against a filename stamp. - parse_
bridge_ args - Extract
origination_uuidand the bridge target channel from bridge() arguments. UsesBridgeDialStringfrom freeswitch-types for correct parsing of[],{},|failover, and,simultaneous ring syntax. - parse_
line - Layer 1 entry point: classify a single line and extract its fields.
- read_
log_ lines - Read newline-delimited log lines, decoding each with the truncated-codepoint case typed distinctly from corruption.
- truncate_
at_ char_ boundary - Largest prefix of
sat mostmax_byteslong that ends on a char boundary.