Skip to content

Logmefmt

Eduard Mishkurov edited this page May 3, 2026 · 3 revisions

logmefmt

logmefmt converts logme records between text, JSON and XML formats. It is intended for offline log processing: converting existing text logs to structured output, renaming fields, and finalizing append-friendly structured streams into complete JSON or XML documents.


Command line help

logmefmt - convert logme records between text, JSON and XML formats
Copyright (c) EFM Software

Usage:
  logmefmt --input text|json|xml --output text|json|xml [options]

Options:
  --input FORMAT          Input format: text, json, xml
  --output FORMAT         Output format: text, json, xml
  --in FILE               Read from FILE instead of stdin
  --out FILE              Write to FILE instead of stdout
  --finalize              Complete JSON/XML output document
  --root NAME             XML root element for --finalize (default: log)
  --field OLD=NEW         Rename field on both input and output sides
  --input-field OLD=NEW   Rename field before conversion
  --output-field OLD=NEW  Rename field after conversion
  --help                  Show this help

Running logmefmt without arguments prints the same help and exits. It does not wait for input from stdin by default.


Text log parsing

When the input format is text, logmefmt parses known logme text prefixes and extracts structured fields where possible:

  • timestamp
  • level
  • process_id
  • thread_id
  • channel
  • subsystem
  • file
  • line
  • method
  • message

The parser is conservative. If a part is not present, the field is simply omitted. The remaining text becomes message, so the original log text is not dropped.


Examples

Convert a text log line to JSON

printf '2026-05-03 10:00:00:123 D [04D2:162E] {NET} #HTTP main.cpp(42): Connect(): connected\n' \
  | logmefmt --input text --output json

Output:

{"timestamp":"2026-05-03 10:00:00:123","level":"DEBUG","process_id":"04D2","thread_id":"162E","channel":"NET","subsystem":"HTTP","file":"main.cpp","line":"42","method":"Connect","message":"connected"}

What happens:

  • the timestamp is written as timestamp
  • D is converted to DEBUG
  • [04D2:162E] becomes process_id and thread_id
  • {NET} becomes channel
  • #HTTP becomes subsystem
  • main.cpp(42) becomes file and line
  • Connect(): becomes method
  • the rest of the line becomes message

Convert a text log line to XML

printf '2026-05-03 10:00:00:123 E [04D2:162E] {NET} #HTTP main.cpp(42): Connect(): failed\n' \
  | logmefmt --input text --output xml

Output:

<event><timestamp>2026-05-03 10:00:00:123</timestamp><level>ERROR</level><process_id>04D2</process_id><thread_id>162E</thread_id><channel>NET</channel><subsystem>HTTP</subsystem><file>main.cpp</file><line>42</line><method>Connect</method><message>failed</message></event>

This produces one <event> element for the input line. Without --finalize, XML output is a stream of events, not a complete XML document.

Preserve an unknown line as message

printf 'plain application output\n' \
  | logmefmt --input text --output xml

Output:

<event><message>plain application output</message></event>

The line does not match the known logme prefix pattern, so no artificial fields are created.

Finalize JSON stream

printf 'first\nsecond\n' \
  | logmefmt --input text --output json --finalize

Output:

[
  {"message":"first"},
  {"message":"second"}
]

Use this when the result must be a valid standalone JSON document. Without --finalize, the output is a JSON-lines style stream of separate objects.

Finalize XML stream with custom root

printf 'first\nsecond\n' \
  | logmefmt --input text --output xml --finalize --root events

Output:

<events>
  <event><message>first</message></event>
  <event><message>second</message></event>
</events>

--root changes the document root name used only when XML finalization is enabled.

Rename fields during conversion

printf '2026-05-03 10:00:00:123 W [04D2:162E] {NET} #HTTP retry\n' \
  | logmefmt --input text --output json --field message=msg --field level=severity

Output:

{"timestamp":"2026-05-03 10:00:00:123","severity":"WARN","process_id":"04D2","thread_id":"162E","channel":"NET","subsystem":"HTTP","msg":"retry"}

--field OLD=NEW renames a field on both the input and output sides. Use --input-field or --output-field when renaming is needed only before or only after conversion.

Clone this wiki locally