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? Get in touch with us via our Contact Us or join our Slack channel.

What did you think of this content?