refactor(config): debrand env — O11Y prefix, DATASTORE store name (no SIGNOZ/CLICKHOUSE in env)
Canonical flat operator key O11Y_DATASTORE_DSN aliases into telemetrystore.datastore.dsn; long structured form kept as internal fallback. Store stays ClickHouse wire-protocol (driver/provider/tables unchanged).
This commit is contained in:
+4
-4
@@ -13,7 +13,7 @@
|
||||
# fetch needs no private git auth — only GOPRIVATE + GOSUMDB=off.
|
||||
#
|
||||
# The browser SPA is served at the edge by hanzoai/static (house-native static
|
||||
# plugin), not bundled here, so the server runs headless (SIGNOZ_WEB_ENABLED=false).
|
||||
# plugin), not bundled here, so the server runs headless (O11Y_WEB_ENABLED=false).
|
||||
# The frontend/ tree is a separate concern — its pnpm-lock.yaml is mid-migration
|
||||
# and not build-ready; bundle it back once that is resolved.
|
||||
|
||||
@@ -76,9 +76,9 @@ COPY --from=backend /out/o11y /usr/local/bin/o11y
|
||||
COPY templates/ /root/templates/
|
||||
|
||||
# The browser SPA is served by hanzoai/static at the edge; run headless. When a
|
||||
# deployment bundles/mounts web assets, set SIGNOZ_WEB_ENABLED=true and
|
||||
# SIGNOZ_WEB_DIRECTORY to their path.
|
||||
ENV SIGNOZ_WEB_ENABLED=false
|
||||
# deployment bundles/mounts web assets, set O11Y_WEB_ENABLED=true and
|
||||
# O11Y_WEB_DIRECTORY to their path.
|
||||
ENV O11Y_WEB_ENABLED=false
|
||||
|
||||
# Public query-service HTTP + query API (constants.HTTPHostPort = 0.0.0.0:8080).
|
||||
EXPOSE 8080
|
||||
|
||||
@@ -37,6 +37,37 @@ SigNoz eras); it dissolved when the whole `pkg/ cmd/` tree was re-synced to one
|
||||
consistent upstream version. Keep it that way: bump by re-syncing to a newer SigNoz
|
||||
`main`, not by piecemeal-porting individual packages.
|
||||
|
||||
The real server binary is `./cmd/community` (NOT `./cmd/server`, which does not
|
||||
exist). Build check: `GOPRIVATE='github.com/hanzoai/*' GOSUMDB=off go build ./cmd/community`.
|
||||
|
||||
## Container image (`ghcr.io/hanzoai/o11y`)
|
||||
|
||||
Root `Dockerfile` + `.github/workflows/docker.yaml` build a standalone community
|
||||
server image on push to `main` and `v*` tags → `ghcr.io/hanzoai/o11y:<sha>` (+ `:main`).
|
||||
This replaces the unrelated **Langfuse** image that previously squatted the tags.
|
||||
|
||||
- Builds ONLY `./cmd/community`. It does NOT import `github.com/hanzoai/cloud`, so
|
||||
go.mod's `replace github.com/hanzoai/cloud => ../cloud` is inert for the image and
|
||||
no cloud sibling is checked out. (Cloud lives only in root `mount.go`, compiled by
|
||||
the `go build ./...` CI job — so `ci.yaml` still needs the sibling; the container
|
||||
does not.) A bare `go mod download` WOULD fail (cloud→../cloud); build the one pkg.
|
||||
- All external deps in its graph are PUBLIC hanzoai/* forks (signoz-otel-collector,
|
||||
govaluate, clickhouse-go-mock, expr) → no private git auth, just
|
||||
`GOPRIVATE=github.com/hanzoai/* GOSUMDB=off`. GHCR push uses `GH_PAT || GITHUB_TOKEN`
|
||||
(the package is linked to hanzoai/o11y, so GITHUB_TOKEN+`packages: write` suffices).
|
||||
- Runs headless: `O11Y_WEB_ENABLED=false`. `routerweb` os.Stat()s its web dir at
|
||||
boot and fatals if missing; the SPA is served by hanzoai/static at the edge. The
|
||||
`frontend/` tree is NOT bundled — its `pnpm-lock.yaml` is STALE vs `package.json`
|
||||
(mid rolldown-vite/oxlint migration), fails `--frozen-lockfile`. TODO: regen lockfile.
|
||||
- Listens on `0.0.0.0:8080` (constants.HTTPHostPort); sqlstore default = sqlite at
|
||||
`/var/lib/signoz/signoz.db`; needs an external ClickHouse for telemetry.
|
||||
|
||||
Boot fix: `pkg/instrumentation/sdk.go` hard-pinned `semconv/v1.40.0.SchemaURL`,
|
||||
which contrib `NewSDK` merges against `resource.Default()` (schema 1.41.0, from the
|
||||
re-synced otel/sdk) — OTEL rejects differing non-empty schema URLs, so `signoz.New`
|
||||
crashed at boot with "conflicting Schema URL". Now sourced from the detected resource
|
||||
(`resource.SchemaURL()`), version-agnostic. Verified: boots, runs migrations, serves :8080.
|
||||
|
||||
## Hanzo layer to re-apply on the green base
|
||||
|
||||
The re-sync reverted these Hanzo-original packages to SigNoz canonical to kill the
|
||||
@@ -46,3 +77,37 @@ OpenFGA is the current default and must be replaced), `pkg/zapreceiver` +
|
||||
`pkg/zapmetricreceiver` (ZAP-native OTLP receivers), `pkg/billing` + `pkg/types/billingtypes`.
|
||||
Preserved through the sync: module path, `mount.go` (the `cloud.Register`/zip mount
|
||||
adapter), `NOTICE`, `LICENSE`.
|
||||
|
||||
## Config env naming (debranded — no SIGNOZ/CLICKHOUSE)
|
||||
|
||||
Operator-facing env vars and config keys are Hanzo-branded, never SigNoz/ClickHouse.
|
||||
Naming-only: the store is still ClickHouse wire-protocol under the hood — the
|
||||
`clickhouse-go` driver, `db.system=clickhouse` semconv, and the `clickhouse`
|
||||
telemetrystore provider registration all stay (implementation, not surface).
|
||||
|
||||
- **Env prefix `O11Y_`** (was `SIGNOZ_`): set once at `pkg/config/envprovider/provider.go`
|
||||
(`prefix`). The koanf env provider derives every structured key from it. Single `_`
|
||||
is the `::` path delimiter, double `__` is a literal `_`.
|
||||
- **Store key segment `datastore`** (was `clickhouse`): the `mapstructure` tag on
|
||||
`telemetrystore.Config.Clickhouse` is `datastore` (the Go field/type keep the
|
||||
`Clickhouse` name — internal). YAML key `telemetrystore.datastore`. Provider
|
||||
selector value stays `clickhouse`.
|
||||
- **Canonical DSN key `O11Y_DATASTORE_DSN`** (flat — THE operator knob): wired as an
|
||||
override alias in `pkg/signoz/config.go` (`mergeAndEnsureBackwardCompatibility`),
|
||||
mapping into `telemetrystore.datastore.dsn`. Value → Hanzo Datastore
|
||||
(`tcp://datastore.hanzo.svc:9000/?database=o11y`, set at deploy time). It takes
|
||||
precedence over the structured `O11Y_TELEMETRYSTORE_DATASTORE_DSN`, which stays as
|
||||
an internal fallback (don't document/set the long form). Keep operator knobs flat and
|
||||
short — no `O11Y_A_B_C_D` compounds where a flat alias reads better.
|
||||
- **Legacy override aliases** in `pkg/signoz/config.go` (`mergeAndEnsureBackwardCompatibility`)
|
||||
debranded too: `O11Y_LOCAL_DB_PATH`, `DatastoreUrl`, `O11Y_SAAS_SEGMENT_KEY`,
|
||||
`O11Y_JWT_SECRET`; and headless web via `O11Y_WEB_ENABLED` / `O11Y_WEB_DIRECTORY`.
|
||||
- **Deliberately NOT renamed** (implementation / not app-config surface): the `clickhouse`
|
||||
provider value + `MustNewName("clickhouse")` registration, `clickhouse-go` driver + mock,
|
||||
SQL/table/DB names (`signoz_traces` etc.) and query-template vars
|
||||
(`SIGNOZ_START_TIME`/`SIGNOZ_END_TIME`), the ClickHouse **server** container in `deploy/`
|
||||
(service/volume names, its own `CLICKHOUSE_SKIP_USER_SETUP` env), the `SIGNOZ_E2E_*`
|
||||
Playwright test-harness vars (separate `tests/e2e` subsystem). The
|
||||
`O11Y_OTEL_COLLECTOR_DATASTORE_*` keys in `deploy/` are consumed by the
|
||||
`hanzoai/signoz-otel-collector` fork — renamed here for consistency; that fork must
|
||||
accept the `_DATASTORE_` segment (coordinated cross-repo rename).
|
||||
|
||||
+4
-3
@@ -138,12 +138,13 @@ telemetrystore:
|
||||
dial_timeout: 5s
|
||||
# Specifies the telemetrystore provider to use.
|
||||
provider: clickhouse
|
||||
clickhouse:
|
||||
# The DSN for Hanzo Datastore.
|
||||
datastore:
|
||||
# The DSN for Hanzo Datastore. Canonical env override: O11Y_DATASTORE_DSN
|
||||
# (e.g. tcp://datastore.hanzo.svc:9000/?database=o11y).
|
||||
dsn: tcp://datastore:9000
|
||||
# The cluster name for Hanzo Datastore.
|
||||
cluster: cluster
|
||||
# The query settings for clickhouse.
|
||||
# The query settings for the datastore.
|
||||
settings:
|
||||
max_execution_time: 0
|
||||
max_execution_time_leaf: 0
|
||||
|
||||
@@ -198,7 +198,7 @@ services:
|
||||
- ./clickhouse-setup/data/observe/:/var/lib/observe/
|
||||
environment:
|
||||
- O11Y_ALERTMANAGER_PROVIDER=observe
|
||||
- O11Y_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_SQLSTORE_SQLITE_PATH=/var/lib/ghcr.io/hanzoai/o11y.db
|
||||
- O11Y_TOKENIZER_JWT_SECRET=secret
|
||||
healthcheck:
|
||||
@@ -229,9 +229,9 @@ services:
|
||||
environment:
|
||||
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
|
||||
- LOW_CARDINAL_EXCEPTION_GROUPING=false
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
|
||||
ports:
|
||||
# - "1777:1777" # pprof extension
|
||||
@@ -243,9 +243,9 @@ services:
|
||||
!!merge <<: *db-depend
|
||||
image: ghcr.io/hanzoai/otel-collector:v0.144.2
|
||||
environment:
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
|
||||
@@ -124,7 +124,7 @@ services:
|
||||
- sqlite:/var/lib/observe/
|
||||
environment:
|
||||
- O11Y_ALERTMANAGER_PROVIDER=observe
|
||||
- O11Y_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_SQLSTORE_SQLITE_PATH=/var/lib/ghcr.io/hanzoai/o11y.db
|
||||
- O11Y_TOKENIZER_JWT_SECRET=secret
|
||||
healthcheck:
|
||||
@@ -155,9 +155,9 @@ services:
|
||||
environment:
|
||||
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
|
||||
- LOW_CARDINAL_EXCEPTION_GROUPING=false
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
|
||||
ports:
|
||||
# - "1777:1777" # pprof extension
|
||||
@@ -169,9 +169,9 @@ services:
|
||||
!!merge <<: *db-depend
|
||||
image: ghcr.io/hanzoai/otel-collector:v0.144.2
|
||||
environment:
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
COMPOSE_PROJECT_NAME=signoz
|
||||
COMPOSE_PROJECT_NAME=o11y
|
||||
@@ -189,7 +189,7 @@ services:
|
||||
- sqlite:/var/lib/observe/
|
||||
environment:
|
||||
- O11Y_ALERTMANAGER_PROVIDER=observe
|
||||
- O11Y_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_SQLSTORE_SQLITE_PATH=/var/lib/ghcr.io/hanzoai/o11y.db
|
||||
- O11Y_TOKENIZER_JWT_SECRET=secret
|
||||
healthcheck:
|
||||
@@ -219,9 +219,9 @@ services:
|
||||
environment:
|
||||
- OTEL_RESOURCE_ATTRIBUTES=host.name=observe-host,os.type=linux
|
||||
- LOW_CARDINAL_EXCEPTION_GROUPING=false
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
|
||||
ports:
|
||||
# - "1777:1777" # pprof extension
|
||||
@@ -232,9 +232,9 @@ services:
|
||||
image: ghcr.io/hanzoai/otel-collector:${OTELCOL_TAG:-v0.144.2}
|
||||
container_name: o11y-telemetrystore-migrator
|
||||
environment:
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
|
||||
@@ -117,7 +117,7 @@ services:
|
||||
- sqlite:/var/lib/observe/
|
||||
environment:
|
||||
- O11Y_ALERTMANAGER_PROVIDER=observe
|
||||
- O11Y_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_SQLSTORE_SQLITE_PATH=/var/lib/ghcr.io/hanzoai/o11y.db
|
||||
- O11Y_TOKENIZER_JWT_SECRET=secret
|
||||
healthcheck:
|
||||
@@ -147,9 +147,9 @@ services:
|
||||
environment:
|
||||
- OTEL_RESOURCE_ATTRIBUTES=host.name=observe-host,os.type=linux
|
||||
- LOW_CARDINAL_EXCEPTION_GROUPING=false
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
|
||||
ports:
|
||||
# - "1777:1777" # pprof extension
|
||||
@@ -160,9 +160,9 @@ services:
|
||||
image: ghcr.io/hanzoai/otel-collector:${OTELCOL_TAG:-v0.144.2}
|
||||
container_name: o11y-telemetrystore-migrator
|
||||
environment:
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_DSN=tcp://clickhouse:9000
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_CLUSTER=cluster
|
||||
- O11Y_OTEL_COLLECTOR_DATASTORE_REPLICATION=true
|
||||
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
|
||||
entrypoint:
|
||||
- /bin/sh
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
prefix string = "SIGNOZ_"
|
||||
prefix string = "O11Y_"
|
||||
scheme string = "env"
|
||||
)
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// clearSignozEnv unsets all existing SIGNOZ_* env vars for the duration of the test.
|
||||
func clearSignozEnv(t *testing.T) {
|
||||
// clearEnv unsets all existing O11Y_* env vars for the duration of the test.
|
||||
func clearEnv(t *testing.T) {
|
||||
t.Helper()
|
||||
for _, kv := range os.Environ() {
|
||||
if strings.HasPrefix(kv, prefix) {
|
||||
@@ -25,12 +25,12 @@ func clearSignozEnv(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetWithStrings(t *testing.T) {
|
||||
clearSignozEnv(t)
|
||||
t.Setenv("SIGNOZ_K1_K2", "string")
|
||||
t.Setenv("SIGNOZ_K3__K4", "string")
|
||||
t.Setenv("SIGNOZ_K5__K6_K7__K8", "string")
|
||||
t.Setenv("SIGNOZ_K9___K10", "string")
|
||||
t.Setenv("SIGNOZ_K11____K12", "string")
|
||||
clearEnv(t)
|
||||
t.Setenv("O11Y_K1_K2", "string")
|
||||
t.Setenv("O11Y_K3__K4", "string")
|
||||
t.Setenv("O11Y_K5__K6_K7__K8", "string")
|
||||
t.Setenv("O11Y_K9___K10", "string")
|
||||
t.Setenv("O11Y_K11____K12", "string")
|
||||
expected := map[string]any{
|
||||
"k1::k2": "string",
|
||||
"k3_k4": "string",
|
||||
@@ -47,7 +47,7 @@ func TestGetWithStrings(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetWithNoPrefix(t *testing.T) {
|
||||
clearSignozEnv(t)
|
||||
clearEnv(t)
|
||||
t.Setenv("K1_K2", "string")
|
||||
t.Setenv("K3_K4", "string")
|
||||
expected := map[string]any{}
|
||||
@@ -60,11 +60,11 @@ func TestGetWithNoPrefix(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetWithGoTypes(t *testing.T) {
|
||||
clearSignozEnv(t)
|
||||
t.Setenv("SIGNOZ_BOOL", "true")
|
||||
t.Setenv("SIGNOZ_STRING", "string")
|
||||
t.Setenv("SIGNOZ_INT", "1")
|
||||
t.Setenv("SIGNOZ_SLICE", "[1,2]")
|
||||
clearEnv(t)
|
||||
t.Setenv("O11Y_BOOL", "true")
|
||||
t.Setenv("O11Y_STRING", "string")
|
||||
t.Setenv("O11Y_INT", "1")
|
||||
t.Setenv("O11Y_SLICE", "[1,2]")
|
||||
expected := map[string]any{
|
||||
"bool": "true",
|
||||
"int": "1",
|
||||
@@ -80,9 +80,9 @@ func TestGetWithGoTypes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetWithGoTypesWithUnmarshal(t *testing.T) {
|
||||
t.Setenv("SIGNOZ_BOOL", "true")
|
||||
t.Setenv("SIGNOZ_STRING", "string")
|
||||
t.Setenv("SIGNOZ_INT", "1")
|
||||
t.Setenv("O11Y_BOOL", "true")
|
||||
t.Setenv("O11Y_STRING", "string")
|
||||
t.Setenv("O11Y_INT", "1")
|
||||
|
||||
type test struct {
|
||||
Bool bool `mapstructure:"bool"`
|
||||
|
||||
+34
-26
@@ -221,13 +221,13 @@ func validateConfig(config Config) error {
|
||||
}
|
||||
|
||||
func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logger, config *Config) {
|
||||
if os.Getenv("SIGNOZ_LOCAL_DB_PATH") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SIGNOZ_LOCAL_DB_PATH is deprecated and scheduled for removal. Please use SIGNOZ_SQLSTORE_SQLITE_PATH instead.")
|
||||
config.SQLStore.Sqlite.Path = os.Getenv("SIGNOZ_LOCAL_DB_PATH")
|
||||
if os.Getenv("O11Y_LOCAL_DB_PATH") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env O11Y_LOCAL_DB_PATH is deprecated and scheduled for removal. Please use O11Y_SQLSTORE_SQLITE_PATH instead.")
|
||||
config.SQLStore.Sqlite.Path = os.Getenv("O11Y_LOCAL_DB_PATH")
|
||||
}
|
||||
|
||||
if os.Getenv("CONTEXT_TIMEOUT") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env CONTEXT_TIMEOUT is deprecated and scheduled for removal. Please use SIGNOZ_APISERVER_TIMEOUT_DEFAULT instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env CONTEXT_TIMEOUT is deprecated and scheduled for removal. Please use O11Y_APISERVER_TIMEOUT_DEFAULT instead.")
|
||||
contextTimeoutDuration, err := time.ParseDuration(os.Getenv("CONTEXT_TIMEOUT") + "s")
|
||||
if err == nil {
|
||||
config.APIServer.Timeout.Default = contextTimeoutDuration
|
||||
@@ -237,7 +237,7 @@ func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logge
|
||||
}
|
||||
|
||||
if os.Getenv("CONTEXT_TIMEOUT_MAX_ALLOWED") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env CONTEXT_TIMEOUT_MAX_ALLOWED is deprecated and scheduled for removal. Please use SIGNOZ_APISERVER_TIMEOUT_MAX instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env CONTEXT_TIMEOUT_MAX_ALLOWED is deprecated and scheduled for removal. Please use O11Y_APISERVER_TIMEOUT_MAX instead.")
|
||||
|
||||
contextTimeoutDuration, err := time.ParseDuration(os.Getenv("CONTEXT_TIMEOUT_MAX_ALLOWED") + "s")
|
||||
if err == nil {
|
||||
@@ -248,27 +248,35 @@ func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logge
|
||||
}
|
||||
|
||||
if os.Getenv("STORAGE") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env STORAGE is deprecated and scheduled for removal. Please use SIGNOZ_TELEMETRYSTORE_PROVIDER instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env STORAGE is deprecated and scheduled for removal. Please use O11Y_TELEMETRYSTORE_PROVIDER instead.")
|
||||
config.TelemetryStore.Provider = os.Getenv("STORAGE")
|
||||
}
|
||||
|
||||
if os.Getenv("ClickHouseUrl") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env ClickHouseUrl is deprecated and scheduled for removal. Please use SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN instead.")
|
||||
config.TelemetryStore.Clickhouse.DSN = os.Getenv("ClickHouseUrl")
|
||||
if os.Getenv("DatastoreUrl") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env DatastoreUrl is deprecated and scheduled for removal. Please use O11Y_DATASTORE_DSN instead.")
|
||||
config.TelemetryStore.Clickhouse.DSN = os.Getenv("DatastoreUrl")
|
||||
}
|
||||
|
||||
// O11Y_DATASTORE_DSN is the canonical, flat operator-facing key for the Hanzo
|
||||
// Datastore connection. It takes precedence over the structured
|
||||
// O11Y_TELEMETRYSTORE_DATASTORE_DSN (telemetrystore.datastore.dsn), which stays
|
||||
// as an internal fallback.
|
||||
if dsn := os.Getenv("O11Y_DATASTORE_DSN"); dsn != "" {
|
||||
config.TelemetryStore.Clickhouse.DSN = dsn
|
||||
}
|
||||
|
||||
if os.Getenv("INVITE_EMAIL_TEMPLATE") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env INVITE_EMAIL_TEMPLATE is deprecated and scheduled for removal. Please use SIGNOZ_EMAILING_TEMPLATES_DIRECTORY instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env INVITE_EMAIL_TEMPLATE is deprecated and scheduled for removal. Please use O11Y_EMAILING_TEMPLATES_DIRECTORY instead.")
|
||||
config.Emailing.Templates.Directory = path.Dir(os.Getenv("INVITE_EMAIL_TEMPLATE"))
|
||||
}
|
||||
|
||||
if os.Getenv("SMTP_ENABLED") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_ENABLED is deprecated and scheduled for removal. Please use SIGNOZ_EMAILING_ENABLED instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_ENABLED is deprecated and scheduled for removal. Please use O11Y_EMAILING_ENABLED instead.")
|
||||
config.Emailing.Enabled = os.Getenv("SMTP_ENABLED") == "true"
|
||||
}
|
||||
|
||||
if os.Getenv("SMTP_HOST") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_HOST is deprecated and scheduled for removal. Please use SIGNOZ_EMAILING_ADDRESS instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_HOST is deprecated and scheduled for removal. Please use O11Y_EMAILING_ADDRESS instead.")
|
||||
if os.Getenv("SMTP_PORT") != "" {
|
||||
config.Emailing.SMTP.Address = os.Getenv("SMTP_HOST") + ":" + os.Getenv("SMTP_PORT")
|
||||
} else {
|
||||
@@ -277,49 +285,49 @@ func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logge
|
||||
}
|
||||
|
||||
if os.Getenv("SMTP_PORT") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_PORT is deprecated and scheduled for removal. Please use SIGNOZ_EMAILING_ADDRESS instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_PORT is deprecated and scheduled for removal. Please use O11Y_EMAILING_ADDRESS instead.")
|
||||
}
|
||||
|
||||
if os.Getenv("SMTP_USERNAME") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_USERNAME is deprecated and scheduled for removal. Please use SIGNOZ_EMAILING_AUTH_USERNAME instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_USERNAME is deprecated and scheduled for removal. Please use O11Y_EMAILING_AUTH_USERNAME instead.")
|
||||
config.Emailing.SMTP.Auth.Username = os.Getenv("SMTP_USERNAME")
|
||||
}
|
||||
|
||||
if os.Getenv("SMTP_PASSWORD") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_PASSWORD is deprecated and scheduled for removal. Please use SIGNOZ_EMAILING_AUTH_PASSWORD instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_PASSWORD is deprecated and scheduled for removal. Please use O11Y_EMAILING_AUTH_PASSWORD instead.")
|
||||
config.Emailing.SMTP.Auth.Password = os.Getenv("SMTP_PASSWORD")
|
||||
}
|
||||
|
||||
if os.Getenv("SMTP_FROM") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_FROM is deprecated and scheduled for removal. Please use SIGNOZ_EMAILING_FROM instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env SMTP_FROM is deprecated and scheduled for removal. Please use O11Y_EMAILING_FROM instead.")
|
||||
config.Emailing.SMTP.From = os.Getenv("SMTP_FROM")
|
||||
}
|
||||
|
||||
if os.Getenv("SIGNOZ_SAAS_SEGMENT_KEY") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SIGNOZ_SAAS_SEGMENT_KEY is deprecated and scheduled for removal. Please use SIGNOZ_ANALYTICS_SEGMENT_KEY instead.")
|
||||
config.Analytics.Segment.Key = os.Getenv("SIGNOZ_SAAS_SEGMENT_KEY")
|
||||
if os.Getenv("O11Y_SAAS_SEGMENT_KEY") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env O11Y_SAAS_SEGMENT_KEY is deprecated and scheduled for removal. Please use O11Y_ANALYTICS_SEGMENT_KEY instead.")
|
||||
config.Analytics.Segment.Key = os.Getenv("O11Y_SAAS_SEGMENT_KEY")
|
||||
}
|
||||
|
||||
if os.Getenv("TELEMETRY_ENABLED") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env TELEMETRY_ENABLED is deprecated and scheduled for removal. Please use SIGNOZ_ANALYTICS_ENABLED instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env TELEMETRY_ENABLED is deprecated and scheduled for removal. Please use O11Y_ANALYTICS_ENABLED instead.")
|
||||
config.Analytics.Enabled = os.Getenv("TELEMETRY_ENABLED") == "true"
|
||||
}
|
||||
|
||||
if os.Getenv("USE_SPAN_METRICS") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env USE_SPAN_METRICS is deprecated and scheduled for removal. Please use SIGNOZ_FLAGGER_CONFIG_BOOLEAN_USE__SPAN__METRICS instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env USE_SPAN_METRICS is deprecated and scheduled for removal. Please use O11Y_FLAGGER_CONFIG_BOOLEAN_USE__SPAN__METRICS instead.")
|
||||
if config.Flagger.Config.Boolean == nil {
|
||||
config.Flagger.Config.Boolean = make(map[string]bool)
|
||||
}
|
||||
config.Flagger.Config.Boolean[flagger.FeatureUseSpanMetrics.String()] = os.Getenv("USE_SPAN_METRICS") == "true"
|
||||
}
|
||||
|
||||
if os.Getenv("SIGNOZ_JWT_SECRET") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env SIGNOZ_JWT_SECRET is deprecated and scheduled for removal. Please use SIGNOZ_TOKENIZER_JWT_SECRET instead.")
|
||||
config.Tokenizer.JWT.Secret = os.Getenv("SIGNOZ_JWT_SECRET")
|
||||
if os.Getenv("O11Y_JWT_SECRET") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env O11Y_JWT_SECRET is deprecated and scheduled for removal. Please use O11Y_TOKENIZER_JWT_SECRET instead.")
|
||||
config.Tokenizer.JWT.Secret = os.Getenv("O11Y_JWT_SECRET")
|
||||
}
|
||||
|
||||
if os.Getenv("KAFKA_SPAN_EVAL") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env KAFKA_SPAN_EVAL is deprecated and scheduled for removal. Please use SIGNOZ_FLAGGER_CONFIG_BOOLEAN_KAFKA__SPAN__EVAL instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env KAFKA_SPAN_EVAL is deprecated and scheduled for removal. Please use O11Y_FLAGGER_CONFIG_BOOLEAN_KAFKA__SPAN__EVAL instead.")
|
||||
if config.Flagger.Config.Boolean == nil {
|
||||
config.Flagger.Config.Boolean = make(map[string]bool)
|
||||
}
|
||||
@@ -327,7 +335,7 @@ func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logge
|
||||
}
|
||||
|
||||
if os.Getenv("RULES_EVAL_DELAY") != "" {
|
||||
logger.WarnContext(ctx, "[Deprecated] env RULES_EVAL_DELAY is deprecated and scheduled for removal. Please use SIGNOZ_RULER_EVAL__DELAY instead.")
|
||||
logger.WarnContext(ctx, "[Deprecated] env RULES_EVAL_DELAY is deprecated and scheduled for removal. Please use O11Y_RULER_EVAL__DELAY instead.")
|
||||
if d, err := time.ParseDuration(os.Getenv("RULES_EVAL_DELAY")); err == nil {
|
||||
config.Ruler.EvalDelay = d
|
||||
} else {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/hanzoai/o11y/pkg/config/configtest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// This is a test to ensure that all fields of config implement the factory.Config interface and are valid with
|
||||
@@ -16,3 +17,15 @@ func TestValidateConfig(t *testing.T) {
|
||||
_, err := NewConfig(context.Background(), logger, configtest.NewResolverConfig())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// O11Y_DATASTORE_DSN is the canonical, flat operator-facing key: it must map into
|
||||
// the telemetrystore datastore DSN via mergeAndEnsureBackwardCompatibility.
|
||||
func TestDatastoreDSNCanonicalAlias(t *testing.T) {
|
||||
const dsn = "tcp://datastore.hanzo.svc:9000/?database=o11y"
|
||||
t.Setenv("O11Y_DATASTORE_DSN", dsn)
|
||||
|
||||
logger := slog.New(slog.DiscardHandler)
|
||||
config, err := NewConfig(context.Background(), logger, configtest.NewResolverConfig())
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, dsn, config.TelemetryStore.Clickhouse.DSN)
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ type Config struct {
|
||||
// Connection is the connection configuration
|
||||
Connection ConnectionConfig `mapstructure:",squash"`
|
||||
|
||||
// Clickhouse is the clickhouse configuration
|
||||
Clickhouse ClickhouseConfig `mapstructure:"clickhouse"`
|
||||
// Clickhouse is the datastore (ClickHouse-protocol) configuration
|
||||
Clickhouse ClickhouseConfig `mapstructure:"datastore"`
|
||||
}
|
||||
|
||||
type ConnectionConfig struct {
|
||||
|
||||
@@ -13,11 +13,11 @@ import (
|
||||
)
|
||||
|
||||
func TestNewWithEnvProvider(t *testing.T) {
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN", "tcp://localhost:9000")
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_MAX__IDLE__CONNS", "60")
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_MAX__OPEN__CONNS", "150")
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_DIAL__TIMEOUT", "5s")
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DEBUG", "true")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_DATASTORE_DSN", "tcp://localhost:9000")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_MAX__IDLE__CONNS", "60")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_MAX__OPEN__CONNS", "150")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_DIAL__TIMEOUT", "5s")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_DATASTORE_DEBUG", "true")
|
||||
|
||||
conf, err := config.New(
|
||||
context.Background(),
|
||||
@@ -50,11 +50,11 @@ func TestNewWithEnvProvider(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewWithEnvProviderWithQuerySettings(t *testing.T) {
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_SETTINGS_MAX__EXECUTION__TIME", "10")
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_SETTINGS_MAX__EXECUTION__TIME__LEAF", "10")
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_SETTINGS_TIMEOUT__BEFORE__CHECKING__EXECUTION__SPEED", "10")
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_SETTINGS_MAX__BYTES__TO__READ", "1000000")
|
||||
t.Setenv("SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_SETTINGS_MAX__RESULT__ROWS", "10000")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_DATASTORE_SETTINGS_MAX__EXECUTION__TIME", "10")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_DATASTORE_SETTINGS_MAX__EXECUTION__TIME__LEAF", "10")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_DATASTORE_SETTINGS_TIMEOUT__BEFORE__CHECKING__EXECUTION__SPEED", "10")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_DATASTORE_SETTINGS_MAX__BYTES__TO__READ", "1000000")
|
||||
t.Setenv("O11Y_TELEMETRYSTORE_DATASTORE_SETTINGS_MAX__RESULT__ROWS", "10000")
|
||||
|
||||
conf, err := config.New(
|
||||
context.Background(),
|
||||
|
||||
@@ -46,7 +46,7 @@ func New(ctx context.Context, providerSettings factory.ProviderSettings, config
|
||||
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/hanzoai/o11y/pkg/tokenizer/jwttokenizer")
|
||||
|
||||
if config.JWT.Secret == "" {
|
||||
settings.Logger().ErrorContext(ctx, "🚨 CRITICAL SECURITY ISSUE: No JWT secret key specified!", slog.String("error", "SIGNOZ_TOKENIZER_JWT_SECRET environment variable is not set. This has dire consequences for the security of the application. Without a JWT secret, user sessions are vulnerable to tampering and unauthorized access. Please set the SIGNOZ_TOKENIZER_JWT_SECRET environment variable immediately. For more information, please refer to https://github.com/hanzoai/o11y/issues/8400."))
|
||||
settings.Logger().ErrorContext(ctx, "🚨 CRITICAL SECURITY ISSUE: No JWT secret key specified!", slog.String("error", "O11Y_TOKENIZER_JWT_SECRET environment variable is not set. This has dire consequences for the security of the application. Without a JWT secret, user sessions are vulnerable to tampering and unauthorized access. Please set the O11Y_TOKENIZER_JWT_SECRET environment variable immediately. For more information, please refer to https://github.com/hanzoai/o11y/issues/8400."))
|
||||
}
|
||||
|
||||
lastObservedAtCache, err := ristretto.NewCache(&ristretto.Config[string, map[valuer.UUID]time.Time]{
|
||||
|
||||
Reference in New Issue
Block a user