Skip to main content

Squillify development is paused indefinitely. Read why, and discover what this experiment achieved. Read the story

MicroSkills Reference

Logfmt Log Parser

observability.parse_logfmt

ProductionBounded custom (Class B)Deterministicstrictfastv1.0.0
File inputNo network

Overview

You send logfmt text and we return one record per line plus an error report that names the line and column of every pair we could not read. The grammar is published in full: a bare value may contain an equals sign, a bare key comes back as null where an empty assignment comes back as an empty string, and an unterminated quote ends that line rather than turning the rest of it into fields nobody logged. Malformed pairs never fail the call, so one stray quote in fifty thousand lines still gives you the other lines. We hold nothing, forward nothing and read no clock.

Nothing else in the catalog turns logfmt into structured fields: the log redactor labels the format but still returns text, so you had to write the grammar yourself and get the equals-sign and quoting rules wrong.

Reliability

Fully deterministic: the same body and options always give you the same records, independent of locale, default time zone and default charset. Malformed pairs are reported rather than fatal, so plan on reading errors on a successful call. Failures, none worth retrying unchanged: OBS_LOGFMT_INPUT_MISSING means neither logs nor fileRef arrived, so send one of them. OBS_LOGFMT_INPUT_INVALID means logs or fileRef was not a string, or the body was empty, so check the payload shape. OBS_LOGFMT_INPUT_TOO_LARGE means the inline body went past 2097152 bytes, so upload it and pass a file reference instead. OBS_LOGFMT_FILE_REF_NOT_ACCESSIBLE means the reference is not readable with these credentials, so upload the object again and use the new reference. OBS_LOGFMT_FILE_TOO_LARGE means the referenced object went past 10000000 bytes, so split it and call once per part. OBS_LOGFMT_LINE_LIMIT_EXCEEDED means the body carries more lines than your maxLines allows, so raise it up to 50000 or split the body. OBS_LOGFMT_FIELD_LIMIT_EXCEEDED means the parse produced more than 200000 fields in total, more than a response can carry, so split the body or turn includeRecords off. OBS_LOGFMT_LIMITS_INVALID means one of the limits fell outside its published range, so bring it back inside and send it again. OBS_LOGFMT_OPTION_UNSUPPORTED means a property or an option value is not one we accept, so drop it or pick a listed value. OBS_LOGFMT_WORK_REFUSED means the projected work went past 16000000 units, and the answer carries both the projection and the budget so you can size a request that fits. OBS_LOGFMT_OUTPUT_TOO_LARGE means the records would not fit the inline response ceiling, so set includeRecords false or send fewer lines.

Context footprint

Returns one record per line, so a large body comes back large; set includeRecords false when you only want the counts and the error report. A successful call costs 3 execution credits.

When to use it

When you hold logfmt text and want records you can query, plus a precise report of what your producer is emitting badly.

When your lines are JSON objects, when you want them grouped rather than parsed, or when you need the text redacted.

Scope

Note
Read logfmt text into key/value records and report every pair that did not parse, with its line and column.

Non-goals

  • Does not store, buffer, index or forward anything between calls
  • Does not scrape, poll or receive logs over a network
  • Does not redact or mask anything — send the text to security.redact_secrets first
  • Does not interpret what a field means or what an error was caused by
  • Does not accept a caller-supplied regular expression on any field

Properties

IdempotentRetry safeStreaming supportedFile input supportedRequires external service

Capabilities

parsing

Cost & billing

Flat rate per invocation

MetercallsBillable onsuccessCost per call3 credits

File handling

Accepts file_refProduces file_refMax input2 MBMax file size9.5 MB

File limits

Constraints this skill applies to your input and generated files. The “Limited by” column shows the static source of each cap; none of these can be raised by upgrading your plan.

LimitValueLimited by
Maximum size per input file9.5 MiBSkill and platform maximum
Maximum number of input files1Skill maximum

How we handle your data

Sensitive output possible
What this means

This skill may receive sensitive content and may return submitted, transformed, extracted, or reformatted content.

Squillify guarantees
  • Runs inside Squillify
  • This skill runs inside Squillify.
  • Payloads are not sent to an external service by this skill.
  • Squillify does not permanently store submitted payloads.
  • Telemetry records metadata only, not submitted content.
  • Submitted payloads are not used for training.
  • Submitted payloads are not reviewed by humans.
  • This skill does not target sensitive data.
  • The response may contain submitted or transformed content.
Your responsibility

Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.

Read the Microskill Data Handling Policy

Input schema

FieldTypeRequiredDescription
logsstringNoRequired unless fileRef is provided. Logfmt text of 1 to 2097152 UTF-8 bytes.
fileRefstringNoOptional Squillify file reference holding up to 10000000 bytes of logfmt text; omit it to parse the inline logs field.
limitsobjectNoClosed caps you can tighten; omit it for maxLines 50000, maxLineLength 8192, maxFieldsPerLine 64, maxValueLength 1024 and maxErrors 500.
includeRecordsbooleanNoWhether parsed records are echoed; omit it for true.
onDuplicateKeystringNoWhich occurrence of a repeated key survives; omit it for LAST_WINS.

Output schema

FieldTypeRequiredDescription
recordsarrayYesOne {line, fields} object per parsed line; empty when includeRecords is false.
errorsarrayYesUp to maxErrors malformed pairs, each a closed {line, column, code} object with optional key.
summaryobjectYesClosed run counters: lineCount, recordCount, blankLineCount, fieldCount, errorCount, errorsTruncated, truncated and sourceKind.

API contract

POST /v1/execute
curl
curl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"observability.parse_logfmt","input":{"logs":"level=info msg=\"request served\" duration_ms=42\n"}}'
Integrations
TypeScript SDK
import { Squillify } from "@squillify/sdk";

const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });

const { output } = await sq.execute("observability.parse_logfmt", {"logs":"level=info msg=\"request served\" url=https://api.example.com/p?a=b&c=d retry\nlevel=warn msg=\"slow upstream\" duration_ms=812\n"});

Errors

CodeHTTPRetryableDescription
VALIDATION_ERROR400NoThe request payload failed schema validation.
UNAUTHORIZED401NoMissing or invalid API key.
SKILL_NOT_ACCESSIBLE403NoThe API key is not granted access to this skill.
SKILL_NOT_AVAILABLE_FOR_PLAN403NoThis skill is not included in your current plan.
PLAN_ELIGIBILITY_UNAVAILABLE503YesPlan eligibility could not be decided. Retry after backoff.
SKILL_NOT_FOUND404NoThe requested skill or version does not exist.
TENANT_RATE_LIMITED429YesRequest rate limit exceeded. Retry after backoff.
QUOTA_EXCEEDED429YesPlan quota exhausted. Retryable once the quota period resets.
EXECUTION_TIMEOUT504YesExecution exceeded the allowed time budget.
OBS_LOGFMT_INPUT_MISSING400NoThe request payload failed this skill's input validation.
OBS_LOGFMT_INPUT_INVALID400NoThe request payload failed this skill's input validation.
OBS_LOGFMT_INPUT_TOO_LARGE429NoA size, quota, rate, or time limit was exceeded.
OBS_LOGFMT_FILE_REF_NOT_ACCESSIBLE412NoThe input is valid but cannot be processed as-is.
OBS_LOGFMT_FILE_TOO_LARGE429NoA size, quota, rate, or time limit was exceeded.
OBS_LOGFMT_LINE_LIMIT_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.
OBS_LOGFMT_FIELD_LIMIT_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.
OBS_LOGFMT_LIMITS_INVALID400NoThe request payload failed this skill's input validation.
OBS_LOGFMT_OPTION_UNSUPPORTED400NoThe skill does not support the requested variant.
OBS_LOGFMT_WORK_REFUSED429NoA size, quota, rate, or time limit was exceeded.
OBS_LOGFMT_OUTPUT_TOO_LARGE429NoA size, quota, rate, or time limit was exceeded.

Other limits

LimitValue
Recommended inline bytes32 KiB

Limitations

  • Does not store, buffer, index or forward anything between calls
  • Does not scrape, poll or receive logs over a network
  • Does not redact or mask anything — send the text to security.redact_secrets first
  • Does not interpret what a field means or what an error was caused by
  • Does not accept a caller-supplied regular expression on any field
  • Reading newline-delimited JSON logs, which observability.parse_json_logs answers
  • Removing secrets from a log body before you share it

How to call

POST /v1/execute (requires authentication)

Request bodyjson
{
  "skillKey": "observability.parse_logfmt",
  "input": {
    "logs": "level=info msg=\"request served\" url=https://api.example.com/p?a=b&c=d retry\nlevel=warn msg=\"slow upstream\" duration_ms=812\n"
  }
}

Examples

Two request lines with a bare key and a URL value

Inputjson
{
  "logs": "level=info msg=\"request served\" url=https://api.example.com/p?a=b&c=d retry\nlevel=warn msg=\"slow upstream\" duration_ms=812\n"
}
Expected outputjson
{
  "records": [
    {
      "line": 1,
      "fields": {
        "level": "info",
        "msg": "request served",
        "url": "https://api.example.com/p?a=b&c=d",
        "retry": null
      }
    },
    {
      "line": 2,
      "fields": {
        "level": "warn",
        "msg": "slow upstream",
        "duration_ms": "812"
      }
    }
  ],
  "errors": [],
  "summary": {
    "lineCount": 2,
    "recordCount": 2,
    "blankLineCount": 0,
    "fieldCount": 7,
    "errorCount": 0,
    "errorsTruncated": false,
    "truncated": false,
    "sourceKind": "INLINE"
  }
}
Tip
The bare value keeps its whole URL because only the first equals sign after a key separates, and the bare key retry comes back null.

A stray quote reported without failing the call

Inputjson
{
  "includeRecords": false,
  "logs": "level=error msg=\"unterminated\n"
}
Expected outputjson
{
  "records": [],
  "errors": [
    {
      "line": 1,
      "code": "UNTERMINATED_QUOTE",
      "column": 17,
      "key": "msg"
    }
  ],
  "summary": {
    "lineCount": 1,
    "recordCount": 1,
    "blankLineCount": 0,
    "fieldCount": 1,
    "errorCount": 1,
    "errorsTruncated": false,
    "truncated": false,
    "sourceKind": "INLINE"
  }
}
Tip
The line's parse ends at the quote, so the remainder is never reinterpreted as further pairs.
  • Turn a captured logfmt stream into records you can filter and join
  • Find the exact line and column where a producer emits malformed pairs

Avoid for

  • Reading newline-delimited JSON logs, which observability.parse_json_logs answers
  • Removing secrets from a log body before you share it

Composable with

Safety & privacy

  • Runs without calling any external service.
  • Your payloads are never stored permanently.
  • Telemetry captures metadata only — never your payload contents.
  • We never train models on your payloads.
  • No human reviews your payloads.

Tags

textlogsparsingobservability