Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
0293145
add env driven capability defaults
Polliog Oct 18, 2026
fe9ccf7
accept service token on admin routes
Polliog Oct 18, 2026
860c0de
rename service token env and tighten tests
Polliog Oct 18, 2026
851e482
add signed upgrade handoff for external billing
Polliog Oct 18, 2026
4d52762
add upgrade and manage billing buttons
Polliog Oct 18, 2026
43a12da
register handoff route only when enabled
Polliog Oct 18, 2026
50cf264
add quota grace and threshold notifications
Polliog Oct 18, 2026
323c30b
cap organizations per user via env
Polliog Oct 18, 2026
a885d31
add projects.max capability with enforcement
Polliog Oct 18, 2026
de12373
add email verification tables
Polliog Oct 18, 2026
1f4a7db
require verified email when enabled
Polliog Oct 18, 2026
862f882
verify email banner and page
Polliog Oct 18, 2026
1ad88c1
require smtp for email verification and share mailer
Polliog Oct 18, 2026
643ac2d
meter ingested metric datapoints
Polliog Oct 18, 2026
dd62577
add metrics datapoint quota
Polliog Oct 18, 2026
1c38a74
type metric datapoints and add record helper
Polliog Oct 18, 2026
477989e
document contributor license agreement
Polliog Oct 18, 2026
8dae26f
document hosting seams
Polliog Oct 18, 2026
a898466
let service token pass the auth plugin
Polliog Oct 18, 2026
06102e3
widen entitlement limits to bigint
Polliog Oct 18, 2026
2e98392
pass hosting seam env vars to compose services
Polliog Oct 18, 2026
c461bfc
enforce projects.max on project restore
Polliog Oct 18, 2026
0a9b19e
dedup quota notices per limit, atomically
Polliog Oct 18, 2026
44e0ca6
hash credentials in rate limit keys
Polliog Oct 18, 2026
de635ca
add env-unset regression suite for hosting seams
Polliog Oct 18, 2026
92b1cae
send register verification email in background
Polliog Oct 18, 2026
c4b8e7f
email new unverified oidc users their link
Polliog Oct 18, 2026
6dbeaab
add upgrade hint to otlp 429 bodies
Polliog Oct 18, 2026
985b179
share the utc month start helper
Polliog Oct 18, 2026
3d6fe5e
document internal org, otlp hint and operator notes
Polliog Oct 18, 2026
0b8b622
update changelog for the final fix wave
Polliog Oct 18, 2026
6ba54e2
log organization creations per user
Polliog Oct 19, 2026
5920930
cap organization creations per month
Polliog Oct 19, 2026
4129c2f
add terms acceptance columns
Polliog Oct 19, 2026
933b355
require terms acceptance when configured
Polliog Oct 19, 2026
903b03d
gate resource creation on pending terms
Polliog Oct 19, 2026
c3c8a19
add terms acceptance to frontend auth api
Polliog Oct 19, 2026
1d5a3d9
terms checkbox and acceptance modal
Polliog Oct 19, 2026
736f81b
document terms acceptance
Polliog Oct 19, 2026
31b91ba
refuse auth-free mode while terms are active
Polliog Oct 19, 2026
00ff337
gate receiver creation like api keys
Polliog Oct 19, 2026
2e86316
recheck terms modal on terms_not_accepted
Polliog Oct 19, 2026
bceefcd
document terms fix round
Polliog Oct 19, 2026
72134f9
meter span and metric bytes
Polliog Oct 19, 2026
0dde718
support multi-signal quotas in the registry
Polliog Oct 19, 2026
157a8b0
add combined telemetry byte quota
Polliog Oct 19, 2026
fa43029
show telemetry quota on the usage page
Polliog Oct 19, 2026
20cea60
document telemetry quota
Polliog Oct 19, 2026
7dfbd2b
bill only customer fields in span and metric bytes
Polliog Oct 19, 2026
c993470
hide null quotas only under a telemetry cap
Polliog Oct 19, 2026
f9b7abf
document customer-only telemetry bytes
Polliog Oct 19, 2026
4afe643
fix telemetry row in hosting docs table
Polliog Oct 19, 2026
e6d164d
Merge branch 'develop' into feat/cloud-seams
Polliog Oct 19, 2026
f70caf2
adapt mailer types to nodemailer 10
Polliog Oct 19, 2026
6368ebb
Merge branch 'feat/cloud-seams' into develop
Polliog Oct 19, 2026
c9ab0fa
bump version to 1.4.0
Polliog Oct 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ or background job (see `docs/security/tenant-isolation-audit.md`):

<!-- If a change is intentionally cross-tenant (admin / platform), say so here. -->

## Contributor License Agreement

- [ ] I have signed the CLA (<https://cla-assistant.io/logtide-dev/logtide>) and my commits use an email linked to my GitHub account.

## Testing

<!-- how this was verified -->
41 changes: 31 additions & 10 deletions CHANGELOG.md

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ For larger changes (new storage engine methods, schema changes, changes to the i

Keep each pull request focused on one problem: no unrelated refactors, dependency upgrades or formatting churn in the same PR.

#### Contributor License Agreement

Before your first pull request can be merged you need to sign the Contributor License Agreement (CLA). A bot posts a comment on your first PR with a link; read the agreement text it shows, then sign by commenting as the bot asks. You sign once, for all your future contributions. You can also sign ahead of time at <https://cla-assistant.io/logtide-dev/logtide>.

The bot recognises you through the email address on your commits, so **commit with an email address that is linked to your GitHub account** (check it under GitHub Settings, Emails). Commits made with an unlinked email cannot be matched to your account and the CLA check will stay pending.

Contributions to the core are licensed under the AGPLv3 like the rest of the code. LogTide is open core, and the CLA also allows the maintainer to use contributions in commercial editions. See the agreement text shown by the bot for the exact terms.

## Development Setup

### Prerequisites
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</p>

<p>
<a href="https://logtide.dev"><strong>☁️ Try Cloud (Free Beta)</strong></a> •
<a href="https://logtide.dev"><strong>☁️ Try Cloud</strong></a> •
<a href="#self-hosting">Self-Host</a> •
<a href="#sdks--integrations">SDKs</a> •
<a href="https://logtide.dev/docs">Docs</a>
Expand All @@ -16,14 +16,14 @@
<a href="https://codecov.io/gh/logtide-dev/logtide"><img src="https://codecov.io/gh/logtide-dev/logtide/branch/main/graph/badge.svg" alt="Coverage"></a>
<a href="https://hub.docker.com/r/logtide/backend"><img src="https://img.shields.io/docker/v/logtide/backend?label=docker&logo=docker" alt="Docker"></a>
<a href="https://artifacthub.io/packages/helm/logtide/logtide"><img src="https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/logtide" alt="Artifact Hub"></a>
<img src="https://img.shields.io/badge/version-1.3.2-blue.svg" alt="Version">
<img src="https://img.shields.io/badge/version-1.4.0-blue.svg" alt="Version">
<img src="https://img.shields.io/badge/license-AGPLv3-blue.svg" alt="License">
<img src="https://img.shields.io/badge/status-beta-success.svg" alt="Status">
<img src="https://img.shields.io/badge/status-stable-success.svg" alt="Status">
</div>

<br />

> **🌊 LogTide 1.3.2 (public beta):** unified **Logs, Traces & Metrics** with a built-in **SIEM**, multi-engine storage (TimescaleDB / ClickHouse / MongoDB), uptime monitoring, parsing pipelines, and custom dashboards.
> **🌊 LogTide 1.4.0:** unified **Logs, Traces & Metrics** with a built-in **SIEM**, multi-engine storage (TimescaleDB / ClickHouse / MongoDB), uptime monitoring, parsing pipelines, and custom dashboards.

---

Expand Down Expand Up @@ -128,7 +128,7 @@ We host it for you. Perfect for testing. [**Sign up at logtide.dev**](https://lo

---

## ✨ Core Features (v1.3.2)
## ✨ Core Features (v1.4.0)

### Monitoring, Pipelines & Dashboards
* 🩺 **Uptime Monitoring & Status Pages:** HTTP/TCP/heartbeat monitors with configurable thresholds, auto-created SIEM incidents on failure, scheduled maintenances, and public Uptime-Kuma-style status pages per project.
Expand Down Expand Up @@ -182,6 +182,8 @@ Ready-to-use SDKs with auto-instrumentation and distributed tracing.

Distributed under the **GNU AGPLv3** License. See `LICENSE` for more information.

Contributions require signing the [Contributor License Agreement](https://cla-assistant.io/logtide-dev/logtide); see `CONTRIBUTING.md`.

---

<div align="center">
Expand Down
49 changes: 49 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,52 @@ DB_USER=logtide
# docker compose -f docker-compose.yml -f docker-compose.traefik.yml up -d --scale backend=3
#
# See docs: https://logtide.dev/docs/deployment#horizontal-scaling

# =============================================================================
# External billing handoff (optional, for hosted deployments)
# =============================================================================
# When BOTH are set, owners/admins see Upgrade / Manage billing buttons on the
# usage page. Clicking one redirects to LOGTIDE_UPGRADE_URL with a short-lived
# (10 minute) HMAC-SHA256 signed token (?t=...). The token never contains
# LogTide session credentials. Setting only one of the two aborts startup.
# URL must be https (http is allowed only for localhost / 127.0.0.1).
# LOGTIDE_UPGRADE_URL=https://billing.example.com/portal
# Min 32 characters. Generate with: openssl rand -base64 48
# LOGTIDE_UPGRADE_SIGNING_SECRET=

# =============================================================================
# Hosting seams (optional, for operators hosting LogTide for others)
# =============================================================================
# Full reference: docs/cloud-seams.md. Everything below is off when unset.
# (LOGTIDE_UPGRADE_URL and LOGTIDE_UPGRADE_SIGNING_SECRET are in the section above.)

# JSON object overriding capability defaults for every org (entitlement rows
# still win). Values: boolean, integer >= 0, or null for unlimited.
# Invalid JSON, unknown capability or wrong type aborts startup.
# CAPABILITY_DEFAULTS_JSON={"projects.max": 3, "quota.grace_percent": 10}

# Static bearer (min 32 characters) letting an external billing service call the
# org entitlements and retention admin endpoints. Generate: openssl rand -base64 48
# LOGTIDE_ADMIN_SERVICE_TOKEN=

# Max organizations one user may own (positive integer, unset = unlimited).
# MAX_ORGANIZATIONS_PER_USER=3

# Max organizations one user may create per UTC calendar month, even if they
# delete them again (positive integer, unset = unlimited).
# MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH=2

# Make new local users confirm their email before creating projects or API keys.
# Requires SMTP_HOST, otherwise startup fails.
# REQUIRE_EMAIL_VERIFICATION=false

# Extra per-IP cap on POST /auth/register per hour (positive integer, unset = off).
# REGISTRATION_RATE_LIMIT_PER_HOUR=10

# Require Terms of Service and Privacy Policy acceptance at registration (and
# again whenever LOGTIDE_TERMS_VERSION changes). Set all three or none: a
# partial set aborts startup. URLs must be https (http only for localhost).
# Ingestion with existing API keys is never blocked.
# LOGTIDE_TERMS_URL=https://example.com/terms
# LOGTIDE_PRIVACY_URL=https://example.com/privacy
# LOGTIDE_TERMS_VERSION=2026-10-19
24 changes: 24 additions & 0 deletions docker/docker-compose.build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ services:
INTERNAL_DSN: ${INTERNAL_DSN:-}
DOCKER_CONTAINER: "true"
SERVICE_NAME: logtide-backend
# Hosting seams: empty = inert (see docs/cloud-seams.md)
CAPABILITY_DEFAULTS_JSON: ${CAPABILITY_DEFAULTS_JSON:-}
LOGTIDE_ADMIN_SERVICE_TOKEN: ${LOGTIDE_ADMIN_SERVICE_TOKEN:-}
LOGTIDE_UPGRADE_URL: ${LOGTIDE_UPGRADE_URL:-}
LOGTIDE_UPGRADE_SIGNING_SECRET: ${LOGTIDE_UPGRADE_SIGNING_SECRET:-}
MAX_ORGANIZATIONS_PER_USER: ${MAX_ORGANIZATIONS_PER_USER:-}
MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH: ${MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH:-}
REQUIRE_EMAIL_VERIFICATION: ${REQUIRE_EMAIL_VERIFICATION:-}
REGISTRATION_RATE_LIMIT_PER_HOUR: ${REGISTRATION_RATE_LIMIT_PER_HOUR:-}
LOGTIDE_TERMS_URL: ${LOGTIDE_TERMS_URL:-}
LOGTIDE_PRIVACY_URL: ${LOGTIDE_PRIVACY_URL:-}
LOGTIDE_TERMS_VERSION: ${LOGTIDE_TERMS_VERSION:-}
STORAGE_ENGINE: ${STORAGE_ENGINE:-timescale}
CLICKHOUSE_HOST: ${CLICKHOUSE_HOST:-clickhouse}
CLICKHOUSE_PORT: ${CLICKHOUSE_PORT:-8123}
Expand Down Expand Up @@ -162,6 +174,18 @@ services:
INTERNAL_DSN: ${INTERNAL_DSN:-}
DOCKER_CONTAINER: "true"
SERVICE_NAME: logtide-worker
# Hosting seams: empty = inert (see docs/cloud-seams.md)
CAPABILITY_DEFAULTS_JSON: ${CAPABILITY_DEFAULTS_JSON:-}
LOGTIDE_ADMIN_SERVICE_TOKEN: ${LOGTIDE_ADMIN_SERVICE_TOKEN:-}
LOGTIDE_UPGRADE_URL: ${LOGTIDE_UPGRADE_URL:-}
LOGTIDE_UPGRADE_SIGNING_SECRET: ${LOGTIDE_UPGRADE_SIGNING_SECRET:-}
MAX_ORGANIZATIONS_PER_USER: ${MAX_ORGANIZATIONS_PER_USER:-}
MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH: ${MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH:-}
REQUIRE_EMAIL_VERIFICATION: ${REQUIRE_EMAIL_VERIFICATION:-}
REGISTRATION_RATE_LIMIT_PER_HOUR: ${REGISTRATION_RATE_LIMIT_PER_HOUR:-}
LOGTIDE_TERMS_URL: ${LOGTIDE_TERMS_URL:-}
LOGTIDE_PRIVACY_URL: ${LOGTIDE_PRIVACY_URL:-}
LOGTIDE_TERMS_VERSION: ${LOGTIDE_TERMS_VERSION:-}
STORAGE_ENGINE: ${STORAGE_ENGINE:-timescale}
CLICKHOUSE_HOST: ${CLICKHOUSE_HOST:-clickhouse}
CLICKHOUSE_PORT: ${CLICKHOUSE_PORT:-8123}
Expand Down
24 changes: 24 additions & 0 deletions docker/docker-compose.simple.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ services:
INTERNAL_DSN: ${INTERNAL_DSN:-}
DOCKER_CONTAINER: "true"
SERVICE_NAME: logtide-backend
# Hosting seams: empty = inert (see docs/cloud-seams.md)
CAPABILITY_DEFAULTS_JSON: ${CAPABILITY_DEFAULTS_JSON:-}
LOGTIDE_ADMIN_SERVICE_TOKEN: ${LOGTIDE_ADMIN_SERVICE_TOKEN:-}
LOGTIDE_UPGRADE_URL: ${LOGTIDE_UPGRADE_URL:-}
LOGTIDE_UPGRADE_SIGNING_SECRET: ${LOGTIDE_UPGRADE_SIGNING_SECRET:-}
MAX_ORGANIZATIONS_PER_USER: ${MAX_ORGANIZATIONS_PER_USER:-}
MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH: ${MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH:-}
REQUIRE_EMAIL_VERIFICATION: ${REQUIRE_EMAIL_VERIFICATION:-}
REGISTRATION_RATE_LIMIT_PER_HOUR: ${REGISTRATION_RATE_LIMIT_PER_HOUR:-}
LOGTIDE_TERMS_URL: ${LOGTIDE_TERMS_URL:-}
LOGTIDE_PRIVACY_URL: ${LOGTIDE_PRIVACY_URL:-}
LOGTIDE_TERMS_VERSION: ${LOGTIDE_TERMS_VERSION:-}
STORAGE_ENGINE: timescale
depends_on:
postgres:
Expand Down Expand Up @@ -135,6 +147,18 @@ services:
INTERNAL_DSN: ${INTERNAL_DSN:-}
DOCKER_CONTAINER: "true"
SERVICE_NAME: logtide-worker
# Hosting seams: empty = inert (see docs/cloud-seams.md)
CAPABILITY_DEFAULTS_JSON: ${CAPABILITY_DEFAULTS_JSON:-}
LOGTIDE_ADMIN_SERVICE_TOKEN: ${LOGTIDE_ADMIN_SERVICE_TOKEN:-}
LOGTIDE_UPGRADE_URL: ${LOGTIDE_UPGRADE_URL:-}
LOGTIDE_UPGRADE_SIGNING_SECRET: ${LOGTIDE_UPGRADE_SIGNING_SECRET:-}
MAX_ORGANIZATIONS_PER_USER: ${MAX_ORGANIZATIONS_PER_USER:-}
MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH: ${MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH:-}
REQUIRE_EMAIL_VERIFICATION: ${REQUIRE_EMAIL_VERIFICATION:-}
REGISTRATION_RATE_LIMIT_PER_HOUR: ${REGISTRATION_RATE_LIMIT_PER_HOUR:-}
LOGTIDE_TERMS_URL: ${LOGTIDE_TERMS_URL:-}
LOGTIDE_PRIVACY_URL: ${LOGTIDE_PRIVACY_URL:-}
LOGTIDE_TERMS_VERSION: ${LOGTIDE_TERMS_VERSION:-}
STORAGE_ENGINE: timescale
depends_on:
backend:
Expand Down
24 changes: 24 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ services:
INTERNAL_DSN: ${INTERNAL_DSN:-}
DOCKER_CONTAINER: "true"
SERVICE_NAME: logtide-backend
# Hosting seams: empty = inert (see docs/cloud-seams.md)
CAPABILITY_DEFAULTS_JSON: ${CAPABILITY_DEFAULTS_JSON:-}
LOGTIDE_ADMIN_SERVICE_TOKEN: ${LOGTIDE_ADMIN_SERVICE_TOKEN:-}
LOGTIDE_UPGRADE_URL: ${LOGTIDE_UPGRADE_URL:-}
LOGTIDE_UPGRADE_SIGNING_SECRET: ${LOGTIDE_UPGRADE_SIGNING_SECRET:-}
MAX_ORGANIZATIONS_PER_USER: ${MAX_ORGANIZATIONS_PER_USER:-}
MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH: ${MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH:-}
REQUIRE_EMAIL_VERIFICATION: ${REQUIRE_EMAIL_VERIFICATION:-}
REGISTRATION_RATE_LIMIT_PER_HOUR: ${REGISTRATION_RATE_LIMIT_PER_HOUR:-}
LOGTIDE_TERMS_URL: ${LOGTIDE_TERMS_URL:-}
LOGTIDE_PRIVACY_URL: ${LOGTIDE_PRIVACY_URL:-}
LOGTIDE_TERMS_VERSION: ${LOGTIDE_TERMS_VERSION:-}
STORAGE_ENGINE: ${STORAGE_ENGINE:-timescale}
CLICKHOUSE_HOST: ${CLICKHOUSE_HOST:-clickhouse}
CLICKHOUSE_PORT: ${CLICKHOUSE_PORT:-8123}
Expand Down Expand Up @@ -175,6 +187,18 @@ services:
INTERNAL_DSN: ${INTERNAL_DSN:-}
DOCKER_CONTAINER: "true"
SERVICE_NAME: logtide-worker
# Hosting seams: empty = inert (see docs/cloud-seams.md)
CAPABILITY_DEFAULTS_JSON: ${CAPABILITY_DEFAULTS_JSON:-}
LOGTIDE_ADMIN_SERVICE_TOKEN: ${LOGTIDE_ADMIN_SERVICE_TOKEN:-}
LOGTIDE_UPGRADE_URL: ${LOGTIDE_UPGRADE_URL:-}
LOGTIDE_UPGRADE_SIGNING_SECRET: ${LOGTIDE_UPGRADE_SIGNING_SECRET:-}
MAX_ORGANIZATIONS_PER_USER: ${MAX_ORGANIZATIONS_PER_USER:-}
MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH: ${MAX_ORGANIZATION_CREATIONS_PER_USER_PER_MONTH:-}
REQUIRE_EMAIL_VERIFICATION: ${REQUIRE_EMAIL_VERIFICATION:-}
REGISTRATION_RATE_LIMIT_PER_HOUR: ${REGISTRATION_RATE_LIMIT_PER_HOUR:-}
LOGTIDE_TERMS_URL: ${LOGTIDE_TERMS_URL:-}
LOGTIDE_PRIVACY_URL: ${LOGTIDE_PRIVACY_URL:-}
LOGTIDE_TERMS_VERSION: ${LOGTIDE_TERMS_VERSION:-}
STORAGE_ENGINE: ${STORAGE_ENGINE:-timescale}
CLICKHOUSE_HOST: ${CLICKHOUSE_HOST:-clickhouse}
CLICKHOUSE_PORT: ${CLICKHOUSE_PORT:-8123}
Expand Down
Loading
Loading