Upload plain-text log files to UptimeEye

Not everything logs JSON. For services with a classic pattern layout and for one-off uploads, /v1/ingest/text takes the raw text: every line becomes an entry and the whole line stays the message. A leading timestamp is used as the event time, a level word (INFO, WARN, ERROR …) becomes the level field, and lines that do not start with a timestamp — stack traces — are folded into the entry they belong to.

Endpoint: https://logs.uptimeeye.com/v1/ingest/text

1.Upload a file

Fields come from the query string: every parameter without a leading underscore becomes a field on every entry.

shell
curl -sS -X POST "https://logs.uptimeeye.com/v1/ingest/text?service=orders&env=prod&_stream_fields=service,env" \
  -H "Authorization: Bearer ue_ingest_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -H "Content-Type: text/plain" \
  --data-binary @/var/log/orders/application.log
# → {"entries": 1834}

2.What a Spring Boot file turns into

application.log
2026-09-04 11:55:01,123 ERROR 1 --- [nio-8080-exec-3] c.e.orders.OrderController : Order 4711 failed
java.lang.IllegalStateException: payment declined
	at com.example.orders.OrderService.place(OrderService.java:88)
Caused by: com.example.PaymentException: card_declined
2026-09-04 11:55:02,000  INFO 1 --- [nio-8080-exec-3] c.e.orders.OrderController : retry scheduled
Note: Two entries: the first has level=error, _time=2026-09-04T11:55:01.123Z and a four-line message including the stack trace; the second is the INFO line.

3.Pipe a process or a journal

shell
# stdout of a process, one request per 5-second batch
java -jar orders.jar 2>&1 | while chunk=$(timeout 5 cat) || [ -n "$chunk" ]; do
  printf '%s\n' "$chunk" | curl -sS -X POST "https://logs.uptimeeye.com/v1/ingest/text?service=orders&env=prod" \
    -H "Authorization: Bearer ue_ingest_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -H "Content-Type: text/plain" --data-binary @-
done

# the last hour of a systemd unit
journalctl -u nginx --since -1h -o short-iso --no-pager | curl -sS -X POST \
  "https://logs.uptimeeye.com/v1/ingest/text?service=nginx&host=$(hostname)" \
  -H "Authorization: Bearer ue_ingest_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -H "Content-Type: text/plain" --data-binary @-

4.Options

  • _time_source=ingest — ignore timestamps in the lines and use the arrival time.
  • _multiline=off — never fold lines; every line is its own entry.
  • _stream_fields=service,env — which of your query fields become stream fields (fast filters).

Fields you get

These show up in the fields panel and can be used in every filter:

  • level when a level word is found
  • the fields from your query string
  • _time from the line, else arrival time

Tips

  • Recognised timestamps: 2026-09-04T11:42:08.877Z, 2026-09-04 11:42:08,877, 2026-09-04T11:42:08+02:00, [2026-09-04 11:42:08]. Without a zone the time is read as UTC — set your JVM or logger to log in UTC, or include the offset in the pattern (%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}).
  • Lines like nginx's 10.0.0.1 - - [04/Sep/2026:11:42:08 +0000] "GET /" 200 have no leading ISO timestamp, so they get the arrival time. Fine for uploads of live output; for history, prefer an agent with a parser.
  • For anything long-running use an agent (Vector, Fluent Bit, Alloy): it tails, batches, retries and remembers where it stopped.

FAQ

Is the endpoint limited in size?
16 MiB per request, uncompressed. Split larger files with split -l 20000 or compress with gzip and send Content-Encoding: gzip.
Are my logs billed as text or as the converted JSON?
As received — the bytes of the text you send.
Where do I get the ingest key?
In the app under API Keys → New API Key → type “Log ingest”. The key starts with ue_ingest_ and is shown once. Management keys (ue_live_) are refused by the ingest endpoint.
How do I check that logs arrive?
Open Logs in the app, pick the 15m range and search for service:=<your service>. New lines are searchable within about a second; Live tail shows them with a ~6 s delay.