.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.48) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "Log::Fmt 3" .TH Log::Fmt 3 2026-10-25 "perl v5.44.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH OVERVIEW .IX Header "OVERVIEW" This library primarily exists to service Log::Dispatchouli\*(Aqs \f(CW\*(C`log_event\*(C'\fR methods. It converts an arrayref of key/value pairs to a string that a human can scan tolerably well, and which a machine can parse about as well. It can also do that tolerably\-okay parsing for you. .SH SPECIFICATION .IX Header "SPECIFICATION" .SS "The logfmt text format" .IX Subsection "The logfmt text format" Although quite a few tools exist for managing \f(CW\*(C`logfmt\*(C'\fR, there is no spec\-like document for it. Because you may require multiple implementations, a specification can be helpful. .PP Every logfmt event is a sequence of pairs in the form \f(CW\*(C`key=value\*(C'\fR. Pairs are separated by a single space. .PP .Vb 5 \& event = pair *(WSP pair) \& pair = key "=" value \& okchr = %x21 / %x23\-3c / %x3e\-5b / %x5d\-7e ; VCHAR minus \e and " and = \& key = 1*(okchr) \& value = key / quoted \& \& quoted = DQUOTE *( escaped / quoted\-ok / okchr / eightbit ) DQUOTE \& escaped = escaped\-special / escaped\-hex \& escaped\-special = "\e\e" / "\en" / "\er" / "\et" / ("\e" DQUOTE) \& escaped\-hex = "\ex{" 2HEXDIG "}" ; lowercase forms okay also \& quoted\-ok = SP / "=" \& eightbit = %x80\-ff .Ve .PP When formatting a value, if a value is already a valid \f(CW\*(C`key\*(C'\fR token, use it without further quoting. .SS "Quoting a Unicode string" .IX Subsection "Quoting a Unicode string" It is preferable to build quoted values from a Unicode string, because it\*(Aqs possible to know whether a given codepoint is a non\-ASCII unsafe character, like \f(CW\*(C`LINE SEPARATOR\*(C'\fR. Safe non\-ASCII characters can be directly UTF\-8 encoded, rather than quoted with \f(CW\*(C`\ex{...}\*(C'\fR. In that way, viewing logfmt events with a standard terminal can show something like: .PP .Vb 1 \& user.name="Jürgen" .Ve .PP To generate a \f(CW\*(C`quoted\*(C'\fR from a Unicode string, for each codepoint: .PP Finally, UTF\-8 encode the entire string and wrap it in double qoutes. .PP \&\fBThis Perl implementation assumes that all string values to be encoded are character strings!\fR .PP \fIQuoting a bytestring\fR .IX Subsection "Quoting a bytestring" .PP Encoding a Unicode string is preferable, but may not be practical. In those cases when you have only a byte sequence, apply these steps. .PP For each byte (using ASCII conventions): .PP Finally, wrap the string in double quotes. .PP \fISpecial values\fR .IX Subsection "Special values" .PP There are no reserved or sentinel values for undefined values, null pointers, or the like. Convention is to use a single identifier surrounded by tildes to indicate such a value. For example, given a null pointer for the \f(CW\*(C`user.name\*(C'\fR value, a system might log: .PP .Vb 1 \& user.name=~null~ .Ve .PP If \f(CW\*(C`~null~\*(C'\fR was a valid username, there would be ambiguity here. The choice of exact sentinels is left to the implementing system. .PP .Vb 4 \& my $octets = Log::Fmt\->format_event_string([ \& key1 => $value1, \& key2 => $value2, \& ]); .Ve .PP Note especially that if any value to encode is a reference \fIto a reference\fR, then String::Flogger is used to encode the referenced value. This means you can embed, in your logfmt, a JSON dump of a structure by passing a reference to the structure, instead of passing the structure itself. .PP String values are assumed to be character strings, and will be UTF\-8 encoded as part of the formatting process. .PP .Vb 1 \& my $kv_pairs = Log::Fmt\->parse_event_string($octets); .Ve .PP Given the kind of (byte) string emitted by \f(CW\*(C`format_event_string\*(C'\fR, this method returns a reference to an array of key/value pairs. After being unquoted, value strings will be UTF\-8 decoded into character strings. .PP This isn\*(Aqt exactly a round trip. First off, the formatting can change illegal keys by replacing characters with question marks, or replacing empty strings with tildes. Secondly, the formatter will expand some values like arrayrefs and hashrefs into multiple keys, but the parser will not recombined those keys into structures. Also, there might be other asymmetric conversions. That said, the string escaping done by the formatter should correctly reverse. .PP If the input string is badly formed, hunks that don\*(Aqt appear to be value key/value pairs will be presented as values for the key \f(CW\*(C`junk\*(C'\fR. .PP .Vb 1 \& my $hashref = Log::Fmt\->parse_event_string_as_hash($line); .Ve .PP This parses the given line as logfmt, then puts the key/value pairs into a hash and returns a reference to it. .PP Because nothing prevents a single key from appearing more than once, you should use this with the understanding that data could be lost. No guarantee is made of which value will be preserved. .SH "POD ERRORS" .IX Header "POD ERRORS" Hey! \fBThe above document had some coding errors, which are explained below:\fR .IP "Around line 55:" 4 .IX Item "Around line 55:" Non\-ASCII character seen before =encoding in \*(Aquser.name="Jürgen"\*(Aq. Assuming UTF\-8 .IP "Around line 113:" 4 .IX Item "Around line 113:" Unknown directive: =method .IP "Around line 239:" 4 .IX Item "Around line 239:" Unknown directive: =method .IP "Around line 304:" 4 .IX Item "Around line 304:" Unknown directive: =method