NOTE: Updates are happening daily but these notes are updated once every two weeks.
2026-10-16
msg or message field is first, and the other fields follow as key=value. The app also finds levels in plain text, for example [WARN] or level=errorcurl command to send a test log. With no hosts, the Hosts page shows the commands to install the CL Agent. You can copy each commandOR and NOT with field filters, for example level:error OR level:warn and NOT level:debug. If a query uses OR between a word and a filter, Search shows an error that tells you why2026-10-05
oom-kill or 10.0.0.1, was a syntax error and the rule never fired. It is now searched as a phrase. field:value filters such as level:error also work in alert rules now. A rule that was failing will start running, so check any full-text rule you had given up on2026-10-04
2026-09-30
clagent present the same source token it already uses to ship logs when it reports host and process information. It defaults on for new installs and off when you upgrade an existing server, so a fleet of older agents keeps checking in until you’re ready to switch it on. clagent built 2026-09-30 or later sends the token automatically, and the settings page lists any active hosts still on an older agent so you can upgrade them first2026-09-29
10.0.0.1 as a syntax error, foo-bar as a column filter and /api/v1 as nothing at all, and the error was swallowed, so the page said No results found for logs that were right there. A bare term with punctuation is now searched as the phrase you typed; wp-adm* still works as a prefix search. A query that really is invalid, such as an unbalanced quote, now shows the error instead of an empty result. Full-text alert rules are unchanged and still need the quotes: "10.0.0.1""disk full", no longer loses the query when you edit it. The form showed the field empty, and saving the rule for any other change wiped the query, after which the rule never firedstate=fail now shows red, with a FAILED badge on the run. Before, it showed green, its page said “Last check was a long while ago” and gave its expected next run as December 1969. A job that has stopped checking in no longer reads “Last ran 1 minute ago”. The ping URL now answers 401 for an unknown API key, so curl -f can catch a typohttp:// monitors no longer show a red TLS expiry of 1970. A keyword monitor no longer sends “keyword not found” followed by “recovered” because of a single connection error. The URL field requires a full http:// or https:// URL; a bare IP address could never be checked/api/v1/log/{token} is rejected instead of storing a blank line. If the server can’t queue a batch sent to /api/v1/ingest_logs, it now answers 503 so your shipper retries; before, it answered 200 for logs it never stored2026-09-28
"Failed password" rule set to once a day sent a message every day for as long as you kept logs, whether or not anyone had failed a login since. The other direction was worse: a rule set to alert on no results could never fire once a single match existed, so a heartbeat rule stayed silent after the heartbeat stopped. SQL rules are unchanged. They already run exactly the query you write, so put the window in the queryoom-kill as a column filter and raises an error, and a SQL rule can raise malformed JSON on a plain-text line. The error surfaced only while reading rows, and it was ignored there. A rule set to alert on results never fired. A rule set to alert on no results fired every time. Both now skip the evaluation and write the error to the server log. Quote hyphenated terms: "oom-kill"2026-09-14
POST /api/v1/ingest_logs/{token} split the body with a scanner whose limit was 65,536 bytes. One line at or over that size ended the split, so that line and every line after it in the same request were thrown away — and the server still answered HTTP 200 with a count of the rows it did take. A four-line body with a 64 KiB line in second place stored one row. Nothing in the response or the logs said so. A single line is now stored whole up to 1 MB. Anything longer is truncated rather than dropped, with ...[truncated by centrallogging: line exceeded 1048576 bytes] on the end so you can find them: SELECT COUNT(*) FROM logs WHERE msg LIKE '%truncated by centrallogging%'. The response gained a lines_truncated count, so {"logs_ingested": 4, "lines_truncated": 1} tells you a line was shortened without you having to compare against what you sent. The gzip path behaves the same way, and a body that cannot be read to the end now reports an error in the response instead of only in the server’s own log. Who this was hitting: anyone posting a JSON line with a large payload, a base64 blob, or a stack trace joined into one line. clagent was not affected — it splits on journal entries, and journald caps a line at 48K2026-09-07
journalctl -o json, which replaces any field where the name, an = and the value together reach 4096 bytes with null unless -a is passed. So a message of about 4088 bytes or more arrived as "MESSAGE": null — the entry was stored, the priority and unit and hostname were stored, and the text was gone. Stack traces, tracebacks, verbose SQL errors and pretty-printed API payloads all clear 4 KB without trying, which made this worst for exactly the lines worth keeping. Nothing reported it: journalctl exits 0 and the server accepted the entry. The agent now passes -a. If you ship the journal yourself with a journalctl -o json | curl pipeline, add -a to it too. To find out whether it has been happening to you, run SELECT COUNT(*) FROM logs WHERE json_valid(msg) AND json_type(msg, '$.MESSAGE') = 'null' against the source2026-08-24
host:port, credentials (leave the username blank for a relay that needs none), a From address and one or more comma-separated To addresses. Port 465 connects with implicit TLS; other ports upgrade to STARTTLS when the server offers it. Like every channel it has a Test button, so you can confirm delivery before pointing alerts at it2026-08-21
2026-08-10
promhttp_metric_handler_requests_total, which reports one series per HTTP status code — are now stored as the sum of their series each scrape. Previously only one arbitrary series was kept, the rest failed with a UNIQUE constraint warning in the logs on every scrape, and because a scrape stopped at the first error other metrics from the same source could be dropped with them. Charts for an affected metric will show a one-time step up to the summed value2026-08-07
json_extract raises an error the first time it meets a line that is not JSON, and rows found before that point had already been returned — so a query over a source containing one plain-text line quietly returned a truncated result set and no error. Add WHERE json_valid(msg) to skip those linesFROM logs query produced an empty file with no errorstate=fail on schedule was flagged as “no longer checking in” shortly after its failure alert — it had not stopped checking in, it was checking in with failures. That second message is now suppressed while a failure is outstanding, and returns once the job succeeds and then goes quiet for realstate=fail now notifies you within a minute. Previously the failed run was recorded and shown in red on the job page, but nothing was sent — you found out when the successful check-in failed to arrive, which takes about 12 minutes for an hourly job and about 5 hours for a daily one. The notification carries the status_code and message from the ping. A job that fails every run does not message you every run: the first failure notifies, then it stays quiet until the job completes successfully or a day passesstatus_code, message and repeated metric=name:value parameters are stored with the ping — previously the documentation showed these but the server read only state and dropped the restPOST or HEAD are now recorded. The cron page has always said all three methods work, but only GET was routed — a POST or HEAD ping was silently rejected2026-07-06
2026-07-05
BACKUP_S3_ENDPOINT environment variable)appdb/ and logs/{source-token}/ prefixes, and automatic cleanup of old backups only touches those prefixes so other objects in a shared bucket are left alone2026-04-17
2026-04-16
2026-04-15
2026-04-11
? to see all shortcuts. Navigate results with j/k, expand with Enter, focus search with /, run queries with Ctrl+Enter, paginate with n/p, and open the time range picker with t.2026-04-10
2026-04-09
2025-12-21
2025-02-13
2025-01-09
2024-12-08
2024-12-06
2024-12-02
2024-12-01
2024-11-26
2024-11-23
2024-11-22
2024-11-20
2024-11-19
2024-11-18
2024-11-17
2024-11-16
2024-11-15
2024-11-14
2024-11-13
2024-11-03
2024-10-26
2024-10-24
2024-10-23
2024-10-19
2024-10-19
2024-10-05
2024-10-03
2024-10-02
2024-08-01
2024-07-25
2024-07-19
2024-07-13
2024-04-30
2024-04-28
2024-03-19
2024-03-16
2024-03-06
2024-03-01
2024-02-22
2024-01-29
2024-01-22
2023-11-21
2023-03-26
2023-03-19
2023-03-18
2023-03-16
2023-03-15
2023-03-14
2023-03-06
2023-03-05
2023-02-29
2023-02-28
2023-02-23
2023-01-27
2023-01-09
2023-01-08
2023-01-06
2023-01-03
2023-12-23
2023-12-18
2023-11-30
2023-11-28
2023-11-26
2023-11-20
💌 Get notified on new features and updates