Custom Logs

Ingest your application or infrastructure logs into Middleware and analyze them in the Logs module alongside built-in sources. This guide shows how to post logs with OTLP/HTTP (JSON) using cURL, explains each field, and maps required attributes.

Prerequisites

  • Your Middleware credentials
  • Outbound network access from the sender to your workspace URL.

Post Your Custom Data

You can send custom logs to the Middleware backend using the API below.

HTTP endpoint:

1POST https://<YOUR_WORKSPACE>.middleware.io:443/v1/logs

Authenticate Your Request

Pass the Middleware API key in the Authorization header as shown here:

1API_KEY="<YOUR_API_KEY>"
2MW_ENDPOINT="https://<YOUR_WORKSPACE>.middleware.io:443"
3
4curl -X POST "$MW_ENDPOINT/v1/logs" \
5  -H "Accept: application/json" \
6  -H "Content-Type: application/json" \
7  -H "Authorization: $API_KEY" \
8  -d @- << 'EOF'
9{
10  "resource_logs": [
11    {
12      "resource": {
13        "attributes": [
14          { "key": "mw.resource_type", "value": { "string_value": "custom" } },
15          { "key": "service.name",   "value": { "string_value": "nginx-123" } },
16          { "key": "mw.account_key", "value": { "string_value": "<YOUR_API_KEY>" } }
17        ]
18      },
19      "scope_logs": [
20        {
21          "log_records": [
22            {
23              "severity_text": "WARN",
24              "severity_number": 11,
25              "body": { "string_value": "upstream server is not accepting request" },
26              "attributes": [
27                { "key": "server", "value": { "string_value": "nginx" } }
28              ],
29              "time_unix_nano": 1758484251000000000
30            }
31          ]
32        }
33      ]
34    }
35  ]
36}
37EOF

Tip: Use environment variables or a secret manager for the key and avoid hard-coding.

Here:

  • Authorization header: Authenticates the HTTP request.
  • resource.attributes.mw.resource_type=custom: Labels the source as Custom so it is easy to find in the Logs UI.
  • resource.attributes.service.name: Lets you filter by service (optional but useful).
  • resource.attributes.mw.account_key: Account scoping as indicated by the schema.
  • log_records[].severity_text / severity_number: Sets human label and numeric level.
  • log_records[].body: The actual log message (string).
  • log_records[].attributes: Any extra dimensions you want to query on (e.g., server, environment).
  • log_records[].time_unix_nano: Nanoseconds since Unix epoch (controls event time in the UI).

You can send multiple logs at once by adding more items to log_records (and/or more resource blocks to resource_logs) in the same request.

Understanding Resource Attributes

(JSON path: resource_logs[] → resource → attributes[])

KeyComplianceDescription
mw.account_keyrequiredUsed to authenticate your data with your Middleware account.
mw.resource_typerequiredLabels the log source as "custom".
service.nameoptionalHelpful for filtering in the Logs module (e.g., service.name: nginx).

Understanding Log Records

(JSON path: resource_logs[] → scope_logs[] → log_records[])

KeyComplianceDescription
severity_textoptionalOne of: FATAL, ERROR, WARN, INFO, DEBUG, TRACE.
severity_numberoptionalMapping: 1–4=TRACE, 5–8=DEBUG, 9–12=INFO, 13–16=WARN, 17–20=ERROR, 21–24=FATAL.
bodyrequiredThe log body you want to ingest (string).
time_unix_nanorequiredEvent timestamp in nanoseconds since Unix epoch (controls placement on the timeline).

Add custom attributes (e.g., environment, host.id, region) to supercharge search, filters, and saved views.

Explore Logs & Build Queries

  1. Open Logs in Middleware.
  2. Use the search bar and filters to narrow by service.name, mw.resource_type, severity, attributes, and time.
  3. Save frequent queries as Saved Views for quick reuse by your team.

Set up Alerts

  1. Create a new Log Alert.
  2. Define a query (e.g., mw.resource_type:custom AND service.name:nginx-123 AND severity>=WARN).
  3. Choose the evaluation window and notification channels.
  4. Save and monitor. Incidents trigger when the condition matches within the window.

Troubleshooting & Best Practices

  • 401/403 / “No data”: Verify the Authorization header, workspace URL, and (if used) mw.account_key.
  • Wrong time on events: Ensure time_unix_nano is correct and the sender’s clock is synced (NTP).
  • Can’t find logs by service: Include service.name consistently; attribute names are case-sensitive.
  • Sensitive data: Avoid sending secrets in body or attributes; use redaction in your log pipeline where possible.
  • Throughput: Batch multiple log_records in one request to reduce overhead.

OTLP/HTTP JSON field reference (at a glance)

ConceptWhere to put itExample
Dataset tagresource.attributes[]mw.resource_type=custom
Account keyresource.attributes[]mw.account_key=<YOUR_API_KEY>
Serviceresource.attributes[]service.name=nginx-123
Messagelog_records[].body.string_value"upstream server is not accepting request"
Severitylog_records[].severity_text/numberWARN / 11
Extra dimslog_records[].attributes[]server=nginx, environment=production
Timestamplog_records[].time_unix_nano1758484251000000000

Need assistance or want to learn more about Middleware? Contact our support team at [email protected] or join our Slack channel.