Release Notes

NOTE: Updates are happening daily but these notes are updated once every two weeks.

2026-10-16

  • When a rule or monitor sends the same alert many times, the Alerts page shows one row for these alerts. The row shows the count, the first and last time, and a 7-day chart. Select the row to see each alert. A rule alert has a View matching logs link
  • An alert with no notification channel shows No channel, not Queued. The Alerts page shows a link to add a channel
  • All list pages have the same header: a title, a short description and the main action. The side menu shows Log Sources and Metric Sources under Configure. You can close the trial banner for 7 days
  • The host page shows the newest processes, the alerts from the last 7 days and a Search logs for this host button. Cron job and website monitor pages also show their alerts
  • The alert rule form has three parts: When, If and Then. Use Test rule to test a rule before you save it. You cannot save a rule that has no log source, query or trigger
  • Search results show the log message first. For JSON logs, the 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=error
  • The Tail page shows log lines in the same format as search results. Select a line to see the full log
  • A source with no logs shows a curl command to send a test log. With no hosts, the Hosts page shows the commands to install the CL Agent. You can copy each command
  • Search accepts OR 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 why
  • With Everything selected, the chart starts at the oldest log
  • On the Alerts page, the recovery alert of a cron job or website monitor is in the same row as the problem. When the monitor recovers, the row shows Resolved and moves below the open alerts. The page shows the number of open and resolved alerts
  • The notification channel form has a new layout. Select a service, then fill in only the fields for that service. The edit page has a Send test notification button. To keep the saved SMTP password, leave the field empty

2026-10-05

  • Full-text alert rules now read their query exactly as the Search page does. Before, the rule’s text went to the search engine unparsed, so a term with punctuation in it, such as 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 on

2026-10-04

  • Full-text alert rules have a Look Back setting. The 5 minute window added on 2026-09-28 was right for a rule that alerts on new lines and wrong for a heartbeat rule watching a job that runs once a day: the line was outside the window on every evaluation but one, so the rule fired every day while the job was fine. Pick Last 25 hours for a daily job or Last 8 days for a weekly one. Existing rules keep the 5 minute window until you change them. SQL rules are unchanged and carry their own window in the query

2026-09-30

  • Host and process check-ins can now require a token. A new setting, Require host & process auth (on the Settings page), makes 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 first
  • The New version available badge now appears only once your server is at least 14 days behind the latest release. Before, it lit up for every release, which with daily updates meant it was almost always on

2026-09-29

  • Search now finds IP addresses, paths and hyphenated words. Full-text search read 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"
  • Searching several sources at once no longer skips results on page 2 and later. Each source was paged separately and then merged, so whenever one source’s logs were all newer than another’s, a whole page of the older source’s lines never appeared on any page
  • An alert rule with a quoted phrase in its FTS query, such as "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 fired
  • Send Test Notification now tells you when Slack or Telegram rejected the message. A revoked Slack webhook or a wrong Telegram chat ID answered with an error that was ignored, so the test said it worked and real alerts were marked sent without arriving. A notification service that stops answering can no longer hold up every alert behind it, and an alert whose rule was deleted, or that has failed to send for 24 hours, is no longer retried every minute
  • Turning off an alert rule that is firing now clears its Firing badge. Before, it stayed on permanently
  • A cron job that reports state=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 typo
  • Editing a website monitor while a check is running no longer undoes your edit, and deleting one mid-check no longer brings it back. A new monitor shows Waiting for first check instead of “Up”, and plain http:// 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
  • On a new install, finishing setup now switches the server to HTTPS as the setup page says. Before, it stayed on plain HTTP until the service was restarted
  • Posting an empty body to /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 stored

2026-09-28

  • A full-text alert rule now looks only at lines received in the last 5 minutes. Before, it searched everything the source had kept. One matching line was enough to keep the rule firing on every evaluation until retention deleted that line. A "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 query
  • An alert rule whose query fails partway through no longer counts as an empty result. Full-text search reads oom-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

  • A long log line no longer discards the rest of the batch it arrived in. 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 48K

2026-09-07

  • The agent no longer loses long log lines. It reads the journal with 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 source

2026-08-24

  • Email is now a notification channel type alongside Slack, Telegram and Pushover. It works with any SMTP server — a provider such as Fastmail or Amazon SES, your company mail server, or a local relay. Set the server as 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 it

2026-08-21

  • A website monitor now alerts only after two failed checks in a row. It sends a recovery message only after it sent an error message. Before, one slow response was enough to send an error alert. The next check passed and sent a recovery alert. If you saw error and recovery pairs about a minute apart, this was the cause. The site was not down
  • You can now set the request timeout for each website monitor on its edit page. Choose 5, 10, 30 or 60 seconds. The default is 10 seconds. Before, every check used a fixed 5 seconds. That is too short for some slower services
  • A failed check now counts as a check. Before, a monitor set to check every 10 minutes was checked again one minute after a failure. This is why a recovery alert always arrived within a minute. It also means a site that stayed down was checked every minute until it came back

2026-08-10

  • Metrics with more than one label set — such as 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 value
  • A website monitor now alerts every time the site goes down, not only the first time. Error, recovery and keyword alerts are deduplicated by tag, and the window for a tag with no configured throttle is over a year — only the TLS expiry alert had one. So the first outage of a monitor notified you and every outage after it was silent, while the check history and the monitor page showed the failure correctly. Those alerts now use a 10-minute window, which still collapses two checks that land together into one message
  • Max Frequency is now a field on the alert rule form. Pick 5 minutes, 15 minutes, 1 hour, 6 hours or once a day. Every rule was previously fixed at once a day with no way to change it, so a recurring problem — a failing payment webhook, a root login — reported itself once and then went quiet. Existing rules keep their once-a-day setting until you change them. Nothing shorter than 5 minutes is offered because rules are only evaluated every 5 minutes
  • You can now choose which notification channel receives alerts. Tick Send alerts to this channel on the one you want; only one channel holds it at a time. Alerts previously always went to the first active channel by creation order, which was a trap rather than a limitation: each channel’s Test button sends to the channel you clicked, so adding Telegram alongside an existing Slack channel, testing it, and seeing it arrive told you nothing about where real alerts would go. With no channel marked the old behaviour still applies, and the Alerts page now labels the channel that receives them
  • The Is Active toggle on a notification channel now saves. Switching a channel off had no effect — the form never applied the value — so the documented way to move alerts to a different channel did not work

2026-08-07

  • A SQL search that fails partway through now says so instead of showing a short answer as a complete one. 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 lines
  • Fixes CSV export, which ran your query against the application database rather than the log source you were searching. Every export of a FROM logs query produced an empty file with no error
  • The Retention Days setting on a log source is now what the nightly cleanup actually uses. The setting saved correctly and was shown correctly, but the sweep deleted anything older than 15 days regardless — so a source set to keep 90 days kept 15, and a source set to keep 3 kept 15. Note that after this update a source set below 15 days will delete down to its setting on the next nightly run. A source set to 0 or a negative number is read as unset and keeps the 15-day default rather than deleting everything
  • A broken cron job now sends one message instead of two. Job health is worked out from successful runs, so a job pinging state=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 real
  • A cron job that pings state=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 passes
  • Cron pings can now record details with a run. status_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 rest
  • The cron job page now charts each numeric metric across the last 100 runs, one chart per metric name, so a job that is getting slower is visible before it starts timing out. The message and exit status are shown beside each recent run, and a non-zero exit status is flagged in red. Jobs that send no metadata see the page exactly as before
  • Cron pings sent with POST 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 rejected
  • Documents Pushover as a notification channel. It has worked in the app for a while but the alerting documentation only listed Slack and Telegram

2026-07-06

  • Scrollbars are now styled to match the app theme everywhere, in both light and dark mode — previously only a few containers had themed scrollbars and the rest (including the main page scrollbar) used the browser default
  • Metric types (gauge vs counter) are now stored in the metrics database instead of only in memory, so counter metrics render as per-second rates immediately after a server restart instead of briefly showing raw cumulative totals until the next scrape
  • The live tail page now shows a “Reconnecting…” indicator and automatically resumes tailing when a request fails (e.g. during a server restart) — previously the tail silently stopped updating while still showing “Live”
  • Metric charts now show a “stale” badge when a background refresh fails, instead of silently showing old data; the badge clears on the next successful refresh
  • Refreshes the metrics page UI: metric names are now grouped by prefix into collapsible sections with a filter box instead of one long list, clicking a metric toggles its chart on and off (plotted metrics are highlighted in the list), charts render as cards in a responsive grid with a link to the metric’s detail page, and quick range buttons (1h/8h/24h/7d) reload every open chart at once
  • Refreshes the metric detail page: adds a time range picker with quick range buttons (the page previously always showed the last 8 hours), a gauge/counter badge, and summary tiles for the latest, min, max, and average value over the selected range
  • The live tail page now shows the keyboard shortcut cheat sheet (press ? or the hint button next to the Live indicator) listing the shortcuts that work while tailing (j/k row navigation, Esc)
  • Removing a filter pill on the search page no longer mangles the query when a quoted phrase contains the same text as the filter — the exact filter token is removed instead of the first matching substring
  • The search time range button now shows a compact label (“30m”, “2d”, “All”) on phones instead of just the dropdown icon
  • Saved queries now capture the full search state: every selected source and the time range are stored along with the query and extracted fields, and are restored when the saved query is loaded (previously only the first source was kept and the time range was lost). The saved query edit page exposes the new source list and time range fields

2026-07-05

  • Moves saved queries in the sidebar under the Search nav item as a collapsible chevron section (expanded by default on the search page), with a Manage Queries link at the bottom of the list, instead of a separate section below the main navigation
  • Adds configuration export and import for moving Central Logging to a new server. Settings → Backup & Migration downloads a single JSON file with all configuration (log sources and their tokens, metric sources, alert rules, notification channels, website monitors, saved queries, transformers, API keys, users and settings). Import it on a fresh install and agents keep ingesting under their original source tokens — no reconfiguration needed. Log data is not included in the export
  • Adds S3 backup settings to the web UI — endpoint, region, bucket, and credentials can now be set on the Settings page instead of (or on top of) environment variables. Settings saved in the UI take precedence
  • Adds support for self-hosted S3-compatible storage (Garage, MinIO, …) for backups via a new endpoint option (also available as the BACKUP_S3_ENDPOINT environment variable)
  • Fixes nightly backups: they now back up the actual application database and include every per-source log database (previously only a stale database path was backed up). Backups are uploaded under 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 alone
  • Makes the cron detail page readable on phones — recent runs are now shown as cards with time, user agent, and IP stacked vertically instead of a cramped 4-column table (which also gains headers and cell padding on larger screens), the frequency and next-run tiles stack on small screens, the ping URL scrolls horizontally instead of overflowing, and long job names wrap in the header
  • Makes the hosts page readable on phones — hosts are now shown as cards with the key details stacked vertically instead of a wide 10-column table, with a sort dropdown replacing the sortable column headers. The full table is still used on larger screens
  • Fixes an extra “phantom scroll” on phones where the last table row (and the top nav after scrolling up) was hidden behind the browser toolbar until you scrolled a second time — the layout now sizes to the visible viewport as the browser chrome shows and hides
  • Improves the mobile experience: the menu is now a proper slide-in drawer that closes when you tap outside it or navigate, and includes Docs and Sign Out. Dark mode and settings are now reachable from the top bar on phones
  • Makes the search time range picker usable on phones — relative presets (Last 30 minutes, Last 24 hours, etc.) are now shown on small screens, and the search button is always visible
  • Wide tables (hosts, processes, SQL search results, notification channels) now scroll horizontally on small screens instead of stretching the page
  • Makes the settings page readable on phones — each setting now stacks its name, input, and description vertically on small screens instead of cramming them into three table columns
  • Adds a real login page with session-based authentication, replacing the browser’s Basic Auth popup for the web UI. Includes a Sign Out button in the nav, and the initial password setup now logs you in automatically. Basic Auth still works for curl/scripts and the API
  • Fixes the failed-login lockout so it applies per IP address instead of per connection

2026-04-17

  • Refreshes the home page: shows a welcome/onboarding view with tabbed code samples (curl, Python, Node.js, Go, file upload) and copy-to-clipboard buttons when you haven’t created any sources yet, otherwise shows a dashboard with 24h log volume tiles, top sources by volume, recent alerts, and quick actions

2026-04-16

  • Refreshes the sources list UI: health indicator dot (fresh/stale/silent), last-log-received timestamp, relative usage bar, name filter box, a friendly empty state, and inline tail/edit/delete actions
  • Refreshes the source edit page UI: grouped sections (settings, transform script, stats, send logs), tabbed ingest examples, stats cards, and a dedicated danger zone for deletion
  • Fixes Transform script editor colors in dark mode
  • Fixes log count and used bytes on the sources list not refreshing when new logs arrive (stats cache now invalidates on create/delete and expires after 30 seconds instead of 15 minutes)
  • Fixes retention days not saving when editing an existing log source

2026-04-15

  • Adds Pushover as a notification channel option

2026-04-11

  • Adds relative timestamps on search results and cron monitoring (e.g. “3m ago”, “2h ago”) — updates live every 30 seconds
  • Adds click-to-copy on field values in expanded log entries and a “Copy JSON” button in the detail header
  • Adds keyboard shortcuts for search — press ? 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

  • Adds multi-source search (search across all log sources at once)
  • Adds search tabs for keeping multiple searches open simultaneously
  • Adds shareable search URLs (search state synced to URL)
  • Adds “search around this time” — click the magnifying glass icon next to any timestamp to open a new tab searching around that moment with a configurable time window
  • Adds sorting to host process table
  • Adds notifications for cron job recovery
  • Fixes website monitor checks

2026-04-09

  • Adds dark mode
  • Adds field filtering in search (Splunk-like field:value syntax)
  • Adds ability to toggle alerts active/inactive from alerts list page
  • Adds alert metadata (last fired time, alert count) to alerts page
  • Adds create alert button from search page, pre-fills query and source
  • Adds FTS query support for alert rules
  • Adds recent successful logins to settings page
  • Adds rate limiting on authentication
  • Improves website monitor UI
  • Fixes web monitor check intervals running longer than configured
  • Web monitors can now check every 1 minute
  • Shows check frequency on monitor detail page
  • Cleans up response time display (e.g. 24ms, 2s)

2025-12-21

  • Added sorting to /hosts page

2025-02-13

  • Improves performance of website monitors page

2025-01-09

  • Adds pretty print SQL button to search page

2024-12-08

  • JSON extract fields now trim the msg field before extracting in FTS

2024-12-06

  • Order FTS results by timestamp desc by default

2024-12-02

  • Adds website URL to TLS expiration alerts

2024-12-01

  • Adds ability to throttle alerts
  • Throttles TLS expiration alerts to 24 hours

2024-11-26

  • Improves SQL syntax highlighting colors

2024-11-23

  • Fixes bug in pagination where extract fields wouldn’t persist

2024-11-22

  • Adds ability to extract fields from the msg JSON in FTS

2024-11-20

  • Adds pagination to full-text search results

2024-11-19

  • Adds TLS expiration to website monitors list page

2024-11-18

  • Improve cron monitoring UI

2024-11-17

  • Improves cron monitoring UI on mobile

2024-11-16

  • Improves website monitor UI for mobile
  • Adds favicons to website monitors

2024-11-15

  • Adds error rate and total log count to website monitor show page

2024-11-14

  • Adds SQL syntax highlighting to saved queries and search
  • Various mobile menu/UI fixes
  • Adds left nav to mobile menu

2024-11-13

  • Adds website monitor concurrency
  • Improves notification message for website monitor alerts

2024-11-03

  • Fix JS timestamp formatting bug

2024-10-26

  • Reduce logging verbosity on website monitors
  • UI styling fixes

2024-10-24

  • Fix bug where saved query form didn’t save source ID

2024-10-23

  • Adds custom user agent to website monitors

2024-10-19

  • Fix host down alert

2024-10-19

  • UI styling

2024-10-05

  • Adds TLS error monitoring for website monitors

2024-10-03

  • UI styling

2024-10-02

  • Adds website monitor keyword alerts

2024-08-01

  • Adds log tailing
  • FTS returns latest when query is empty

2024-07-25

  • Adds host process monitoring

2024-07-19

  • UI styling

2024-07-13

  • CLAgent OpenBSD host info is sent more often

2024-04-30

  • Sign macOS binaries

2024-04-28

  • Adds is_active to host so we can disable monitoring for hosts that are terminated

2024-03-19

  • Hosts alert when no longer checking in
  • Hosts UI cleanup, OS icon, sorting

2024-03-16

  • Adds OS icons to hosts page

2024-03-06

  • adds IP to website monitor logs, adapts log retetion to sharded log dbs
  • Adds success message to cla install
  • fix UI and broken links from alert rule show page
  • fixes source selection from alert rule link
  • mobile fixes

2024-03-01

  • Adds highlighted search terms

2024-02-22

  • toggle SQL/FTS
  • show row count in log source page

2024-01-29

  • Adds some styling to setup flow

2024-01-22

  • Self-host JS files

2023-11-21

  • Adds initial cron monitoring

2023-03-26

  • Adds metrics tracking, support for prometheus metrics scraping

2023-03-19

  • Hosts alert when no longer checking in
  • Hosts UI cleanup, OS icon, sorting

2023-03-18

  • Adds concurrent queue workers

2023-03-16

  • Adds OS icons to hosts page

2023-03-15

  • Fixes single log queue with new architecture

2023-03-14

  • Switch to queue architecture

2023-03-06

  • Log row expand UI fixes
  • Mobile UI fixes
  • Fixes source selection from alert rule link
  • Fix UI and broken links from alert rule show page
  • Adds success message to CL Agent install

2023-03-05

  • Adds IP to website monitor logs, adapts log retetion to sharded log dbs

2023-02-29

  • Adds highlighted search terms
  • UI enhancement: Sticky top the log column heade

2023-02-28

2023-02-23

  • Adds log sources
  • Splits log DBs into separate database per source
  • Better search
  • UI enhancements

2023-01-27

  • Adds installation/setup flow
  • Automatic TLS certs
  • Log alerts now indicate which are alerts are firing

2023-01-09

  • Adds indicator next to firing log alerts

2023-01-08

  • Adds show hosts page

2023-01-06

  • Simple -update flag for clagent

2023-01-03

  • Adds ability to delete log alert rules

2023-12-23

  • Adds settings, page, delete cron, UI enhancements

2023-12-18

  • Adds intial website monitoring, alerts coming next

2023-11-30

  • Adds cron alerting

2023-11-28

  • Adds IP, useragent to cron monitoring

2023-11-26

  • Added basic cron monitoring without alerts, alerts coming soon

2023-11-20

  • Initial release

💌 Get notified on new features and updates

Only sent when a new version is released. Nothing else.