Skip to content

v1.6.0

Choose a tag to compare

@Polliog Polliog released this 03 Nov 08:29
· 88 commits to main since this release
0101928

A large feature release focused on day-to-day use: a log query language that works the same on TimescaleDB, ClickHouse and MongoDB, a reworked Logs explorer with saved searches, error triage, a single incidents inbox, alert rules with state and snooze, Slack, Teams and PagerDuty destinations, project health checks, an extension system and a redesigned app shell. Docker images now run on Node.js 24.

Before upgrading: this release adds migrations 062 to 074 and some of them rewrite existing rows, so take a database backup first. Going back to 1.5.x on the same database is not supported. MongoDB 5.2 or later is now required, and alert notifications now follow the rule state (see Changed).

Added

  • Extension system: operators can load ES modules with LOGTIDE_EXTENSIONS that add routes under /api/v1/ext/<name>, their own Postgres schema with SQL migrations, background jobs and crons, mail, entitlement and retention access, public config in GET /api/v1/auth/config, and frontend settings pages through a build-time registry. See docs/extensions.md.
  • Log query language: one search syntax on every storage engine (TimescaleDB, ClickHouse and MongoDB): words, "exact phrases", -exclusions, OR between terms, and field filters such as service:api, -level:debug, level:(error OR critical), env:(prod OR staging), user.id:*, -host:web-1 and path:*admin*. level, service, host, trace, session and span are built-in fields; every other key filters on log metadata, including nested keys like user.id. Pasted log lines, times, URLs and IP addresses are searched as plain text, and real mistakes (an unclosed quote or parenthesis, a misplaced OR) are reported at the exact position (400 with position on the API). GET /api/v1/logs parses q with it by default, and live tail over WebSocket and SSE accepts the full query and filters on the server.
  • Logs explorer: the search bar highlights the query as you type, shows inline errors, autocompletes fields and values and has a syntax help popover. A volume histogram stacked by level lets you drag to zoom the time range or click a bar to narrow to that bucket. A facet sidebar shows Level, Service, Host and up to eight metadata keys with value counts, include and exclude, and keys you can pin per project. The details panel shows metadata as a key/value tree where every value can be filtered, excluded, added as a column or copied, and trace and session ids link to their pages. Built-in columns can be hidden and reordered, "Copy link" works for the current view and for each log (opening a log link centres the list on it), and "Create alert" opens the alert builder pre-filled with the current project and query. Live tail can be paused and resumed, pauses by itself when you scroll away from the newest logs (with an "N new logs" button) and shows its connection state. Log context loads 25 more logs in either direction with "Same service" and "Same host" toggles, and correlated events use a 15 minute, 1 hour or 6 hour window.
  • Saved searches: save, rename, update and delete log searches, private or shared with the organization, plus recent searches that remember the query, projects, time range and view. New capability saved_searches.max_per_org (unlimited by default). Migration 063.
  • Logs API: GET /api/v1/logs/count, GET /api/v1/logs/histogram (log volume by level, automatic bucket size or an explicit bucketSeconds, at most 1,000 buckets), GET /api/v1/logs/facets (top values with counts) and GET /api/v1/logs/fields (metadata keys seen in recent logs). Log responses (list, single log, context, live tail) now include hostname, spanId and sessionId.
  • Time range and project scope: a shared scope bar on the explore pages offers ten time range presets (15 minutes to 30 days) and a custom range with calendar and typed start and end times, shows the time zone next to the range, and remembers your last project and time range per browser. Project and time window are carried in the page URL (project=all means every project), so a shared link opens with the same scope. One shared formatter applies your time zone and 12/24 hour preferences everywhere.
  • Traces and APM: an operations table per service (requests, error rate, p50, p95, p99, throughput) where a click filters the trace list, a latency histogram with drag-to-filter on duration, attribute filters with key:value clauses, sortable start time and duration, and a p95 latency card. Trace detail keeps a span side panel next to the waterfall (attributes, resource attributes, events, exception stack traces, an inline Logs tab), links error spans to their error group and offers "Filter traces by this" on any attribute. The service map links nodes to Logs, Errors and Traces and exports PNG. API: GET /api/v1/traces/operations, GET /api/v1/traces/latency-histogram, operation, attr, sortBy and sortOrder on GET /api/v1/traces, and p95_duration_ms on GET /api/v1/traces/stats.
  • Error triage: the Errors page filters by project and time range, sorts by last seen, first seen or event count, shows a trend sparkline per error and defaults to open errors. Errors can be assigned to a member and resolved, reopened, ignored or assigned in bulk; an error can be ignored forever, until a date or until N more events, and reopens on its next occurrence after that with an "Escalating" notification. An error that recurs after being resolved reopens with a "Regressed" badge. The detail page shows the latest event with Older and Newer navigation, its breadcrumbs, links to the trace, the surrounding logs and the session, and who resolved it and when. API: PATCH /api/v1/error-groups/:id, POST /api/v1/error-groups/bulk, GET /api/v1/error-groups/trends, GET /api/v1/error-groups/:id/events and GET /api/v1/error-groups/by-trace/:traceId; GET /api/v1/error-groups accepts several projects, from, to, sort and assignedTo. Migration 064.
  • Web vitals, Metrics explorer and Sessions: a Web vitals page with p75 for LCP, INP, CLS, FCP and TTFB, the good / needs improvement / poor split and a per-route breakdown for the top 20 routes, computed from a bounded sample of 10,000 records with the sample count shown. The Metrics explorer gets a one-row query builder with where filters, group by (up to 2 labels), rate for counters, p50/p95/p99, automatic interval, units and "Add to dashboard", with its state in the URL. Sessions is a top-level page with time range, browser, device, entry URL and user columns when your SDK sends them, and the session detail links traces, error groups and logs.
  • Dashboards: dashboards can be duplicated and renamed, created from the Service health, Errors overview, Web vitals and Security overview templates, and shared by link (?id= and ?range=). Every panel form has a project selector and suggests metric names, services and metadata keys as you type, metric charts group by up to two labels, and panels link to Logs and Traces with their own scope and time window. New POST /api/v1/custom-dashboards/:id/panels appends a panel.
  • Incidents inbox: one list for alerts, uptime outages, security detections and manual incidents, with status, severity, source, project and assignee, bulk acknowledge, resolve and assign, and live updates. Incident detail has a single timeline of events, comments and history plus source-specific panels. The API is GET /api/v1/incidents (filters for status, source, severity, assignee me / unassigned / anyone, several projects and detection rule; sorting by last event, created time or severity), with detail (including the alert triggers or monitor checks behind an incident), comments, history and bulk actions. Incidents record who acknowledged and who resolved them and when the last event happened, and the live stream at /api/v1/siem/events covers every source and accepts a source filter. Migration 062 generalizes the incidents table.
  • Alert rule state and snooze: alert rules show whether they are Firing, OK, Snoozed or Disabled, when they last triggered and were last evaluated, who will be notified and their triggers in the last 24 hours (GET /api/v1/alerts returns state, lastTriggeredAt, lastEvaluatedAt, lastNotifiedAt, snoozedUntil, renotifyMinutes, query and triggersLast24h). POST /api/v1/alerts/:id/snooze { until } mutes a rule for up to 365 days and DELETE ends the snooze; the UI offers 1 hour, 4 hours, 24 hours or a date. A snoozed rule keeps evaluating but sends no triggers or re-notifications, and if it is still firing when the snooze ends you get one notification. Migration 065.
  • Alert query and scope: threshold rules accept a query in the logs query language (combined with the rule's levels, service and metadata filters; invalid queries are rejected with 400 { error, position }), an explicit scope (all projects or one project) and renotifyMinutes (5 to 1,440) to repeat the notification while the rule keeps firing. The alert preview accepts query and metadataFilters, and /dashboard/alerts?create=1 opens the builder pre-filled with project, query, levels, service and name.
  • alert.resolved webhook event and alert incidents: sent to the rule's webhook destinations when a firing rule returns to OK. alert.triggered payloads also carry alert_rule_id, renotify, firing_since and incident_id. A rule that starts firing opens an incident (or updates its open one) and the incident resolves when the rule recovers, is disabled or is deleted; at most one active incident exists per rule or monitor, and these incidents send no extra "incident created" notification.
  • Slack, Microsoft Teams and PagerDuty destinations: native message formats for Slack, Teams (incoming webhooks and Power Automate Workflows) and PagerDuty (a trigger when an alert fires or an error is new, regressed or escalating, a resolve when it recovers; migration 067). Destinations can be tested before saving, and Settings > Notifications groups Destinations, Routing, Digests and Delivery log. Rule forms show a "Will notify" line before you save, backed by the read-only GET /api/v1/notification-routing/preview, and a routing overview lists the rules that override the default destinations.
  • Detection rules management: a rules table with search, filters (severity, tactic, source, enabled), bulk enable, disable and delete, hits in the last 7 days and last fired time, and a rule page with YAML, recent matches, destinations and editing for custom rules. Rules can be previewed on the last 24 hours or 7 days of logs (at most the 50,000 most recent logs) and imported from YAML in Security > Detection rules. Rule exceptions stop known-good matches from creating detections and notifications, with optional expiry and a per-rule limit capability sigma.exceptions.max_per_rule (migration 066).
  • Uptime monitors: SSL certificate monitors (warn when fewer than N days remain, default 14) and DNS record monitors (A, AAAA, CNAME, MX, TXT with an optional expected value). The monitor form covers HTTP method, expected status, headers and body checks, severity, per-monitor destinations with a "Will notify" summary, and a public display name and group. The monitor detail page has Edit, a response time chart, an outages list and uptime for 24 hours, 7, 30 and 90 days. A monitor going down opens an incident and resolves it on recovery when "Resolve the incident automatically on recovery" is on. Migration 068.
  • Status page: logo, title, description and accent colour, grouped components with public display names and order, optional monitor type labels, 90 days of history, and status updates and scheduled maintenance that list the components they affect. Email subscriptions use double opt-in and one-click unsubscribe (available when SMTP is configured; at most 3 confirmation emails per address per 24 hours and 200 pending addresses per page), with a per-organization subscriber limit status_page.subscribers.max that counts only confirmed subscribers. Changes to the status page configuration, components and subscribers are recorded in the audit log. Migrations 069 and 072.
  • Onboarding and sign-in: forgot password (a reset link from the sign-in page when email is configured; links work once for 1 hour and a reset signs you out of all devices; migration 070), onboarding that resumes where you left off, and a Connect step with ready-to-copy setup for Node.js, Python, Go, Ruby, PHP, Java / Kotlin, .NET, Browser JS, OpenTelemetry, Fluent Bit and cURL built from your real API address. LogTide waits for the first log, trace, metric or error and shows troubleshooting tips if nothing arrives after a minute. Project settings has a Connect section with endpoints, DSN and snippets, API keys created from this release show a prefix (for example lp_ab12cd..., migration 071), and GET /api/v1/projects/last-events reports each project's latest event time.
  • Settings and members: Settings is organized into Account, Organization, Data, Notifications and Projects groups, every page says who its settings apply to, and account settings (Profile, Preferences, Security) live there. The Members page explains what owners, admins and members can do, and owners can transfer ownership to another member (the previous owner becomes an admin, recorded in the audit log; the new owner must be under MAX_ORGANIZATIONS_PER_USER when it is set). Admins and owners see a banner when the organization is over a usage limit or blocked. PII masking rules can be scoped to a single project from the UI, and pipeline preview can load one of the 20 most recent logs of a project.
  • Navigation and shell: the command palette searches projects, dashboards, monitors, alert rules, saved searches and settings pages, "Open trace" jumps straight to the trace, and keyboard shortcuts cover every sidebar page (g d, g l, g t, g m, g e, g s, g w, g i, g a, g u, g r, g p; ? lists what is available). Project cards show when the last event arrived (or "Waiting for data" with a Connect button), project pages have a breadcrumb and quick links to that project's pages, and the header organization name is a switcher breadcrumb ("Organization / Project"). The app shows a loading skeleton while it starts and an error screen with Retry and "Copy error details".
  • Projects table: the Projects page is a table with health, log volume, error rate and open incidents per project, and a banner warns owners and admins when a usage quota is close to its limit.
  • Project page: each project has a health header, summary tiles, a side navigation and new Health and Notifications sections (health issues with mute, the silent-project threshold and which destinations are told about health problems).
  • Project health checks: LogTide watches every project for a project that stopped sending data, records rejected by PII masking, logs, spans and metrics with out-of-range timestamps, and data sent with a revoked API key. An issue is notified when it opens and when it resolves through notification routing (new project_health event type, webhook events project.health.opened and project.health.resolved, and an in-app notification). Data pages (Logs, Metrics, Traces, Errors) show a banner when the projects in scope have open health issues. Upgrading does not flood your inbox: problems that already exist when the checks first run are shown in the app but not notified, and a project that was already idle shows as Inactive instead of alerting; it alerts if it resumes sending and then stops again.
  • Instance admin rework: All organizations, All users and All projects are sortable tables (server-side sort and order on GET /api/v1/admin/users, /organizations and /projects) with filters (role and status for users, organization and deleted state for projects), debounced search kept in the URL, owner and organization counts, and links between organizations, users and projects. Organization, user and project pages follow the new project page layout (summary tiles, sections, danger zone), entitlements show readable labels, whether each value is a default or an override, and a per-key reset (DELETE /api/v1/admin/organizations/:id/entitlements/:capability). Instance overview, usage and system health state the time window of every number, load each card independently and keep their data on screen while refreshing; settings save per section; auth providers show their URLs, a labelled enabled switch and a Test connection button. New GET /api/v1/admin/projects/summary gives instance-wide project totals.
  • Shared design system: Inter and JetBrains Mono are bundled so the app looks the same offline and in air-gapped installs, and shared page header, empty state, confirm dialog, data table, pagination, key value table, copy button, avatar and severity badge components are used across pages.
  • ClickHouse and MongoDB feature parity: log volume histograms, facet counts, metadata field discovery, session lists, per-operation latency stats and latency histograms, span search by span or resource attributes and by duration, and trace search by operation or attributes now work on TimescaleDB, ClickHouse and MongoDB with the same results (a conformance suite pins the shared behaviour). TimescaleDB standalone installs (the reservoir package without the LogTide backend) now get the session_id column, the spans hypertable and the traces table on first start.

Changed

  • Alert notifications follow the rule state: a threshold rule now notifies once when it starts firing, again every renotifyMinutes while it keeps firing (never, if unset) and sends alert.resolved when it recovers. Before, a rule notified on every one-minute evaluation that found enough new logs, so a sustained problem produced a notification per minute. Threshold rules now count all matching logs in the last time_window minutes on every run instead of only the logs since the last trigger, so the same rule can see a higher count than before. Rate-of-change rules keep their cooldown behaviour and also get state, incidents and alert.resolved. Alert history, digests and the dashboard alert counts now show one entry per notification. Migration 065 starts a rule as firing when it has alert history inside its window (all others start ok), so a rule that notified shortly before the upgrade does not notify again right after it; such a rule notifies again only after it resolves and fires again.
  • Snoozed rules still send resolve events: while a rule is snoozed, triggers and re-notifications are suppressed, but alert.resolved, the PagerDuty resolve and the incident resolve are still sent. Disabling or deleting a firing rule sends the resolve as well.
  • Status page settings on projects are admin-only: PUT /api/v1/projects/:id answers 403 to non-admin members when the body sets statusPageVisibility, statusPagePassword or slug; renaming a project and the other fields stay allowed.
  • Members get read-only pages for PII masking, pipelines and digests: only organization owners and admins can change PII masking rules, log pipelines and identifier extraction patterns, and members see those pages, the pipelines (with a View button) and the digests read-only. Members also no longer see destination webhook URLs (which embed Slack and Discord tokens), and the status page settings are read-only for them.
  • Admins can no longer invite admins: inviting someone with the admin role is now limited to the organization owner, matching the existing rule that only owners promote members to admin (403 "Only the organization owner can invite admins"). Admins can still invite members, and owners can promote them afterwards.
  • organizationId is required on PII masking and identifier extraction routes: /api/v1/pii-masking and the organization-scoped /api/v1/patterns routes answer 400 when organizationId is missing, instead of silently using the user's first organization. The settings pages send the current organization; API scripts that called these routes without it must add it.
  • Incidents are one inbox: alerts, uptime outages, security detections and manual incidents share a single list and API. /api/v1/siem/incidents is now an alias of /api/v1/incidents and returns incidents of every source (add source=sigma for the previous result set), security incidents moved from Security to Incidents, and the status "Investigating" is shown as "Acknowledged" (stored values are unchanged). "False positive" can only be set on security incidents, assigning an incident to or filtering by someone outside the organization is rejected, and admin stats count open incidents of every source.
  • Project Overview and Alerts tabs removed: the project Overview and Alerts tabs are gone, their content now lives on the project page and the Alerts page filtered by project. Old URLs redirect.
  • Renamed routes keep working: /dashboard/search is now /dashboard/logs, /dashboard/monitoring is /dashboard/uptime, /dashboard/projects/:id/sessions is /dashboard/sessions?project=:id, /dashboard/projects/:id/performance is /dashboard/web-vitals?project=:id, /dashboard/security/incidents is /dashboard/incidents (?source=sigma on the list), and /dashboard/account and the old settings URLs lead to the new Settings pages. Old links, bookmarks and notification emails redirect with their filters and query strings intact.
  • Renamed concepts: Monitoring is now Uptime and its "Incidents" tab is "Status updates"; channels are Destinations, Webhook deliveries is the Delivery log, webhook receivers are Inbound webhooks, email digests live under Notifications, patterns are Identifier extraction, and the "Time series" dashboard panel is "Log volume" (existing dashboards are unaffected). The security dashboard is now Security overview with project and time scope, working drill-downs and setup empty states, and instance admin pages are labelled Instance overview, Instance usage, Instance settings, All organizations, All projects and All users.
  • Sidebar and shortcuts: the sidebar is organized into Explore, Monitor, Security and Manage. Shortcuts changed: g s opens Sessions (was Logs, use g l), g e opens Errors (was Security) and g r opens Security (was Errors), g u opens Uptime (was g o). Switching organization takes you to the matching list page, creating an organization lands on "Create your first project", project delete moved to the project's Settings, and the project Performance and Sessions tabs are replaced by links to the Web vitals and Sessions pages.
  • Notification fallback: when no destination resolves for an event of any type (alerts and security detections included), the organization owners and admins are emailed if SMTP is configured. Previously the audience depended on the event type, severity and role, and alerts and detections sent no email. A destination that is not email (a Slack default, for example) no longer also emails members; to notify every member, add an email destination in Routing. Alert rules no longer need a destination: with none they use the organization's default destinations for alerts, and detection rules now use their own destinations and the Security detections default (neither was read before).
  • Teams and Logic Apps webhooks: generic webhook destinations that point at Power Automate Workflows or Azure Logic Apps URLs (*.logic.azure.com/workflows/..., *.api.powerplatform.com/...) now receive a Teams Adaptive Card instead of the raw event envelope, because these URLs cannot be told apart from Teams flows. If such a destination feeds a flow that parses the envelope, send to it through a URL on another host. Slack webhook URLs receive a Slack message instead of the raw payload.
  • Log search behaviour: q is parsed with the query language and the "Full-text / Substring" selector is gone (send searchMode=substring to keep plain substring matching, or wrap text in quotes). Words match whole words case-insensitively on every engine, TimescaleDB also matches English word variants (connection finds connections), and quoted phrases match anywhere in the message. Every filter is part of the query, so shared links, saved searches, export and live tail carry the same filters; older links with service, level, traceId, sessionId, logId or substring mode keep working. Results load as you scroll, 50 at a time, from a window frozen at query time ("Results as of ..." with Refresh) instead of numbered pages, and /api/v1/logs/context accepts before and after from 0 to 100 (was 1 to 50).
  • Metadata filters match the same way on every engine: nested keys resolve (user.id finds {"user": {"id": 42}}), a dotted key matches the exact key first and then the nested path (this also reaches OpenTelemetry resource attributes such as resource.service.name), numbers and booleans match by their text (status:500, ok:false), and excluding a value keeps logs that do not have the field. Arrays and objects have no text: contains never matches their JSON, equality no longer matches their JSON text on TimescaleDB, and paths never index into arrays (errors.0.code no longer resolves, including in display columns and CSV export). Existing alert rules with metadata_filters follow the same rules and may start or stop matching; review rules that filtered on dotted keys, numbers or arrays after upgrading.
  • Top values dashboard panels: top-N and distinct panels on metadata fields resolve literal dotted keys and nested paths on every engine and count numbers by their text. Numeric values now appear on ClickHouse, and array and object values are dropped on TimescaleDB and MongoDB. The Web vitals dashboard template works on MongoDB.
  • Engine-specific search changes: on MongoDB free-text search now requires every word (it used to match any) and matches whole words without English stemming; on ClickHouse words match whole words only (underscores and non-English letters included) and phrases match case-insensitively for every alphabet; on TimescaleDB searching for common words such as "down" or "not", words inside hostnames, URLs and file paths, and words with underscores finds the matching logs, and searching user no longer matches user_id. Log analytics reads (count, histogram, facets, field discovery) stop after 30 seconds on ClickHouse and MongoDB, as they already did on TimescaleDB.
  • MongoDB 5.2 or later required: the new log analytics, trace matching and filters on dotted or nested metadata keys need MongoDB 5.2 or later (the bundled image runs 7.0, which is recommended). On versions older than 7.0, per-operation latency percentiles are approximated from latency buckets.
  • Log counts, histogram and facets are capped at 31 days: the log explorer count, histogram and facets endpoints answer 400 for a time range longer than 31 days (the longest preset of the time picker), and a query that exceeds the storage engine time limit now answers 503 "query took too long" instead of a server error. New optional environment variable ANALYTICS_TIMEOUT_MS overrides that time limit on ClickHouse and MongoDB (unset keeps 30 seconds, 0 disables it).
  • New migrations and indexes: this release adds migrations 062 to 074 (incidents generalization, saved searches, error triage, alert rule lifecycle, rule exceptions, PagerDuty destinations, monitor SSL/DNS and display fields, status page configuration and subscribers, password reset tokens, API key prefix and onboarding state, subscriber confirmation counters, project health checks and their rollout), applied automatically on start. Some of them rewrite existing rows (incidents, alert rules, Sigma rules), so take a database backup before upgrading: going back to 1.5.x on the same database is not supported. ClickHouse gets the lowercase message index idx_message_lower_ngram and MongoDB the spans index idx_span_operation_time on the next start, without rewriting existing data (the ClickHouse index covers logs written after the upgrade).
  • Uptime monitors: HTTP monitors without an expected status now pass on any 2xx response instead of only 200. DNS monitors follow the existing MONITOR_ALLOW_PRIVATE_TARGETS switch (default false): single-label and internal names are refused when the monitor is created, and A/AAAA answers in private ranges are reported as blocked and never stored, so self-hosted installs that monitor internal DNS must set it to true.
  • Errors and detections: regression and escalation notifications are no longer held back by the 15 minute error notification throttle, and the error list is titled "Errors" without error group cards. Sigma detection notifications are limited to one per rule every 5 minutes per worker process (detections are still recorded).
  • Traces: the "Avg duration" card is replaced by p95 latency, the service filter is a single select, trace to logs links open the Logs explorer with the trace time window (5 minutes either side), and inline span previews in the trace list are replaced by the side panel. Traces keep project, time range and filters in the URL.
  • Onboarding and projects: onboarding is four short steps (verify email when required, workspace, connect, done) with organization and first project created on one screen, sign-up no longer asks you to confirm the password, and project settings are organized as General, Connect, API keys, Inbound webhooks and Danger zone. Deleting a project says what happens (it moves to the trash for 30 days and can be restored) and asks you to type the project name.
  • Design and wording: severity, log level and status colours use one palette (medium amber, high red, critical purple) in badges and charts, highlighted menu items are visible in light mode, cards lift from the page background in dark mode and purple text is readable in dark mode. Destructive actions ask for confirmation in a red dialog (organization and account deletion require typing the name), alert notification titles and email subjects use sentence case with thousands separators, and self-hosted Usage pages say "This instance has no limits".
  • CSV export: values starting with =, +, -, @, tab or carriage return get a leading ' so spreadsheets do not run them as formulas (JSON and NDJSON stay raw), and the CSV now includes project, host, session and your custom columns.
  • Sessions API: the sessions list uses cursor pagination and no longer reports a total, and it now works on ClickHouse and MongoDB (it only worked on TimescaleDB).
  • Instance admin: deleting a project from the instance admin is a soft delete like the project settings delete (it used to remove the row immediately), soft-deleted projects are left out of every admin count and list unless the deleted filter asks for them, project log counts in the admin are labelled and computed over the last 30 days, and invalid page, limit, sort or filter values on admin lists return 400.

Removed

  • In-app billing proxy and Billing page, LOGTIDE_BILLING_API_URL and LOGTIDE_BILLING_API_TOKEN. Both variables are ignored with a startup warning, and billingEnabled is no longer in GET /api/v1/auth/config.

Fixed

  • Log export ignored filters: export now uses exactly the active query and scope; metadata filters and search mode used to be ignored.
  • Live tail: it reconnects after a dropped connection (up to five attempts, then a Reconnect button) instead of showing "Live" on a dead stream, streams only matching logs when the query has metadata conditions (it used to stream every log), and ?live=true links start it.
  • Logs error and empty states: a failed search shows an error with Retry instead of the "start sending logs" screen, which now appears only when the selected projects have never received a log.
  • Error detail showed the first occurrence: the error detail page claimed to show the most recent occurrence but showed the first one, "View error group" in the exception dialog opens the group instead of an unfiltered list, and reopening or ignoring an error no longer records the acting user as its resolver.
  • Sessions list: it crashed on every row (undefined formatTime), and the sessions count ignored the errors filter so pagination was wrong.
  • Trace navigation: opening a trace from the command palette or an old ?traceId= link now opens the trace, trace detail reloads when navigating between traces, stale list responses no longer overwrite newer ones, the service map layout no longer reshuffles on reload and its PNG export works.
  • Metrics explorer ignored group by and the header service selector, and now reloads when the project or time range changes.
  • Engine search bugs: span search now filters by operation name on every engine (the filter was ignored); MongoDB free-text search works when the logs collection is a time-series collection; MongoDB metadata keys that contain dots (such as OpenTelemetry http.status_code) now match, and the hostname filter of top-value panels (geo map) is applied; ClickHouse metadata filters and facets match numbers and booleans; TimescaleDB log counts filtered by session honour the filter and -key:* keeps logs stored without any metadata.
  • Incident fixes: history shows the user who made a change instead of the assignee or an unrelated administrator, reopening a resolved incident clears its resolution time, unassigning works, updating an unknown incident returns 404 instead of a server error, and the Security overview counts only security incidents. The live security stream no longer re-sends the newest detection every two seconds and no longer misses updates to older incidents.
  • Alert fixes: one alert rule that fails to evaluate no longer stops the other rules from notifying in the same run, "Show matched logs" uses all of the rule's criteria, alert history times follow your display preferences, and the documented time_window of alert.triggered is in minutes (it was documented as seconds).
  • Destination secrets: editing a destination without retyping its secret no longer removes it, a stored secret is only reused when the URL stays on the same origin, and bearer tokens, passwords and routing keys are no longer returned by the API. Webhook URLs are hidden from the delivery log for non-admin members and the Retry button appears only for deliveries that can be retried.
  • Uptime fixes: recovery notifications are no longer sent for monitors that never reached their failure threshold, monitor detail no longer shows another monitor's data after switching quickly, and the status page no longer labels a shorter history as "45d ago".
  • Onboarding fixes: the Fluent Bit snippet matches your host, port and TLS, the cURL example in the API key dialog sends a valid request, API key DSNs use the scheme and port of your install, the Python snippet imports the real package (logtide_sdk), and onboarding no longer exits for good after a reload or fails with an unverified email.
  • Dashboards and projects: deleting or renaming a dashboard no longer reports success when the request failed, the project overview "Recent errors" opens the Errors page, and a remembered project from another organization no longer sticks after switching organizations.
  • Layout and polish: the mobile menu drawer animates, the organization name no longer overflows the header, the notifications panel fits small screens, and severity colours match across pages in light and dark mode.
  • Instance admin fixes: editing an OIDC or LDAP provider no longer replaces its client secret or bind password with the masked placeholder (which broke sign-in) or forces auto-registration on; saving one entitlement no longer turns every inherited default into an override; an admin can no longer disable their own account, and the last active admin can no longer be disabled or demoted (409); admin pages show the server's error message; unknown users, organizations and projects return 404 and malformed ids 400 instead of 500; % and _ in admin searches are matched literally; active sessions count only unexpired sessions; the settings page keeps a default user outside the first 100 users and refuses auth-free mode without one; deleting an organization now clears its API key, project and capability caches.

Security

  • Regular expression denial of service in Sigma rules: a Sigma rule using the re modifier with a catastrophic pattern could stall the matcher, both when previewing a rule and when matching incoming logs in the worker. Patterns now run behind a 100 ms deadline in a worker thread; a pattern that exceeds it is disabled and never matches again, and patterns over 512 characters are refused. Rule previews also stop at their time limit inside a single page of logs.
  • Database password in migration logs: the migration step printed DATABASE_URL with the password in clear text at every backend start; it is no longer logged, and the masked URL printed by the backend hides any password. An unparsable DATABASE_URL (for example a password with an unencoded # or %) now fails at startup with a message that explains it instead of Cannot read properties of undefined (reading 'searchParams').
  • Auth provider secrets in admin responses: creating or updating an auth provider returned the stored client secret or bind password in the response; it is now masked like the provider list.
  • Docker images and CI moved from Node.js 20 to Node.js 24 (issue #315): both stages of the backend and frontend images were built FROM node:20-alpine, so published images (1.5.0 included) run Node 20.20.2. Node 20 reached end of life on 2026-04-30 and gets no further security releases; the October 2026 Node.js security release (22.23.4, 24.22.1, 26.12.1), which fixes a Brotli decoder out-of-bounds write (CVE-2026-111497) and two TLS certificate hostname verification bypasses (CVE-2026-105483, CVE-2026-106069) among others, has no Node 20 fix. The images now build and run on node:24-alpine (LTS, supported until 2028-04-30), and CI and the image publishing workflow test and build on Node 24. Native dependencies (bcrypt, msgpackr-extract) use Node-API and rebuild unchanged. engines.node stays >=20.0.0 for source installs.

Full changelog: https://github.com/logtide-dev/logtide/blob/main/CHANGELOG.md