— Developer Tools

Free logfmt Parser

Paste key=value log lines to read them as a table with a column per key, or convert them to JSON lines for other tools.

— Samples
Lines parsed 4Keys 13Skipped 0Valid
Live

What is a logfmt Parser?

logfmt is a plain-text log format of key=value pairs on one line, such as level=info msg="server started" port=8080. It’s easy for people to read and for machines to parse. This parser lays logfmt lines out as a table, or converts them to JSON, one object per line.

Parsing follows go-logfmt, the reference implementation also used by Grafana Loki’s logfmt stage: values are bare or double-quoted with backslash escapes, a key with no equals sign is a flag set to true, and key= is an empty string. Lines that break the rules, such as an unclosed quote, are skipped and listed by number.

Key Features

A Column for Every Key

Every key across all lines becomes a column, in the order it first appears, so lines with different fields still line up.

JSON Lines Output

Convert to NDJSON, one object per line, for jq, a log pipeline or a database import. Flags become true and values stay strings.

Level Counts

Values of level, lvl, severity or Heroku’s at key are counted, so you see at a glance how many errors and warnings a log holds.

Bad Lines Pointed Out

Lines with an unclosed quote or a stray quote are skipped and listed by line number instead of silently mangled.

Logs Stay Private

Parsing runs in your browser, so log lines with hosts, user IDs or errors are never uploaded.

Perfect for everyone

  • Developers reading service logs
  • SREs triaging incidents
  • Heroku users reading router logs
  • Anyone converting logfmt for another tool

How to Use the logfmt Parser

Paste the lines, then read the table or copy the JSON.

1

Paste the Log Lines

Copy from a terminal, heroku logs, kubectl logs or a log file. Blank lines are ignored, and each other line is one event.

2

Read the Table

Each line becomes a row and each key a column, with the source line number first. The summary lists keys and level counts.

3

Check Skipped Lines

Lines that aren’t valid logfmt are listed by number. Plain-text lines mixed into the log are the usual cause.

4

Convert to JSON Lines

Switch to JSON lines and copy or download the output for jq, a script or a log ingestion tool.

Worked Examples

logfmt Lines, Parsed

Each answer is the parser’s output for the lines on the left: the summary in Table mode, or the JSON in JSON lines mode. Work out the keys before you reveal it.

REF_001Table, two events

“level=info msg="server started" port=8080 level=info msg=request method=GET path=/api status=200”

REF_002JSON, quoted value

“level=info msg="server started" port=8080”

REF_003JSON, escaped quotes

“level=warn msg="slow \"orders\" query" ms=840”

REF_004JSON, bare flag

“level=error msg="db timeout" retry”

REF_005Table, level counts

“level=info msg=a level=error msg=b level=info msg=c level=warn msg=d”

REF_006Table, Heroku H12

“at=error code=H12 desc="Request timeout" method=POST path="/checkout" status=503 service=30000ms”

REF_007Table, skipped lines

“level=info msg=ok Starting server on :8080 level=info msg="open quote”

REF_008JSON, empty value

“user= region=eu-west-1”

REF_009JSON, colons and equals in values

“err=dial:tcp:10.0.0.5:5432 url=https://api.example.com/v1?x=1”

REF_010Not logfmt

“"just a quoted sentence”

Format Rules

How logfmt Is Written

logfmt has no formal standard, but go-logfmt’s behaviour is the de facto one. These are its rules.

01 / ONE

One Event per Line

Each line is a complete event, so logs stay greppable and line-based tools keep working.

“Can one logfmt event span two lines?”

02 / PAIRS

Pairs Separated by Spaces

A line is key=value pairs separated by one or more spaces. Order doesn’t matter, but keeping it consistent helps humans.

“What separates two pairs?”

03 / BARE

Bare Values Stop at a Space

Unquoted values run until the next space, so they may contain colons, slashes and equals signs.

“Does path=/a/b need quotes?”

04 / QUOTE

Quote Values With Spaces

A value containing spaces must be in double quotes, as in msg="server started".

“How do you log a message with spaces?”

05 / BACKSLASH

Backslash Escapes in Quotes

Inside quotes, a backslash escapes a quote or another backslash, and \n stands for a line break.

“How do you put a quote inside a quoted value?”

06 / KEYS

Keys Without Values Are Flags

A key with no equals sign, such as retry, means true. It’s a compact way to mark boolean conditions.

“What does a bare retry mean?”

07 / EMPTY

Empty Values Are Allowed

key= sets an empty string, which is different from leaving the key out.

“Is user= the same as no user key?”

08 / VALUES

Values Are Untyped

Everything is text. 200 and true are strings until a consumer decides otherwise, so the JSON output keeps them as strings.

“Is status=200 a number in logfmt?”

09 / KEYS

Keys Avoid Spaces and Quotes

A key may not contain a space, an equals sign or a quote. Dots and underscores are common for nesting, as in http.status.

“Is http.status a valid key?”

10 / DUPLICATE

Duplicate Keys

The format doesn’t forbid repeating a key on one line, but consumers usually keep only the last value. Avoid duplicates.

“Which value do most parsers keep for a repeated key?”

Heroku Codes

Heroku Router Error Codes in logfmt

Heroku’s router writes errors as logfmt lines with at=error and a code key. These are the ones you’ll see most.

01 / H10

H10, App Crashed

A web dyno crashed or failed to start, so the router has nothing to send requests to. Check the app’s own logs for the crash.

“What does code=H10 mean?”

02 / H12

H12, Request Timeout

The app took longer than 30 seconds to send its first byte, so the router returned 503. Move slow work to a background job.

“How long before an H12?”

03 / H13

H13, Connection Closed Without Response

The dyno accepted the connection but closed it without responding, often because a worker process was killed mid-request.

“What does code=H13 mean?”

04 / H14

H14, No Web Dynos Running

The app has no web dynos scaled up. Scale the web process to at least one.

“Which code means zero web dynos?”

05 / H15

H15, Idle Connection

A connection sat idle for 55 seconds with no data, so the router closed it. Long-polling clients should send keepalives.

“How long can a connection stay idle?”

06 / H18

H18, Server Request Interrupted

The app closed the socket while the router was still sending the request or reading the response.

“What does code=H18 mean?”

07 / H20

H20, App Boot Timeout

The web process didn’t bind to its port within 60 seconds of starting. Make sure it listens on the PORT environment variable.

“Which variable must the web process listen on?”

08 / H27

H27, Client Request Interrupted

The client hung up before the response finished, for example by closing the browser tab. It’s logged as info-level noise in most apps.

“Who interrupts the request in an H27?”

09 / R14

R14, Memory Quota Exceeded

A dyno used more memory than its plan allows and started swapping, which slows everything. Reduce memory use or upgrade the dyno.

“What does R14 mean?”

10 / TIMING

Timing Keys

connect is the time to reach the dyno and service the time it took to respond, both in milliseconds. A high service time points at the app.

“Which key shows how long the app took?”

Where logfmt Comes From

Many tools write or read logfmt, often without calling it that.

Heroku

Heroku’s router and platform logs are logfmt, with at, method, path, status and timing keys on every request.

Go Services

Go’s log/slog TextHandler writes key=value lines, and libraries such as logrus and go-kit log have logfmt formatters.

Grafana Loki

Loki’s LogQL has a logfmt parser stage that turns keys into labels you can filter on, such as level and status.

Prometheus and Grafana

Prometheus, Grafana and other Go projects in that ecosystem log in logfmt by default.

Python and Ruby

structlog for Python and many Ruby loggers offer key=value renderers that produce logfmt.

Shell Scripts

Writing echo "level=info msg=done" is the simplest structured logging there is, and it parses like any other logfmt.

logfmt Mistakes

These are the habits that make logfmt hard to parse.

Tip 01

Unquoted Messages With Spaces

msg=server started becomes msg=server plus a flag called started. Quote any value that can contain spaces.

Tip 02

Unescaped Quotes

A quote inside a quoted value ends it early. Escape it with a backslash, or use a logging library that does.

Tip 03

Multi-Line Stack Traces

Printing a stack trace after a logfmt line breaks the one-event-per-line rule. Put the trace in a quoted field instead.

Tip 04

Mixing Plain Text and logfmt

Startup banners and library output in plain text become noise. Route them through the same logger.

Tip 05

Inconsistent Key Names

status, status_code and http.status in one service make filtering painful. Agree on names across services.

Tip 06

Units Only in Your Head

dur=840 could be milliseconds or seconds. Put the unit in the key or the value, as in dur_ms=840 or dur=840ms.

Tip 07

Logging Secrets

Key=value logging makes it easy to log a whole object, including tokens. Allowlist fields rather than logging everything.

Tip 08

Huge Values

Request bodies dumped into a field make lines enormous. Log a size or hash, not the content.

When to Parse logfmt

Whenever key=value logs are easier to read lined up, or another tool needs them as JSON.

Triaging an Incident

Paste the lines around an error and scan the table for the status, duration or host that changed.

Reading Heroku Router Logs

See every request’s path, status, dyno and service time in columns, and spot H12 timeouts quickly.

Feeding jq or a Script

Convert to JSON lines, then filter with jq or load the events into a script or spreadsheet.

Checking a Logger’s Output

Make sure a new service’s logs parse cleanly before shipping them to Loki or another backend.

Counting Errors

The level counts show how many errors and warnings a chunk of log holds, without writing a query.

Writing a Loki Query

See which keys exist before writing a LogQL logfmt filter, so the label names are right.

Sharing Log Evidence

Download the table or JSON to attach to an incident report, with only the lines that matter.

Related developer tools

Frequently Asked Questions