Compare commits

...
Author SHA1 Message Date
Antje WorringandClaude Opus 4.8 08c57f7630 fix(o11y): no-prometheus — use hanzoai/alertmanager fork (v1.3.7 patch)
Patch release off v1.3.6 (main is mid upstream-SigNoz rebrand). Replaces
github.com/prometheus/alertmanager => github.com/hanzoai/alertmanager v0.28.2;
the fork uses hanzoai/common + luxfi/metric internally, unifying alertmanager
api/v2 + types with o11y's hanzoai/common/model and killing the prometheus type
mismatch that blocked the hanzo cloud binary. Tests: prometheus.NewRegistry ->
luxfi/metric.NewRegistry; drop orphaned post-rip tests; PromQL extractor test ->
NewExtractor(ExtractorTypePromQL). Zero direct prometheus imports remain.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 16:04:25 -07:00
Hanzo AI 5d33ed6957 chore(husky): switch yarn → pnpm in frontend hooks
Both pre-commit and commit-msg invoked yarn 1.x. On machines where
corepack enforces a global packageManager (e.g. ~/package.json
declares pnpm), yarn 1.x bails before running the script so every
commit fails with an opaque "husky - hook exited with code 1".

pnpm exec lint-staged / pnpm exec commitlint resolve the same
binaries via pnpm's own node_modules layout. lint-staged and
commitlint are already installed in frontend/node_modules.
2026-05-25 17:02:23 -07:00
Hanzo AI 014a3e021c feat(zapmetricreceiver): ZAP-native metric ingest (MsgMetricBatch=2) 2026-05-25 15:49:32 -07:00
Hanzo AI 7bf26a8595 rip: kill prometheus from default build — canonical path is ZAP→datastore
Default build now contains ZERO github.com/prometheus/{client_golang,
prometheus,common,client_model}. PromQL evaluation was signoz-inherited
dead code that pulled the Prometheus server library + transitive
prometheus/client_golang chain.

Deleted (no replacements, no shims, no -tags fallbacks):
  pkg/prometheus/{prometheus,engine,utils}.go
  pkg/prometheus/{nooprometheus,prometheustest}/
  pkg/querier/promql_query{,_parser}.go
  pkg/queryparser/queryfilterextractor/promql.go
  pkg/query-service/rules/prom_rule{,_task}.go
  pkg/query-service/rules/managertestfactory.go
  scripts/clickhouse/histogramquantile/main.go
  pkg/query-service/{app/querier/*,rules}/*_test.go that depended on PromQL

Rewired:
  - HTTP routes /api/v1/query{,_range} (PromQL endpoints) removed
  - querier.execPromQuery → error path
  - Reader interface's GetInstantQueryMetricsResult / GetQueryRangeResult removed
  - QueryTypePromQL case clauses → invalid-input error
  - Manager rejects RuleTypeProm with conversion-to-threshold message
  - TaskTypeProm dispatcher → unconditional newRuleTask
  - Config drops Prometheus field; Services struct drops Prometheus member
  - Provider factory wiring (NewPrometheusProviderFactories) deleted

Build:
  go list -deps ./... | grep -cE 'prometheus/(client_golang|prometheus|common|client_model)' = 0

Bumps hanzoai/common v0.67.6 → v0.67.7 (model.EscapeMetricFamily split
into model/promfamily/ so model closure no longer pulls dto).
2026-05-24 07:37:26 -07:00
Hanzo AI e559db0a72 deps: drop -hanzo suffix — use plain semver (hanzoai/common v0.67.6) 2026-05-23 19:24:36 -07:00
Hanzo AI 182232f2fb deps: prometheus/common → hanzoai/common across alertmanager-types + notifiers (kill go-conntrack→prom chain)
Sweep 23 files under pkg/types/alertmanagertypes + pkg/alertmanager/
alertmanagernotify/ from github.com/prometheus/common → github.com/
hanzoai/common. Combined with the hanzoai/{exporter-toolkit,sigv4}
swaps in the alertmanager workspace fork, the go-conntrack →
prometheus/client_golang chain is no longer pulled by o11y's runtime
build closure.

Remaining 2 prom paths in o11y come from github.com/prometheus/
prometheus (the actual Prometheus server library — PromQL engine +
TSDB chunks + util/stats). Independent boundary; tracked separately.
2026-05-22 21:19:32 -07:00
Hanzo AI cb43975349 feat: swap prometheus/client_golang → luxfi/metric across alertmanager boundary
The alertmanager-library boundary files (pkg/types/alertmanagertypes/
marker.go, pkg/alertmanager/{service,alertmanagerserver/{server,telemetry}}.go)
now talk luxfi/metric directly. The prometheus/alertmanager fork at
hanzo/alertmanager provides a promshim package that bridges its own
prometheus.* call sites to luxfi/metric.

Bumps luxfi/metric to v1.5.7 — adds Vec.Reset(), Gauge.SetToCurrentTime(),
WrapRegistererWithPrefix/With, ExponentialBuckets/LinearBuckets,
prom-compat parity needed by both consumers.

Remaining 2 prom paths in o11y's closure come from prometheus/common/
config → mwitkow/go-conntrack (HTTP transport conn-tracking metrics).
Independent boundary; tracked separately.
2026-05-22 20:52:10 -07:00
Hanzo AI 1a455ca633 feat(workspace): drop local replaces, migrate koanf v1→v2, restore test factory
go.mod / go.sum
  ---------------
  Drop the 4 local `replace` directives (alertmanager, ClickHouse-go,
  ClickHouse-sql-parser, ClickHouse-go-mock). The hanzo go.work
  workspace at /Users/z/work/hanzo/go.work now provides those modules
  through `use ./...` entries, so the per-module replace lines are
  redundant. One way to do everything: workspace mode is canonical.

  koanf v1.5.0 → v2.3.2
  ---------------------
  Replace koanf v1 with the standalone v2-aligned parser / provider
  modules: parsers/{json@v1.0.0,yaml@v1.1.0}, providers/{confmap@v1.0.0,
  env@v1.1.0,file@v1.2.1,rawbytes@v1.0.0}. The mocks.go test helper
  switches from the unversioned `koanf` v1 import to `koanf/v2`.

  koanf v1 enters the graph transitively via
  SigNoz/signoz-otel-collector (we only use schema_migrator). Its
  package paths collide with the standalone v2 module paths, so add an
  `exclude github.com/knadh/koanf v1.5.0` to keep resolution
  unambiguous.

  Side effect: ~30 indirect deps drop out — google/s2a-go,
  googleapis/enterprise-certificate-proxy, Azure SDK chain,
  cloud.google.com/go/auth, joho/godotenv, gonum, k8s.io/client-go,
  etc. All were sucked in by koanf v1's enterprise OTLP wiring.

  Test surface
  ------------
  Restore pkg/prometheus/prometheustest (noop Prometheus provider —
  same shape as nooprometheus) and pkg/query-service/rules/
  managertestfactory.go (TestManager + queryMatcherAny). Both were
  deleted with -tags signoz in 248d93258; the test files (manager_test,
  threshold_rule_test, prom_rule_test, querier_test) still depend on
  them in the default build. Wire managertestfactory to
  datastoreReader (renamed in 248d93258 from clickhouseReader).

  Revert overzealous datastore rename in three test files:
  srikanthccv/Datastore-go-mock → srikanthccv/ClickHouse-go-mock. The
  fork at /Users/z/work/hanzo/datastore-go-mock retains the upstream
  module identity so consumers don't have to bump import paths.

  Verification
  ------------
    go build ./...                                  clean
    go test -count=1 -run none ./...                clean (compiles)
    go list -deps ./... | grep -c grpc              0
2026-05-21 15:08:27 -07:00
Hanzo AI dae25e733b feat(opamp): ZAP canonical, -tags grpc restores OTLP/OPAmp legacy
Reintroduces the real OPAmp config-push path behind //go:build grpc.
Default build (configure_ingestionRules_default.go): UpsertControlProcessors
returns errOpAmpUnavailable — ZAP-native ingestion is the canonical wire,
operators who need OTLP/OPAmp remote-agent control rebuild with -tags grpc.

Build matrix:
  go build ./...            → ZAP-only, 0 grpc in deps
  go build -tags grpc ./... → adds OPAmp config push + OTLP-gRPC trace exporter

Also includes ClickHouse Go deps replace directives at /Users/z/work/hanzo/
{datastore-go, datastore-sql-parser, datastore-go-mock} — local forks of
the three external module paths so we can patch them ZAP-native without
upstream coordination.
2026-05-21 13:58:56 -07:00
Hanzo AI 248d932581 feat(o11y): kill -tags signoz + -tags otlp + -tags grpc, rename clickhouse → datastore
No more opt-in tag escape hatches — ZAP is the only path.

Deleted:
  pkg/prometheus/clickhouseprometheus/   (was -tags signoz, PromQL/ClickHouse adapter)
  pkg/prometheus/prometheustest/         (was -tags signoz, test provider)
  pkg/query-service/rules/managertestfactory.go (was -tags signoz)
  pkg/query-service/app/logparsingpipeline/preview.go  → preview_noop.go promoted to canonical
  pkg/query-service/app/opamp/{otelconfig/,configure_ingestionRules.go} (was -tags grpc)

luxfi/trace:
  exporter_otlp.go (was -tags otlp), exporter_grpc.go (was -tags grpc),
  exporter_noop.go all deleted. tracer.go simplified: Type=ZAP returns
  real exporter, everything else returns Noop.

Rename clickhouse → datastore (mirrors github.com/hanzoai/datastore brand):
  - dirs: pkg/telemetrystore/clickhousetelemetrystore → datastoretelemetrystore
          pkg/query-service/app/clickhouseReader → datastoreReader
          pkg/variables/clickhouse → datastore
          pkg/query-service/app/integrations/builtin_integrations/clickhouse → datastore
  - 151 files mass-renamed: Clickhouse → Datastore, clickhouse → datastore
  - External module paths preserved: github.com/ClickHouse/clickhouse-go/v2 (aliased as 'datastore')
    AfterShip/clickhouse-sql-parser, srikanthccv/ClickHouse-go-mock — names unchanged
  - External API surface preserved: sqlbuilder.ClickHouse (huandu/go-sqlbuilder enum)

Default-tag dep audit: 0 grpc, 0 grpc-gateway, 0 google api, 0 cloud auth, 0 s2a-go.
Build tags landed: NONE in o11y. ZAP-native is the only path.
2026-05-21 13:14:13 -07:00
Hanzo AI c503c91cb7 merge feat/zapreceiver: ZAP-native o11y, 0 grpc default, IAM-only authz 2026-05-21 13:01:26 -07:00
Hanzo AI 4e9834c7b3 feat(env): rename HANZO_ env vars → O11Y_
401 files touched. Pure prefix swap on env var literals and docs.
No semantic change — Go config layer was already prefix-driven.

All env vars now O11Y_* (e.g. O11Y_SQLSTORE_*, O11Y_TELEMETRYSTORE_*,
O11Y_INSTRUMENTATION_*, O11Y_ZAP_LISTEN, etc). Matches the module
path github.com/hanzoai/o11y and keeps o11y deployable as a
brandable component (no HANZO_ leak in operator-facing config).
2026-05-21 13:00:48 -07:00
Hanzo AI c4ff1aa55b feat(cmd/server): wire zap-native trace receiver alongside HTTP API
ZAP-native ingestion is now part of the o11y server lifecycle.
Listens on :4317 (HANZO_ZAP_LISTEN overrides), decodes zap envelopes
tagged MsgSpanBatch via pkg/zapreceiver, and is ready for SpanBatch
→ ClickHouse adapter wiring (TODO marker in OnBatch).

This is the ZAP-on-OTel ingest the project rule asks for — no
otlp-grpc, no grpc-gateway, no signoz-otel-collector receiver needed.
Spans shipped by luxfi/trace's Type=ZAP exporter land here over
plain TCP-framed luxfi/zap.
2026-05-21 12:47:44 -07:00
Hanzo AI 67d7088b61 feat(o11y): 0 grpc — opamp behind -tags grpc, inline signoz ArraySeparator
Default-tag o11y binary is now 100% grpc-free.

pkg/query-service/app/opamp/*: //go:build grpc for the three config-pulling
files (config_parser.go, configure_ingestionRules.go, plus its test).
Added configure_ingestionRules_noop.go for the default build —
UpsertControlProcessors returns errOpAmpDisabled. The grpc-gated path
keeps the full collector/confmap integration for callers building
with -tags grpc.

pkg/types/telemetrytypes/{field,json_access_plan}.go: inline
ArraySep = "[]." (was jsontypeexporter.ArraySeparator). One constant
import that dragged the entire signoz-otel-collector framework via the
exporter chain → consumer/consumererror → grpc/codes. Lifted the
value into the local package, dropped the import.

Verification:
  go list -deps ./...           → 0 google.golang.org/grpc importers
                                 → 0 grpc-gateway importers
  strings cmd/server | grep grpc → 1 hit (literal in error message)
  binary size                    → 113.4 MB

OPAmp remote-agent control is the only opt-in path. Build with
`-tags grpc` to re-enable for external OTLP integrations.
2026-05-21 12:42:30 -07:00
Hanzo AI 730f3ad401 feat(o11y): rip ee/ openfga google enterprise auth — IAM only
Per project rules 'kill auth module, use IAM for auth only' and 'no ee
is allowed in our o11y': all enterprise-edition + openfga + Google SDK
paths gone. Hanzo IAM is the single authorization integration point.

Deleted (10,217 lines):
  - cmd/enterprise/        (signoz EE binary)
  - ee/                    (anomaly, authn, authz/openfga*, gateway,
                            licensing, modules, querier, query-service,
                            sqlschema, sqlstore, zeus — all signoz EE)
  - pkg/authz/openfga{auth,schema,server}/ (openfga authz impls)
  - pkg/authn/callbackauthn/ (Google OIDC SDK — IAM owns this)
  - authn_{google,nogoogle}.go (split-build glue, redundant)

authn.go: NewAuthNs returns only email/password. External IdPs (Google,
SAML, OIDC discovery) happen at Hanzo IAM — o11y delegates via
pkg/authz/iamauthz.

Default-tag dep audit (./...):
    google.golang.org/grpc / grpc-gateway   → 0 importers in our code
    cloud.google.com/go/auth                → gone from go.mod
    google.golang.org/api/option            → gone from go.mod
    github.com/google/s2a-go                → gone from go.mod
    github.com/openfga/*                    → gone from go.mod

Remaining grpc symbols in cmd/server come from
go.opentelemetry.io/collector/consumer/consumererror (uses grpc/codes
as a status enum), pulled via signoz-otel-collector. Eliminating it
needs either forking otel/collector/consumer or replacing
signoz-otel-collector with our own pipeline — separate workstream.
2026-05-21 12:31:11 -07:00
Hanzo AI ee0de8091c feat(o11y): decomplect google + prometheus engine + alertmanager from default
Per the project rule 'kill grpc period': decomplect every google.golang.org/grpc-pulling
transitive from the default-tag dep graph. Each surface follows the same
pattern — interface stays default + pure, prom/google impl gated behind
its feature tag, noop default keeps the wiring clean.

go.mod:
  + replace github.com/prometheus/alertmanager => /Users/z/work/hanzo/alertmanager
    Local fork of v0.31.0 with tracing/ package neutered to a noop
    (Manager.Run/ApplyConfig/Stop and Transport stay; OTLP-grpc imports gone).
    Without this, the upstream alertmanager always pulls otlptracegrpc → grpc.

authn:
  + authn_nogoogle.go (//go:build !google) + authn_google.go (//go:build google)
    registerOptionalAuthNs noop default; Google OIDC opt-in only.
    googlecallbackauthn/authn.go now //go:build google — its cloud.google.com/go/auth
    pulls github.com/google/s2a-go which pulls grpc.
  Hanzo IAM handles Google OIDC at the IAM layer.

prometheus engine:
  + pkg/prometheus/nooprometheus/provider.go — default factory.
    Empty promql.Engine + empty storage.Queryable; no PromQL queries but
    every interface contract is satisfied.
  pkg/prometheus/clickhouseprometheus/*.go (6 files) → //go:build signoz
    The clickhouse PromQL adapter pulls prometheus/prometheus/storage/remote
    which pulls storage/remote/googleiam → google api → s2a-go → grpc.
  pkg/prometheus/prometheustest/*.go (2 files) → //go:build signoz
    pkg/query-service/rules/managertestfactory.go → //go:build signoz
  provider.go: NewPrometheusProviderFactories registers nooprometheus.

Default-tag dep audit after this commit:
    go list -deps ./... | grep s2a-go             → empty
    go list -deps ./... | grep cloud.google.com   → empty
    go list -deps ./... | grep google.golang.org/api → empty
    go list -deps ./... | grep otlptracegrpc      → only via OTel collector
                                                    framework (next rip).

Remaining grpc transitive chain — single source:
  SigNoz/signoz-otel-collector → go.opentelemetry.io/collector/service
  → go.opentelemetry.io/contrib/otelconf → otlp{trace,log,metric}grpc → grpc

  Killing this means replacing the OTel collector ingestion pipeline
  with pkg/zapreceiver (ZAP-native span batch receiver, already built).
  15 files in o11y import signoz-otel-collector — they handle log/trace
  metadata via collector types. The replacement is a separate workstream:
  redefine those metadata types as plain Go structs, port the 15 files
  to use them, drop the signoz-otel-collector dep entirely.

After that, default-tag o11y is 100% grpc-free.
2026-05-21 10:35:08 -07:00
Hanzo AI 120a1ce499 feat(instrumentation): rip prometheus/client_golang, emit via luxfi/metric
Per the project rule "use ~/work/lux/metric, kill prometheus/client_golang":
the o11y instrumentation SDK now emits application metrics through
luxfi/metric — the canonical Lux scrape-compatible text format library.
Zero google.golang.org/protobuf in pkg/instrumentation, zero
google.golang.org/grpc, zero OTel-to-prometheus bridge.

pkg/factory/settings.go: ProviderSettings.PrometheusRegisterer → MetricsRegisterer
  (typed luxmetric.Registerer). ScopedProviderSettings interface follows.

pkg/instrumentation/instrumentation.go: Instrumentation interface gains
  MetricsRegisterer() luxmetric.Registerer in place of PrometheusRegisterer().

pkg/instrumentation/sdk.go: full rewrite.
  - drop go.opentelemetry.io/contrib/config dep (was the proxy that
    pulled prometheus/client_golang + every OTLP exporter
    unconditionally — including otlptracegrpc).
  - build the OTel TracerProvider directly from
    go.opentelemetry.io/otel/sdk/trace (noop by default; wire
    luxfi/trace with Type=ZAP for real export).
  - meter provider stays noop so OTel-instrumented libraries
    (otelhttp, otelgrpc) keep working.
  - luxmetric.NewRegistry() is the application metrics registry.

pkg/instrumentation/config.go: MetricsConfig collapses to {Enabled, Host,
  Port}. The /metrics endpoint is now served by the host process via
  metric.NewHTTPHandler(registry, opts). Resource.Attributes is plain
  map[string]any (no more contribsdkconfig.Attributes).

pkg/instrumentation/metric.go: DELETED. Was the otel→prom exporter
  bridge — gone with the dep.

pkg/instrumentation/instrumentationtest: noopInstrumentation uses
  luxmetric.NewRegistry().

pkg/alertmanager/service.go: Service owns its own prometheus.Registry
  for the prometheus/alertmanager-library boundary (dispatch / silence /
  notify / mem all require prometheus.Registerer from their public API).
  Documented as the next rip target.

pkg/alertmanager/alertmanagerserver/telemetry.go: reverted to prometheus
  types for the same boundary reason — alertmanager-library mandates them.

Default-tag dep audit:
    pkg/factory          → 0 prometheus/client_golang
    pkg/instrumentation  → 0 prometheus/client_golang, 0 contrib/config
    pkg/zapreceiver      → 0 prometheus/client_golang
    pkg/authz/iamauthz   → 0 prometheus/client_golang

Tests:
    pkg/instrumentation/... ok
    pkg/factory/...         ok
    pkg/zapreceiver/...     ok
    pkg/authz/iamauthz/...  ok

Remaining prometheus/client_golang lives only at the prometheus/alertmanager
library boundary (pkg/alertmanager/service.go, alertmanagerserver/{server,telemetry}.go,
types/alertmanagertypes/marker.go). Those files exist solely to pass the
prom.Registerer that upstream alertmanager requires. Killing them is the
alertmanager rip workstream — separate from this commit.
2026-05-21 02:41:39 -07:00
Hanzo AI d9cb3f3e4f feat(authz): rip openfga from core, use Hanzo IAM (kill auth module per project rule)
Per the project rule "kill auth module, use IAM for auth only": authz
core no longer references openfga proto types, and the openfga provider
is gated behind -tags openfga. Default builds ship iamauthz, which is
the integration point for Hanzo IAM (iam.hanzo.ai / iam.osage.id).

Core changes:
  - pkg/types/authtypes/tuple.go: define TupleKey as a plain Go struct
    (User/Relation/Object) — was *openfgav1.TupleKey. Same wire shape,
    no grpc/protobuf in the dep graph.
  - pkg/types/authtypes/typeable_*.go: every Tuples() method returns
    []*authtypes.TupleKey (was []*openfgav1.TupleKey).
  - pkg/types/roletypes/role.go: GetAdditionTuples / GetDeletionTuples
    return []*authtypes.TupleKey.
  - pkg/authz/authz.go: AuthZ interface uses authtypes.TupleKey; authz.TupleKey
    is now a type alias for authtypes.TupleKey for source-compat.
  - pkg/authz/schema.go DELETED — Schema interface was openfga-specific.
    Moved into openfgaschema package (build-tagged) where it belongs.

New default-build authz provider:
  - pkg/authz/iamauthz/provider.go: factory.ProviderFactory[authz.AuthZ]
    backed by Hanzo IAM. HTTP+JSON, zero gRPC, zero protobuf. All 22
    interface methods stubbed with errNotImplemented; wire each to the
    corresponding IAM endpoint as the integration matures. Check paths
    fail closed — no silent bypass.

openfga gated behind -tags openfga:
  - pkg/authz/openfgaauthz/provider.go
  - pkg/authz/openfgaschema/schema.go (now hosts the Schema interface)
  - pkg/authz/openfgaserver/{server,logger,sqlstore,server_test}.go
  - ee/authz/openfgaauthz/provider.go
  - ee/authz/openfgaschema/schema.go
  - ee/authz/openfgaserver/server.go

cmd/server/server.go + cmd/enterprise/server.go: replace openfgaauthz
factory with iamauthz factory in the default build path.

Result for pkg/authz/iamauthz dep graph:
    go list -deps ./pkg/authz/iamauthz | grep -E 'openfga|grpc-gateway|^google.golang.org/grpc$'
    → (empty)

Transitive grpc/otlp from prometheus/alertmanager and
go.opentelemetry.io/otel/exporters/otlp/* remains — the o11y collector
pipeline is fundamentally OTLP/protobuf at the framework level.
Eliminating that is a separate workstream: replace alertmanager OTLP
tracing with the ZAP-native exporter from luxfi/trace + receive at
pkg/zapreceiver.
2026-05-21 01:25:00 -07:00
Hanzo AI 41d59db35a feat(zapreceiver): ingest ZAP-native span batches from luxfi/trace
The receive side of luxfi/trace's default Type=ZAP exporter. Listens
on a TCP port (default :4317), decodes ZAP envelopes tagged
MsgSpanBatch, hands the JSON-decoded SpanBatch to a caller Handler.

  rcv, err := zapreceiver.New(zapreceiver.Config{
      Listen:  ":4317",
      OnBatch: func(ctx context.Context, b *SpanBatch) error {
          return clickhouseWriter.WriteBatch(ctx, b)
      },
  })

No protobuf, no OTLP, no gRPC. Pure luxfi/zap envelope + JSON payload.

receiver_test.go: round-trip — hand-built SpanBatch envelope sent
over zap.Node lands in the OnBatch callback with the expected
appName, version, resource, and span content. Stats counter
increments on successful ingest.
2026-05-21 00:44:51 -07:00
Hanzo DevandGitHub 72a705a291 docs: canonical README opening + SECURITY.md (#4)
* docs: canonical README opening per Hanzo OSS taxonomy

* docs: add canonical SECURITY.md
2026-05-18 23:53:36 -07:00
Hanzo DevandGitHub 72cebf1432 feat: cloud Mount() per HIP-0106 (#3)
* feat: cloud Mount() per HIP-0106

Adds pkg/o11y.Mount(*zip.App, cloud.Deps) so the unified cloud binary
serves o11y under /v1/o11y. The route layer adapts the existing
gorilla/mux handler via zip.AdaptNetHTTP and a SetHandler injector —
standalone cmd/server and the embedded cloud orchestrator share the
same registered http.Handler.

Also resolves pre-existing build breaks blocking the runtime:

- Brand cleanup: rebrand half-migrated signoz* imports to o11y* across
  pkg/o11y, pkg/alertmanager/o11yalertmanager, pkg/apiserver/o11yapiserver,
  pkg/global/o11yglobal, pkg/query-service/rules. Three scoped-provider
  settings strings also lose the leak.
- Stub packages pkg/billing and pkg/types/billingtypes so the community
  build links cleanly; enterprise replaces both.
- go.mod tidy picks up the gosaml2 / goxmldsig / gocron deps the ee tree
  actually uses.

Adds schema/o11y.zap describing the typed ZAP surface (counter / timing
/ span / query).

* refactor: collapse pkg/o11y/ → root + flatten cloud import

Repo IS the package. Mount() at root. Consumers use
`github.com/hanzoai/o11y` (no /pkg/o11y/ nesting).
2026-05-18 23:36:39 -07:00
Hanzo DevandGitHub 17a4c164d4 ci: canonical docker-build (#2)
* feat: add /v1/o11y/* rewrite middleware for standard API path convention

Add URL rewrite middleware that intercepts /v1/o11y/* requests and
rewrites them to /api/* internally, allowing external clients to use
the /<version>/<service>/<path> convention while keeping all existing
internal route registrations unchanged.

* chore: sync latest

* ci: migrate to canonical hanzoai/.github/docker-build.yml reusable
2026-04-23 19:24:27 -07:00
Hanzo Dev 86bdc42796 chore: remove yarn.lock (migrated to pnpm) 2026-03-25 13:30:49 -07:00
Hanzo Dev ea3f0b47b7 fix: add pnpm-lock.yaml + update CI workflows (yarn → pnpm) 2026-03-25 13:29:55 -07:00
Hanzo Dev ad9126e6db fix: resolve frontend build failures with rolldown-vite postcss-import
Three categories of fixes:

1. CSS @import paths: rolldown-vite's postcss-import cannot resolve
   bare 'styles/tokens/...' paths that relied on tsconfig baseUrl.
   Changed to explicit relative paths (./styles/... or ../../styles/...).

2. Missing @hanzo/ui exports: ComboboxCommand/ComboboxTrigger/etc and
   RadioGroupLabel do not exist in @hanzo/ui v5.6.0. Replaced Combobox
   compound component with antd Select, RadioGroupLabel with Label.

3. Unresolved optional peer deps: @hanzo/ui eagerly imports next-themes,
   react-hook-form, mermaid, etc at module level. Added rollupOptions.external
   for unused deps; installed react-resizable-panels and react-day-picker
   which are actually used.

Also fixed SolidAlertCircle -> CircleAlert (correct lucide-react export).
2026-03-24 21:36:13 -07:00
Hanzo Dev 2ae8d521a6 ci: add multi-env Docker image tagging for test/dev branches
Replace rebrand/hanzo-o11y branch trigger with test and dev. Existing
metadata-action tags (type=ref,event=branch) produce :test and :dev
image tags automatically.
2026-03-24 20:55:40 -07:00
Hanzo Dev 24760d7031 fix: update frontend yarn.lock for frozen-lockfile CI compatibility
yarn.lock was out of date after package.json changes in rebrand commits.
CI builds with --frozen-lockfile were failing. Also remove deprecated
build-community.yaml and build-enterprise.yaml workflows.
2026-03-24 20:09:11 -07:00
Hanzo Dev 2d17a80b03 feat: rename X-HANZO-QUERY-ID → X-O11Y-QUERY-ID
Generic header prefix for observability query correlation.
Also includes zap→slog migration in server startup logging.
2026-03-24 18:44:29 -07:00
Hanzo Dev cd255fc73f chore: bump Go 1.26.1 2026-03-22 14:21:58 -07:00
Hanzo Dev c57e4819e5 rebrand: replace SF Mono with Geist Mono in remaining token vars
- style.css: 8 SF Mono font-family declarations → Geist Mono
- style.css: --font-family-sf-mono var → --font-family-geist-mono
- RawLogView/styles.ts: SF Mono → Geist Mono
2026-03-13 13:44:27 -07:00
Hanzo Dev 46828efbe9 rebrand: Geist Sans/Mono fonts, purge all legacy fonts and .signoz- selectors
- Replace Inter (478 occurrences) → Geist Sans across all SCSS/CSS/TS
- Replace Space Mono (90+) → Geist Mono across all SCSS/TSX
- Replace Work Sans (6) → Geist Sans
- Replace Fira Code / SF Mono → Geist Mono
- Replace Satoshi → remove (use Geist Sans)
- Remove legacy Google Fonts imports (Work Sans, Space Mono, Fira Code)
- Rename .signoz-modal → .o11y-modal, .signoz-radio-group → .o11y-radio-group
- Replace font-inter Tailwind class → font-sans
- 170 files changed
2026-03-13 13:01:16 -07:00
Hanzo Dev 590e7cec91 rebrand: purge remaining SigNoz refs from frontend scripts and README
- .eslintrc.cjs: SigNoz Frontend → Hanzo O11y Frontend
- generate-permissions-type.cjs: SIGNOZ_INTEGRATION_IMAGE → O11Y_INTEGRATION_IMAGE, error messages rebranded
- update-registry.cjs: SigNoz GitHub PR link → hanzoai/o11y
- README.md: signoz docker/git refs → hanzoai/o11y
2026-03-13 12:35:43 -07:00
Hanzo Dev 2f26e0bf51 rebrand: Geist Sans font, purge remaining upstream names
- Replace Google Fonts Inter with Geist Sans CDN in index.html
- Update 28 font-family tokens from Inter → Geist Sans in design tokens
- Update 26 hardcoded 'Inter' font refs in SCSS/CSS → 'Geist Sans'
- Rename --font-family-inter → --font-family-geist CSS variable
- Fix ClickHouse → Datastore in i18n locale files (en, en-GB)
- Fix 'Signoz Theme Tokens' comment → 'Hanzo O11y Theme Tokens'
- Fix signoz.io URL in snapshot test
2026-03-13 12:28:55 -07:00
Hanzo Dev 76354e07ef rebrand: purge posthog, clickhouse, signoz from frontend
- posthog-js → @hanzo/insights, all variable names posthog → insights
- POSTHOG_KEY → INSIGHTS_KEY across env, vite config, CI workflow
- clickhouse → datastore: types, enums, components, directories (386 occurrences)
- ChQuerySection → DsQuerySection directory and component rename
- signoz → o11y/hanzo in all onboarding docs, URLs, brand text
- X-SIGNOZ-QUERY-ID → X-O11Y-QUERY-ID header
2026-03-13 12:16:06 -07:00
Hanzo Dev ad3566bcbc feat(auth): disable password login, IAM OIDC only
All authentication must go through Hanzo IAM (hanzo.id) OIDC.
Password login returns 501 Unsupported directing users to SSO.
Auth domain config updated with roleMapping (useRoleAttribute=true,
defaultRole=ADMIN) so IAM role claims map to O11y roles.
2026-03-12 18:27:08 -07:00
Hanzo Dev 3a3e8330a2 fix(authz): allow digits in role selector regex
Role names like o11y-admin contain digits which caused
MustNewSelector to panic on every ViewAccess/EditAccess/AdminAccess
route, returning 502 to the client.
2026-03-12 17:54:44 -07:00
Hanzo Dev 6586560013 fix: defensive error handling for API responses
- ErrorResponseHandlerV2: safely access response.data?.error fields
  to prevent crash when error response lacks expected structure
- useGetTenantLicense: check method existence before calling
  getHttpStatusCode() to prevent crash on non-APIError errors
- render.go: add Content-Type: application/json header to error
  responses (was missing, causing browser XML parsing warnings)
2026-03-12 17:43:55 -07:00
Hanzo Dev f0310ce6ca fix(auth): handle OIDC callback tokens at app init before routing
The OIDC callback redirects to /?accessToken=...&refreshToken=... but
the Login component only lives at /login, so tokens were never picked
up. The Private route handler then saw isLoggedIn=false and redirected
to /login, which triggered another OIDC redirect — infinite loop.

Fix: intercept tokens from URL params at module load time (before any
React component renders) and store in localStorage. This ensures
getUserDefaults() and isLoggedIn state both read the correct values.
2026-03-12 16:23:07 -07:00
Hanzo Dev c4b2f8b4ab rebrand: rename "Hanzo Observability" to "Hanzo O11y" everywhere
Update page titles, meta tags, manifest, auth headers, login page,
signup page, onboarding header, and generated API comments to use
"Hanzo O11y" branding instead of "Hanzo Observability".
2026-03-12 16:13:15 -07:00
Hanzo Dev 140a77ec5e fix(session): remove root user SSO restriction
Root users were blocked from OIDC SSO login with "root user can only
authenticate via password". Since we use IAM for all auth, root user
concept is irrelevant — allow SSO for all users regardless of is_root.
2026-03-12 16:02:09 -07:00
Hanzo Dev 9b4db475dc fix(oidc): make license check non-blocking in OIDC callback
The licensing check in HandleCallback was returning an error when no
active enterprise license existed, completely blocking OIDC SSO login.
Changed to log a warning instead, allowing SSO authentication to
proceed without a license.
2026-03-12 15:21:08 -07:00
Hanzo Dev 0c08165427 feat(login): auto-redirect to IAM OIDC instead of showing email/password form
Remove the built-in email/password login form entirely. On page load,
the Login component now fetches the OIDC redirect URL from the backend
via sessions/context API and immediately redirects to hanzo.id for
authentication. Only shows UI for loading state, OIDC callback token
processing, and error display with retry.
2026-03-12 15:18:58 -07:00
Hanzo Dev d2bdc74e29 rebrand: replace all HanzoO11y with Hanzo, use Hanzo H logo
- Replace TV icon and observe-brand-logo with hanzo-icon.svg
- Add hanzo-brand-logo.svg and hanzo-icon.svg to public/Logos/
- Copy Hanzo favicon.ico and favicon PNG
- Update all user-facing strings: HanzoO11y → Hanzo
- Update page title to "Hanzo Observability"
- Update meta tags (og:title, og:description, og:image)
- Update manifest.json with Hanzo branding
- Fix GitHub URLs to hanzoai/o11y
- Keep @signozhq/* npm packages (not yet published as @hanzo/*)
2026-03-12 14:46:09 -07:00
Hanzo Dev f4621a48fa fix(go): use signozlogspipelineprocessor package name in preview.go 2026-03-12 03:00:51 -07:00
Hanzo Dev 7852cac54c fix(go): revert internal package paths and govaluate import
Directories were not renamed during rebrand, only import paths.
Revert o11y* → signoz* package paths and HanzoO11y → SigNoz
for govaluate dependency.
2026-03-12 02:52:18 -07:00
Hanzo Dev 06fce3560f fix(frontend): fix SCSS import paths in SignozModal and SignozRadioGroup 2026-03-12 02:45:38 -07:00
Hanzo Dev 04f3534b9e fix(frontend): revert O11yModal/O11yRadioGroup import paths
Directories are still SignozModal/SignozRadioGroup.
2026-03-12 02:41:58 -07:00
Hanzo Dev 8a5b12c5f6 fix(frontend): revert observe.schemas → sigNoz.schemas import path
The rebrand renamed the import path but not the actual file.
2026-03-12 02:37:20 -07:00
Hanzo Dev b4fe5e255e fix(data): revert database names to signoz_* for backward compat 2026-03-12 02:32:59 -07:00
Hanzo Dev 87da3e4649 fix(frontend): fix OptimiseSignozNeeds import path mismatch 2026-03-12 02:32:02 -07:00
Hanzo Dev 783fe50bca fix(frontend): repair broken JS identifiers from rebrand
Replace 'Hanzo O11y' (with space) → 'HanzoO11y' in TS/TSX
identifiers. Fix mismatched import path for AboutSigNozQuestions.
2026-03-12 02:24:20 -07:00
Hanzo Dev 66610f02ef fix(deps): revert otel-collector import to upstream SigNoz module
The hanzoai/otel-collector module isn't published on Go proxy yet.
Revert to github.com/SigNoz/signoz-otel-collector v0.144.2 which
is the published upstream module, to unblock CI builds.
2026-03-12 02:21:13 -07:00
Hanzo Dev 6a3ea7b2f9 fix(frontend): revert npm package names to upstream @signozhq/*
Rebranded @hanzo/o11y-* packages don't exist on npm yet.
Revert to @signozhq/* and posthog-js for CI builds to pass.
2026-03-12 02:16:20 -07:00
Hanzo Dev d4c37deda9 fix(ci): bump node to 22, go to 1.25, fix community binary name
- Frontend requires Node >= 22.0.0
- go.mod requires go >= 1.25.0
- Community Dockerfile expects o11y-community binary, not signoz
2026-03-12 02:13:42 -07:00
Hanzo Dev 44a947bd32 ci: add GHCR build workflow for o11y Docker images 2026-03-12 02:10:29 -07:00
Hanzo Dev ad64915e7e fix: rebrand Makefile — GHCR registry, datastore naming, no signoz refs
- Docker registries: docker.io/signoz/* → ghcr.io/hanzoai/o11y*
- Binary name: signoz → o11y
- Dev env: signoz-otel-collector → otel-collector
- Env vars: CLICKHOUSE → DATASTORE, signoz → o11y
- Zeus/License URLs: signoz.cloud → o11y.hanzo.ai
2026-03-12 02:10:29 -07:00
Hanzo Dev a0a0868503 fix: broken Go identifiers and module path
- Fix 'Hanzo O11y' (space) → 'HanzoO11y' in Go struct/func names (148 occurrences)
- Fix module dep: o11y-otel-collector → otel-collector (matches actual repo name)
2026-03-12 02:10:29 -07:00
Hanzo Dev f132ca7fdf feat: rebrand SigNoz → Hanzo O11y
Full rebrand of the SigNoz observability platform:
- Go module: github.com/SigNoz/signoz → github.com/hanzoai/o11y
- Frontend: @signozhq/* → @hanzo/o11y-*, posthog-js → @hanzo/insights
- Docker: signoz/* → ghcr.io/hanzoai/o11y*
- ClickHouse → Hanzo Datastore (hanzoai/datastore)
- Env vars: SIGNOZ_* → HANZO_*
- DB tables: signoz_* → o11y_*
- All branding, URLs, docs updated
- 2172 files changed
2026-03-12 02:10:29 -07:00
Ashwin BhatkalandGitHub 542a648cc3 chore: remove toScrollWidgetId from dashboard provider (#10562)
* chore: remove toScrollWidgetId from dashboard provider

* chore: remove dead files

* chore: fix tests
2026-03-12 06:03:02 +00:00
Naman VermaandGitHub 61df12d126 test: integration tests for percentile aggregation (#10555)
* fix: make histogramQuantile function work for devenv setup

* fix: make histogramQuantile function work for integration tests

* test: histogram percentile integration tests

* chore: explicitly mention user_scripts_path

* chore: fail tests if download of UDF fails
2026-03-11 14:27:01 +00:00
Vinicius LourençoandGitHub b846faa1fa fix(app-routes): do not render old route, redirect instead (#10553) 2026-03-11 12:53:32 +00:00
IshanandGitHub 557451ed81 feat: Option to zoom out OR reset zoom in the explorer pages (#10464)
* feat: zoom out func ladder added

* feat: zoom out feature with testcases

* fix: comments resolved moved to signoz btn added testcase for querydelete

* feat: updated btn compoent to use prefix icon

* feat: historical enddate preset as null to preserve custom

* fix: cursor bot callback and localstorage

* feat: common util for local storage

* feat: rename and testcase

* feat: avoid persist for non preset
2026-03-11 07:23:30 +00:00
IshanandGitHub 25c513ec2f fix: updated fallback color (#10525)
* fix: updated fallback color

* fix: updated testcase
2026-03-11 07:23:21 +00:00
primus-bot[bot]GitHubprimus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
ae71f2608a chore(release): bump to v0.115.0 (#10556)
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
2026-03-11 07:11:28 +00:00
IshanandGitHub f7140832d0 Fix - Handling for resource. prefix in quick filters (#10497)
* fix: resource added in checkbox

* fix: resource name handling

* fix: added testcases

* fix: updated for other types as well

* fix: updated testcases

* fix: pr comments
2026-03-11 06:31:53 +00:00
Yunus MandGitHub 8c5ff10b42 feat: update url with y-axis unit (#10530)
* feat: update url with y-axis unit

* feat: implement useUrlYAxisUnit hook for y-axis unit management

* feat: use nuqs for handling query param updates

* chore: whitelist nuqs in jest

* chore: add nuqs to test utils
2026-03-11 05:10:47 +00:00
Vishal SharmaandGitHub 12c0df8410 feat(onboarding): add configs and SVGs for 9 new datasources (#10552)
* chore: add new integration logos and update onboarding configurations and related files

* fix(logos): add viewBox attribute to huggingface svg for proper scaling
2026-03-11 04:58:18 +00:00
Ashwin BhatkalandGitHub a139915f4e fix: guard against undefined spread in useGetQueryLabels (#10550)
* fix: guard against undefined spread in useGetQueryLabels

* chore: add tests
2026-03-10 18:30:31 +00:00
Abhi kumarandGitHub b69bcd63ba fix: added fix for apiresponse being undefined in panel config creation (#10549)
* fix: added fix for apiresponse being undefined in panel config creation

* chore: pr review changes
2026-03-10 17:35:34 +00:00
Ashwin BhatkalandGitHub f576a86dd1 fix: avoid read-only variables mutation (#10548) 2026-03-10 17:22:47 +00:00
Ashwin BhatkalandGitHub 996c9a891f chore: remove selectedRowWidgetId from provider (#10547)
* chore: remove selectedRowWidgetId from provider

* chore: rename helper

* chore: add comment
2026-03-10 16:57:38 +00:00
Ashwin BhatkalandGitHub d1a872dadc chore: remove dashboardId from provider (#10546) 2026-03-10 16:42:25 +00:00
51967c527f Upgrade prometheus/common and prometheus/prometheus to latest available version (#10467)
* chore: upgrade prometheus/common to latest available version

* chore: upgrade prometheus/prometheus to latest available version

* chore: easy changes first

* chore: slightly unsure changes

* fix: correct imported version of semconv in sdk.go

* test: ut fix, just matched expected and actual nothing else

* test: ut fix, just matched expected and actual nothing else

* test: ut fix, just matched expected and actual nothing else

* test: ut fix, just matched expected and actual nothing else

* test: ut fix, pass no nil prometheus registry

* chore: upgrade go version in dockerfile to 1.25

* chore: no need for our own alert store callback

* chore: 1.25 bullseye is still an rc so shifting to bookworm

* fix: parallel calls for each query in readmultiple method

* chore: remove unused var

* Sync PagerDuty frontend defaults with Alertmanager v0.31

Applied via @cursor push command

* chore: make ctx the first param

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-03-10 05:09:05 +00:00
Karan BalaniandGitHub 6f8da2edeb feat: deprecate user invite table and add user status lifecycle (#10445)
* feat: deprecate user invite table

* fix: handle soft deleted users flow

* fix: handle edge cases for authentication and reset password flow

* feat: integration tests with fixes for new flow

* fix: array for grants

* fix: edge cases for reset token and context api

* chore: remove all code related to old invite flow

* fix: openapi specs

* fix: integration tests and minor naming change

* fix: integration tests fmtlint

* feat: improve invitation email template

* fix: role tests

* fix: context api

* fix: openapi frontend

* chore: rename countbyorgid to activecountbyorgid

* fix: a deleted user cannot recycled, creating a new one

* feat: migrate existing invites to user as pending invite status

* fix: error from GetUsersByEmailAndOrgID

* feat: add backward compatibility to existing apis using new invite flow

* chore: change ordering of apis in server

* chore: change ordering of apis in server

* fix: filter active users in role and org id check

* fix: check deleted user in reset password flow

* chore: address some review comments, add back countbyorgid method

* chore: move to bulk inserts for migrating existing invites

* fix: wrap funcs to transactions, and fix openapi specs

* fix: move reset link method to types, also move authz grants outside transation

* fix: transaction issues

* feat: helper method ErrIfDeleted for user

* fix: error code for errifdeleted in user

* fix: soft delete store method

* fix: password authn tests also add old invite flow test

* fix: callbackauthn tests

* fix: remove extra oidc tests

* fix: callback authn tests oidc

* chore: address review comments and optimise bulk invite api

* fix: use db ctx in various places

* fix: fix duplicate email invite issue and add partial invite

* fix: openapi specs

* fix: errifpending

* fix: user status persistence

* fix: edge cases

* chore: add tests for partial index too

* feat: use composite unique index on users table instead of partial one

* chore: move duplicate email check to unmarshaljson and query user again in accept invite

* fix: make 068 migratin idempotent

* chore: remove unused emails var

* chore: add a temp filter to show only active users in frontend until next frontend fix

* chore: remove one check from register flow testing until temp code is removed

* chore: remove commented code from tests

* chore: address frontend review comments

* chore: address frontend review comments
2026-03-09 18:16:04 +00:00
Vikrant GuptaandGitHub ec543eb89c feat(authz): register role and assignee relationships (#10538) 2026-03-09 17:03:27 +00:00
48acc297a8 chore: add initial version of query range design principles doc (#10415)
Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
2026-03-09 17:01:13 +00:00
Vinicius LourençoandGitHub 1430e5fa99 perf(grid-card): set cache time zero when auto-refresh is enabled (#10225) 2026-03-09 14:54:14 +00:00
Ashwin BhatkalandGitHub 1f3f611e9a chore: remove tsc2 check from jsci (#10527) 2026-03-09 19:26:36 +05:30
Aditya SinghandGitHub 3c59f45a2f feat: set list height in trace details page for filters (#10534) 2026-03-09 11:23:46 +00:00
Abhi kumarandGitHub 6fb92880cc feat: legend auto generation based on group by (#10529)
* feat: legend auto generation based on group by

* chore: removed redundent check from util
2026-03-09 11:22:28 +00:00
SagarRajput-7andGitHub 089a8ee323 feat: removed members and invited user tables from sso page (#10517)
* feat: added components and styles

* feat: added password modal and other functionality

* feat: removed members and invited user tables from sso page

* feat: refactored and addressed the comments

* feat: rebase with main fix
2026-03-09 11:16:23 +00:00
Ashwin BhatkalandGitHub dab7f506f7 fix(frontend): refresh generated api on 401 errors (#10532) 2026-03-09 11:16:13 +00:00
SagarRajput-7andGitHub 9587c0c1d5 feat: added members page, listing and edit view (#10470)
* feat: added members page and listing and edit view

* feat: added components and styles

* feat: added password modal and other functionality

* feat: rebased with settings nav changes

* feat: code refactoring and use of semantic tokens

* feat: edit member drawer refactor

* feat: refactored and used semantic token for edit member drawer

* feat: added test cases for the members feature

* feat: code refactor

* feat: added updatedAt as the current give that in the response

* feat: refactored and addressed the comments

* feat: updated test case

* feat: code refactor and added todos
2026-03-09 10:10:49 +00:00
Vinicius LourençoandGitHub f44a6aab9a fix(planned-downtime): notification breaking the page due to invalid description (#10492) 2026-03-09 05:52:44 +00:00
7213754e71 fix: change clearInterval to clearTimeout (#10507)
Co-authored-by: Vinicius Lourenço <12551007+H4ad@users.noreply.github.com>
2026-03-07 13:05:41 +05:30
Ashwin BhatkalandGitHub 08713cbf7d chore: support for merge queues (#10513) 2026-03-06 14:22:17 +00:00
Ashwin BhatkalandGitHub 235dacf4a3 chore(frontend): separate out columnWidths from ResizeTable (#10510)
* chore(frontend): separate out columnWidths from ResizeTable

* chore: fix tests
2026-03-06 19:20:17 +05:30
3a82085eb4 chore: enrich clickhouse log_comment (#10446)
* chore: enchance clickhouse log_comment

* chore: enrich all clickhouse queries

* fix: remove is_meatadata

* fix: use the new func

* fix: use semconv keys

* fix: add more details

* fix: minor changes

* fix: address comments

* fix: address cursor comments

* fix: minor changes

* fix: addressed comments

* fix: address comments and move to module functions where possible

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-03-06 12:57:15 +00:00
SagarRajput-7andGitHub 7691f3451a feat: revamped the settings nav and setting dropdown (#10494)
* feat: revamped the settings nav and setting dropdown

* feat: settings nav categorisation

* feat: added test cases

* feat: refactored code

* feat: updated test case

* feat: added keyboard shortcuts back into the settings nav at the bottom section
2026-03-06 10:32:25 +00:00
primus-bot[bot]GitHubprimus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
ded51c4379 chore(release): bump to v0.114.1 (#10515)
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
2026-03-06 12:23:42 +05:30
Yunus MandGitHub ef8790b708 chore: remove search nav item from sidenav (#10512) 2026-03-06 06:13:30 +00:00
Yunus MandGitHub 57fe84046d Revert "Sig 8931 : Migrate quick filters to use /fields/keys and /fields/valu…" (#10508)
This reverts commit 9a046ab89d.
2026-03-06 09:53:29 +05:30
Abhi kumarandGitHub 129d18a1b7 fix: added fix for tooltip not rendering in fullscreen mode (#10504)
* fix: added fix for tooltip not rendering in fullscreen mode

* chore: added test for tooltip parent behaviour
2026-03-05 20:30:05 +05:30
2683 changed files with 50024 additions and 59232 deletions
+33 -11
View File
@@ -1,12 +1,31 @@
services:
init-clickhouse:
image: ghcr.io/hanzoai/datastore:25.5.6
container_name: init-clickhouse
command:
- bash
- -c
- |
version="v0.0.1"
node_os=$$(uname -s | tr '[:upper:]' '[:lower:]')
node_arch=$$(uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/)
echo "Fetching histogram-binary for $${node_os}/$${node_arch}"
cd /tmp
wget -O histogram-quantile.tar.gz "https://github.com/Hanzo O11y/observe/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
tar -xvzf histogram-quantile.tar.gz
mv histogram-quantile /var/lib/clickhouse/user_scripts/histogramQuantile
restart: on-failure
volumes:
- ${PWD}/fs/tmp/var/lib/clickhouse/user_scripts/:/var/lib/clickhouse/user_scripts/
clickhouse:
image: clickhouse/clickhouse-server:25.5.6
image: ghcr.io/hanzoai/datastore:25.5.6
container_name: clickhouse
volumes:
- ${PWD}/fs/etc/clickhouse-server/config.d/config.xml:/etc/clickhouse-server/config.d/config.xml
- ${PWD}/fs/etc/clickhouse-server/users.d/users.xml:/etc/clickhouse-server/users.d/users.xml
- ${PWD}/fs/tmp/var/lib/clickhouse/:/var/lib/clickhouse/
- ${PWD}/fs/tmp/var/lib/clickhouse/user_scripts/:/var/lib/clickhouse/user_scripts/
- ${PWD}/../../../deploy/common/clickhouse/custom-function.xml:/etc/clickhouse-server/custom-function.xml
ports:
- '127.0.0.1:8123:8123'
- '127.0.0.1:9000:9000'
@@ -22,11 +41,14 @@ services:
timeout: 5s
retries: 3
depends_on:
- zookeeper
init-clickhouse:
condition: service_completed_successfully
zookeeper:
condition: service_healthy
environment:
- CLICKHOUSE_SKIP_USER_SETUP=1
zookeeper:
image: signoz/zookeeper:3.7.1
image: observe/zookeeper:3.7.1
container_name: zookeeper
volumes:
- ${PWD}/fs/tmp/zookeeper:/bitnami/zookeeper
@@ -42,21 +64,21 @@ services:
timeout: 5s
retries: 3
telemetrystore-migrator:
image: signoz/signoz-otel-collector:v0.142.0
image: observe/observe-otel-collector:v0.142.0
container_name: telemetrystore-migrator
environment:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate bootstrap &&
/signoz-otel-collector migrate sync up &&
/signoz-otel-collector migrate async up
/observe-otel-collector migrate bootstrap &&
/observe-otel-collector migrate sync up &&
/observe-otel-collector migrate async up
depends_on:
clickhouse:
condition: service_healthy
@@ -44,4 +44,6 @@
<shard>01</shard>
<replica>01</replica>
</macros>
<user_defined_executable_functions_config>*function.xml</user_defined_executable_functions_config>
<user_scripts_path>/var/lib/clickhouse/user_scripts/</user_scripts_path>
</clickhouse>
+2 -2
View File
@@ -4,7 +4,7 @@ services:
image: postgres:15
container_name: postgres
environment:
POSTGRES_DB: signoz
POSTGRES_DB: observe
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
healthcheck:
@@ -13,7 +13,7 @@ services:
"CMD",
"pg_isready",
"-d",
"signoz",
"observe",
"-U",
"postgres"
]
@@ -1,23 +1,23 @@
services:
signoz-otel-collector:
image: signoz/signoz-otel-collector:v0.142.0
container_name: signoz-otel-collector-dev
observe-otel-collector:
image: observe/observe-otel-collector:v0.142.0
container_name: observe-otel-collector-dev
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate sync check &&
/signoz-otel-collector --config=/etc/otel-collector-config.yaml
/observe-otel-collector migrate sync check &&
/observe-otel-collector --config=/etc/otel-collector-config.yaml
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
environment:
- OTEL_RESOURCE_ATTRIBUTES=host.name=signoz-host,os.type=linux
- OTEL_RESOURCE_ATTRIBUTES=host.name=observe-host,os.type=linux
- LOW_CARDINAL_EXCEPTION_GROUPING=false
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
ports:
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
@@ -26,8 +26,8 @@ processors:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors: [env, system]
timeout: 2s
signozspanmetrics/delta:
metrics_exporter: signozclickhousemetrics
observespanmetrics/delta:
metrics_exporter: observeclickhousemetrics
metrics_flush_interval: 60s
latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ]
dimensions_cache_size: 100000
@@ -41,7 +41,7 @@ processors:
# This is added to ensure the uniqueness of the timeseries
# Otherwise, identical timeseries produced by multiple replicas of
# collectors result in incorrect APM metrics
- name: signoz.collector.id
- name: observe.collector.id
- name: service.version
- name: browser.platform
- name: browser.mobile
@@ -60,13 +60,13 @@ extensions:
exporters:
clickhousetraces:
datasource: tcp://host.docker.internal:9000/signoz_traces
datasource: tcp://host.docker.internal:9000/observe_traces
low_cardinal_exception_grouping: ${env:LOW_CARDINAL_EXCEPTION_GROUPING}
use_new_schema: true
signozclickhousemetrics:
dsn: tcp://host.docker.internal:9000/signoz_metrics
observeclickhousemetrics:
dsn: tcp://host.docker.internal:9000/observe_metrics
clickhouselogsexporter:
dsn: tcp://host.docker.internal:9000/signoz_logs
dsn: tcp://host.docker.internal:9000/observe_logs
timeout: 10s
use_new_schema: true
@@ -80,16 +80,16 @@ service:
pipelines:
traces:
receivers: [otlp]
processors: [signozspanmetrics/delta, batch]
processors: [observespanmetrics/delta, batch]
exporters: [clickhousetraces]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [signozclickhousemetrics]
exporters: [observeclickhousemetrics]
metrics/prometheus:
receivers: [prometheus]
processors: [batch]
exporters: [signozclickhousemetrics]
exporters: [observeclickhousemetrics]
logs:
receivers: [otlp]
processors: [batch]
+19 -19
View File
@@ -4,15 +4,15 @@
# that they own.
/frontend/ @SigNoz/frontend-maintainers
/frontend/ @hanzoai/frontend-maintainers
# Onboarding
/frontend/src/container/OnboardingV2Container/onboarding-configs/onboarding-config-with-links.json @makeavish
/frontend/src/container/OnboardingV2Container/AddDataSource/AddDataSource.tsx @makeavish
/deploy/ @SigNoz/devops
.github @SigNoz/devops
/deploy/ @hanzoai/devops
.github @hanzoai/devops
# Scaffold Owners
@@ -111,36 +111,36 @@
# OpenAPI types generator
/frontend/src/api @SigNoz/frontend-maintainers
/frontend/src/api @hanzoai/frontend-maintainers
# Dashboard Owners
/frontend/src/hooks/dashboard/ @SigNoz/pulse-frontend
/frontend/src/providers/Dashboard/ @SigNoz/pulse-frontend
/frontend/src/hooks/dashboard/ @hanzoai/pulse-frontend
/frontend/src/providers/Dashboard/ @hanzoai/pulse-frontend
## Dashboard Types
/frontend/src/api/types/dashboard/ @SigNoz/pulse-frontend
/frontend/src/api/types/dashboard/ @hanzoai/pulse-frontend
## Dashboard List
/frontend/src/pages/DashboardsListPage/ @SigNoz/pulse-frontend
/frontend/src/container/ListOfDashboard/ @SigNoz/pulse-frontend
/frontend/src/pages/DashboardsListPage/ @hanzoai/pulse-frontend
/frontend/src/container/ListOfDashboard/ @hanzoai/pulse-frontend
## Dashboard Page
/frontend/src/pages/DashboardPage/ @SigNoz/pulse-frontend
/frontend/src/container/DashboardContainer/ @SigNoz/pulse-frontend
/frontend/src/container/GridCardLayout/ @SigNoz/pulse-frontend
/frontend/src/container/NewWidget/ @SigNoz/pulse-frontend
/frontend/src/pages/DashboardPage/ @hanzoai/pulse-frontend
/frontend/src/container/DashboardContainer/ @hanzoai/pulse-frontend
/frontend/src/container/GridCardLayout/ @hanzoai/pulse-frontend
/frontend/src/container/NewWidget/ @hanzoai/pulse-frontend
## Public Dashboard Page
/frontend/src/pages/PublicDashboard/ @SigNoz/pulse-frontend
/frontend/src/container/PublicDashboardContainer/ @SigNoz/pulse-frontend
/frontend/src/pages/PublicDashboard/ @hanzoai/pulse-frontend
/frontend/src/container/PublicDashboardContainer/ @hanzoai/pulse-frontend
## Dashboard Libs + Components
/frontend/src/lib/uPlotV2/ @SigNoz/pulse-frontend
/frontend/src/lib/dashboard/ @SigNoz/pulse-frontend
/frontend/src/lib/dashboardVariables/ @SigNoz/pulse-frontend
/frontend/src/components/NewSelect/ @SigNoz/pulse-frontend
/frontend/src/lib/uPlotV2/ @hanzoai/pulse-frontend
/frontend/src/lib/dashboard/ @hanzoai/pulse-frontend
/frontend/src/lib/dashboardVariables/ @hanzoai/pulse-frontend
/frontend/src/components/NewSelect/ @hanzoai/pulse-frontend
@@ -1,6 +1,6 @@
---
name: Performance issue report
about: Long response times, high resource usage? Ensuring that SigNoz is scalable
about: Long response times, high resource usage? Ensuring that Hanzo O11y is scalable
is our top priority
title: ''
labels: ''
@@ -30,4 +30,4 @@ Please provide details of OS version etc.
#### *Thank you* for your performance issue report we want SigNoz to be blazing fast!
#### *Thank you* for your performance issue report we want Hanzo O11y to be blazing fast!
+3 -3
View File
@@ -1,13 +1,13 @@
---
name: Request Dashboard
about: Request a new dashboard for the SigNoz Dashboards repository
about: Request a new dashboard for the Hanzo O11y Dashboards repository
title: '[Dashboard Request] '
labels: 'dashboard-template'
assignees: ''
---
<!-- Use this template to request a new dashboard for the SigNoz Dashboards repository. Providing detailed information will help us understand your needs better and speed up the dashboard creation process. -->
<!-- Use this template to request a new dashboard for the Hanzo O11y Dashboards repository. Providing detailed information will help us understand your needs better and speed up the dashboard creation process. -->
## Dashboard Name
@@ -46,4 +46,4 @@ assignees: ''
## 📋 Notes
Please review the [CONTRIBUTING.md](https://github.com/SigNoz/dashboards/blob/main/CONTRIBUTING.md) for guidelines on dashboard structure, naming conventions, and how to submit a pull request.
Please review the [CONTRIBUTING.md](https://github.com/Hanzo O11y/dashboards/blob/main/CONTRIBUTING.md) for guidelines on dashboard structure, naming conventions, and how to submit a pull request.
+3 -3
View File
@@ -4,13 +4,13 @@
# Comment to be posted to on first time issues
newIssueWelcomeComment: >
Thanks for opening this issue. A team member should give feedback soon.
In the meantime, feel free to check out the [contributing guidelines](https://github.com/signoz/signoz/blob/main/CONTRIBUTING.md).
In the meantime, feel free to check out the [contributing guidelines](https://github.com/observe/observe/blob/main/CONTRIBUTING.md).
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
# Comment to be posted to on PRs from first time contributors in your repository
newPRWelcomeComment: >
Welcome to the SigNoz community! Thank you for your first pull request and making this project better. 🤗
Welcome to the Hanzo O11y community! Thank you for your first pull request and making this project better. 🤗
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
@@ -20,7 +20,7 @@ firstPRMergeComment: >
![minion-party](https://i.imgur.com/Xlg59lP.gif)
We here at SigNoz are proud of you! 🥳
We here at Hanzo O11y are proud of you! 🥳
# Configuration for request-info - https://github.com/behaviorbot/request-info
-82
View File
@@ -1,82 +0,0 @@
name: build-community
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+"
defaults:
run:
shell: bash
env:
PRIMUS_HOME: .primus
MAKE: make --no-print-directory --makefile=.primus/src/make/main.mk
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.build-info.outputs.version }}
hash: ${{ steps.build-info.outputs.hash }}
time: ${{ steps.build-info.outputs.time }}
branch: ${{ steps.build-info.outputs.branch }}
steps:
- name: self-checkout
uses: actions/checkout@v4
- id: token
name: github-token-gen
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.PRIMUS_APP_ID }}
private-key: ${{ secrets.PRIMUS_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: primus-checkout
uses: actions/checkout@v4
with:
repository: signoz/primus
ref: main
path: .primus
token: ${{ steps.token.outputs.token }}
- name: build-info
run: |
echo "version=$($MAKE info-version)" >> $GITHUB_OUTPUT
echo "hash=$($MAKE info-commit-short)" >> $GITHUB_OUTPUT
echo "time=$($MAKE info-timestamp)" >> $GITHUB_OUTPUT
echo "branch=$($MAKE info-branch)" >> $GITHUB_OUTPUT
js-build:
uses: signoz/primus.workflows/.github/workflows/js-build.yaml@main
needs: prepare
secrets: inherit
with:
PRIMUS_REF: main
JS_SRC: frontend
JS_OUTPUT_ARTIFACT_CACHE_KEY: community-jsbuild-${{ github.sha }}
JS_OUTPUT_ARTIFACT_PATH: frontend/build
DOCKER_BUILD: false
DOCKER_MANIFEST: false
go-build:
uses: signoz/primus.workflows/.github/workflows/go-build.yaml@main
needs: [prepare, js-build]
secrets: inherit
with:
PRIMUS_REF: main
GO_VERSION: 1.24
GO_NAME: signoz-community
GO_INPUT_ARTIFACT_CACHE_KEY: community-jsbuild-${{ github.sha }}
GO_INPUT_ARTIFACT_PATH: frontend/build
GO_BUILD_CONTEXT: ./cmd/community
GO_BUILD_FLAGS: >-
-tags timetzdata
-ldflags='-s -w
-X github.com/SigNoz/signoz/pkg/version.version=${{ needs.prepare.outputs.version }}
-X github.com/SigNoz/signoz/pkg/version.variant=community
-X github.com/SigNoz/signoz/pkg/version.hash=${{ needs.prepare.outputs.hash }}
-X github.com/SigNoz/signoz/pkg/version.time=${{ needs.prepare.outputs.time }}
-X github.com/SigNoz/signoz/pkg/version.branch=${{ needs.prepare.outputs.branch }}
-X github.com/SigNoz/signoz/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr'
DOCKER_BASE_IMAGES: '{"alpine": "alpine:3.20.3"}'
DOCKER_DOCKERFILE_PATH: ./cmd/community/Dockerfile.multi-arch
DOCKER_MANIFEST: true
DOCKER_PROVIDERS: dockerhub
-117
View File
@@ -1,117 +0,0 @@
name: build-enterprise
on:
push:
tags:
- v*
defaults:
run:
shell: bash
env:
PRIMUS_HOME: .primus
MAKE: make --no-print-directory --makefile=.primus/src/make/main.mk
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
docker_providers: ${{ steps.set-docker-providers.outputs.providers }}
version: ${{ steps.build-info.outputs.version }}
hash: ${{ steps.build-info.outputs.hash }}
time: ${{ steps.build-info.outputs.time }}
branch: ${{ steps.build-info.outputs.branch }}
steps:
- name: self-checkout
uses: actions/checkout@v4
- id: token
name: github-token-gen
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.PRIMUS_APP_ID }}
private-key: ${{ secrets.PRIMUS_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: primus-checkout
uses: actions/checkout@v4
with:
repository: signoz/primus
ref: main
path: .primus
token: ${{ steps.token.outputs.token }}
- name: build-info
id: build-info
run: |
echo "version=$($MAKE info-version)" >> $GITHUB_OUTPUT
echo "hash=$($MAKE info-commit-short)" >> $GITHUB_OUTPUT
echo "time=$($MAKE info-timestamp)" >> $GITHUB_OUTPUT
echo "branch=$($MAKE info-branch)" >> $GITHUB_OUTPUT
- name: set-docker-providers
id: set-docker-providers
run: |
if [[ ${{ github.event.ref }} =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ || ${{ github.event.ref }} =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
echo "providers=dockerhub gcp" >> $GITHUB_OUTPUT
else
echo "providers=gcp" >> $GITHUB_OUTPUT
fi
- name: create-dotenv
run: |
mkdir -p frontend
echo 'CI=1' > frontend/.env
echo 'VITE_INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' >> frontend/.env
echo 'VITE_SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
echo 'VITE_SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> frontend/.env
echo 'VITE_SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> frontend/.env
echo 'VITE_SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> frontend/.env
echo 'VITE_SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> frontend/.env
echo 'VITE_TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> frontend/.env
echo 'VITE_TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> frontend/.env
echo 'VITE_POSTHOG_KEY="${{ secrets.POSTHOG_KEY }}"' >> frontend/.env
echo 'VITE_PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> frontend/.env
echo 'VITE_APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> frontend/.env
echo 'VITE_PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> frontend/.env
echo 'VITE_DOCS_BASE_URL="https://signoz.io"' >> frontend/.env
- name: cache-dotenv
uses: actions/cache@v4
with:
path: frontend/.env
key: enterprise-dotenv-${{ github.sha }}
js-build:
uses: signoz/primus.workflows/.github/workflows/js-build.yaml@main
needs: prepare
secrets: inherit
with:
PRIMUS_REF: main
JS_SRC: frontend
JS_INPUT_ARTIFACT_CACHE_KEY: enterprise-dotenv-${{ github.sha }}
JS_INPUT_ARTIFACT_PATH: frontend/.env
JS_OUTPUT_ARTIFACT_CACHE_KEY: enterprise-jsbuild-${{ github.sha }}
JS_OUTPUT_ARTIFACT_PATH: frontend/build
DOCKER_BUILD: false
DOCKER_MANIFEST: false
go-build:
uses: signoz/primus.workflows/.github/workflows/go-build.yaml@main
needs: [prepare, js-build]
secrets: inherit
with:
PRIMUS_REF: main
GO_VERSION: 1.24
GO_INPUT_ARTIFACT_CACHE_KEY: enterprise-jsbuild-${{ github.sha }}
GO_INPUT_ARTIFACT_PATH: frontend/build
GO_BUILD_CONTEXT: ./cmd/enterprise
GO_BUILD_FLAGS: >-
-tags timetzdata
-ldflags='-s -w
-X github.com/SigNoz/signoz/pkg/version.version=${{ needs.prepare.outputs.version }}
-X github.com/SigNoz/signoz/pkg/version.variant=enterprise
-X github.com/SigNoz/signoz/pkg/version.hash=${{ needs.prepare.outputs.hash }}
-X github.com/SigNoz/signoz/pkg/version.time=${{ needs.prepare.outputs.time }}
-X github.com/SigNoz/signoz/pkg/version.branch=${{ needs.prepare.outputs.branch }}
-X github.com/SigNoz/signoz/ee/zeus.url=https://api.signoz.cloud
-X github.com/SigNoz/signoz/ee/zeus.deprecatedURL=https://license.signoz.io
-X github.com/SigNoz/signoz/ee/query-service/constants.LicenseSignozIo=https://license.signoz.io/api/v1
-X github.com/SigNoz/signoz/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr'
DOCKER_BASE_IMAGES: '{"alpine": "alpine:3.20.3"}'
DOCKER_DOCKERFILE_PATH: ./cmd/enterprise/Dockerfile.multi-arch
DOCKER_MANIFEST: true
DOCKER_PROVIDERS: ${{ needs.prepare.outputs.docker_providers }}
+25
View File
@@ -0,0 +1,25 @@
name: Docker
on:
workflow_dispatch:
push:
branches: [main, test, dev]
tags: [v*]
permissions:
contents: read
packages: write
jobs:
docker:
uses: hanzoai/.github/.github/workflows/docker-build.yml@main
with:
image: ghcr.io/hanzoai/o11y
pre-build-command: |
cd frontend && corepack enable && pnpm install --frozen-lockfile && pnpm run build
cd ..
VERSION=$(git describe --tags --always)
HASH=$(git rev-parse --short HEAD)
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
BRANCH=$(git rev-parse --abbrev-ref HEAD)
LDFLAGS="-X github.com/hanzoai/o11y/pkg/version.version=$VERSION -X github.com/hanzoai/o11y/pkg/version.hash=$HASH -X github.com/hanzoai/o11y/pkg/version.time=$TIMESTAMP -X github.com/hanzoai/o11y/pkg/version.branch=$BRANCH"
mkdir -p target/linux-amd64
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$LDFLAGS" -o target/linux-amd64/o11y ./cmd/server/
secrets: inherit
+15 -15
View File
@@ -38,7 +38,7 @@ jobs:
- name: primus-checkout
uses: actions/checkout@v4
with:
repository: signoz/primus
repository: observe/primus
ref: main
path: .primus
token: ${{ steps.token.outputs.token }}
@@ -69,14 +69,14 @@ jobs:
echo 'VITE_PYLON_APP_ID="${{ secrets.NP_PYLON_APP_ID }}"' >> frontend/.env
echo 'VITE_APPCUES_APP_ID="${{ secrets.NP_APPCUES_APP_ID }}"' >> frontend/.env
echo 'VITE_PYLON_IDENTITY_SECRET="${{ secrets.NP_PYLON_IDENTITY_SECRET }}"' >> frontend/.env
echo 'VITE_DOCS_BASE_URL="https://staging.signoz.io"' >> frontend/.env
echo 'VITE_DOCS_BASE_URL="https://staging.o11y.hanzo.ai"' >> frontend/.env
- name: cache-dotenv
uses: actions/cache@v4
with:
path: frontend/.env
key: staging-dotenv-${{ github.sha }}
js-build:
uses: signoz/primus.workflows/.github/workflows/js-build.yaml@main
uses: observe/primus.workflows/.github/workflows/js-build.yaml@main
needs: prepare
secrets: inherit
with:
@@ -89,7 +89,7 @@ jobs:
DOCKER_BUILD: false
DOCKER_MANIFEST: false
go-build:
uses: signoz/primus.workflows/.github/workflows/go-build.yaml@main
uses: observe/primus.workflows/.github/workflows/go-build.yaml@main
needs: [prepare, js-build]
secrets: inherit
with:
@@ -101,22 +101,22 @@ jobs:
GO_BUILD_FLAGS: >-
-tags timetzdata
-ldflags='-s -w
-X github.com/SigNoz/signoz/pkg/version.version=${{ needs.prepare.outputs.version }}
-X github.com/SigNoz/signoz/pkg/version.variant=enterprise
-X github.com/SigNoz/signoz/pkg/version.hash=${{ needs.prepare.outputs.hash }}
-X github.com/SigNoz/signoz/pkg/version.time=${{ needs.prepare.outputs.time }}
-X github.com/SigNoz/signoz/pkg/version.branch=${{ needs.prepare.outputs.branch }}
-X github.com/SigNoz/signoz/ee/zeus.url=https://api.staging.signoz.cloud
-X github.com/SigNoz/signoz/ee/zeus.deprecatedURL=https://license.staging.signoz.cloud
-X github.com/SigNoz/signoz/ee/query-service/constants.LicenseSignozIo=https://license.staging.signoz.cloud/api/v1
-X github.com/SigNoz/signoz/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr'
-X github.com/Hanzo O11y/observe/pkg/version.version=${{ needs.prepare.outputs.version }}
-X github.com/Hanzo O11y/observe/pkg/version.variant=enterprise
-X github.com/Hanzo O11y/observe/pkg/version.hash=${{ needs.prepare.outputs.hash }}
-X github.com/Hanzo O11y/observe/pkg/version.time=${{ needs.prepare.outputs.time }}
-X github.com/Hanzo O11y/observe/pkg/version.branch=${{ needs.prepare.outputs.branch }}
-X github.com/Hanzo O11y/observe/ee/zeus.url=https://api.staging.o11y.hanzo.ai
-X github.com/Hanzo O11y/observe/ee/zeus.deprecatedURL=https://license.staging.o11y.hanzo.ai
-X github.com/Hanzo O11y/observe/ee/query-service/constants.LicenseObserveIo=https://license.staging.o11y.hanzo.ai/api/v1
-X github.com/Hanzo O11y/observe/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr'
DOCKER_BASE_IMAGES: '{"alpine": "alpine:3.20.3"}'
DOCKER_DOCKERFILE_PATH: ./cmd/enterprise/Dockerfile.multi-arch
DOCKER_MANIFEST: true
DOCKER_PROVIDERS: gcp
staging:
if: ${{ contains(github.event.label.name, 'staging:') || github.event.ref == 'refs/heads/main' }}
uses: signoz/primus.workflows/.github/workflows/github-trigger.yaml@main
uses: observe/primus.workflows/.github/workflows/github-trigger.yaml@main
secrets: inherit
needs: [prepare, go-build]
with:
@@ -125,4 +125,4 @@ jobs:
GITHUB_SILENT: true
GITHUB_REPOSITORY_NAME: charts-saas-v3-staging
GITHUB_EVENT_NAME: releaser
GITHUB_EVENT_PAYLOAD: '{"deployment": "${{ needs.prepare.outputs.deployment }}", "signoz_version": "${{ needs.prepare.outputs.version }}"}'
GITHUB_EVENT_PAYLOAD: '{"deployment": "${{ needs.prepare.outputs.deployment }}", "observe_version": "${{ needs.prepare.outputs.version }}"}'
+4
View File
@@ -7,10 +7,14 @@ on:
pull_request_target:
types:
- labeled
merge_group:
types:
- checks_requested
jobs:
refcheck:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
runs-on: ubuntu-latest
+16 -7
View File
@@ -7,13 +7,17 @@ on:
pull_request_target:
types:
- labeled
merge_group:
types:
- checks_requested
jobs:
test:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/go-test.yaml@main
uses: observe/primus.workflows/.github/workflows/go-test.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
@@ -21,33 +25,37 @@ jobs:
GO_VERSION: 1.24
fmt:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/go-fmt.yaml@main
uses: observe/primus.workflows/.github/workflows/go-fmt.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
GO_VERSION: 1.24
lint:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/go-lint.yaml@main
uses: observe/primus.workflows/.github/workflows/go-lint.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
GO_VERSION: 1.24
deps:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/go-deps.yaml@main
uses: observe/primus.workflows/.github/workflows/go-deps.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
GO_VERSION: 1.24
build:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
runs-on: ubuntu-latest
@@ -79,6 +87,7 @@ jobs:
make docker-build-enterprise
openapi:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
runs-on: ubuntu-latest
@@ -98,8 +107,8 @@ jobs:
with:
node-version: "22"
- name: install-frontend
run: cd frontend && yarn install
run: cd frontend && pnpm install
- name: generate-api-clients
run: |
cd frontend && yarn generate:api
git diff --compact-summary --exit-code || (echo; echo "Unexpected difference in generated api clients. Run yarn generate:api in frontend/ locally and commit."; exit 1)
cd frontend && pnpm run generate:api
git diff --compact-summary --exit-code || (echo; echo "Unexpected difference in generated api clients. Run pnpm run generate:api in frontend/ locally and commit."; exit 1)
+174
View File
@@ -0,0 +1,174 @@
name: gor-observe
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+"
permissions:
contents: write
jobs:
prepare:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: get-sha
shell: bash
run: |
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: dotenv-frontend
working-directory: frontend
run: |
echo 'VITE_INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > .env
echo 'VITE_SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> .env
echo 'VITE_SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> .env
echo 'VITE_SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> .env
echo 'VITE_SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> .env
echo 'VITE_SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> .env
echo 'VITE_TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> .env
echo 'VITE_TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> .env
echo 'VITE_INSIGHTS_KEY="${{ secrets.INSIGHTS_KEY }}"' >> .env
echo 'VITE_PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> .env
echo 'VITE_APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> .env
echo 'VITE_PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> .env
echo 'VITE_DOCS_BASE_URL="https://o11y.hanzo.ai"' >> .env
- name: node-setup
uses: actions/setup-node@v5
with:
node-version: "22"
- name: build-frontend
run: make js-build
- name: upload-frontend-artifact
uses: actions/upload-artifact@v4
with:
name: frontend-build-${{ env.sha_short }}
path: frontend/build
build:
needs: prepare
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
env:
CONFIG_PATH: cmd/server/.goreleaser.yaml
runs-on: ${{ matrix.os }}
steps:
- name: checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: setup-qemu
uses: docker/setup-qemu-action@v3
if: matrix.os == 'ubuntu-latest'
- name: setup-buildx
uses: docker/setup-buildx-action@v3
if: matrix.os == 'ubuntu-latest'
- name: ghcr-login
uses: docker/login-action@v3
if: matrix.os != 'macos-latest'
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: setup-go
uses: actions/setup-go@v5
with:
go-version: "1.24"
- name: cross-compilation-tools
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
- name: get-sha
shell: bash
run: |
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: download-frontend-artifact
uses: actions/download-artifact@v4
with:
name: frontend-build-${{ env.sha_short }}
path: frontend/build
- name: cache-linux
uses: actions/cache@v4
if: matrix.os == 'ubuntu-latest'
with:
path: dist/linux
key: observe-linux-${{ env.sha_short }}
- name: cache-darwin
uses: actions/cache@v4
if: matrix.os == 'macos-latest'
with:
path: dist/darwin
key: observe-darwin-${{ env.sha_short }}
- name: release
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
version: "~> v2"
args: release --config ${{ env.CONFIG_PATH }} --clean --split
workdir: .
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
release:
runs-on: ubuntu-latest
needs: build
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
steps:
- name: checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: setup-qemu
uses: docker/setup-qemu-action@v3
- name: setup-buildx
uses: docker/setup-buildx-action@v3
- name: cosign-installer
uses: sigstore/cosign-installer@v3.8.1
- name: download-syft
uses: anchore/sbom-action/download-syft@v0.18.0
- name: ghcr-login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: setup-go
uses: actions/setup-go@v5
with:
go-version: "1.24"
# copy the caches from build
- name: get-sha
shell: bash
run: |
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: cache-linux
id: cache-linux
uses: actions/cache@v4
with:
path: dist/linux
key: observe-linux-${{ env.sha_short }}
- name: cache-darwin
id: cache-darwin
uses: actions/cache@v4
with:
path: dist/darwin
key: observe-darwin-${{ env.sha_short }}
# release
- uses: goreleaser/goreleaser-action@v6
if: steps.cache-linux.outputs.cache-hit == 'true' && steps.cache-darwin.outputs.cache-hit == 'true' # only run if caches hit
with:
distribution: goreleaser-pro
version: "~> v2"
args: continue --merge
workdir: .
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
+5 -5
View File
@@ -1,4 +1,4 @@
name: gor-signoz-community
name: gor-observe-community
on:
push:
@@ -82,13 +82,13 @@ jobs:
if: matrix.os == 'ubuntu-latest'
with:
path: dist/linux
key: signoz-community-linux-${{ env.sha_short }}
key: observe-community-linux-${{ env.sha_short }}
- name: cache-darwin
uses: actions/cache@v4
if: matrix.os == 'macos-latest'
with:
path: dist/darwin
key: signoz-community-darwin-${{ env.sha_short }}
key: observe-community-darwin-${{ env.sha_short }}
- name: release
uses: goreleaser/goreleaser-action@v6
with:
@@ -138,13 +138,13 @@ jobs:
uses: actions/cache@v4
with:
path: dist/linux
key: signoz-community-linux-${{ env.sha_short }}
key: observe-community-linux-${{ env.sha_short }}
- name: cache-darwin
id: cache-darwin
uses: actions/cache@v4
with:
path: dist/darwin
key: signoz-community-darwin-${{ env.sha_short }}
key: observe-community-darwin-${{ env.sha_short }}
# release
- uses: goreleaser/goreleaser-action@v6
+6 -6
View File
@@ -1,4 +1,4 @@
name: gor-signoz
name: gor-observe
on:
push:
@@ -36,7 +36,7 @@ jobs:
echo 'VITE_PYLON_APP_ID="${{ secrets.PYLON_APP_ID }}"' >> .env
echo 'VITE_APPCUES_APP_ID="${{ secrets.APPCUES_APP_ID }}"' >> .env
echo 'VITE_PYLON_IDENTITY_SECRET="${{ secrets.PYLON_IDENTITY_SECRET }}"' >> .env
echo 'VITE_DOCS_BASE_URL="https://signoz.io"' >> .env
echo 'VITE_DOCS_BASE_URL="https://o11y.hanzo.ai"' >> .env
- name: node-setup
uses: actions/setup-node@v5
with:
@@ -98,13 +98,13 @@ jobs:
if: matrix.os == 'ubuntu-latest'
with:
path: dist/linux
key: signoz-linux-${{ env.sha_short }}
key: observe-linux-${{ env.sha_short }}
- name: cache-darwin
uses: actions/cache@v4
if: matrix.os == 'macos-latest'
with:
path: dist/darwin
key: signoz-darwin-${{ env.sha_short }}
key: observe-darwin-${{ env.sha_short }}
- name: release
uses: goreleaser/goreleaser-action@v6
with:
@@ -153,13 +153,13 @@ jobs:
uses: actions/cache@v4
with:
path: dist/linux
key: signoz-linux-${{ env.sha_short }}
key: observe-linux-${{ env.sha_short }}
- name: cache-darwin
id: cache-darwin
uses: actions/cache@v4
with:
path: dist/darwin
key: signoz-darwin-${{ env.sha_short }}
key: observe-darwin-${{ env.sha_short }}
# release
- uses: goreleaser/goreleaser-action@v6
+15 -22
View File
@@ -7,62 +7,54 @@ on:
pull_request_target:
types:
- labeled
merge_group:
types:
- checks_requested
jobs:
tsc:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
- name: setup node
uses: actions/setup-node@v5
with:
node-version: "22"
- name: install
run: cd frontend && yarn install
- name: tsc
run: cd frontend && yarn tsc
tsc2:
if: |
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/js-tsc.yaml@main
uses: observe/primus.workflows/.github/workflows/js-tsc.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
JS_SRC: frontend
test:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/js-test.yaml@main
uses: observe/primus.workflows/.github/workflows/js-test.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
JS_SRC: frontend
fmt:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/js-fmt.yaml@main
uses: observe/primus.workflows/.github/workflows/js-fmt.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
JS_SRC: frontend
lint:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
uses: signoz/primus.workflows/.github/workflows/js-lint.yaml@main
uses: observe/primus.workflows/.github/workflows/js-lint.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
JS_SRC: frontend
md-languages:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
runs-on: ubuntu-latest
@@ -73,6 +65,7 @@ jobs:
run: bash frontend/scripts/validate-md-languages.sh
authz:
if: |
github.event_name == 'merge_group' ||
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
runs-on: ubuntu-latest
@@ -88,7 +81,7 @@ jobs:
- name: Install frontend dependencies
working-directory: ./frontend
run: |
yarn install
pnpm install
- name: Install uv
uses: astral-sh/setup-uv@v5
@@ -105,7 +98,7 @@ jobs:
- name: Generate permissions.type.ts
working-directory: ./frontend
run: |
yarn generate:permissions-type
pnpm run generate:permissions-type
- name: Teardown test environment
if: always()
+1 -1
View File
@@ -10,7 +10,7 @@ on:
jobs:
remove:
if: github.event.pull_request.head.repo.fork || github.event.pull_request.user.login == 'dependabot[bot]'
uses: signoz/primus.workflows/.github/workflows/github-label.yaml@main
uses: observe/primus.workflows/.github/workflows/github-label.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
+4 -4
View File
@@ -15,18 +15,18 @@ on:
jobs:
verify:
uses: signoz/primus.workflows/.github/workflows/github-verify.yaml@main
uses: observe/primus.workflows/.github/workflows/github-verify.yaml@main
secrets: inherit
with:
PRIMUS_REF: main
GITHUB_TEAM_NAME: releaser
GITHUB_MEMBER_NAME: ${{ github.actor }}
signoz:
observe:
if: ${{ always() && (needs.verify.result == 'success' || github.event.name == 'schedule') }}
uses: signoz/primus.workflows/.github/workflows/releaser.yaml@main
uses: observe/primus.workflows/.github/workflows/releaser.yaml@main
secrets: inherit
needs: [verify]
with:
PRIMUS_REF: main
PROJECT_NAME: signoz
PROJECT_NAME: observe
RELEASE_TYPE: ${{ inputs.release_type || 'minor' }}
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
echo "release_type=${release_type}" >> "$GITHUB_OUTPUT"
charts:
if: ${{ !startsWith(github.event.release.tag_name, 'histogram-quantile/') }}
uses: signoz/primus.workflows/.github/workflows/github-trigger.yaml@main
uses: observe/primus.workflows/.github/workflows/github-trigger.yaml@main
secrets: inherit
needs: [detect]
with:
+7
View File
@@ -0,0 +1,7 @@
name: Workflow Sanity
on:
pull_request:
paths: ['.github/workflows/**']
jobs:
sanity:
uses: hanzoai/.github/.github/workflows/workflow-sanity.yml@main
+1 -1
View File
@@ -21,7 +21,7 @@ linters:
noerrors:
deny:
- pkg: errors
desc: Do not use errors package. Use github.com/SigNoz/signoz/pkg/errors instead.
desc: Do not use errors package. Use github.com/Hanzo O11y/observe/pkg/errors instead.
nozap:
deny:
- pkg: go.uber.org/zap
+2 -2
View File
@@ -1,14 +1,14 @@
# Link to template variables: https://pkg.go.dev/github.com/vektra/mockery/v3/config#TemplateData
template: testify
packages:
github.com/SigNoz/signoz/pkg/alertmanager:
github.com/Hanzo O11y/observe/pkg/alertmanager:
config:
all: true
dir: '{{.InterfaceDir}}/alertmanagertest'
filename: "alertmanager.go"
structname: 'Mock{{.InterfaceName}}'
pkgname: '{{.SrcPackageName}}test'
github.com/SigNoz/signoz/pkg/tokenizer:
github.com/Hanzo O11y/observe/pkg/tokenizer:
config:
all: true
dir: '{{.InterfaceDir}}/tokenizertest'
+11 -11
View File
@@ -1,12 +1,12 @@
# SigNoz Community Advocate Program
# Hanzo O11y Community Advocate Program
Our community is filled with passionate developers who love SigNoz and have been helping spread the word about observability across the world. The SigNoz Community Advocate Program is our way of recognizing these incredible community members and creating deeper collaboration opportunities.
Our community is filled with passionate developers who love Hanzo O11y and have been helping spread the word about observability across the world. The Hanzo O11y Community Advocate Program is our way of recognizing these incredible community members and creating deeper collaboration opportunities.
## What is the SigNoz Community Advocate Program?
## What is the Hanzo O11y Community Advocate Program?
The SigNoz Community Advocate Program celebrates and supports community members who are already passionate about observability and helping fellow developers. If you're someone who loves discussing SigNoz, helping others with their implementations, or sharing knowledge about observability practices, this program is designed with you in mind.
The Hanzo O11y Community Advocate Program celebrates and supports community members who are already passionate about observability and helping fellow developers. If you're someone who loves discussing Hanzo O11y, helping others with their implementations, or sharing knowledge about observability practices, this program is designed with you in mind.
Our advocates are the heart of the SigNoz community, helping other developers succeed with observability and providing valuable insights that help us build better products.
Our advocates are the heart of the Hanzo O11y community, helping other developers succeed with observability and providing valuable insights that help us build better products.
## What Do Advocates Do?
@@ -14,7 +14,7 @@ Our advocates are the heart of the SigNoz community, helping other developers su
- Help fellow developers in our Slack community and GitHub Discussions
- Answer questions and share solutions
- Guide newcomers through SigNoz self-host implementations
- Guide newcomers through Hanzo O11y self-host implementations
2. **Knowledge Sharing**
@@ -32,7 +32,7 @@ Our advocates are the heart of the SigNoz community, helping other developers su
**Recognition & Swag**
- Official recognition as a SigNoz advocate
- Official recognition as a Hanzo O11y advocate
- Welcome hamper upon joining
- Exclusive swag box within your first 3 months
- Feature on our website (with your permission)
@@ -40,7 +40,7 @@ Our advocates are the heart of the SigNoz community, helping other developers su
**Early Access**
- First look at new features and updates
- Direct line to the SigNoz team for feedback and suggestions
- Direct line to the Hanzo O11y team for feedback and suggestions
- Opportunity to influence product roadmap
**Community Impact**
@@ -51,12 +51,12 @@ Our advocates are the heart of the SigNoz community, helping other developers su
## How Does It Work?
Currently, the SigNoz Community Advocate Program is **invite-only**. We're starting with a small group of passionate community members who have already been making a difference.
Currently, the Hanzo O11y Community Advocate Program is **invite-only**. We're starting with a small group of passionate community members who have already been making a difference.
We'll be working closely with our first advocates to shape the program details, benefits, and structure based on what works best for everyone involved.
If you're interested in learning more about the program or want to get more involved in the SigNoz community, join our [Slack community](https://signoz-community.slack.com/) and let us know!
If you're interested in learning more about the program or want to get more involved in the Hanzo O11y community, join our [Slack community](https://signoz-community.slack.com/) and let us know!
---
*The SigNoz Community Advocate Program recognizes and celebrates the amazing community members who are already passionate about helping fellow developers succeed with observability.*
*The Hanzo O11y Community Advocate Program recognizes and celebrates the amazing community members who are already passionate about helping fellow developers succeed with observability.*
Symlink
+1
View File
@@ -0,0 +1 @@
LLM.md
Symlink
+1
View File
@@ -0,0 +1 @@
LLM.md
+1 -1
View File
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at dev@signoz.io. All
reported by contacting the project team at dev@o11y.hanzo.ai. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
+14 -14
View File
@@ -5,19 +5,19 @@ Thank you for your interest in contributing to our project! We greatly value fee
## How can I contribute?
### Finding Issues to Work On
- Check our [existing open issues](https://github.com/SigNoz/signoz/issues?q=is%3Aopen+is%3Aissue)
- Look for [good first issues](https://github.com/SigNoz/signoz/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) to start with
- Review [recently closed issues](https://github.com/SigNoz/signoz/issues?q=is%3Aissue+is%3Aclosed) to avoid duplicates
- Check our [existing open issues](https://github.com/Hanzo O11y/signoz/issues?q=is%3Aopen+is%3Aissue)
- Look for [good first issues](https://github.com/Hanzo O11y/signoz/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) to start with
- Review [recently closed issues](https://github.com/Hanzo O11y/signoz/issues?q=is%3Aissue+is%3Aclosed) to avoid duplicates
### Types of Contributions
1. **Report Bugs**: Use our [Bug Report template](https://github.com/SigNoz/signoz/issues/new?assignees=&labels=&template=bug_report.md&title=)
2. **Request Features**: Submit using [Feature Request template](https://github.com/SigNoz/signoz/issues/new?assignees=&labels=&template=feature_request.md&title=)
1. **Report Bugs**: Use our [Bug Report template](https://github.com/Hanzo O11y/signoz/issues/new?assignees=&labels=&template=bug_report.md&title=)
2. **Request Features**: Submit using [Feature Request template](https://github.com/Hanzo O11y/signoz/issues/new?assignees=&labels=&template=feature_request.md&title=)
3. **Improve Documentation**: Create an issue with the `documentation` label
4. **Report Performance Issues**: Use our [Performance Issue template](https://github.com/SigNoz/signoz/issues/new?assignees=&labels=&template=performance-issue-report.md&title=)
5. **Request Dashboards**: Submit using [Dashboard Request template](https://github.com/SigNoz/signoz/issues/new?assignees=&labels=dashboard-template&projects=&template=request_dashboard.md&title=%5BDashboard+Request%5D+)
6. **Report Security Issues**: Follow our [Security Policy](https://github.com/SigNoz/signoz/security/policy)
7. **Join Discussions**: Participate in [project discussions](https://github.com/SigNoz/signoz/discussions)
4. **Report Performance Issues**: Use our [Performance Issue template](https://github.com/Hanzo O11y/signoz/issues/new?assignees=&labels=&template=performance-issue-report.md&title=)
5. **Request Dashboards**: Submit using [Dashboard Request template](https://github.com/Hanzo O11y/signoz/issues/new?assignees=&labels=dashboard-template&projects=&template=request_dashboard.md&title=%5BDashboard+Request%5D+)
6. **Report Security Issues**: Follow our [Security Policy](https://github.com/Hanzo O11y/signoz/security/policy)
7. **Join Discussions**: Participate in [project discussions](https://github.com/Hanzo O11y/signoz/discussions)
### Creating Helpful Issues
@@ -61,10 +61,10 @@ We follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
## How can I contribute to other repositories?
You can find other repositories in the [SigNoz](https://github.com/SigNoz) organization to contribute to. Here is a list of **highlighted** repositories:
You can find other repositories in the [Hanzo O11y](https://github.com/Hanzo O11y) organization to contribute to. Here is a list of **highlighted** repositories:
- [charts](https://github.com/SigNoz/charts)
- [dashboards](https://github.com/SigNoz/dashboards)
- [charts](https://github.com/Hanzo O11y/charts)
- [dashboards](https://github.com/Hanzo O11y/dashboards)
Each repository has its own contributing guidelines. Please refer to the guidelines of the repository you want to contribute to.
@@ -77,6 +77,6 @@ Need assistance? Join our Slack community:
## Where do I go from here?
- Set up your [development environment](docs/contributing/development.md)
- Deploy and observe [SigNoz in action with OpenTelemetry Demo Application](docs/otel-demo-docs.md)
- Explore the [SigNoz Community Advocate Program](ADVOCATE.md), which recognises contributors who support the community, share their expertise, and help shape SigNoz's future.
- Deploy and observe [Hanzo O11y in action with OpenTelemetry Demo Application](docs/otel-demo-docs.md)
- Explore the [Hanzo O11y Community Advocate Program](ADVOCATE.md), which recognises contributors who support the community, share their expertise, and help shape Hanzo O11y's future.
- Write [integration tests](docs/contributing/go/integration.md)
+7
View File
@@ -0,0 +1,7 @@
# o11y — AI Assistant Context
<h1 align="center" style="border-bottom: none">
<a href="https://o11y.hanzo.ai" target="_blank">
<img alt="Hanzo O11y" src="https://github.com/user-attachments/assets/ef9a33f7-12d7-4c94-8908-0a02b22f0c18" width="100" height="100">
</a>
<br>Hanzo O11y
+31 -31
View File
@@ -3,7 +3,7 @@
##############################################################
SHELL := /bin/bash
SRC ?= $(shell pwd)
NAME ?= signoz
NAME ?= o11y
OS ?= $(shell uname -s | tr '[A-Z]' '[a-z]')
ARCH ?= $(shell uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g')
COMMIT_SHORT_SHA ?= $(shell git rev-parse --short HEAD)
@@ -13,26 +13,26 @@ TIMESTAMP ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
ARCHS ?= amd64 arm64
TARGET_DIR ?= $(shell pwd)/target
ZEUS_URL ?= https://api.signoz.cloud
GO_BUILD_LDFLAG_ZEUS_URL = -X github.com/SigNoz/signoz/ee/zeus.url=$(ZEUS_URL)
LICENSE_URL ?= https://license.signoz.io
GO_BUILD_LDFLAG_LICENSE_SIGNOZ_IO = -X github.com/SigNoz/signoz/ee/zeus.deprecatedURL=$(LICENSE_URL)
ZEUS_URL ?= https://api.o11y.hanzo.ai
GO_BUILD_LDFLAG_ZEUS_URL = -X github.com/hanzoai/o11y/ee/zeus.url=$(ZEUS_URL)
LICENSE_URL ?= https://license.o11y.hanzo.ai
GO_BUILD_LDFLAG_LICENSE_HANZO_IO = -X github.com/hanzoai/o11y/ee/zeus.deprecatedURL=$(LICENSE_URL)
GO_BUILD_VERSION_LDFLAGS = -X github.com/SigNoz/signoz/pkg/version.version=$(VERSION) -X github.com/SigNoz/signoz/pkg/version.hash=$(COMMIT_SHORT_SHA) -X github.com/SigNoz/signoz/pkg/version.time=$(TIMESTAMP) -X github.com/SigNoz/signoz/pkg/version.branch=$(BRANCH_NAME)
GO_BUILD_VERSION_LDFLAGS = -X github.com/hanzoai/o11y/pkg/version.version=$(VERSION) -X github.com/hanzoai/o11y/pkg/version.hash=$(COMMIT_SHORT_SHA) -X github.com/hanzoai/o11y/pkg/version.time=$(TIMESTAMP) -X github.com/hanzoai/o11y/pkg/version.branch=$(BRANCH_NAME)
GO_BUILD_ARCHS_COMMUNITY = $(addprefix go-build-community-,$(ARCHS))
GO_BUILD_CONTEXT_COMMUNITY = $(SRC)/cmd/community
GO_BUILD_LDFLAGS_COMMUNITY = $(GO_BUILD_VERSION_LDFLAGS) -X github.com/SigNoz/signoz/pkg/version.variant=community
GO_BUILD_LDFLAGS_COMMUNITY = $(GO_BUILD_VERSION_LDFLAGS) -X github.com/hanzoai/o11y/pkg/version.variant=community
GO_BUILD_ARCHS_ENTERPRISE = $(addprefix go-build-enterprise-,$(ARCHS))
GO_BUILD_ARCHS_ENTERPRISE_RACE = $(addprefix go-build-enterprise-race-,$(ARCHS))
GO_BUILD_CONTEXT_ENTERPRISE = $(SRC)/cmd/enterprise
GO_BUILD_LDFLAGS_ENTERPRISE = $(GO_BUILD_VERSION_LDFLAGS) -X github.com/SigNoz/signoz/pkg/version.variant=enterprise $(GO_BUILD_LDFLAG_ZEUS_URL) $(GO_BUILD_LDFLAG_LICENSE_SIGNOZ_IO)
GO_BUILD_LDFLAGS_ENTERPRISE = $(GO_BUILD_VERSION_LDFLAGS) -X github.com/hanzoai/o11y/pkg/version.variant=enterprise $(GO_BUILD_LDFLAG_ZEUS_URL) $(GO_BUILD_LDFLAG_LICENSE_HANZO_IO)
DOCKER_BUILD_ARCHS_COMMUNITY = $(addprefix docker-build-community-,$(ARCHS))
DOCKERFILE_COMMUNITY = $(SRC)/cmd/community/Dockerfile
DOCKER_REGISTRY_COMMUNITY ?= docker.io/signoz/signoz-community
DOCKER_REGISTRY_COMMUNITY ?= ghcr.io/hanzoai/o11y-community
DOCKER_BUILD_ARCHS_ENTERPRISE = $(addprefix docker-build-enterprise-,$(ARCHS))
DOCKERFILE_ENTERPRISE = $(SRC)/cmd/enterprise/Dockerfile
DOCKER_REGISTRY_ENTERPRISE ?= docker.io/signoz/signoz
DOCKER_REGISTRY_ENTERPRISE ?= ghcr.io/hanzoai/o11y
JS_BUILD_CONTEXT = $(SRC)/frontend
##############################################################
@@ -61,16 +61,16 @@ devenv-postgres: ## Run postgres in devenv
@cd .devenv/docker/postgres; \
docker compose -f compose.yaml up -d
.PHONY: devenv-signoz-otel-collector
devenv-signoz-otel-collector: ## Run signoz-otel-collector in devenv (requires clickhouse to be running)
.PHONY: devenv-otel-collector
devenv-otel-collector: ## Run otel-collector in devenv (requires datastore to be running)
@cd .devenv/docker/signoz-otel-collector; \
docker compose -f compose.yaml up -d
.PHONY: devenv-up
devenv-up: devenv-clickhouse devenv-signoz-otel-collector ## Start both clickhouse and signoz-otel-collector for local development
devenv-up: devenv-clickhouse devenv-otel-collector ## Start both datastore and otel-collector for local development
@echo "Development environment is ready!"
@echo " - ClickHouse: http://localhost:8123"
@echo " - Signoz OTel Collector: grpc://localhost:4317, http://localhost:4318"
@echo " - Datastore: http://localhost:8123"
@echo " - OTEL Collector: grpc://localhost:4317, http://localhost:4318"
.PHONY: devenv-clickhouse-clean
devenv-clickhouse-clean: ## Clean all ClickHouse data from filesystem
@@ -83,14 +83,14 @@ devenv-clickhouse-clean: ## Clean all ClickHouse data from filesystem
##############################################################
.PHONY: go-run-enterprise
go-run-enterprise: ## Runs the enterprise go backend server
@SIGNOZ_INSTRUMENTATION_LOGS_LEVEL=debug \
SIGNOZ_SQLSTORE_SQLITE_PATH=signoz.db \
SIGNOZ_WEB_ENABLED=false \
SIGNOZ_TOKENIZER_JWT_SECRET=secret \
SIGNOZ_ALERTMANAGER_PROVIDER=signoz \
SIGNOZ_TELEMETRYSTORE_PROVIDER=clickhouse \
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://127.0.0.1:9000 \
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_CLUSTER=cluster \
@HANZO_INSTRUMENTATION_LOGS_LEVEL=debug \
HANZO_SQLSTORE_SQLITE_PATH=o11y.db \
HANZO_WEB_ENABLED=false \
HANZO_TOKENIZER_JWT_SECRET=secret \
HANZO_ALERTMANAGER_PROVIDER=o11y \
HANZO_TELEMETRYSTORE_PROVIDER=datastore \
HANZO_TELEMETRYSTORE_DATASTORE_DSN=tcp://127.0.0.1:9000 \
HANZO_TELEMETRYSTORE_DATASTORE_CLUSTER=cluster \
go run -race \
$(GO_BUILD_CONTEXT_ENTERPRISE)/*.go server
@@ -100,14 +100,14 @@ go-test: ## Runs go unit tests
.PHONY: go-run-community
go-run-community: ## Runs the community go backend server
@SIGNOZ_INSTRUMENTATION_LOGS_LEVEL=debug \
SIGNOZ_SQLSTORE_SQLITE_PATH=signoz.db \
SIGNOZ_WEB_ENABLED=false \
SIGNOZ_TOKENIZER_JWT_SECRET=secret \
SIGNOZ_ALERTMANAGER_PROVIDER=signoz \
SIGNOZ_TELEMETRYSTORE_PROVIDER=clickhouse \
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://127.0.0.1:9000 \
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_CLUSTER=cluster \
@HANZO_INSTRUMENTATION_LOGS_LEVEL=debug \
HANZO_SQLSTORE_SQLITE_PATH=o11y.db \
HANZO_WEB_ENABLED=false \
HANZO_TOKENIZER_JWT_SECRET=secret \
HANZO_ALERTMANAGER_PROVIDER=o11y \
HANZO_TELEMETRYSTORE_PROVIDER=datastore \
HANZO_TELEMETRYSTORE_DATASTORE_DSN=tcp://127.0.0.1:9000 \
HANZO_TELEMETRYSTORE_DATASTORE_CLUSTER=cluster \
go run -race \
$(GO_BUILD_CONTEXT_COMMUNITY)/*.go server
+36 -36
View File
@@ -1,28 +1,28 @@
<p align="center">
<img src="https://res.cloudinary.com/dcv3epinx/image/upload/v1618904450/signoz-images/LogoGithub_sigfbu.svg" alt="SigNoz-logo" width="240" />
<img src="https://res.cloudinary.com/dcv3epinx/image/upload/v1618904450/signoz-images/LogoGithub_sigfbu.svg" alt="Hanzo O11y-logo" width="240" />
<p align="center">Überwache deine Anwendungen und behebe Probleme in deinen bereitgestellten Anwendungen. SigNoz ist eine Open Source Alternative zu DataDog, New Relic, etc.</p>
<p align="center">Überwache deine Anwendungen und behebe Probleme in deinen bereitgestellten Anwendungen. Hanzo O11y ist eine Open Source Alternative zu DataDog, New Relic, etc.</p>
</p>
<p align="center">
<img alt="Downloads" src="https://img.shields.io/docker/pulls/signoz/query-service?label=Downloads"> </a>
<img alt="GitHub issues" src="https://img.shields.io/github/issues/signoz/signoz"> </a>
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20SigNoz,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://signoz.io/&via=SigNozHQ&hashtags=opensource,signoz,observability">
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20Hanzo O11y,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://o11y.hanzo.ai/&via=Hanzo O11yHQ&hashtags=opensource,signoz,observability">
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
</p>
<h3 align="center">
<a href="https://signoz.io/docs"><b>Dokumentation</b></a> &bull;
<a href="https://github.com/SigNoz/signoz/blob/main/README.md"><b>Readme auf Englisch </b></a> &bull;
<a href="https://github.com/SigNoz/signoz/blob/main/README.zh-cn.md"><b>ReadMe auf Chinesisch</b></a> &bull;
<a href="https://github.com/SigNoz/signoz/blob/main/README.pt-br.md"><b>ReadMe auf Portugiesisch</b></a> &bull;
<a href="https://signoz.io/slack"><b>Slack Community</b></a> &bull;
<a href="https://twitter.com/SigNozHq"><b>Twitter</b></a>
<a href="https://o11y.hanzo.ai/docs"><b>Dokumentation</b></a> &bull;
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.md"><b>Readme auf Englisch </b></a> &bull;
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.zh-cn.md"><b>ReadMe auf Chinesisch</b></a> &bull;
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.pt-br.md"><b>ReadMe auf Portugiesisch</b></a> &bull;
<a href="https://o11y.hanzo.ai/slack"><b>Slack Community</b></a> &bull;
<a href="https://twitter.com/Hanzo O11yHq"><b>Twitter</b></a>
</h3>
##
SigNoz hilft Entwicklern, Anwendungen zu überwachen und Probleme in ihren bereitgestellten Anwendungen zu beheben. Mit SigNoz können Sie Folgendes tun:
Hanzo O11y hilft Entwicklern, Anwendungen zu überwachen und Probleme in ihren bereitgestellten Anwendungen zu beheben. Mit Hanzo O11y können Sie Folgendes tun:
👉 Visualisieren Sie Metriken, Traces und Logs in einer einzigen Oberfläche.
@@ -70,7 +70,7 @@ SigNoz hilft Entwicklern, Anwendungen zu überwachen und Probleme in ihren berei
## Werde Teil unserer Slack Community
Sag Hi zu uns auf [Slack](https://signoz.io/slack) 👋
Sag Hi zu uns auf [Slack](https://o11y.hanzo.ai/slack) 👋
<br /><br />
@@ -83,19 +83,19 @@ Sag Hi zu uns auf [Slack](https://signoz.io/slack) 👋
- Filtern Sie Traces nach Dienstname, Operation, Latenz, Fehler, Tags/Annotationen.
- Führen Sie Aggregationen auf Trace-Daten (Ereignisse/Spans) durch, um geschäftsrelevante Metriken zu erhalten. Beispielsweise können Sie die Fehlerquote und die 99tes Perzentillatenz für `customer_type: gold` oder `deployment_version: v2` oder `external_call: paypal` erhalten.
- Native Unterstützung für OpenTelemetry-Logs, erweiterten Log-Abfrage-Builder und automatische Log-Sammlung aus dem Kubernetes-Cluster.
- Blitzschnelle Log-Analytik ([Logs Perf. Benchmark](https://signoz.io/blog/logs-performance-benchmark/))
- Blitzschnelle Log-Analytik ([Logs Perf. Benchmark](https://o11y.hanzo.ai/blog/logs-performance-benchmark/))
- End-to-End-Sichtbarkeit der Infrastrukturleistung, Aufnahme von Metriken aus allen Arten von Host-Umgebungen.
- Einfache Einrichtung von Benachrichtigungen mit dem selbst erstellbaren Abfrage-Builder.
<br /><br />
## Wieso SigNoz?
## Wieso Hanzo O11y?
Als Entwickler fanden wir es anstrengend, uns für jede kleine Funktion, die wir haben wollten, auf Closed Source SaaS Anbieter verlassen zu müssen. Closed Source Anbieter überraschen ihre Kunden zum Monatsende oft mit hohen Rechnungen, die keine Transparenz bzgl. der Kostenaufteilung bieten.
Wir wollten eine selbst gehostete, Open Source Variante von Lösungen wie DataDog, NewRelic für Firmen anbieten, die Datenschutz und Sicherheitsbedenken haben, bei der Weitergabe von Kundendaten an Drittanbieter.
Open Source gibt dir außerdem die totale Kontrolle über deine Konfiguration, Stichprobenentnahme und Betriebszeit. Du kannst des Weiteren neue Module auf Basis von SigNoz bauen, die erweiterte, geschäftsspezifische Funktionen anbieten.
Open Source gibt dir außerdem die totale Kontrolle über deine Konfiguration, Stichprobenentnahme und Betriebszeit. Du kannst des Weiteren neue Module auf Basis von Hanzo O11y bauen, die erweiterte, geschäftsspezifische Funktionen anbieten.
### Languages supported:
@@ -115,25 +115,25 @@ Hier findest du die vollständige Liste von unterstützten Programmiersprachen -
<br /><br />
## Erste Schritte mit SigNoz
## Erste Schritte mit Hanzo O11y
### Bereitstellung mit Docker
Bitte folge den [hier](https://signoz.io/docs/install/docker/) aufgelisteten Schritten um deine Anwendung mit Docker bereitzustellen.
Bitte folge den [hier](https://o11y.hanzo.ai/docs/install/docker/) aufgelisteten Schritten um deine Anwendung mit Docker bereitzustellen.
Die [Anleitungen zur Fehlerbehebung](https://signoz.io/docs/install/troubleshooting/) könnten hilfreich sein, falls du auf irgendwelche Schwierigkeiten stößt.
Die [Anleitungen zur Fehlerbehebung](https://o11y.hanzo.ai/docs/install/troubleshooting/) könnten hilfreich sein, falls du auf irgendwelche Schwierigkeiten stößt.
<p>&nbsp </p>
### Deploy in Kubernetes using Helm
Bitte folge den [hier](https://signoz.io/docs/deployment/helm_chart) aufgelisteten Schritten, um deine Anwendung mit Helm Charts bereitzustellen.
Bitte folge den [hier](https://o11y.hanzo.ai/docs/deployment/helm_chart) aufgelisteten Schritten, um deine Anwendung mit Helm Charts bereitzustellen.
<br /><br />
## Vergleiche mit bekannten Tools
### SigNoz vs Prometheus
### Hanzo O11y vs Prometheus
Prometheus ist gut, falls du dich nur für Metriken interessierst. Wenn du eine nahtlose Integration von Metriken und Einzelschritt-Fehlersuchen haben möchtest, ist die Kombination aus Prometheus und Jaeger nicht das Richtige für dich.
@@ -141,54 +141,54 @@ Unser Ziel ist es, eine integrierte Benutzeroberfläche aus Metriken und Einzels
<p>&nbsp </p>
### SigNoz vs Jaeger
### Hanzo O11y vs Jaeger
Jaeger kümmert sich nur um verteilte Einzelschritt-Fehlersuche. SigNoz erstellt sowohl Metriken als auch Einzelschritt-Fehlersuche, daneben haben wir auch Protokoll Verwaltung auf unserem Plan.
Jaeger kümmert sich nur um verteilte Einzelschritt-Fehlersuche. Hanzo O11y erstellt sowohl Metriken als auch Einzelschritt-Fehlersuche, daneben haben wir auch Protokoll Verwaltung auf unserem Plan.
Außerdem hat SigNoz noch mehr spezielle Funktionen im Vergleich zu Jaeger:
Außerdem hat Hanzo O11y noch mehr spezielle Funktionen im Vergleich zu Jaeger:
- Jaeger UI zeigt keine Metriken für Einzelschritt-Fehlersuchen oder für gefilterte Einzelschritt-Fehlersuchen an.
- Jaeger erstellt keine Aggregate für gefilterte Einzelschritt-Fehlersuchen, z. B. die P99 Latenz von Abfragen mit dem Tag `customer_type=premium`, was hingegen mit SigNoz leicht umsetzbar ist.
- Jaeger erstellt keine Aggregate für gefilterte Einzelschritt-Fehlersuchen, z. B. die P99 Latenz von Abfragen mit dem Tag `customer_type=premium`, was hingegen mit Hanzo O11y leicht umsetzbar ist.
<p>&nbsp </p>
### SigNoz vs Elastic
### Hanzo O11y vs Elastic
- Die Verwaltung von SigNoz-Protokollen basiert auf 'ClickHouse', einem spaltenbasierten OLAP-Datenspeicher, der aggregierte Protokollanalyseabfragen wesentlich effizienter macht.
- Die Verwaltung von Hanzo O11y-Protokollen basiert auf 'ClickHouse', einem spaltenbasierten OLAP-Datenspeicher, der aggregierte Protokollanalyseabfragen wesentlich effizienter macht.
- 50 % geringerer Ressourcenbedarf im Vergleich zu Elastic während der Aufnahme.
Wir haben Benchmarks veröffentlicht, die Elastic mit SignNoz vergleichen. Schauen Sie es sich [hier](https://signoz.io/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
Wir haben Benchmarks veröffentlicht, die Elastic mit SignNoz vergleichen. Schauen Sie es sich [hier](https://o11y.hanzo.ai/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
<p>&nbsp </p>
### SigNoz vs Loki
### Hanzo O11y vs Loki
- SigNoz unterstützt Aggregationen von Daten mit hoher Kardinalität über ein großes Volumen, Loki hingegen nicht.
- SigNoz unterstützt Indizes über Daten mit hoher Kardinalität und hat keine Beschränkungen hinsichtlich der Anzahl der Indizes, während Loki maximale Streams erreicht, wenn ein paar Indizes hinzugefügt werden.
- Das Durchsuchen großer Datenmengen ist in Loki im Vergleich zu SigNoz schwierig und langsam.
- Hanzo O11y unterstützt Aggregationen von Daten mit hoher Kardinalität über ein großes Volumen, Loki hingegen nicht.
- Hanzo O11y unterstützt Indizes über Daten mit hoher Kardinalität und hat keine Beschränkungen hinsichtlich der Anzahl der Indizes, während Loki maximale Streams erreicht, wenn ein paar Indizes hinzugefügt werden.
- Das Durchsuchen großer Datenmengen ist in Loki im Vergleich zu Hanzo O11y schwierig und langsam.
Wir haben Benchmarks veröffentlicht, die Loki mit SigNoz vergleichen. Schauen Sie es sich [hier](https://signoz.io/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
Wir haben Benchmarks veröffentlicht, die Loki mit Hanzo O11y vergleichen. Schauen Sie es sich [hier](https://o11y.hanzo.ai/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
<br /><br />
## Zum Projekt beitragen
Wir ❤️ Beiträge zum Projekt, egal ob große oder kleine. Bitte lies dir zuerst die [CONTRIBUTING.md](CONTRIBUTING.md), durch, bevor du anfängst, Beiträge zu SigNoz zu machen.
Du bist dir nicht sicher, wie du anfangen sollst? Schreib uns einfach auf dem #contributing Kanal in unserer [slack community](https://signoz.io/slack)
Wir ❤️ Beiträge zum Projekt, egal ob große oder kleine. Bitte lies dir zuerst die [CONTRIBUTING.md](CONTRIBUTING.md), durch, bevor du anfängst, Beiträge zu Hanzo O11y zu machen.
Du bist dir nicht sicher, wie du anfangen sollst? Schreib uns einfach auf dem #contributing Kanal in unserer [slack community](https://o11y.hanzo.ai/slack)
<br /><br />
## Dokumentation
Du findest unsere Dokumentation unter https://signoz.io/docs/. Falls etwas unverständlich ist oder fehlt, öffne gerne ein Github Issue mit dem Label `documentation` oder schreib uns über den Community Slack Channel.
Du findest unsere Dokumentation unter https://o11y.hanzo.ai/docs/. Falls etwas unverständlich ist oder fehlt, öffne gerne ein Github Issue mit dem Label `documentation` oder schreib uns über den Community Slack Channel.
<br /><br />
## Gemeinschaft
Werde Teil der [slack community](https://signoz.io/slack) um mehr über verteilte Einzelschritt-Fehlersuche, Messung von Systemzuständen oder SigNoz zu erfahren und sich mit anderen Nutzern und Mitwirkenden in Verbindung zu setzen.
Werde Teil der [slack community](https://o11y.hanzo.ai/slack) um mehr über verteilte Einzelschritt-Fehlersuche, Messung von Systemzuständen oder Hanzo O11y zu erfahren und sich mit anderen Nutzern und Mitwirkenden in Verbindung zu setzen.
Falls du irgendwelche Ideen, Fragen oder Feedback hast, kannst du sie gerne über unsere [Github Discussions](https://github.com/SigNoz/signoz/discussions) mit uns teilen.
Falls du irgendwelche Ideen, Fragen oder Feedback hast, kannst du sie gerne über unsere [Github Discussions](https://github.com/Hanzo O11y/signoz/discussions) mit uns teilen.
Wie immer, Dank an unsere großartigen Mitwirkenden!
+108 -67
View File
@@ -1,26 +1,67 @@
# o11y
Metrics, traces, logs — the unified observability spine for the Hanzo platform. OpenTelemetry-native, OLAP-backed via Hanzo Datastore.
[![Status](https://img.shields.io/badge/status-stable-green)]()
[![License](https://img.shields.io/badge/license-MIT-blue)]()
## Quick start
```bash
docker compose -f compose.yml up -d
```
Open `http://localhost:3301`.
## What this is
`o11y` is the unified APM / logs / traces / metrics surface every Hanzo service emits to. OpenTelemetry on the wire, Hanzo Datastore (OLAP column store) on disk. Multi-tenant by design — 309 `X-Org-Id` call sites — every panel scopes by org from the JWT. Sits behind `gateway` like every other Hanzo subsystem; eventually mounts under `hanzoai/cloud` per HIP-0106.
## Specs
Implements:
- HIP-0106 Unified Cloud Binary (o11y subsystem)
## Architecture
```
instrumented app -> OTLP -> o11y collector
|
Hanzo Datastore (OLAP column store)
|
APM | logs | traces | metrics
|
queries scoped by X-Org-Id from JWT
|
dashboards | alerting | exceptions
```
---
<h1 align="center" style="border-bottom: none">
<a href="https://signoz.io" target="_blank">
<img alt="SigNoz" src="https://github.com/user-attachments/assets/ef9a33f7-12d7-4c94-8908-0a02b22f0c18" width="100" height="100">
<a href="https://o11y.hanzo.ai" target="_blank">
<img alt="Hanzo O11y" src="https://github.com/user-attachments/assets/ef9a33f7-12d7-4c94-8908-0a02b22f0c18" width="100" height="100">
</a>
<br>SigNoz
<br>Hanzo O11y
</h1>
<p align="center">All your logs, metrics, and traces in one place. Monitor your application, spot issues before they occur and troubleshoot downtime quickly with rich context. SigNoz is a cost-effective open-source alternative to Datadog and New Relic. Visit <a href="https://signoz.io" target="_blank">signoz.io</a> for the full documentation, tutorials, and guide.</p>
<p align="center">All your logs, metrics, and traces in one place. Monitor your application, spot issues before they occur and troubleshoot downtime quickly with rich context. Hanzo O11y is a cost-effective open-source alternative to Datadog and New Relic. Visit <a href="https://o11y.hanzo.ai" target="_blank">o11y.hanzo.ai</a> for the full documentation, tutorials, and guide.</p>
<p align="center">
<img alt="GitHub issues" src="https://img.shields.io/github/issues/signoz/signoz"> </a>
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20SigNoz,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://signoz.io/&via=SigNozHQ&hashtags=opensource,signoz,observability">
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20Hanzo O11y,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://o11y.hanzo.ai/&via=Hanzo O11yHQ&hashtags=opensource,signoz,observability">
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
</p>
<h3 align="center">
<a href="https://signoz.io/docs"><b>Documentation</b></a> &bull;
<a href="https://github.com/SigNoz/signoz/blob/main/README.zh-cn.md"><b>ReadMe in Chinese</b></a> &bull;
<a href="https://github.com/SigNoz/signoz/blob/main/README.de-de.md"><b>ReadMe in German</b></a> &bull;
<a href="https://github.com/SigNoz/signoz/blob/main/README.pt-br.md"><b>ReadMe in Portuguese</b></a> &bull;
<a href="https://signoz.io/slack"><b>Slack Community</b></a> &bull;
<a href="https://twitter.com/SigNozHq"><b>Twitter</b></a>
<a href="https://o11y.hanzo.ai/docs"><b>Documentation</b></a> &bull;
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.zh-cn.md"><b>ReadMe in Chinese</b></a> &bull;
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.de-de.md"><b>ReadMe in German</b></a> &bull;
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.pt-br.md"><b>ReadMe in Portuguese</b></a> &bull;
<a href="https://o11y.hanzo.ai/slack"><b>Slack Community</b></a> &bull;
<a href="https://twitter.com/Hanzo O11yHq"><b>Twitter</b></a>
</h3>
## Features
@@ -28,29 +69,29 @@
### Application Performance Monitoring
Use SigNoz APM to monitor your applications and services. It comes with out-of-box charts for key application metrics like p99 latency, error rate, Apdex and operations per second. You can also monitor the database and external calls made from your application. Read [more](https://signoz.io/application-performance-monitoring/).
Use Hanzo O11y APM to monitor your applications and services. It comes with out-of-box charts for key application metrics like p99 latency, error rate, Apdex and operations per second. You can also monitor the database and external calls made from your application. Read [more](https://o11y.hanzo.ai/application-performance-monitoring/).
You can [instrument](https://signoz.io/docs/instrumentation/) your application with OpenTelemetry to get started.
You can [instrument](https://o11y.hanzo.ai/docs/instrumentation/) your application with OpenTelemetry to get started.
![apm-cover](https://github.com/user-attachments/assets/fa5c0396-0854-4c8b-b972-9b62fd2a70d2)
### Logs Management
SigNoz can be used as a centralized log management solution. We use ClickHouse (used by likes of Uber & Cloudflare) as a datastore, ⎯ an extremely fast and highly optimized storage for logs data. Instantly search through all your logs using quick filters and a powerful query builder.
Hanzo O11y can be used as a centralized log management solution. We use ClickHouse (used by likes of Uber & Cloudflare) as a datastore, ⎯ an extremely fast and highly optimized storage for logs data. Instantly search through all your logs using quick filters and a powerful query builder.
You can also create charts on your logs and monitor them with customized dashboards. Read [more](https://signoz.io/log-management/).
You can also create charts on your logs and monitor them with customized dashboards. Read [more](https://o11y.hanzo.ai/log-management/).
![logs-management-cover](https://github.com/user-attachments/assets/343588ee-98fb-4310-b3d2-c5bacf9c7384)
### Distributed Tracing
Distributed Tracing is essential to troubleshoot issues in microservices applications. Powered by OpenTelemetry, distributed tracing in SigNoz can help you track user requests across services to help you identify performance bottlenecks.
Distributed Tracing is essential to troubleshoot issues in microservices applications. Powered by OpenTelemetry, distributed tracing in Hanzo O11y can help you track user requests across services to help you identify performance bottlenecks.
See user requests in a detailed breakdown with the help of Flamegraphs and Gantt Charts. Click on any span to see the entire trace represented beautifully, which will help you make sense of where issues actually occurred in the flow of requests.
Read [more](https://signoz.io/distributed-tracing/).
Read [more](https://o11y.hanzo.ai/distributed-tracing/).
![distributed-tracing-cover](https://github.com/user-attachments/assets/9bfe060a-0c40-4922-9b55-8a97e1a4076c)
@@ -62,7 +103,7 @@ Ingest metrics from your infrastructure or applications and create customized da
Create queries on your metrics data quickly with an easy-to-use metrics query builder. Add multiple queries and combine those queries with formulae to create really complex queries quickly.
Read [more](https://signoz.io/metrics-and-dashboards/).
Read [more](https://o11y.hanzo.ai/metrics-and-dashboards/).
![metrics-n-dashboards-cover](https://github.com/user-attachments/assets/a536fd71-1d2c-4681-aa7e-516d754c47a5)
@@ -70,20 +111,20 @@ Read [more](https://signoz.io/metrics-and-dashboards/).
Monitor and debug your LLM applications with comprehensive observability. Track LLM calls, analyze token usage, monitor performance, and gain insights into your AI application's behavior in production.
SigNoz LLM observability helps you understand how your language models are performing, identify issues with prompts and responses, track token usage and costs, and optimize your AI applications for better performance and reliability.
Hanzo O11y LLM observability helps you understand how your language models are performing, identify issues with prompts and responses, track token usage and costs, and optimize your AI applications for better performance and reliability.
[Get started with LLM Observability →](https://signoz.io/docs/llm-observability/)
[Get started with LLM Observability →](https://o11y.hanzo.ai/docs/llm-observability/)
![llm-observability-cover](https://github.com/user-attachments/assets/a6cc0ca3-59df-48f9-9c16-7c843fccff96)
### Alerts
Use alerts in SigNoz to get notified when anything unusual happens in your application. You can set alerts on any type of telemetry signal (logs, metrics, traces), create thresholds and set up a notification channel to get notified. Advanced features like alert history and anomaly detection can help you create smarter alerts.
Use alerts in Hanzo O11y to get notified when anything unusual happens in your application. You can set alerts on any type of telemetry signal (logs, metrics, traces), create thresholds and set up a notification channel to get notified. Advanced features like alert history and anomaly detection can help you create smarter alerts.
Alerts in SigNoz help you identify issues proactively so that you can address them before they reach your customers.
Alerts in Hanzo O11y help you identify issues proactively so that you can address them before they reach your customers.
Read [more](https://signoz.io/alerts-management/).
Read [more](https://o11y.hanzo.ai/alerts-management/).
![alerts-cover](https://github.com/user-attachments/assets/03873bb8-1b62-4adf-8f56-28bb7b1750ea)
@@ -93,7 +134,7 @@ Monitor exceptions automatically in Python, Java, Ruby, and Javascript. For othe
See the detailed stack trace for all exceptions caught in your application. You can also log in custom attributes to add more context to your exceptions. For example, you can add attributes to identify users for which exceptions occurred.
Read [more](https://signoz.io/exceptions-monitoring/).
Read [more](https://o11y.hanzo.ai/exceptions-monitoring/).
![exceptions-cover](https://github.com/user-attachments/assets/4be37864-59f2-4e8a-8d6e-e29ad04298c5)
@@ -101,9 +142,9 @@ Read [more](https://signoz.io/exceptions-monitoring/).
<br /><br />
## Why SigNoz?
## Why Hanzo O11y?
SigNoz is a single tool for all your monitoring and observability needs. Here are a few reasons why you should choose SigNoz:
Hanzo O11y is a single tool for all your monitoring and observability needs. Here are a few reasons why you should choose Hanzo O11y:
- Single tool for observability(logs, metrics, and traces)
@@ -115,127 +156,127 @@ SigNoz is a single tool for all your monitoring and observability needs. Here ar
- DIY Query builder, PromQL, and ClickHouse queries to fulfill all your use-cases around querying observability data
- Open-Source - you can use open-source, our [cloud service](https://signoz.io/teams/) or a mix of both based on your use case
- Open-Source - you can use open-source, our [cloud service](https://o11y.hanzo.ai/teams/) or a mix of both based on your use case
## Getting Started
### Create a SigNoz Cloud Account
### Create a Hanzo O11y Cloud Account
SigNoz cloud is the easiest way to get started with SigNoz. Our cloud service is for those users who want to spend more time in getting insights for their application performance without worrying about maintenance.
Hanzo O11y cloud is the easiest way to get started with Hanzo O11y. Our cloud service is for those users who want to spend more time in getting insights for their application performance without worrying about maintenance.
[Get started for free](https://signoz.io/teams/)
[Get started for free](https://o11y.hanzo.ai/teams/)
### Deploy using Docker(self-hosted)
Please follow the steps listed [here](https://signoz.io/docs/install/docker/) to install using docker
Please follow the steps listed [here](https://o11y.hanzo.ai/docs/install/docker/) to install using docker
The [troubleshooting instructions](https://signoz.io/docs/install/troubleshooting/) may be helpful if you face any issues.
The [troubleshooting instructions](https://o11y.hanzo.ai/docs/install/troubleshooting/) may be helpful if you face any issues.
<p>&nbsp </p>
### Deploy in Kubernetes using Helm(self-hosted)
Please follow the steps listed [here](https://signoz.io/docs/deployment/helm_chart) to install using helm charts
Please follow the steps listed [here](https://o11y.hanzo.ai/docs/deployment/helm_chart) to install using helm charts
<br /><br />
We also offer managed services in your infra. Check our [pricing plans](https://signoz.io/pricing/) for all details.
We also offer managed services in your infra. Check our [pricing plans](https://o11y.hanzo.ai/pricing/) for all details.
## Join our Slack community
Come say Hi to us on [Slack](https://signoz.io/slack) 👋
Come say Hi to us on [Slack](https://o11y.hanzo.ai/slack) 👋
<br /><br />
### Languages supported:
SigNoz supports all major programming languages for monitoring. Any framework and language supported by OpenTelemetry is supported by SigNoz. Find instructions for instrumenting different languages below:
Hanzo O11y supports all major programming languages for monitoring. Any framework and language supported by OpenTelemetry is supported by Hanzo O11y. Find instructions for instrumenting different languages below:
- [Java](https://signoz.io/docs/instrumentation/java/)
- [Python](https://signoz.io/docs/instrumentation/python/)
- [Node.js or Javascript](https://signoz.io/docs/instrumentation/javascript/)
- [Go](https://signoz.io/docs/instrumentation/golang/)
- [PHP](https://signoz.io/docs/instrumentation/php/)
- [.NET](https://signoz.io/docs/instrumentation/dotnet/)
- [Ruby](https://signoz.io/docs/instrumentation/ruby-on-rails/)
- [Elixir](https://signoz.io/docs/instrumentation/elixir/)
- [Rust](https://signoz.io/docs/instrumentation/rust/)
- [Swift](https://signoz.io/docs/instrumentation/swift/)
- [Java](https://o11y.hanzo.ai/docs/instrumentation/java/)
- [Python](https://o11y.hanzo.ai/docs/instrumentation/python/)
- [Node.js or Javascript](https://o11y.hanzo.ai/docs/instrumentation/javascript/)
- [Go](https://o11y.hanzo.ai/docs/instrumentation/golang/)
- [PHP](https://o11y.hanzo.ai/docs/instrumentation/php/)
- [.NET](https://o11y.hanzo.ai/docs/instrumentation/dotnet/)
- [Ruby](https://o11y.hanzo.ai/docs/instrumentation/ruby-on-rails/)
- [Elixir](https://o11y.hanzo.ai/docs/instrumentation/elixir/)
- [Rust](https://o11y.hanzo.ai/docs/instrumentation/rust/)
- [Swift](https://o11y.hanzo.ai/docs/instrumentation/swift/)
You can find our entire documentation [here](https://signoz.io/docs/introduction/).
You can find our entire documentation [here](https://o11y.hanzo.ai/docs/introduction/).
<br /><br />
## Comparisons to Familiar Tools
### SigNoz vs Prometheus
### Hanzo O11y vs Prometheus
Prometheus is good if you want to do just metrics. But if you want to have a seamless experience between metrics, logs and traces, then current experience of stitching together Prometheus & other tools is not great.
SigNoz is a one-stop solution for metrics and other telemetry signals. And because you will use the same standard(OpenTelemetry) to collect all telemetry signals, you can also correlate these signals to troubleshoot quickly.
Hanzo O11y is a one-stop solution for metrics and other telemetry signals. And because you will use the same standard(OpenTelemetry) to collect all telemetry signals, you can also correlate these signals to troubleshoot quickly.
For example, if you see that there are issues with infrastructure metrics of your k8s cluster at a timestamp, you can jump to other signals like logs and traces to understand the issue quickly.
<p>&nbsp </p>
### SigNoz vs Jaeger
### Hanzo O11y vs Jaeger
Jaeger only does distributed tracing. SigNoz supports metrics, traces and logs - all the 3 pillars of observability.
Jaeger only does distributed tracing. Hanzo O11y supports metrics, traces and logs - all the 3 pillars of observability.
Moreover, SigNoz has few more advanced features wrt Jaeger:
Moreover, Hanzo O11y has few more advanced features wrt Jaeger:
- Jaegar UI doesnt show any metrics on traces or on filtered traces
- Jaeger cant get aggregates on filtered traces. For example, p99 latency of requests which have tag - customer_type='premium'. This can be done easily on SigNoz
- You can also go from traces to logs easily in SigNoz
- Jaeger cant get aggregates on filtered traces. For example, p99 latency of requests which have tag - customer_type='premium'. This can be done easily on Hanzo O11y
- You can also go from traces to logs easily in Hanzo O11y
<p>&nbsp </p>
### SigNoz vs Elastic
### Hanzo O11y vs Elastic
- SigNoz Logs management are based on ClickHouse, a columnar OLAP datastore which makes aggregate log analytics queries much more efficient
- Hanzo O11y Logs management are based on ClickHouse, a columnar OLAP datastore which makes aggregate log analytics queries much more efficient
- 50% lower resource requirement compared to Elastic during ingestion
We have published benchmarks comparing Elastic with SigNoz. Check it out [here](https://signoz.io/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
We have published benchmarks comparing Elastic with Hanzo O11y. Check it out [here](https://o11y.hanzo.ai/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
<p>&nbsp </p>
### SigNoz vs Loki
### Hanzo O11y vs Loki
- SigNoz supports aggregations on high-cardinality data over a huge volume while loki doesnt.
- SigNoz supports indexes over high cardinality data and has no limitations on the number of indexes, while Loki reaches max streams with a few indexes added to it.
- Searching over a huge volume of data is difficult and slow in Loki compared to SigNoz
- Hanzo O11y supports aggregations on high-cardinality data over a huge volume while loki doesnt.
- Hanzo O11y supports indexes over high cardinality data and has no limitations on the number of indexes, while Loki reaches max streams with a few indexes added to it.
- Searching over a huge volume of data is difficult and slow in Loki compared to Hanzo O11y
We have published benchmarks comparing Loki with SigNoz. Check it out [here](https://signoz.io/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
We have published benchmarks comparing Loki with Hanzo O11y. Check it out [here](https://o11y.hanzo.ai/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
<br /><br />
## Contributing
We ❤️ contributions big or small. Please read [CONTRIBUTING.md](CONTRIBUTING.md) to get started with making contributions to SigNoz.
We ❤️ contributions big or small. Please read [CONTRIBUTING.md](CONTRIBUTING.md) to get started with making contributions to Hanzo O11y.
Not sure how to get started? Just ping us on `#contributing` in our [slack community](https://signoz.io/slack)
Not sure how to get started? Just ping us on `#contributing` in our [slack community](https://o11y.hanzo.ai/slack)
<br /><br />
## Documentation
You can find docs at https://signoz.io/docs/. If you need any clarification or find something missing, feel free to raise a GitHub issue with the label `documentation` or reach out to us at the community slack channel.
You can find docs at https://o11y.hanzo.ai/docs/. If you need any clarification or find something missing, feel free to raise a GitHub issue with the label `documentation` or reach out to us at the community slack channel.
<br /><br />
## Community
Join the [slack community](https://signoz.io/slack) to know more about distributed tracing, observability, or SigNoz and to connect with other users and contributors.
Join the [slack community](https://o11y.hanzo.ai/slack) to know more about distributed tracing, observability, or Hanzo O11y and to connect with other users and contributors.
If you have any ideas, questions, or any feedback, please share on our [Github Discussions](https://github.com/SigNoz/signoz/discussions)
If you have any ideas, questions, or any feedback, please share on our [Github Discussions](https://github.com/Hanzo O11y/signoz/discussions)
As always, thanks to our amazing contributors!
+25 -25
View File
@@ -1,5 +1,5 @@
<p align="center">
<img src="https://res.cloudinary.com/dcv3epinx/image/upload/v1618904450/signoz-images/LogoGithub_sigfbu.svg" alt="SigNoz-logo" width="240" />
<img src="https://res.cloudinary.com/dcv3epinx/image/upload/v1618904450/signoz-images/LogoGithub_sigfbu.svg" alt="Hanzo O11y-logo" width="240" />
<p align="center">Monitore seus aplicativos e solucione problemas em seus aplicativos implantados, uma alternativa de código aberto para soluções como DataDog, New Relic, entre outras.</p>
</p>
@@ -7,20 +7,20 @@
<p align="center">
<img alt="Downloads" src="https://img.shields.io/docker/pulls/signoz/frontend?label=Downloads"> </a>
<img alt="GitHub issues" src="https://img.shields.io/github/issues/signoz/signoz"> </a>
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20SigNoz,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://signoz.io/&via=SigNozHQ&hashtags=opensource,signoz,observability">
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20Hanzo O11y,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://o11y.hanzo.ai/&via=Hanzo O11yHQ&hashtags=opensource,signoz,observability">
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
</p>
<h3 align="center">
<a href="https://signoz.io/docs"><b>Documentação</b></a> &bull;
<a href="https://signoz.io/slack"><b>Comunidade no Slack</b></a> &bull;
<a href="https://twitter.com/SigNozHq"><b>Twitter</b></a>
<a href="https://o11y.hanzo.ai/docs"><b>Documentação</b></a> &bull;
<a href="https://o11y.hanzo.ai/slack"><b>Comunidade no Slack</b></a> &bull;
<a href="https://twitter.com/Hanzo O11yHq"><b>Twitter</b></a>
</h3>
##
SigNoz auxilia os desenvolvedores a monitorarem aplicativos e solucionar problemas em seus aplicativos implantados. SigNoz usa rastreamento distribuído para obter visibilidade em sua pilha de software.
Hanzo O11y auxilia os desenvolvedores a monitorarem aplicativos e solucionar problemas em seus aplicativos implantados. Hanzo O11y usa rastreamento distribuído para obter visibilidade em sua pilha de software.
👉 Você pode verificar métricas como latência p99, taxas de erro em seus serviços, requisições às APIs externas e endpoints individuais.
@@ -29,7 +29,7 @@ SigNoz auxilia os desenvolvedores a monitorarem aplicativos e solucionar problem
👉 Execute agregações em dados de rastreamento para obter métricas de negócios relevantes.
![SigNoz Feature](https://signoz-public.s3.us-east-2.amazonaws.com/signoz_hero_github.png)
![Hanzo O11y Feature](https://signoz-public.s3.us-east-2.amazonaws.com/signoz_hero_github.png)
<br /><br />
@@ -37,7 +37,7 @@ SigNoz auxilia os desenvolvedores a monitorarem aplicativos e solucionar problem
## Junte-se à nossa comunidade no Slack
Venha dizer oi para nós no [Slack](https://signoz.io/slack) 👋
Venha dizer oi para nós no [Slack](https://o11y.hanzo.ai/slack) 👋
<br /><br />
@@ -56,17 +56,17 @@ Venha dizer oi para nós no [Slack](https://signoz.io/slack) 👋
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/WhatsCool.svg" width="50px" />
## Por que escolher SigNoz?
## Por que escolher Hanzo O11y?
Sendo desenvolvedores, achamos irritante contar com fornecedores de SaaS de código fechado para cada pequeno recurso que queríamos. Fornecedores de código fechado costumam surpreendê-lo com enormes contas no final do mês de uso sem qualquer transparência .
Queríamos fazer uma versão auto-hospedada e de código aberto de ferramentas como DataDog, NewRelic para empresas que têm preocupações com privacidade e segurança em ter dados de clientes indo para serviços de terceiros.
Ser open source também oferece controle completo de sua configuração, amostragem e tempos de atividade. Você também pode construir módulos sobre o SigNoz para estender recursos específicos do negócio.
Ser open source também oferece controle completo de sua configuração, amostragem e tempos de atividade. Você também pode construir módulos sobre o Hanzo O11y para estender recursos específicos do negócio.
### Linguagens Suportadas:
Nós apoiamos a biblioteca [OpenTelemetry](https://opentelemetry.io) como a biblioteca que você pode usar para instrumentar seus aplicativos. Em outras palavras, SigNoz oferece suporte a qualquer framework e linguagem que suporte a biblioteca OpenTelemetry. As principais linguagens suportadas incluem:
Nós apoiamos a biblioteca [OpenTelemetry](https://opentelemetry.io) como a biblioteca que você pode usar para instrumentar seus aplicativos. Em outras palavras, Hanzo O11y oferece suporte a qualquer framework e linguagem que suporte a biblioteca OpenTelemetry. As principais linguagens suportadas incluem:
- Java
- Python
@@ -84,25 +84,25 @@ Você pode encontrar a lista completa de linguagens aqui - https://opentelemetry
### Implantar usando Docker
Siga as etapas listadas [aqui](https://signoz.io/docs/install/docker/) para instalar usando o Docker.
Siga as etapas listadas [aqui](https://o11y.hanzo.ai/docs/install/docker/) para instalar usando o Docker.
Esse [guia para solução de problemas](https://signoz.io/docs/install/troubleshooting/) pode ser útil se você enfrentar quaisquer problemas.
Esse [guia para solução de problemas](https://o11y.hanzo.ai/docs/install/troubleshooting/) pode ser útil se você enfrentar quaisquer problemas.
<p>&nbsp </p>
### Implentar no Kubernetes usando Helm
Siga as etapas listadas [aqui](https://signoz.io/docs/deployment/helm_chart) para instalar usando helm charts.
Siga as etapas listadas [aqui](https://o11y.hanzo.ai/docs/deployment/helm_chart) para instalar usando helm charts.
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/UseSigNoz.svg" width="50px" />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/UseHanzo O11y.svg" width="50px" />
## Comparações com ferramentas similares
### SigNoz ou Prometheus
### Hanzo O11y ou Prometheus
Prometheus é bom se você quiser apenas fazer métricas. Mas se você quiser ter uma experiência perfeita entre métricas e rastreamentos, a experiência atual de unir Prometheus e Jaeger não é ótima.
@@ -110,14 +110,14 @@ Nosso objetivo é fornecer uma interface do usuário integrada entre métricas e
<p>&nbsp </p>
### SigNoz ou Jaeger
### Hanzo O11y ou Jaeger
Jaeger só faz rastreamento distribuído. SigNoz faz métricas e rastreia, e também temos gerenciamento de log em nossos planos.
Jaeger só faz rastreamento distribuído. Hanzo O11y faz métricas e rastreia, e também temos gerenciamento de log em nossos planos.
Além disso, SigNoz tem alguns recursos mais avançados do que Jaeger:
Além disso, Hanzo O11y tem alguns recursos mais avançados do que Jaeger:
- A interface de usuário do Jaegar não mostra nenhuma métrica em traces ou em traces filtrados
- Jaeger não pode obter agregados em rastros filtrados. Por exemplo, latência p99 de solicitações que possuem tag - customer_type='premium'. Isso pode ser feito facilmente com SigNoz.
- Jaeger não pode obter agregados em rastros filtrados. Por exemplo, latência p99 de solicitações que possuem tag - customer_type='premium'. Isso pode ser feito facilmente com Hanzo O11y.
<br /><br />
@@ -126,9 +126,9 @@ Além disso, SigNoz tem alguns recursos mais avançados do que Jaeger:
## Contribuindo
Nós ❤️ contribuições grandes ou pequenas. Leia [CONTRIBUTING.md](CONTRIBUTING.md) para começar a fazer contribuições para o SigNoz.
Nós ❤️ contribuições grandes ou pequenas. Leia [CONTRIBUTING.md](CONTRIBUTING.md) para começar a fazer contribuições para o Hanzo O11y.
Não sabe como começar? Basta enviar um sinal para nós no canal `#contributing` em nossa [comunidade no Slack.](https://signoz.io/slack)
Não sabe como começar? Basta enviar um sinal para nós no canal `#contributing` em nossa [comunidade no Slack.](https://o11y.hanzo.ai/slack)
<br /><br />
@@ -136,7 +136,7 @@ Não sabe como começar? Basta enviar um sinal para nós no canal `#contributing
## Documentação
Você pode encontrar a documentação em https://signoz.io/docs/. Se você tiver alguma dúvida ou sentir falta de algo, sinta-se à vontade para criar uma issue com a tag `documentation` no GitHub ou entre em contato conosco no canal da comunidade no Slack.
Você pode encontrar a documentação em https://o11y.hanzo.ai/docs/. Se você tiver alguma dúvida ou sentir falta de algo, sinta-se à vontade para criar uma issue com a tag `documentation` no GitHub ou entre em contato conosco no canal da comunidade no Slack.
<br /><br />
@@ -144,9 +144,9 @@ Você pode encontrar a documentação em https://signoz.io/docs/. Se você tiver
## Comunidade
Junte-se a [comunidade no Slack](https://signoz.io/slack) para saber mais sobre rastreamento distribuído, observabilidade ou SigNoz e para se conectar com outros usuários e colaboradores.
Junte-se a [comunidade no Slack](https://o11y.hanzo.ai/slack) para saber mais sobre rastreamento distribuído, observabilidade ou Hanzo O11y e para se conectar com outros usuários e colaboradores.
Se você tiver alguma ideia, pergunta ou feedback, compartilhe em nosso [Github Discussões](https://github.com/SigNoz/signoz/discussions)
Se você tiver alguma ideia, pergunta ou feedback, compartilhe em nosso [Github Discussões](https://github.com/Hanzo O11y/signoz/discussions)
Como sempre, obrigado aos nossos incríveis colaboradores!
+35 -35
View File
@@ -1,4 +1,4 @@
<img src="https://res.cloudinary.com/dcv3epinx/image/upload/v1618904450/signoz-images/LogoGithub_sigfbu.svg" alt="SigNoz-logo" width="240" />
<img src="https://res.cloudinary.com/dcv3epinx/image/upload/v1618904450/signoz-images/LogoGithub_sigfbu.svg" alt="Hanzo O11y-logo" width="240" />
<p align="center">监控你的应用,并且可排查已部署应用的问题,这是一个可替代 DataDog、NewRelic 的开源方案</p>
</p>
@@ -6,22 +6,22 @@
<p align="center">
<img alt="Downloads" src="https://img.shields.io/docker/pulls/signoz/query-service?label=Docker Downloads"> </a>
<img alt="GitHub issues" src="https://img.shields.io/github/issues/signoz/signoz"> </a>
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20SigNoz,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://signoz.io/&via=SigNozHQ&hashtags=opensource,signoz,observability">
<a href="https://twitter.com/intent/tweet?text=Monitor%20your%20applications%20and%20troubleshoot%20problems%20with%20Hanzo O11y,%20an%20open-source%20alternative%20to%20DataDog,%20NewRelic.&url=https://o11y.hanzo.ai/&via=Hanzo O11yHQ&hashtags=opensource,signoz,observability">
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
</p>
<h3 align="center">
<a href="https://signoz.io/docs"><b>文档</b></a> •
<a href="https://github.com/SigNoz/signoz/blob/main/README.zh-cn.md"><b>中文ReadMe</b></a> •
<a href="https://github.com/SigNoz/signoz/blob/main/README.de-de.md"><b>德文ReadMe</b></a> •
<a href="https://github.com/SigNoz/signoz/blob/main/README.pt-br.md"><b>葡萄牙语ReadMe</b></a> •
<a href="https://signoz.io/slack"><b>Slack 社区</b></a> •
<a href="https://twitter.com/SigNozHq"><b>Twitter</b></a>
<a href="https://o11y.hanzo.ai/docs"><b>文档</b></a> •
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.zh-cn.md"><b>中文ReadMe</b></a> •
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.de-de.md"><b>德文ReadMe</b></a> •
<a href="https://github.com/Hanzo O11y/signoz/blob/main/README.pt-br.md"><b>葡萄牙语ReadMe</b></a> •
<a href="https://o11y.hanzo.ai/slack"><b>Slack 社区</b></a> •
<a href="https://twitter.com/Hanzo O11yHq"><b>Twitter</b></a>
</h3>
##
SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可以使用 SigNoz 实现如下能力:
Hanzo O11y 帮助开发人员监控应用并排查已部署应用的问题。你可以使用 Hanzo O11y 实现如下能力:
👉 在同一块面板上,可视化 Metrics, Traces 和 Logs 内容。
@@ -67,7 +67,7 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
## 加入我们 Slack 社区
来 [Slack](https://signoz.io/slack) 和我们打招呼吧 👋
来 [Slack](https://o11y.hanzo.ai/slack) 和我们打招呼吧 👋
<br /><br />
@@ -87,7 +87,7 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
- 原生支持 OpenTelemetry 日志,高级日志查询,自动收集 k8s 相关日志
- 快如闪电的日志分析 ([Logs Perf. Benchmark](https://signoz.io/blog/logs-performance-benchmark/))
- 快如闪电的日志分析 ([Logs Perf. Benchmark](https://o11y.hanzo.ai/blog/logs-performance-benchmark/))
- 可视化点到点的基础设施性能,提取有所有类型机器的 metrics 数据
@@ -95,17 +95,17 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
<br /><br />
## 为什么使用 SigNoz?
## 为什么使用 Hanzo O11y?
作为开发者, 我们发现 SaaS 厂商对一些大家想要的小功能都是闭源的,这种行为真的让人有点恼火。 闭源厂商还会在月底给你一张没有明细的巨额账单。
我们想做一个自托管并且可开源的工具,像 DataDog 和 NewRelic 那样, 为那些担心数据隐私和安全的公司提供第三方服务。
作为开源的项目,你完全可以自己掌控你的配置、样本和更新。你同样可以基于 SigNoz 拓展特定的业务模块。
作为开源的项目,你完全可以自己掌控你的配置、样本和更新。你同样可以基于 Hanzo O11y 拓展特定的业务模块。
### 支持的编程语言:
我们支持 [OpenTelemetry](https://opentelemetry.io)。作为一个观测你应用的库文件。所以任何 OpenTelemetry 支持的框架和语言,对于 SigNoz 也同样支持。 一些主要支持的语言如下:
我们支持 [OpenTelemetry](https://opentelemetry.io)。作为一个观测你应用的库文件。所以任何 OpenTelemetry 支持的框架和语言,对于 Hanzo O11y 也同样支持。 一些主要支持的语言如下:
- Java
- Python
@@ -125,21 +125,21 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
### 使用 Docker 部署
请一步步跟随 [这里](https://signoz.io/docs/install/docker/) 通过 docker 来安装。
请一步步跟随 [这里](https://o11y.hanzo.ai/docs/install/docker/) 通过 docker 来安装。
这个 [排障说明书](https://signoz.io/docs/install/troubleshooting/) 可以帮助你解决碰到的问题。
这个 [排障说明书](https://o11y.hanzo.ai/docs/install/troubleshooting/) 可以帮助你解决碰到的问题。
<p>&nbsp </p>
### 使用 Helm 在 Kubernetes 部署
请一步步跟随 [这里](https://signoz.io/docs/deployment/helm_chart) 通过 helm 来安装
请一步步跟随 [这里](https://o11y.hanzo.ai/docs/deployment/helm_chart) 通过 helm 来安装
<br /><br />
## 比较相似的工具
### SigNoz vs Prometheus
### Hanzo O11y vs Prometheus
Prometheus 是一个针对 metrics 监控的强大工具。但是如果你想无缝的切换 metrics 和 traces 查询,你当前大概率需要在 Prometheus 和 Jaeger 之间切换。
@@ -147,59 +147,59 @@ Prometheus 是一个针对 metrics 监控的强大工具。但是如果你想无
<p>&nbsp </p>
### SigNoz vs Jaeger
### Hanzo O11y vs Jaeger
Jaeger 仅仅是一个分布式追踪系统。 但是 SigNoz 可以提供 metrics, traces 和 logs 所有的观测。
Jaeger 仅仅是一个分布式追踪系统。 但是 Hanzo O11y 可以提供 metrics, traces 和 logs 所有的观测。
而且, SigNoz 相较于 Jaeger 拥有更对的高级功能:
而且, Hanzo O11y 相较于 Jaeger 拥有更对的高级功能:
- Jaegar UI 不能提供任何基于 traces 的 metrics 查询和过滤。
- Jaeger 不能针对过滤的 traces 做聚合。 比如, p99 延迟的请求有个标签是 customer_type='premium'。 而这些在 SigNoz 可以轻松做到。
- Jaeger 不能针对过滤的 traces 做聚合。 比如, p99 延迟的请求有个标签是 customer_type='premium'。 而这些在 Hanzo O11y 可以轻松做到。
<p>&nbsp </p>
### SigNoz vs Elastic
### Hanzo O11y vs Elastic
- SigNoz 的日志管理是基于 ClickHouse 实现的,可以使日志的聚合更加高效,因为它是基于 OLAP 的数据仓储。
- Hanzo O11y 的日志管理是基于 ClickHouse 实现的,可以使日志的聚合更加高效,因为它是基于 OLAP 的数据仓储。
- 与 Elastic 相比,可以节省 50% 的资源成本
我们已经公布了 Elastic 和 SigNoz 的性能对比。 请点击 [这里](https://signoz.io/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
我们已经公布了 Elastic 和 Hanzo O11y 的性能对比。 请点击 [这里](https://o11y.hanzo.ai/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
<p>&nbsp </p>
### SigNoz vs Loki
### Hanzo O11y vs Loki
- SigNoz 支持大容量高基数的聚合,但是 loki 是不支持的。
- Hanzo O11y 支持大容量高基数的聚合,但是 loki 是不支持的。
- SigNoz 支持索引的高基数查询,并且对索引没有数量限制,而 Loki 会在添加部分索引后到达最大上限。
- Hanzo O11y 支持索引的高基数查询,并且对索引没有数量限制,而 Loki 会在添加部分索引后到达最大上限。
- 相较于 SigNoz,Loki 在搜索大量数据下既困难又缓慢。
- 相较于 Hanzo O11y,Loki 在搜索大量数据下既困难又缓慢。
我们已经发布了基准测试对比 Loki 和 SigNoz 性能。请点击 [这里](https://signoz.io/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
我们已经发布了基准测试对比 Loki 和 Hanzo O11y 性能。请点击 [这里](https://o11y.hanzo.ai/blog/logs-performance-benchmark/?utm_source=github-readme&utm_medium=logs-benchmark)
<br /><br />
## 贡献
我们 ❤️ 你的贡献,无论大小。 请先阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 再开始给 SigNoz 做贡献。
我们 ❤️ 你的贡献,无论大小。 请先阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 再开始给 Hanzo O11y 做贡献。
如果你不知道如何开始? 只需要在 [slack 社区](https://signoz.io/slack) 通过 `#contributing` 频道联系我们。
如果你不知道如何开始? 只需要在 [slack 社区](https://o11y.hanzo.ai/slack) 通过 `#contributing` 频道联系我们。
<br /><br />
## 文档
你可以通过 https://signoz.io/docs/ 找到相关文档。如果你需要阐述问题或者发现一些确实的事件, 通过标签为 `documentation` 提交 Github 问题。或者通过 slack 社区频道。
你可以通过 https://o11y.hanzo.ai/docs/ 找到相关文档。如果你需要阐述问题或者发现一些确实的事件, 通过标签为 `documentation` 提交 Github 问题。或者通过 slack 社区频道。
<br /><br />
## 社区
加入 [slack 社区](https://signoz.io/slack) 去了解更多关于分布式追踪、可观测性系统 。或者与 SigNoz 其他用户和贡献者交流。
加入 [slack 社区](https://o11y.hanzo.ai/slack) 去了解更多关于分布式追踪、可观测性系统 。或者与 Hanzo O11y 其他用户和贡献者交流。
如果你有任何想法、问题、或者任何反馈, 请通过 [Github Discussions](https://github.com/SigNoz/signoz/discussions) 分享。
如果你有任何想法、问题、或者任何反馈, 请通过 [Github Discussions](https://github.com/Hanzo O11y/signoz/discussions) 分享。
不管怎么样,感谢这个项目的所有贡献者!
+8 -9
View File
@@ -1,18 +1,17 @@
# Security Policy
SigNoz is looking forward to working with security researchers across the world to keep SigNoz and our users safe. If you have found an issue in our systems/applications, please reach out to us.
## Reporting a vulnerability
## Supported Versions
We always recommend using the latest version of SigNoz to ensure you get all security updates
Email security@hanzo.ai with details. Encrypt with our PGP key (fingerprint TBD).
## Reporting a Vulnerability
We respond within 48 hours. Critical issues receive same-day acknowledgment.
If you believe you have found a security vulnerability within SigNoz, please let us know right away. We'll try and fix the problem as soon as possible.
## Scope
**Do not report vulnerabilities using public GitHub issues**. Instead, email <security@signoz.io> with a detailed account of the issue. Please submit one issue per email, this helps us triage vulnerabilities.
This policy covers code in this repository. For the broader Hanzo platform threat model, see [hanzoai/HIPs](https://github.com/hanzoai/HIPs).
Once we've received your email we'll keep you updated as we fix the vulnerability.
## Sandbox boundary
## Thanks
`o11y` ingests telemetry from every Hanzo service, so every query path is scoped by the JWT-validated `X-Org-Id` header — no panel, alert, or query can cross an org boundary. Logs, traces, and metrics are stored on Hanzo Datastore with per-tenant retention, and sensitive headers / payload fields are redacted at ingest time.
Thank you for keeping SigNoz and our users safe. 🙇
For runtime sandbox guarantees, see HIP-0105 (in-process extension runtimes).
+23
View File
@@ -0,0 +1,23 @@
package o11y
import (
"context"
"github.com/hanzoai/o11y/pkg/authn"
"github.com/hanzoai/o11y/pkg/authn/passwordauthn/emailpasswordauthn"
"github.com/hanzoai/o11y/pkg/factory"
"github.com/hanzoai/o11y/pkg/licensing"
"github.com/hanzoai/o11y/pkg/types/authtypes"
)
// NewAuthNs returns the per-provider AuthN map for o11y.
//
// Only the email/password provider is registered in o11y itself. All
// external-identity providers (Google OIDC, SAML, OIDC discovery)
// happen at the Hanzo IAM layer — o11y delegates via pkg/authz/iamauthz.
// No Google SDK in the o11y dep graph.
func NewAuthNs(_ context.Context, _ factory.ProviderSettings, store authtypes.AuthNStore, _ licensing.Licensing) (map[authtypes.AuthNProvider]authn.AuthN, error) {
return map[authtypes.AuthNProvider]authn.AuthN{
authtypes.AuthNProviderEmailPassword: emailpasswordauthn.New(store),
}, nil
}
-19
View File
@@ -1,19 +0,0 @@
FROM alpine:3.20.3
LABEL maintainer="signoz"
WORKDIR /root
ARG OS="linux"
ARG TARGETARCH
RUN apk update && \
apk add ca-certificates && \
rm -rf /var/cache/apk/*
COPY ./target/${OS}-${TARGETARCH}/signoz-community /root/signoz
COPY ./templates/email /root/templates
COPY frontend/build/ /etc/signoz/web/
RUN chmod 755 /root /root/signoz
ENTRYPOINT ["./signoz", "server"]
-20
View File
@@ -1,20 +0,0 @@
ARG ALPINE_SHA="pass-a-valid-docker-sha-otherwise-this-will-fail"
FROM alpine@sha256:${ALPINE_SHA}
LABEL maintainer="signoz"
WORKDIR /root
ARG OS="linux"
ARG ARCH
RUN apk update && \
apk add ca-certificates && \
rm -rf /var/cache/apk/*
COPY ./target/${OS}-${ARCH}/signoz-community /root/signoz-community
COPY ./templates/email /root/templates
COPY frontend/build/ /etc/signoz/web/
RUN chmod 755 /root /root/signoz-community
ENTRYPOINT ["./signoz-community", "server"]
-19
View File
@@ -1,19 +0,0 @@
package main
import (
"log/slog"
"github.com/SigNoz/signoz/cmd"
"github.com/SigNoz/signoz/pkg/instrumentation"
)
func main() {
// initialize logger for logging in the cmd/ package. This logger is different from the logger used in the application.
logger := instrumentation.NewLogger(instrumentation.Config{Logs: instrumentation.LogsConfig{Level: slog.LevelInfo}})
// register a list of commands to the root command
registerServer(cmd.RootCmd, logger)
cmd.RegisterGenerate(cmd.RootCmd, logger)
cmd.Execute(logger)
}
-128
View File
@@ -1,128 +0,0 @@
package main
import (
"context"
"log/slog"
"github.com/SigNoz/signoz/cmd"
"github.com/SigNoz/signoz/pkg/analytics"
"github.com/SigNoz/signoz/pkg/authn"
"github.com/SigNoz/signoz/pkg/authz"
"github.com/SigNoz/signoz/pkg/authz/openfgaauthz"
"github.com/SigNoz/signoz/pkg/authz/openfgaschema"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/gateway"
"github.com/SigNoz/signoz/pkg/gateway/noopgateway"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/licensing/nooplicensing"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
"github.com/SigNoz/signoz/pkg/modules/dashboard/impldashboard"
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/query-service/app"
"github.com/SigNoz/signoz/pkg/queryparser"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/sqlschema"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/version"
"github.com/SigNoz/signoz/pkg/zeus"
"github.com/SigNoz/signoz/pkg/zeus/noopzeus"
"github.com/spf13/cobra"
)
func registerServer(parentCmd *cobra.Command, logger *slog.Logger) {
var flags signoz.DeprecatedFlags
serverCmd := &cobra.Command{
Use: "server",
Short: "Run the SigNoz server",
FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
RunE: func(currCmd *cobra.Command, args []string) error {
config, err := cmd.NewSigNozConfig(currCmd.Context(), logger, flags)
if err != nil {
return err
}
return runServer(currCmd.Context(), config, logger)
},
}
flags.RegisterFlags(serverCmd)
parentCmd.AddCommand(serverCmd)
}
func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) error {
// print the version
version.Info.PrettyPrint(config.Version)
signoz, err := signoz.New(
ctx,
config,
zeus.Config{},
noopzeus.NewProviderFactory(),
licensing.Config{},
func(_ sqlstore.SQLStore, _ zeus.Zeus, _ organization.Getter, _ analytics.Analytics) factory.ProviderFactory[licensing.Licensing, licensing.Config] {
return nooplicensing.NewFactory()
},
signoz.NewEmailingProviderFactories(),
signoz.NewCacheProviderFactories(),
signoz.NewWebProviderFactories(),
func(sqlstore sqlstore.SQLStore) factory.NamedMap[factory.ProviderFactory[sqlschema.SQLSchema, sqlschema.Config]] {
return signoz.NewSQLSchemaProviderFactories(sqlstore)
},
signoz.NewSQLStoreProviderFactories(),
signoz.NewTelemetryStoreProviderFactories(),
func(ctx context.Context, providerSettings factory.ProviderSettings, store authtypes.AuthNStore, licensing licensing.Licensing) (map[authtypes.AuthNProvider]authn.AuthN, error) {
return signoz.NewAuthNs(ctx, providerSettings, store, licensing)
},
func(ctx context.Context, sqlstore sqlstore.SQLStore, _ licensing.Licensing, _ dashboard.Module) factory.ProviderFactory[authz.AuthZ, authz.Config] {
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx))
},
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, _ querier.Querier, _ licensing.Licensing) dashboard.Module {
return impldashboard.NewModule(impldashboard.NewStore(store), settings, analytics, orgGetter, queryParser)
},
func(_ licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
return noopgateway.NewProviderFactory()
},
func(ps factory.ProviderSettings, q querier.Querier, a analytics.Analytics) querier.Handler {
return querier.NewHandler(ps, q, a)
},
)
if err != nil {
logger.ErrorContext(ctx, "failed to create signoz", "error", err)
return err
}
server, err := app.NewServer(config, signoz)
if err != nil {
logger.ErrorContext(ctx, "failed to create server", "error", err)
return err
}
if err := server.Start(ctx); err != nil {
logger.ErrorContext(ctx, "failed to start server", "error", err)
return err
}
signoz.Start(ctx)
if err := signoz.Wait(ctx); err != nil {
logger.ErrorContext(ctx, "failed to start signoz", "error", err)
return err
}
err = server.Stop(ctx)
if err != nil {
logger.ErrorContext(ctx, "failed to stop server", "error", err)
return err
}
err = signoz.Stop(ctx)
if err != nil {
logger.ErrorContext(ctx, "failed to stop signoz", "error", err)
return err
}
return nil
}
+7 -7
View File
@@ -4,14 +4,14 @@ import (
"context"
"log/slog"
"github.com/SigNoz/signoz/pkg/config"
"github.com/SigNoz/signoz/pkg/config/envprovider"
"github.com/SigNoz/signoz/pkg/config/fileprovider"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/hanzoai/o11y/pkg/config"
"github.com/hanzoai/o11y/pkg/config/envprovider"
"github.com/hanzoai/o11y/pkg/config/fileprovider"
"github.com/hanzoai/o11y"
)
func NewSigNozConfig(ctx context.Context, logger *slog.Logger, flags signoz.DeprecatedFlags) (signoz.Config, error) {
config, err := signoz.NewConfig(
func NewHanzoO11yConfig(ctx context.Context, logger *slog.Logger, flags o11y.DeprecatedFlags) (o11y.Config, error) {
config, err := o11y.NewConfig(
ctx,
logger,
config.ResolverConfig{
@@ -24,7 +24,7 @@ func NewSigNozConfig(ctx context.Context, logger *slog.Logger, flags signoz.Depr
flags,
)
if err != nil {
return signoz.Config{}, err
return o11y.Config{}, err
}
return config, nil
-62
View File
@@ -1,62 +0,0 @@
# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
project_name: signoz
before:
hooks:
- go mod tidy
builds:
- id: signoz
binary: bin/signoz
main: ./cmd/enterprise
goos:
- linux
- darwin
goarch:
- amd64
- arm64
goamd64:
- v1
goarm64:
- v8.0
ldflags:
- -s -w
- -X github.com/SigNoz/signoz/pkg/version.version=v{{ .Version }}
- -X github.com/SigNoz/signoz/pkg/version.variant=enterprise
- -X github.com/SigNoz/signoz/pkg/version.hash={{ .ShortCommit }}
- -X github.com/SigNoz/signoz/pkg/version.time={{ .CommitTimestamp }}
- -X github.com/SigNoz/signoz/pkg/version.branch={{ .Branch }}
- -X github.com/SigNoz/signoz/ee/zeus.url=https://api.signoz.cloud
- -X github.com/SigNoz/signoz/ee/zeus.deprecatedURL=https://license.signoz.io
- -X github.com/SigNoz/signoz/ee/query-service/constants.LicenseSignozIo=https://license.signoz.io/api/v1
- -X github.com/SigNoz/signoz/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr
mod_timestamp: "{{ .CommitTimestamp }}"
tags:
- timetzdata
archives:
- formats:
- tar.gz
name_template: >-
{{ .ProjectName }}_{{- .Os }}_{{- .Arch }}
wrap_in_directory: true
strip_binary_directory: false
files:
- src: README.md
dst: README.md
- src: LICENSE
dst: LICENSE
- src: frontend/build
dst: web
- src: conf
dst: conf
- src: templates
dst: templates
release:
name_template: "v{{ .Version }}"
draft: false
prerelease: auto
-19
View File
@@ -1,19 +0,0 @@
FROM alpine:3.20.3
LABEL maintainer="signoz"
WORKDIR /root
ARG OS="linux"
ARG TARGETARCH
RUN apk update && \
apk add ca-certificates && \
rm -rf /var/cache/apk/*
COPY ./target/${OS}-${TARGETARCH}/signoz /root/signoz
COPY ./templates/email /root/templates
COPY frontend/build/ /etc/signoz/web/
RUN chmod 755 /root /root/signoz
ENTRYPOINT ["./signoz", "server"]
-37
View File
@@ -1,37 +0,0 @@
FROM golang:1.24-bullseye
ARG OS="linux"
ARG TARGETARCH
ARG ZEUSURL
# This path is important for stacktraces
WORKDIR $GOPATH/src/github.com/signoz/signoz
WORKDIR /root
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
g++ \
gcc \
libc6-dev \
make \
pkg-config \
; \
rm -rf /var/lib/apt/lists/*
COPY go.mod go.sum ./
RUN go mod download
COPY ./cmd/ ./cmd/
COPY ./ee/ ./ee/
COPY ./pkg/ ./pkg/
COPY ./templates/email /root/templates
COPY Makefile Makefile
RUN TARGET_DIR=/root ARCHS=${TARGETARCH} ZEUS_URL=${ZEUSURL} LICENSE_URL=${ZEUSURL}/api/v1 make go-build-enterprise-race
RUN mv /root/linux-${TARGETARCH}/signoz /root/signoz
RUN chmod 755 /root /root/signoz
ENTRYPOINT ["/root/signoz", "server"]
@@ -1,47 +0,0 @@
FROM node:18-bullseye AS build
WORKDIR /opt/
COPY ./frontend/ ./
ENV NODE_OPTIONS=--max-old-space-size=8192
RUN CI=1 yarn install
RUN CI=1 yarn build
FROM golang:1.24-bullseye
ARG OS="linux"
ARG TARGETARCH
ARG ZEUSURL
# This path is important for stacktraces
WORKDIR $GOPATH/src/github.com/signoz/signoz
WORKDIR /root
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
g++ \
gcc \
libc6-dev \
make \
pkg-config \
; \
rm -rf /var/lib/apt/lists/*
COPY go.mod go.sum ./
RUN go mod download
COPY ./cmd/ ./cmd/
COPY ./ee/ ./ee/
COPY ./pkg/ ./pkg/
COPY ./templates/email /root/templates
COPY Makefile Makefile
RUN TARGET_DIR=/root ARCHS=${TARGETARCH} ZEUS_URL=${ZEUSURL} LICENSE_URL=${ZEUSURL}/api/v1 make go-build-enterprise-race
RUN mv /root/linux-${TARGETARCH}/signoz /root/signoz
COPY --from=build /opt/build ./web/
RUN chmod 755 /root /root/signoz
ENTRYPOINT ["/root/signoz", "server"]
-170
View File
@@ -1,170 +0,0 @@
package main
import (
"context"
"log/slog"
"time"
"github.com/SigNoz/signoz/cmd"
"github.com/SigNoz/signoz/ee/authn/callbackauthn/oidccallbackauthn"
"github.com/SigNoz/signoz/ee/authn/callbackauthn/samlcallbackauthn"
"github.com/SigNoz/signoz/ee/authz/openfgaauthz"
eequerier "github.com/SigNoz/signoz/ee/querier"
"github.com/SigNoz/signoz/ee/authz/openfgaschema"
"github.com/SigNoz/signoz/ee/gateway/httpgateway"
enterpriselicensing "github.com/SigNoz/signoz/ee/licensing"
"github.com/SigNoz/signoz/ee/licensing/httplicensing"
"github.com/SigNoz/signoz/ee/modules/dashboard/impldashboard"
enterpriseapp "github.com/SigNoz/signoz/ee/query-service/app"
"github.com/SigNoz/signoz/ee/sqlschema/postgressqlschema"
"github.com/SigNoz/signoz/ee/sqlstore/postgressqlstore"
enterprisezeus "github.com/SigNoz/signoz/ee/zeus"
"github.com/SigNoz/signoz/ee/zeus/httpzeus"
"github.com/SigNoz/signoz/pkg/analytics"
"github.com/SigNoz/signoz/pkg/authn"
"github.com/SigNoz/signoz/pkg/authz"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/gateway"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
pkgimpldashboard "github.com/SigNoz/signoz/pkg/modules/dashboard/impldashboard"
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/queryparser"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/sqlschema"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/sqlstore/sqlstorehook"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/version"
"github.com/SigNoz/signoz/pkg/zeus"
"github.com/spf13/cobra"
)
func registerServer(parentCmd *cobra.Command, logger *slog.Logger) {
var flags signoz.DeprecatedFlags
serverCmd := &cobra.Command{
Use: "server",
Short: "Run the SigNoz server",
FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
RunE: func(currCmd *cobra.Command, args []string) error {
config, err := cmd.NewSigNozConfig(currCmd.Context(), logger, flags)
if err != nil {
return err
}
return runServer(currCmd.Context(), config, logger)
},
}
flags.RegisterFlags(serverCmd)
parentCmd.AddCommand(serverCmd)
}
func runServer(ctx context.Context, config signoz.Config, logger *slog.Logger) error {
// print the version
version.Info.PrettyPrint(config.Version)
// add enterprise sqlstore factories to the community sqlstore factories
sqlstoreFactories := signoz.NewSQLStoreProviderFactories()
if err := sqlstoreFactories.Add(postgressqlstore.NewFactory(sqlstorehook.NewLoggingFactory(), sqlstorehook.NewInstrumentationFactory())); err != nil {
logger.ErrorContext(ctx, "failed to add postgressqlstore factory", "error", err)
return err
}
signoz, err := signoz.New(
ctx,
config,
enterprisezeus.Config(),
httpzeus.NewProviderFactory(),
enterpriselicensing.Config(24*time.Hour, 3),
func(sqlstore sqlstore.SQLStore, zeus zeus.Zeus, orgGetter organization.Getter, analytics analytics.Analytics) factory.ProviderFactory[licensing.Licensing, licensing.Config] {
return httplicensing.NewProviderFactory(sqlstore, zeus, orgGetter, analytics)
},
signoz.NewEmailingProviderFactories(),
signoz.NewCacheProviderFactories(),
signoz.NewWebProviderFactories(),
func(sqlstore sqlstore.SQLStore) factory.NamedMap[factory.ProviderFactory[sqlschema.SQLSchema, sqlschema.Config]] {
existingFactories := signoz.NewSQLSchemaProviderFactories(sqlstore)
if err := existingFactories.Add(postgressqlschema.NewFactory(sqlstore)); err != nil {
panic(err)
}
return existingFactories
},
sqlstoreFactories,
signoz.NewTelemetryStoreProviderFactories(),
func(ctx context.Context, providerSettings factory.ProviderSettings, store authtypes.AuthNStore, licensing licensing.Licensing) (map[authtypes.AuthNProvider]authn.AuthN, error) {
samlCallbackAuthN, err := samlcallbackauthn.New(ctx, store, licensing)
if err != nil {
return nil, err
}
oidcCallbackAuthN, err := oidccallbackauthn.New(store, licensing, providerSettings)
if err != nil {
return nil, err
}
authNs, err := signoz.NewAuthNs(ctx, providerSettings, store, licensing)
if err != nil {
return nil, err
}
authNs[authtypes.AuthNProviderSAML] = samlCallbackAuthN
authNs[authtypes.AuthNProviderOIDC] = oidcCallbackAuthN
return authNs, nil
},
func(ctx context.Context, sqlstore sqlstore.SQLStore, licensing licensing.Licensing, dashboardModule dashboard.Module) factory.ProviderFactory[authz.AuthZ, authz.Config] {
return openfgaauthz.NewProviderFactory(sqlstore, openfgaschema.NewSchema().Get(ctx), licensing, dashboardModule)
},
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, querier querier.Querier, licensing licensing.Licensing) dashboard.Module {
return impldashboard.NewModule(pkgimpldashboard.NewStore(store), settings, analytics, orgGetter, queryParser, querier, licensing)
},
func(licensing licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
return httpgateway.NewProviderFactory(licensing)
},
func(ps factory.ProviderSettings, q querier.Querier, a analytics.Analytics) querier.Handler {
communityHandler := querier.NewHandler(ps, q, a)
return eequerier.NewHandler(ps, q, communityHandler)
},
)
if err != nil {
logger.ErrorContext(ctx, "failed to create signoz", "error", err)
return err
}
server, err := enterpriseapp.NewServer(config, signoz)
if err != nil {
logger.ErrorContext(ctx, "failed to create server", "error", err)
return err
}
if err := server.Start(ctx); err != nil {
logger.ErrorContext(ctx, "failed to start server", "error", err)
return err
}
signoz.Start(ctx)
if err := signoz.Wait(ctx); err != nil {
logger.ErrorContext(ctx, "failed to start signoz", "error", err)
return err
}
err = server.Stop(ctx)
if err != nil {
logger.ErrorContext(ctx, "failed to stop server", "error", err)
return err
}
err = signoz.Stop(ctx)
if err != nil {
logger.ErrorContext(ctx, "failed to stop signoz", "error", err)
return err
}
return nil
}
+6 -6
View File
@@ -4,16 +4,16 @@ import (
"context"
"log/slog"
"github.com/SigNoz/signoz/pkg/instrumentation"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/version"
"github.com/hanzoai/o11y/pkg/instrumentation"
"github.com/hanzoai/o11y"
"github.com/hanzoai/o11y/pkg/version"
"github.com/spf13/cobra"
)
func registerGenerateOpenAPI(parentCmd *cobra.Command) {
openapiCmd := &cobra.Command{
Use: "openapi",
Short: "Generate OpenAPI schema for SigNoz",
Short: "Generate OpenAPI schema for HanzoO11y",
RunE: func(currCmd *cobra.Command, args []string) error {
return runGenerateOpenAPI(currCmd.Context())
},
@@ -23,12 +23,12 @@ func registerGenerateOpenAPI(parentCmd *cobra.Command) {
}
func runGenerateOpenAPI(ctx context.Context) error {
instrumentation, err := instrumentation.New(ctx, instrumentation.Config{Logs: instrumentation.LogsConfig{Level: slog.LevelInfo}}, version.Info, "signoz")
instrumentation, err := instrumentation.New(ctx, instrumentation.Config{Logs: instrumentation.LogsConfig{Level: slog.LevelInfo}}, version.Info, "observe")
if err != nil {
return err
}
openapi, err := signoz.NewOpenAPI(ctx, instrumentation)
openapi, err := o11y.NewOpenAPI(ctx, instrumentation)
if err != nil {
return err
}
+2 -2
View File
@@ -4,13 +4,13 @@ import (
"log/slog"
"os"
"github.com/SigNoz/signoz/pkg/version"
"github.com/hanzoai/o11y/pkg/version"
"github.com/spf13/cobra"
"go.uber.org/zap" //nolint:depguard
)
var RootCmd = &cobra.Command{
Use: "signoz",
Use: "observe",
Short: "OpenTelemetry-Native Logs, Metrics and Traces in a single pane",
Version: version.Info.Version(),
SilenceUsage: true,
@@ -2,15 +2,15 @@
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
project_name: signoz-community
project_name: observe-community
before:
hooks:
- go mod tidy
builds:
- id: signoz
binary: bin/signoz
- id: observe
binary: bin/observe
main: ./cmd/community
goos:
- linux
@@ -24,12 +24,12 @@ builds:
- v8.0
ldflags:
- -s -w
- -X github.com/SigNoz/signoz/pkg/version.version=v{{ .Version }}
- -X github.com/SigNoz/signoz/pkg/version.variant=community
- -X github.com/SigNoz/signoz/pkg/version.hash={{ .ShortCommit }}
- -X github.com/SigNoz/signoz/pkg/version.time={{ .CommitTimestamp }}
- -X github.com/SigNoz/signoz/pkg/version.branch={{ .Branch }}
- -X github.com/SigNoz/signoz/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr
- -X github.com/Hanzo O11y/observe/pkg/version.version=v{{ .Version }}
- -X github.com/Hanzo O11y/observe/pkg/version.variant=community
- -X github.com/Hanzo O11y/observe/pkg/version.hash={{ .ShortCommit }}
- -X github.com/Hanzo O11y/observe/pkg/version.time={{ .CommitTimestamp }}
- -X github.com/Hanzo O11y/observe/pkg/version.branch={{ .Branch }}
- -X github.com/Hanzo O11y/observe/pkg/analytics.key=9kRrJ7oPCGPEJLF6QjMPLt5bljFhRQBr
mod_timestamp: "{{ .CommitTimestamp }}"
tags:
- timetzdata
+19
View File
@@ -0,0 +1,19 @@
FROM alpine:3.20.3
LABEL maintainer="hanzoai"
WORKDIR /root
ARG OS="linux"
ARG TARGETARCH
RUN apk update && \
apk add ca-certificates && \
rm -rf /var/cache/apk/*
COPY ./target/${OS}-${TARGETARCH}/o11y-community /root/o11y
COPY ./templates/email /root/templates
COPY frontend/build/ /etc/o11y/web/
RUN chmod 755 /root /root/o11y
ENTRYPOINT ["./o11y", "server"]
@@ -1,7 +1,7 @@
ARG ALPINE_SHA="pass-a-valid-docker-sha-otherwise-this-will-fail"
FROM alpine@sha256:${ALPINE_SHA}
LABEL maintainer="signoz"
LABEL maintainer="hanzoai"
WORKDIR /root
ARG OS="linux"
@@ -11,10 +11,10 @@ RUN apk update && \
apk add ca-certificates && \
rm -rf /var/cache/apk/*
COPY ./target/${OS}-${ARCH}/signoz /root/signoz
COPY ./target/${OS}-${ARCH}/o11y-community /root/o11y-community
COPY ./templates/email /root/templates
COPY frontend/build/ /etc/signoz/web/
COPY frontend/build/ /etc/o11y/web/
RUN chmod 755 /root /root/signoz
RUN chmod 755 /root /root/o11y-community
ENTRYPOINT ["./signoz", "server"]
ENTRYPOINT ["./o11y-community", "server"]
@@ -3,8 +3,8 @@ package main
import (
"log/slog"
"github.com/SigNoz/signoz/cmd"
"github.com/SigNoz/signoz/pkg/instrumentation"
"github.com/hanzoai/o11y/cmd"
"github.com/hanzoai/o11y/pkg/instrumentation"
)
func main() {
+164
View File
@@ -0,0 +1,164 @@
package main
import (
"context"
"log/slog"
"os"
"github.com/hanzoai/o11y/cmd"
"github.com/hanzoai/o11y/pkg/analytics"
"github.com/hanzoai/o11y/pkg/authn"
"github.com/hanzoai/o11y/pkg/authz"
"github.com/hanzoai/o11y/pkg/authz/iamauthz"
"github.com/hanzoai/o11y/pkg/factory"
"github.com/hanzoai/o11y/pkg/gateway"
"github.com/hanzoai/o11y/pkg/gateway/noopgateway"
"github.com/hanzoai/o11y/pkg/licensing"
"github.com/hanzoai/o11y/pkg/licensing/nooplicensing"
"github.com/hanzoai/o11y/pkg/modules/dashboard"
"github.com/hanzoai/o11y/pkg/modules/dashboard/impldashboard"
"github.com/hanzoai/o11y/pkg/modules/organization"
"github.com/hanzoai/o11y/pkg/querier"
"github.com/hanzoai/o11y/pkg/query-service/app"
"github.com/hanzoai/o11y/pkg/queryparser"
"github.com/hanzoai/o11y"
"github.com/hanzoai/o11y/pkg/sqlschema"
"github.com/hanzoai/o11y/pkg/sqlstore"
"github.com/hanzoai/o11y/pkg/types/authtypes"
"github.com/hanzoai/o11y/pkg/version"
"github.com/hanzoai/o11y/pkg/zapreceiver"
"github.com/hanzoai/o11y/pkg/zeus"
"github.com/hanzoai/o11y/pkg/zeus/noopzeus"
"github.com/spf13/cobra"
)
func registerServer(parentCmd *cobra.Command, logger *slog.Logger) {
var flags o11y.DeprecatedFlags
serverCmd := &cobra.Command{
Use: "server",
Short: "Run the HanzoO11y server",
FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
RunE: func(currCmd *cobra.Command, args []string) error {
config, err := cmd.NewHanzoO11yConfig(currCmd.Context(), logger, flags)
if err != nil {
return err
}
return runServer(currCmd.Context(), config, logger)
},
}
flags.RegisterFlags(serverCmd)
parentCmd.AddCommand(serverCmd)
}
func runServer(ctx context.Context, config o11y.Config, logger *slog.Logger) error {
// print the version
version.Info.PrettyPrint(config.Version)
o11y, err := o11y.New(
ctx,
config,
zeus.Config{},
noopzeus.NewProviderFactory(),
licensing.Config{},
func(_ sqlstore.SQLStore, _ zeus.Zeus, _ organization.Getter, _ analytics.Analytics) factory.ProviderFactory[licensing.Licensing, licensing.Config] {
return nooplicensing.NewFactory()
},
o11y.NewEmailingProviderFactories(),
o11y.NewCacheProviderFactories(),
o11y.NewWebProviderFactories(),
func(sqlstore sqlstore.SQLStore) factory.NamedMap[factory.ProviderFactory[sqlschema.SQLSchema, sqlschema.Config]] {
return o11y.NewSQLSchemaProviderFactories(sqlstore)
},
o11y.NewSQLStoreProviderFactories(),
o11y.NewTelemetryStoreProviderFactories(),
func(ctx context.Context, providerSettings factory.ProviderSettings, store authtypes.AuthNStore, licensing licensing.Licensing) (map[authtypes.AuthNProvider]authn.AuthN, error) {
return o11y.NewAuthNs(ctx, providerSettings, store, licensing)
},
func(_ context.Context, sqlstore sqlstore.SQLStore, _ licensing.Licensing, _ dashboard.Module) factory.ProviderFactory[authz.AuthZ, authz.Config] {
return iamauthz.NewProviderFactory(sqlstore)
},
func(store sqlstore.SQLStore, settings factory.ProviderSettings, analytics analytics.Analytics, orgGetter organization.Getter, queryParser queryparser.QueryParser, _ querier.Querier, _ licensing.Licensing) dashboard.Module {
return impldashboard.NewModule(impldashboard.NewStore(store), settings, analytics, orgGetter, queryParser)
},
func(_ licensing.Licensing) factory.ProviderFactory[gateway.Gateway, gateway.Config] {
return noopgateway.NewProviderFactory()
},
func(ps factory.ProviderSettings, q querier.Querier, a analytics.Analytics) querier.Handler {
return querier.NewHandler(ps, q, a)
},
)
if err != nil {
logger.ErrorContext(ctx, "failed to create o11y", "error", err)
return err
}
server, err := app.NewServer(config, o11y)
if err != nil {
logger.ErrorContext(ctx, "failed to create server", "error", err)
return err
}
if err := server.Start(ctx); err != nil {
logger.ErrorContext(ctx, "failed to start server", "error", err)
return err
}
// ZAP-native trace ingestion. Spans shipped by luxfi/trace's
// Type=ZAP exporter land here and (TODO) get written to the
// telemetry store. Defaults to :4317; O11Y_ZAP_LISTEN overrides.
// This is the OTel-on-ZAP path that replaces OTLP-gRPC ingestion
// — no protobuf, no grpc, just zap envelopes.
zapRcv, err := zapreceiver.New(zapreceiver.Config{
Listen: zapReceiverAddr(),
Logger: logger,
OnBatch: func(_ context.Context, b *zapreceiver.SpanBatch) error {
logger.DebugContext(ctx, "zap span batch received",
"appName", b.AppName,
"version", b.Version,
"spans", len(b.Spans),
)
// TODO(zap-ingest): write batch.Spans into telemetrystore.TelemetryStore
// once the SpanBatch → Datastore adapter lands.
return nil
},
})
if err != nil {
logger.WarnContext(ctx, "zap-native receiver disabled", "error", err)
} else {
defer zapRcv.Stop()
logger.InfoContext(ctx, "zap-native trace receiver listening", "addr", zapReceiverAddr())
}
o11y.Start(ctx)
if err := o11y.Wait(ctx); err != nil {
logger.ErrorContext(ctx, "failed to start o11y", "error", err)
return err
}
err = server.Stop(ctx)
if err != nil {
logger.ErrorContext(ctx, "failed to stop server", "error", err)
return err
}
err = o11y.Stop(ctx)
if err != nil {
logger.ErrorContext(ctx, "failed to stop o11y", "error", err)
return err
}
return nil
}
// zapReceiverAddr returns the bind address for the ZAP span receiver.
// O11Y_ZAP_LISTEN overrides; default is :4317 (canonical o11y ZAP port).
func zapReceiverAddr() string {
if v := os.Getenv("O11Y_ZAP_LISTEN"); v != "" {
return v
}
return ":4317"
}
+1 -1
View File
@@ -4,7 +4,7 @@ import (
"context"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/hanzoai/o11y/pkg/errors"
"go.uber.org/zap" //nolint:depguard
"go.uber.org/zap/zapcore" //nolint:depguard
)
+14 -12
View File
@@ -1,13 +1,13 @@
##################### SigNoz Configuration Example #####################
##################### Hanzo O11y Configuration Example #####################
#
# Do not modify this file
#
##################### Global #####################
global:
# the url under which the signoz apiserver is externally reachable.
# the url under which the o11y apiserver is externally reachable.
external_url: <unset>
# the url where the SigNoz backend receives telemetry data (traces, metrics, logs) from instrumented applications.
# the url where the Hanzo O11y backend receives telemetry data (traces, metrics, logs) from instrumented applications.
ingestion_url: <unset>
##################### Version #####################
@@ -46,7 +46,7 @@ web:
# The prefix to serve web on
prefix: /
# The directory containing the static build files.
directory: /etc/signoz/web
directory: /etc/o11y/web
##################### Cache #####################
cache:
@@ -77,7 +77,7 @@ sqlstore:
max_open_conns: 100
sqlite:
# The path to the SQLite database file.
path: /var/lib/signoz/signoz.db
path: /var/lib/observe/observe.db
# Mode is the mode to use for the sqlite database.
mode: delete
# BusyTimeout is the timeout for the sqlite database to wait for a lock.
@@ -111,6 +111,8 @@ querier:
max_concurrent_queries: 4
##################### TelemetryStore #####################
# Uses Hanzo Datastore (hanzoai/datastore) as the telemetry storage backend.
# The datastore is a high-performance columnar database (ClickHouse-compatible).
telemetrystore:
# Maximum number of idle connections in the connection pool.
max_idle_conns: 50
@@ -121,9 +123,9 @@ telemetrystore:
# Specifies the telemetrystore provider to use.
provider: clickhouse
clickhouse:
# The DSN to use for clickhouse.
dsn: tcp://localhost:9000
# The cluster name to use for clickhouse.
# The DSN for Hanzo Datastore.
dsn: tcp://datastore:9000
# The cluster name for Hanzo Datastore.
cluster: cluster
# The query settings for clickhouse.
settings:
@@ -148,8 +150,8 @@ prometheus:
##################### Alertmanager #####################
alertmanager:
# Specifies the alertmanager provider to use.
provider: signoz
signoz:
provider: observe
observe:
# The poll interval for periodically syncing the alertmanager with the config in the store.
poll_interval: 1m
# The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). Used for generating relative and absolute links back to Alertmanager itself.
@@ -192,7 +194,7 @@ emailing:
enabled: false
templates:
# The directory containing the email templates. This directory should contain a list of files defined at pkg/types/emailtypes/template.go.
directory: /opt/signoz/conf/templates/email
directory: /opt/observe/conf/templates/email
format:
header:
enabled: false
@@ -250,7 +252,7 @@ analytics:
##################### StatsReporter #####################
statsreporter:
# Whether to enable stats reporter. This is used to provide valuable insights to the SigNoz team. It does not collect any sensitive/PII data.
# Whether to enable stats reporter. This is used to provide valuable insights to the Hanzo O11y team. It does not collect any sensitive/PII data.
enabled: true
# The interval at which the stats are collected.
interval: 6h
+1 -1
View File
@@ -22,4 +22,4 @@ rule_files:
scrape_configs: []
remote_read:
- url: tcp://localhost:9000/signoz_metrics
- url: tcp://localhost:9000/observe_metrics
+72 -77
View File
@@ -1,4 +1,4 @@
package signoz
package o11y
import (
"context"
@@ -9,38 +9,37 @@ import (
"reflect"
"time"
"github.com/SigNoz/signoz/pkg/alertmanager"
"github.com/SigNoz/signoz/pkg/analytics"
"github.com/SigNoz/signoz/pkg/apiserver"
"github.com/SigNoz/signoz/pkg/cache"
"github.com/SigNoz/signoz/pkg/config"
"github.com/SigNoz/signoz/pkg/emailing"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/flagger"
"github.com/SigNoz/signoz/pkg/gateway"
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/instrumentation"
"github.com/SigNoz/signoz/pkg/modules/metricsexplorer"
"github.com/SigNoz/signoz/pkg/modules/user"
"github.com/SigNoz/signoz/pkg/prometheus"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/ruler"
"github.com/SigNoz/signoz/pkg/sharder"
"github.com/SigNoz/signoz/pkg/sqlmigration"
"github.com/SigNoz/signoz/pkg/sqlmigrator"
"github.com/SigNoz/signoz/pkg/sqlschema"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/statsreporter"
"github.com/SigNoz/signoz/pkg/telemetrystore"
"github.com/SigNoz/signoz/pkg/tokenizer"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/SigNoz/signoz/pkg/version"
"github.com/SigNoz/signoz/pkg/web"
"github.com/hanzoai/o11y/pkg/alertmanager"
"github.com/hanzoai/o11y/pkg/analytics"
"github.com/hanzoai/o11y/pkg/apiserver"
"github.com/hanzoai/o11y/pkg/cache"
"github.com/hanzoai/o11y/pkg/config"
"github.com/hanzoai/o11y/pkg/emailing"
"github.com/hanzoai/o11y/pkg/errors"
"github.com/hanzoai/o11y/pkg/factory"
"github.com/hanzoai/o11y/pkg/flagger"
"github.com/hanzoai/o11y/pkg/gateway"
"github.com/hanzoai/o11y/pkg/global"
"github.com/hanzoai/o11y/pkg/instrumentation"
"github.com/hanzoai/o11y/pkg/modules/metricsexplorer"
"github.com/hanzoai/o11y/pkg/modules/user"
"github.com/hanzoai/o11y/pkg/querier"
"github.com/hanzoai/o11y/pkg/ruler"
"github.com/hanzoai/o11y/pkg/sharder"
"github.com/hanzoai/o11y/pkg/sqlmigration"
"github.com/hanzoai/o11y/pkg/sqlmigrator"
"github.com/hanzoai/o11y/pkg/sqlschema"
"github.com/hanzoai/o11y/pkg/sqlstore"
"github.com/hanzoai/o11y/pkg/statsreporter"
"github.com/hanzoai/o11y/pkg/telemetrystore"
"github.com/hanzoai/o11y/pkg/tokenizer"
"github.com/hanzoai/o11y/pkg/valuer"
"github.com/hanzoai/o11y/pkg/version"
"github.com/hanzoai/o11y/pkg/web"
"github.com/spf13/cobra"
)
// Config defines the entire input configuration of signoz.
// Config defines the entire input configuration of o11y.
type Config struct {
// Global config
Global global.Config `mapstructure:"global"`
@@ -78,9 +77,6 @@ type Config struct {
// TelemetryStore config
TelemetryStore telemetrystore.Config `mapstructure:"telemetrystore"`
// Prometheus config
Prometheus prometheus.Config `mapstructure:"prometheus"`
// Alertmanager config
Alertmanager alertmanager.Config `mapstructure:"alertmanager" yaml:"alertmanager"`
@@ -140,15 +136,15 @@ func (df *DeprecatedFlags) RegisterFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&df.Cluster, "cluster", "cluster", "(cluster name - defaults to 'cluster')")
cmd.Flags().StringVar(&df.GatewayUrl, "gateway-url", "", "(url to the gateway)")
_ = cmd.Flags().MarkDeprecated("max-idle-conns", "use SIGNOZ_TELEMETRYSTORE_MAX__IDLE__CONNS instead")
_ = cmd.Flags().MarkDeprecated("max-open-conns", "use SIGNOZ_TELEMETRYSTORE_MAX__OPEN__CONNS instead")
_ = cmd.Flags().MarkDeprecated("dial-timeout", "use SIGNOZ_TELEMETRYSTORE_DIAL__TIMEOUT instead")
_ = cmd.Flags().MarkDeprecated("config", "use SIGNOZ_PROMETHEUS_CONFIG instead")
_ = cmd.Flags().MarkDeprecated("flux-interval", "use SIGNOZ_QUERIER_FLUX__INTERVAL instead")
_ = cmd.Flags().MarkDeprecated("flux-interval-for-trace-detail", "use SIGNOZ_QUERIER_FLUX__INTERVAL instead")
_ = cmd.Flags().MarkDeprecated("cluster", "use SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_CLUSTER instead")
_ = cmd.Flags().MarkDeprecated("prefer-span-metrics", "use SIGNOZ_FLAGGER_CONFIG_BOOLEAN_USE__SPAN__METRICS instead")
_ = cmd.Flags().MarkDeprecated("gateway-url", "use SIGNOZ_GATEWAY_URL instead")
_ = cmd.Flags().MarkDeprecated("max-idle-conns", "use O11Y_TELEMETRYSTORE_MAX__IDLE__CONNS instead")
_ = cmd.Flags().MarkDeprecated("max-open-conns", "use O11Y_TELEMETRYSTORE_MAX__OPEN__CONNS instead")
_ = cmd.Flags().MarkDeprecated("dial-timeout", "use O11Y_TELEMETRYSTORE_DIAL__TIMEOUT instead")
_ = cmd.Flags().MarkDeprecated("config", "use O11Y_PROMETHEUS_CONFIG instead")
_ = cmd.Flags().MarkDeprecated("flux-interval", "use O11Y_QUERIER_FLUX__INTERVAL instead")
_ = cmd.Flags().MarkDeprecated("flux-interval-for-trace-detail", "use O11Y_QUERIER_FLUX__INTERVAL instead")
_ = cmd.Flags().MarkDeprecated("cluster", "use O11Y_TELEMETRYSTORE_DATASTORE_CLUSTER instead")
_ = cmd.Flags().MarkDeprecated("prefer-span-metrics", "use O11Y_FLAGGER_CONFIG_BOOLEAN_USE__SPAN__METRICS instead")
_ = cmd.Flags().MarkDeprecated("gateway-url", "use O11Y_GATEWAY_URL instead")
}
func NewConfig(ctx context.Context, logger *slog.Logger, resolverConfig config.ResolverConfig, deprecatedFlags DeprecatedFlags) (Config, error) {
@@ -164,7 +160,6 @@ func NewConfig(ctx context.Context, logger *slog.Logger, resolverConfig config.R
sqlschema.NewConfigFactory(),
apiserver.NewConfigFactory(),
telemetrystore.NewConfigFactory(),
prometheus.NewConfigFactory(),
alertmanager.NewConfigFactory(),
querier.NewConfigFactory(),
ruler.NewConfigFactory(),
@@ -214,13 +209,13 @@ func validateConfig(config Config) error {
}
func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logger, config *Config, deprecatedFlags DeprecatedFlags) {
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
@@ -230,7 +225,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 {
@@ -241,46 +236,46 @@ 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_TELEMETRYSTORE_DATASTORE_DSN instead.")
config.TelemetryStore.Clickhouse.DSN = os.Getenv("DatastoreUrl")
}
if deprecatedFlags.MaxIdleConns != 50 {
logger.WarnContext(ctx, "[Deprecated] flag --max-idle-conns is deprecated and scheduled for removal. Please use SIGNOZ_TELEMETRYSTORE_MAX__IDLE__CONNS instead.")
logger.WarnContext(ctx, "[Deprecated] flag --max-idle-conns is deprecated and scheduled for removal. Please use O11Y_TELEMETRYSTORE_MAX__IDLE__CONNS instead.")
config.TelemetryStore.Connection.MaxIdleConns = deprecatedFlags.MaxIdleConns
}
if deprecatedFlags.MaxOpenConns != 100 {
logger.WarnContext(ctx, "[Deprecated] flag --max-open-conns is deprecated and scheduled for removal. Please use SIGNOZ_TELEMETRYSTORE_MAX__OPEN__CONNS instead.")
logger.WarnContext(ctx, "[Deprecated] flag --max-open-conns is deprecated and scheduled for removal. Please use O11Y_TELEMETRYSTORE_MAX__OPEN__CONNS instead.")
config.TelemetryStore.Connection.MaxOpenConns = deprecatedFlags.MaxOpenConns
}
if deprecatedFlags.DialTimeout != 5*time.Second {
logger.WarnContext(ctx, "[Deprecated] flag --dial-timeout is deprecated and scheduled for removal. Please use SIGNOZ_TELEMETRYSTORE_DIAL__TIMEOUT instead.")
logger.WarnContext(ctx, "[Deprecated] flag --dial-timeout is deprecated and scheduled for removal. Please use O11Y_TELEMETRYSTORE_DIAL__TIMEOUT instead.")
config.TelemetryStore.Connection.DialTimeout = deprecatedFlags.DialTimeout
}
if deprecatedFlags.Config != "" {
logger.WarnContext(ctx, "[Deprecated] flag --config is deprecated for passing prometheus config. The flag will be used for passing the entire SigNoz config. More details can be found at https://github.com/SigNoz/signoz/issues/6805.")
logger.WarnContext(ctx, "[Deprecated] flag --config is deprecated for passing prometheus config. The flag will be used for passing the entire HanzoO11y config. More details can be found at https://github.com/hanzoai/o11y/issues/6805.")
}
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 {
@@ -289,36 +284,36 @@ 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 deprecatedFlags.FluxInterval != "" {
logger.WarnContext(ctx, "[Deprecated] flag --flux-interval is deprecated and scheduled for removal. Please use SIGNOZ_QUERIER_FLUX__INTERVAL instead.")
logger.WarnContext(ctx, "[Deprecated] flag --flux-interval is deprecated and scheduled for removal. Please use O11Y_QUERIER_FLUX__INTERVAL instead.")
fluxInterval, err := time.ParseDuration(deprecatedFlags.FluxInterval)
if err != nil {
logger.WarnContext(ctx, "Error parsing --flux-interval, using default value.")
@@ -328,16 +323,16 @@ func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logge
}
if deprecatedFlags.FluxIntervalForTraceDetail != "" {
logger.WarnContext(ctx, "[Deprecated] flag --flux-interval-for-trace-detail is deprecated and scheduled for complete removal. Please use SIGNOZ_QUERIER_FLUX__INTERVAL instead.")
logger.WarnContext(ctx, "[Deprecated] flag --flux-interval-for-trace-detail is deprecated and scheduled for complete removal. Please use O11Y_QUERIER_FLUX__INTERVAL instead.")
}
if deprecatedFlags.Cluster != "" {
logger.WarnContext(ctx, "[Deprecated] flag --cluster is deprecated and scheduled for removal. Please use SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_CLUSTER instead.")
logger.WarnContext(ctx, "[Deprecated] flag --cluster is deprecated and scheduled for removal. Please use O11Y_TELEMETRYSTORE_DATASTORE_CLUSTER instead.")
config.TelemetryStore.Clickhouse.Cluster = deprecatedFlags.Cluster
}
if deprecatedFlags.PreferSpanMetrics {
logger.WarnContext(ctx, "[Deprecated] flag --prefer-span-metrics is deprecated and scheduled for removal. Please use SIGNOZ_FLAGGER_CONFIG_BOOLEAN_USE__SPAN__METRICS instead.")
logger.WarnContext(ctx, "[Deprecated] flag --prefer-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)
}
@@ -345,7 +340,7 @@ func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logge
}
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)
}
@@ -353,7 +348,7 @@ func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logge
}
if deprecatedFlags.GatewayUrl != "" {
logger.WarnContext(ctx, "[Deprecated] flag --gateway-url is deprecated and scheduled for removal. Please use SIGNOZ_GATEWAY_URL instead.")
logger.WarnContext(ctx, "[Deprecated] flag --gateway-url is deprecated and scheduled for removal. Please use O11Y_GATEWAY_URL instead.")
u, err := url.Parse(deprecatedFlags.GatewayUrl)
if err != nil {
logger.WarnContext(ctx, "Error parsing --gateway-url, using default value.")
@@ -362,13 +357,13 @@ func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logge
}
}
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)
}
+2 -2
View File
@@ -1,11 +1,11 @@
package signoz
package o11y
import (
"context"
"log/slog"
"testing"
"github.com/SigNoz/signoz/pkg/config/configtest"
"github.com/hanzoai/o11y/pkg/config/configtest"
"github.com/stretchr/testify/assert"
)
+1 -1
View File
@@ -1,4 +1,4 @@
{
"url": "https://context7.com/signoz/signoz",
"url": "https://context7.com/o11y/o11y",
"public_key": "pk_6g9GfjdkuPEIDuTGAxnol"
}
+6 -6
View File
@@ -42,13 +42,13 @@ cd generator/hotrod
docker compose up -d
```
In a couple of minutes, you should see the data generated from hotrod in SigNoz UI.
In a couple of minutes, you should see the data generated from hotrod in Hanzo O11y UI.
For more details, please refer to the [SigNoz documentation](https://signoz.io/docs/install/docker/).
For more details, please refer to the [Hanzo O11y documentation](https://o11y.hanzo.ai/docs/install/docker/).
## Docker Swarm
To install SigNoz using Docker Swarm, run the following command:
To install Hanzo O11y using Docker Swarm, run the following command:
```sh
cd deploy/docker-swarm
@@ -71,11 +71,11 @@ cd generator/hotrod
docker stack deploy -c docker-compose.yaml hotrod
```
In a couple of minutes, you should see the data generated from hotrod in SigNoz UI.
In a couple of minutes, you should see the data generated from hotrod in Hanzo O11y UI.
For more details, please refer to the [SigNoz documentation](https://signoz.io/docs/install/docker-swarm/).
For more details, please refer to the [Hanzo O11y documentation](https://o11y.hanzo.ai/docs/install/docker-swarm/).
## Uninstall/Troubleshoot?
Go to our official documentation site [signoz.io/docs](https://signoz.io/docs) for more.
Go to our official documentation site [o11y.hanzo.ai/docs](https://o11y.hanzo.ai/docs) for more.
@@ -0,0 +1 @@
server_endpoint: ws://observe:4320/v1/opamp
@@ -22,4 +22,4 @@ rule_files: []
scrape_configs: []
remote_read:
- url: tcp://clickhouse:9000/signoz_metrics
- url: tcp://clickhouse:9000/observe_metrics
@@ -1 +0,0 @@
server_endpoint: ws://signoz:4320/v1/opamp
+45 -45
View File
@@ -1,7 +1,7 @@
version: "3"
x-common: &common
networks:
- signoz-net
- o11y-net
deploy:
restart_policy:
condition: on-failure
@@ -11,13 +11,13 @@ x-common: &common
max-file: "3"
x-clickhouse-defaults: &clickhouse-defaults
!!merge <<: *common
image: clickhouse/clickhouse-server:25.5.6
image: ghcr.io/hanzoai/datastore:25.5.6
tty: true
deploy:
labels:
signoz.io/scrape: "true"
signoz.io/port: "9363"
signoz.io/path: "/metrics"
o11y.hanzo.ai/scrape: "true"
o11y.hanzo.ai/port: "9363"
o11y.hanzo.ai/path: "/metrics"
depends_on:
- zookeeper-1
- zookeeper-2
@@ -41,13 +41,13 @@ x-clickhouse-defaults: &clickhouse-defaults
- CLICKHOUSE_SKIP_USER_SETUP=1
x-zookeeper-defaults: &zookeeper-defaults
!!merge <<: *common
image: signoz/zookeeper:3.7.1
image: ghcr.io/hanzoai/zookeeper:3.7.1
user: root
deploy:
labels:
signoz.io/scrape: "true"
signoz.io/port: "9141"
signoz.io/path: "/metrics"
o11y.hanzo.ai/scrape: "true"
o11y.hanzo.ai/port: "9141"
o11y.hanzo.ai/path: "/metrics"
healthcheck:
test:
- CMD-SHELL
@@ -64,7 +64,7 @@ x-db-depend: &db-depend
services:
init-clickhouse:
!!merge <<: *common
image: clickhouse/clickhouse-server:25.5.6
image: ghcr.io/hanzoai/datastore:25.5.6
command:
- bash
- -c
@@ -74,7 +74,7 @@ services:
node_arch=$$(uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/)
echo "Fetching histogram-binary for $${node_os}/$${node_arch}"
cd /tmp
wget -O histogram-quantile.tar.gz "https://github.com/SigNoz/signoz/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
wget -O histogram-quantile.tar.gz "https://github.com/Hanzo O11y/observe/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
tar -xvzf histogram-quantile.tar.gz
mv histogram-quantile /var/lib/clickhouse/user_scripts/histogramQuantile
deploy:
@@ -188,19 +188,19 @@ services:
- ../common/clickhouse/user_scripts:/var/lib/clickhouse/user_scripts/
- ./clickhouse-setup/data/clickhouse-3/:/var/lib/clickhouse/
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
observe:
!!merge <<: *db-depend
image: signoz/signoz:v0.114.0
image: ghcr.io/hanzoai/o11y:v0.115.0
ports:
- "8080:8080" # signoz port
- "8080:8080" # observe port
# - "6060:6060" # pprof port
volumes:
- ./clickhouse-setup/data/signoz/:/var/lib/signoz/
- ./clickhouse-setup/data/observe/:/var/lib/observe/
environment:
- SIGNOZ_ALERTMANAGER_PROVIDER=signoz
- SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_SQLSTORE_SQLITE_PATH=/var/lib/signoz/signoz.db
- SIGNOZ_TOKENIZER_JWT_SECRET=secret
- O11Y_ALERTMANAGER_PROVIDER=observe
- O11Y_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_SQLSTORE_SQLITE_PATH=/var/lib/ghcr.io/hanzoai/o11y.db
- O11Y_TOKENIZER_JWT_SECRET=secret
healthcheck:
test:
- CMD
@@ -213,14 +213,14 @@ services:
retries: 3
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:v0.144.2
image: ghcr.io/hanzoai/otel-collector:v0.144.2
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate sync check &&
/signoz-otel-collector --config=/etc/otel-collector-config.yaml --manager-config=/etc/manager-config.yaml --copy-path=/var/tmp/collector-config.yaml
/o11y-otel-collector migrate sync check &&
/o11y-otel-collector --config=/etc/otel-collector-config.yaml --manager-config=/etc/manager-config.yaml --copy-path=/var/tmp/collector-config.yaml
configs:
- source: otel-collector-config
target: /etc/otel-collector-config.yaml
@@ -229,50 +229,50 @@ services:
environment:
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
- LOW_CARDINAL_EXCEPTION_GROUPING=false
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
ports:
# - "1777:1777" # pprof extension
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
deploy:
replicas: 3
signoz-telemetrystore-migrator:
o11y-telemetrystore-migrator:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:v0.144.2
image: ghcr.io/hanzoai/otel-collector:v0.144.2
environment:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate bootstrap &&
/signoz-otel-collector migrate sync up &&
/signoz-otel-collector migrate async up
/o11y-otel-collector migrate bootstrap &&
/o11y-otel-collector migrate sync up &&
/o11y-otel-collector migrate async up
networks:
signoz-net:
name: signoz-net
o11y-net:
name: o11y-net
volumes:
clickhouse:
name: signoz-clickhouse
name: o11y-datastore
clickhouse-2:
name: signoz-clickhouse-2
name: o11y-datastore-2
clickhouse-3:
name: signoz-clickhouse-3
name: o11y-datastore-3
sqlite:
name: signoz-sqlite
name: o11y-sqlite
zookeeper-1:
name: signoz-zookeeper-1
name: o11y-zookeeper-1
zookeeper-2:
name: signoz-zookeeper-2
name: o11y-zookeeper-2
zookeeper-3:
name: signoz-zookeeper-3
name: o11y-zookeeper-3
configs:
clickhouse-config:
file: ../common/clickhouse/config.xml
@@ -285,4 +285,4 @@ configs:
otel-collector-config:
file: ./otel-collector-config.yaml
otel-manager-config:
file: ../common/signoz/otel-collector-opamp-config.yaml
file: ../common/observe/otel-collector-opamp-config.yaml
+41 -41
View File
@@ -1,7 +1,7 @@
version: "3"
x-common: &common
networks:
- signoz-net
- o11y-net
deploy:
restart_policy:
condition: on-failure
@@ -11,13 +11,13 @@ x-common: &common
max-file: "3"
x-clickhouse-defaults: &clickhouse-defaults
!!merge <<: *common
image: clickhouse/clickhouse-server:25.5.6
image: ghcr.io/hanzoai/datastore:25.5.6
tty: true
deploy:
labels:
signoz.io/scrape: "true"
signoz.io/port: "9363"
signoz.io/path: "/metrics"
o11y.hanzo.ai/scrape: "true"
o11y.hanzo.ai/port: "9363"
o11y.hanzo.ai/path: "/metrics"
depends_on:
- init-clickhouse
- zookeeper-1
@@ -40,13 +40,13 @@ x-clickhouse-defaults: &clickhouse-defaults
- CLICKHOUSE_SKIP_USER_SETUP=1
x-zookeeper-defaults: &zookeeper-defaults
!!merge <<: *common
image: signoz/zookeeper:3.7.1
image: ghcr.io/hanzoai/zookeeper:3.7.1
user: root
deploy:
labels:
signoz.io/scrape: "true"
signoz.io/port: "9141"
signoz.io/path: "/metrics"
o11y.hanzo.ai/scrape: "true"
o11y.hanzo.ai/port: "9141"
o11y.hanzo.ai/path: "/metrics"
healthcheck:
test:
- CMD-SHELL
@@ -61,7 +61,7 @@ x-db-depend: &db-depend
services:
init-clickhouse:
!!merge <<: *common
image: clickhouse/clickhouse-server:25.5.6
image: ghcr.io/hanzoai/datastore:25.5.6
command:
- bash
- -c
@@ -71,7 +71,7 @@ services:
node_arch=$$(uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/)
echo "Fetching histogram-binary for $${node_os}/$${node_arch}"
cd /tmp
wget -O histogram-quantile.tar.gz "https://github.com/SigNoz/signoz/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
wget -O histogram-quantile.tar.gz "https://github.com/Hanzo O11y/observe/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
tar -xvzf histogram-quantile.tar.gz
mv histogram-quantile /var/lib/clickhouse/user_scripts/histogramQuantile
deploy:
@@ -115,18 +115,18 @@ services:
- clickhouse:/var/lib/clickhouse/
- ../common/clickhouse/user_scripts:/var/lib/clickhouse/user_scripts/
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
observe:
!!merge <<: *db-depend
image: signoz/signoz:v0.114.0
image: ghcr.io/hanzoai/o11y:v0.115.0
ports:
- "8080:8080" # signoz port
- "8080:8080" # observe port
volumes:
- sqlite:/var/lib/signoz/
- sqlite:/var/lib/observe/
environment:
- SIGNOZ_ALERTMANAGER_PROVIDER=signoz
- SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_SQLSTORE_SQLITE_PATH=/var/lib/signoz/signoz.db
- SIGNOZ_TOKENIZER_JWT_SECRET=secret
- O11Y_ALERTMANAGER_PROVIDER=observe
- O11Y_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_SQLSTORE_SQLITE_PATH=/var/lib/ghcr.io/hanzoai/o11y.db
- O11Y_TOKENIZER_JWT_SECRET=secret
healthcheck:
test:
- CMD
@@ -139,14 +139,14 @@ services:
retries: 3
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:v0.144.2
image: ghcr.io/hanzoai/otel-collector:v0.144.2
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate sync check &&
/signoz-otel-collector --config=/etc/otel-collector-config.yaml --manager-config=/etc/manager-config.yaml --copy-path=/var/tmp/collector-config.yaml
/o11y-otel-collector migrate sync check &&
/o11y-otel-collector --config=/etc/otel-collector-config.yaml --manager-config=/etc/manager-config.yaml --copy-path=/var/tmp/collector-config.yaml
configs:
- source: otel-collector-config
target: /etc/otel-collector-config.yaml
@@ -155,42 +155,42 @@ services:
environment:
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
- LOW_CARDINAL_EXCEPTION_GROUPING=false
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
ports:
# - "1777:1777" # pprof extension
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
deploy:
replicas: 3
signoz-telemetrystore-migrator:
o11y-telemetrystore-migrator:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:v0.144.2
image: ghcr.io/hanzoai/otel-collector:v0.144.2
environment:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate bootstrap &&
/signoz-otel-collector migrate sync up &&
/signoz-otel-collector migrate async up
/o11y-otel-collector migrate bootstrap &&
/o11y-otel-collector migrate sync up &&
/o11y-otel-collector migrate async up
networks:
signoz-net:
name: signoz-net
o11y-net:
name: o11y-net
volumes:
clickhouse:
name: signoz-clickhouse
name: o11y-datastore
sqlite:
name: signoz-sqlite
name: o11y-sqlite
zookeeper-1:
name: signoz-zookeeper-1
name: o11y-zookeeper-1
configs:
clickhouse-config:
file: ../common/clickhouse/config.xml
@@ -203,4 +203,4 @@ configs:
otel-collector-config:
file: ./otel-collector-config.yaml
otel-manager-config:
file: ../common/signoz/otel-collector-opamp-config.yaml
file: ../common/observe/otel-collector-opamp-config.yaml
@@ -1,7 +1,7 @@
version: "3"
x-common: &common
networks:
- signoz-net
- o11y-net
extra_hosts:
- host.docker.internal:host-gateway
logging:
@@ -20,7 +20,7 @@ services:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://host.docker.internal:4318 #
load-hotrod:
<<: *common
image: "signoz/locust:1.2.3"
image: "observe/locust:1.2.3"
environment:
ATTACKED_HOST: http://hotrod:8080
LOCUST_MODE: standalone
@@ -33,6 +33,6 @@ services:
- ../../../common/locust-scripts:/locust
networks:
signoz-net:
name: signoz-net
o11y-net:
name: o11y-net
external: true
@@ -1,7 +1,7 @@
version: "3"
x-common: &common
networks:
- signoz-net
- o11y-net
extra_hosts:
- host.docker.internal:host-gateway
logging:
@@ -22,9 +22,9 @@ services:
- ./otel-agent-config.yaml:/etc/otel-collector-config.yaml
- /:/hostfs:ro
environment:
- SIGNOZ_COLLECTOR_ENDPOINT=http://host.docker.internal:4317 # In case of external SigNoz or cloud, update the endpoint and access token
- O11Y_COLLECTOR_ENDPOINT=http://host.docker.internal:4317 # In case of external Hanzo O11y or cloud, update the endpoint and access token
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
# - SIGNOZ_ACCESS_TOKEN="<your-access-token>"
# - O11Y_ACCESS_TOKEN="<your-access-token>"
# Before exposing the ports, make sure the ports are not used by other services
# ports:
# - "4317:4317"
@@ -39,9 +39,9 @@ services:
- ./otel-metrics-config.yaml:/etc/otel-collector-config.yaml
- /var/run/docker.sock:/var/run/docker.sock
environment:
- SIGNOZ_COLLECTOR_ENDPOINT=http://host.docker.internal:4317 # In case of external SigNoz or cloud, update the endpoint and access token
- O11Y_COLLECTOR_ENDPOINT=http://host.docker.internal:4317 # In case of external Hanzo O11y or cloud, update the endpoint and access token
- OTEL_RESOURCE_ATTRIBUTES=host.name={{.Node.Hostname}},os.type={{.Node.Platform.OS}}
# - SIGNOZ_ACCESS_TOKEN="<your-access-token>"
# - O11Y_ACCESS_TOKEN="<your-access-token>"
# Before exposing the ports, make sure the ports are not used by other services
# ports:
# - "4317:4317"
@@ -64,6 +64,6 @@ services:
- otel-agent
networks:
signoz-net:
name: signoz-net
o11y-net:
name: o11y-net
external: true
@@ -41,8 +41,8 @@ receivers:
field: attributes.timestamp
# please remove names from below if you want to collect logs from them
- type: filter
id: signoz_logs_filter
expr: 'attributes.container_name matches "^(signoz_(logspout|signoz|otel-collector|clickhouse|zookeeper))|(infra_(logspout|otel-agent|otel-metrics)).*"'
id: observe_logs_filter
expr: 'attributes.container_name matches "^(observe_(logspout|observe|otel-collector|clickhouse|zookeeper))|(infra_(logspout|otel-agent|otel-metrics)).*"'
processors:
batch:
send_batch_size: 10000
@@ -64,11 +64,11 @@ extensions:
endpoint: 0.0.0.0:1777
exporters:
otlp:
endpoint: ${env:SIGNOZ_COLLECTOR_ENDPOINT}
endpoint: ${env:O11Y_COLLECTOR_ENDPOINT}
tls:
insecure: true
headers:
signoz-access-token: ${env:SIGNOZ_ACCESS_TOKEN}
observe-access-token: ${env:O11Y_ACCESS_TOKEN}
# debug: {}
service:
telemetry:
@@ -32,7 +32,7 @@ receivers:
- action: keep
regex: true
source_labels:
- __meta_dockerswarm_service_label_signoz_io_scrape
- __meta_dockerswarm_service_label_observe_io_scrape
- regex: ([^:]+)(?::\d+)?
replacement: $1
source_labels:
@@ -47,10 +47,10 @@ receivers:
- target_label: __address__
source_labels:
- swarm_container_ip
- __meta_dockerswarm_service_label_signoz_io_port
- __meta_dockerswarm_service_label_observe_io_port
separator: ":"
- source_labels:
- __meta_dockerswarm_service_label_signoz_io_path
- __meta_dockerswarm_service_label_observe_io_path
target_label: __metrics_path__
- source_labels:
- __meta_dockerswarm_service_label_com_docker_stack_namespace
@@ -81,11 +81,11 @@ extensions:
endpoint: 0.0.0.0:1777
exporters:
otlp:
endpoint: ${env:SIGNOZ_COLLECTOR_ENDPOINT}
endpoint: ${env:O11Y_COLLECTOR_ENDPOINT}
tls:
insecure: true
headers:
signoz-access-token: ${env:SIGNOZ_ACCESS_TOKEN}
observe-access-token: ${env:O11Y_ACCESS_TOKEN}
# debug: {}
service:
telemetry:
+18 -18
View File
@@ -1,5 +1,5 @@
connectors:
signozmeter:
observemeter:
metrics_flush_interval: 1h
dimensions:
- name: service.name
@@ -36,8 +36,8 @@ processors:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors: [env, system]
timeout: 2s
signozspanmetrics/delta:
metrics_exporter: signozclickhousemetrics
observespanmetrics/delta:
metrics_exporter: observeclickhousemetrics
metrics_flush_interval: 60s
latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ]
dimensions_cache_size: 100000
@@ -51,7 +51,7 @@ processors:
# This is added to ensure the uniqueness of the timeseries
# Otherwise, identical timeseries produced by multiple replicas of
# collectors result in incorrect APM metrics
- name: signoz.collector.id
- name: observe.collector.id
- name: service.version
- name: browser.platform
- name: browser.mobile
@@ -68,24 +68,24 @@ extensions:
endpoint: 0.0.0.0:1777
exporters:
clickhousetraces:
datasource: tcp://clickhouse:9000/signoz_traces
datasource: tcp://clickhouse:9000/observe_traces
low_cardinal_exception_grouping: ${env:LOW_CARDINAL_EXCEPTION_GROUPING}
use_new_schema: true
signozclickhousemetrics:
dsn: tcp://clickhouse:9000/signoz_metrics
observeclickhousemetrics:
dsn: tcp://clickhouse:9000/observe_metrics
clickhouselogsexporter:
dsn: tcp://clickhouse:9000/signoz_logs
dsn: tcp://clickhouse:9000/observe_logs
timeout: 10s
use_new_schema: true
signozclickhousemeter:
dsn: tcp://clickhouse:9000/signoz_meter
observeclickhousemeter:
dsn: tcp://clickhouse:9000/observe_meter
timeout: 45s
sending_queue:
enabled: false
metadataexporter:
cache:
provider: in_memory
dsn: tcp://clickhouse:9000/signoz_metadata
dsn: tcp://clickhouse:9000/observe_metadata
enabled: true
timeout: 45s
service:
@@ -98,21 +98,21 @@ service:
pipelines:
traces:
receivers: [otlp]
processors: [signozspanmetrics/delta, batch]
exporters: [clickhousetraces, metadataexporter, signozmeter]
processors: [observespanmetrics/delta, batch]
exporters: [clickhousetraces, metadataexporter, observemeter]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [signozclickhousemetrics, metadataexporter, signozmeter]
exporters: [observeclickhousemetrics, metadataexporter, observemeter]
metrics/prometheus:
receivers: [prometheus]
processors: [batch]
exporters: [signozclickhousemetrics, metadataexporter, signozmeter]
exporters: [observeclickhousemetrics, metadataexporter, observemeter]
logs:
receivers: [otlp]
processors: [batch]
exporters: [clickhouselogsexporter, metadataexporter, signozmeter]
exporters: [clickhouselogsexporter, metadataexporter, observemeter]
metrics/meter:
receivers: [signozmeter]
receivers: [observemeter]
processors: [batch/meter]
exporters: [signozclickhousemeter]
exporters: [observeclickhousemeter]
+56 -56
View File
@@ -1,7 +1,7 @@
version: "3"
x-common: &common
networks:
- signoz-net
- o11y-net
restart: unless-stopped
logging:
options:
@@ -10,12 +10,12 @@ x-common: &common
x-clickhouse-defaults: &clickhouse-defaults
!!merge <<: *common
# addding non LTS version due to this fix https://github.com/ClickHouse/ClickHouse/commit/32caf8716352f45c1b617274c7508c86b7d1afab
image: clickhouse/clickhouse-server:25.5.6
image: ghcr.io/hanzoai/datastore:25.5.6
tty: true
labels:
signoz.io/scrape: "true"
signoz.io/port: "9363"
signoz.io/path: "/metrics"
o11y.hanzo.ai/scrape: "true"
o11y.hanzo.ai/port: "9363"
o11y.hanzo.ai/path: "/metrics"
depends_on:
init-clickhouse:
condition: service_completed_successfully
@@ -44,12 +44,12 @@ x-clickhouse-defaults: &clickhouse-defaults
- CLICKHOUSE_SKIP_USER_SETUP=1
x-zookeeper-defaults: &zookeeper-defaults
!!merge <<: *common
image: signoz/zookeeper:3.7.1
image: ghcr.io/hanzoai/zookeeper:3.7.1
user: root
labels:
signoz.io/scrape: "true"
signoz.io/port: "9141"
signoz.io/path: "/metrics"
o11y.hanzo.ai/scrape: "true"
o11y.hanzo.ai/port: "9141"
o11y.hanzo.ai/path: "/metrics"
healthcheck:
test:
- CMD-SHELL
@@ -69,8 +69,8 @@ x-db-depend: &db-depend
services:
init-clickhouse:
!!merge <<: *common
image: clickhouse/clickhouse-server:25.5.6
container_name: signoz-init-clickhouse
image: ghcr.io/hanzoai/datastore:25.5.6
container_name: o11y-init-datastore
command:
- bash
- -c
@@ -80,7 +80,7 @@ services:
node_arch=$$(uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/)
echo "Fetching histogram-binary for $${node_os}/$${node_arch}"
cd /tmp
wget -O histogram-quantile.tar.gz "https://github.com/SigNoz/signoz/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
wget -O histogram-quantile.tar.gz "https://github.com/Hanzo O11y/observe/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
tar -xvzf histogram-quantile.tar.gz
mv histogram-quantile /var/lib/clickhouse/user_scripts/histogramQuantile
restart: on-failure
@@ -88,7 +88,7 @@ services:
- ../common/clickhouse/user_scripts:/var/lib/clickhouse/user_scripts/
zookeeper-1:
!!merge <<: *zookeeper-defaults
container_name: signoz-zookeeper-1
container_name: o11y-zookeeper-1
# ports:
# - "2181:2181"
# - "2888:2888"
@@ -104,7 +104,7 @@ services:
- ZOO_PROMETHEUS_METRICS_PORT_NUMBER=9141
zookeeper-2:
!!merge <<: *zookeeper-defaults
container_name: signoz-zookeeper-2
container_name: o11y-zookeeper-2
# ports:
# - "2182:2181"
# - "2889:2888"
@@ -120,7 +120,7 @@ services:
- ZOO_PROMETHEUS_METRICS_PORT_NUMBER=9141
zookeeper-3:
!!merge <<: *zookeeper-defaults
container_name: signoz-zookeeper-3
container_name: o11y-zookeeper-3
# ports:
# - "2183:2181"
# - "2890:2888"
@@ -136,7 +136,7 @@ services:
- ZOO_PROMETHEUS_METRICS_PORT_NUMBER=9141
clickhouse:
!!merge <<: *clickhouse-defaults
container_name: signoz-clickhouse
container_name: o11y-datastore
# ports:
# - "9000:9000"
# - "8123:8123"
@@ -151,7 +151,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
clickhouse-2:
!!merge <<: *clickhouse-defaults
container_name: signoz-clickhouse-2
container_name: o11y-datastore-2
# ports:
# - "9001:9000"
# - "8124:8123"
@@ -166,7 +166,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
clickhouse-3:
!!merge <<: *clickhouse-defaults
container_name: signoz-clickhouse-3
container_name: o11y-datastore-3
# ports:
# - "9002:9000"
# - "8125:8123"
@@ -179,19 +179,19 @@ services:
- ../common/clickhouse/cluster.ha.xml:/etc/clickhouse-server/config.d/cluster.xml
- clickhouse-3:/var/lib/clickhouse/
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
observe:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.114.0}
container_name: signoz
image: ghcr.io/hanzoai/o11y:${VERSION:-v0.115.0}
container_name: observe
ports:
- "8080:8080" # signoz port
- "8080:8080" # observe port
volumes:
- sqlite:/var/lib/signoz/
- sqlite:/var/lib/observe/
environment:
- SIGNOZ_ALERTMANAGER_PROVIDER=signoz
- SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_SQLSTORE_SQLITE_PATH=/var/lib/signoz/signoz.db
- SIGNOZ_TOKENIZER_JWT_SECRET=secret
- O11Y_ALERTMANAGER_PROVIDER=observe
- O11Y_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_SQLSTORE_SQLITE_PATH=/var/lib/ghcr.io/hanzoai/o11y.db
- O11Y_TOKENIZER_JWT_SECRET=secret
healthcheck:
test:
- CMD
@@ -204,62 +204,62 @@ services:
retries: 3
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.2}
container_name: signoz-otel-collector
image: ghcr.io/hanzoai/otel-collector:${OTELCOL_TAG:-v0.144.2}
container_name: o11y-otel-collector
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate sync check &&
/signoz-otel-collector --config=/etc/otel-collector-config.yaml --manager-config=/etc/manager-config.yaml --copy-path=/var/tmp/collector-config.yaml
/o11y-otel-collector migrate sync check &&
/o11y-otel-collector --config=/etc/otel-collector-config.yaml --manager-config=/etc/manager-config.yaml --copy-path=/var/tmp/collector-config.yaml
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
- ../common/signoz/otel-collector-opamp-config.yaml:/etc/manager-config.yaml
- ../common/observe/otel-collector-opamp-config.yaml:/etc/manager-config.yaml
environment:
- OTEL_RESOURCE_ATTRIBUTES=host.name=signoz-host,os.type=linux
- OTEL_RESOURCE_ATTRIBUTES=host.name=observe-host,os.type=linux
- LOW_CARDINAL_EXCEPTION_GROUPING=false
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
ports:
# - "1777:1777" # pprof extension
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
signoz-telemetrystore-migrator:
o11y-telemetrystore-migrator:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.2}
container_name: signoz-telemetrystore-migrator
image: ghcr.io/hanzoai/otel-collector:${OTELCOL_TAG:-v0.144.2}
container_name: o11y-telemetrystore-migrator
environment:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate bootstrap &&
/signoz-otel-collector migrate sync up &&
/signoz-otel-collector migrate async up
/o11y-otel-collector migrate bootstrap &&
/o11y-otel-collector migrate sync up &&
/o11y-otel-collector migrate async up
restart: on-failure
networks:
signoz-net:
name: signoz-net
o11y-net:
name: o11y-net
volumes:
clickhouse:
name: signoz-clickhouse
name: o11y-datastore
clickhouse-2:
name: signoz-clickhouse-2
name: o11y-datastore-2
clickhouse-3:
name: signoz-clickhouse-3
name: o11y-datastore-3
sqlite:
name: signoz-sqlite
name: o11y-sqlite
zookeeper-1:
name: signoz-zookeeper-1
name: o11y-zookeeper-1
zookeeper-2:
name: signoz-zookeeper-2
name: o11y-zookeeper-2
zookeeper-3:
name: signoz-zookeeper-3
name: o11y-zookeeper-3
+48 -48
View File
@@ -1,7 +1,7 @@
version: "3"
x-common: &common
networks:
- signoz-net
- o11y-net
restart: unless-stopped
logging:
options:
@@ -9,12 +9,12 @@ x-common: &common
max-file: "3"
x-clickhouse-defaults: &clickhouse-defaults
!!merge <<: *common
image: clickhouse/clickhouse-server:25.5.6
image: ghcr.io/hanzoai/datastore:25.5.6
tty: true
labels:
signoz.io/scrape: "true"
signoz.io/port: "9363"
signoz.io/path: "/metrics"
o11y.hanzo.ai/scrape: "true"
o11y.hanzo.ai/port: "9363"
o11y.hanzo.ai/path: "/metrics"
depends_on:
init-clickhouse:
condition: service_completed_successfully
@@ -39,12 +39,12 @@ x-clickhouse-defaults: &clickhouse-defaults
- CLICKHOUSE_SKIP_USER_SETUP=1
x-zookeeper-defaults: &zookeeper-defaults
!!merge <<: *common
image: signoz/zookeeper:3.7.1
image: ghcr.io/hanzoai/zookeeper:3.7.1
user: root
labels:
signoz.io/scrape: "true"
signoz.io/port: "9141"
signoz.io/path: "/metrics"
o11y.hanzo.ai/scrape: "true"
o11y.hanzo.ai/port: "9141"
o11y.hanzo.ai/path: "/metrics"
healthcheck:
test:
- CMD-SHELL
@@ -60,8 +60,8 @@ x-db-depend: &db-depend
services:
init-clickhouse:
!!merge <<: *common
image: clickhouse/clickhouse-server:25.5.6
container_name: signoz-init-clickhouse
image: ghcr.io/hanzoai/datastore:25.5.6
container_name: o11y-init-datastore
command:
- bash
- -c
@@ -71,7 +71,7 @@ services:
node_arch=$$(uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/)
echo "Fetching histogram-binary for $${node_os}/$${node_arch}"
cd /tmp
wget -O histogram-quantile.tar.gz "https://github.com/SigNoz/signoz/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
wget -O histogram-quantile.tar.gz "https://github.com/Hanzo O11y/observe/releases/download/histogram-quantile%2F$${version}/histogram-quantile_$${node_os}_$${node_arch}.tar.gz"
tar -xvzf histogram-quantile.tar.gz
mv histogram-quantile /var/lib/clickhouse/user_scripts/histogramQuantile
restart: on-failure
@@ -79,7 +79,7 @@ services:
- ../common/clickhouse/user_scripts:/var/lib/clickhouse/user_scripts/
zookeeper-1:
!!merge <<: *zookeeper-defaults
container_name: signoz-zookeeper-1
container_name: o11y-zookeeper-1
# ports:
# - "2181:2181"
# - "2888:2888"
@@ -94,7 +94,7 @@ services:
- ZOO_PROMETHEUS_METRICS_PORT_NUMBER=9141
clickhouse:
!!merge <<: *clickhouse-defaults
container_name: signoz-clickhouse
container_name: o11y-datastore
# ports:
# - "9000:9000"
# - "8123:8123"
@@ -107,19 +107,19 @@ services:
- ../common/clickhouse/cluster.xml:/etc/clickhouse-server/config.d/cluster.xml
- clickhouse:/var/lib/clickhouse/
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
observe:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.114.0}
container_name: signoz
image: ghcr.io/hanzoai/o11y:${VERSION:-v0.115.0}
container_name: observe
ports:
- "8080:8080" # signoz port
- "8080:8080" # observe port
volumes:
- sqlite:/var/lib/signoz/
- sqlite:/var/lib/observe/
environment:
- SIGNOZ_ALERTMANAGER_PROVIDER=signoz
- SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_SQLSTORE_SQLITE_PATH=/var/lib/signoz/signoz.db
- SIGNOZ_TOKENIZER_JWT_SECRET=secret
- O11Y_ALERTMANAGER_PROVIDER=observe
- O11Y_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_SQLSTORE_SQLITE_PATH=/var/lib/ghcr.io/hanzoai/o11y.db
- O11Y_TOKENIZER_JWT_SECRET=secret
healthcheck:
test:
- CMD
@@ -132,54 +132,54 @@ services:
retries: 3
otel-collector:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.2}
container_name: signoz-otel-collector
image: ghcr.io/hanzoai/otel-collector:${OTELCOL_TAG:-v0.144.2}
container_name: o11y-otel-collector
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate sync check &&
/signoz-otel-collector --config=/etc/otel-collector-config.yaml --manager-config=/etc/manager-config.yaml --copy-path=/var/tmp/collector-config.yaml
/o11y-otel-collector migrate sync check &&
/o11y-otel-collector --config=/etc/otel-collector-config.yaml --manager-config=/etc/manager-config.yaml --copy-path=/var/tmp/collector-config.yaml
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
- ../common/signoz/otel-collector-opamp-config.yaml:/etc/manager-config.yaml
- ../common/observe/otel-collector-opamp-config.yaml:/etc/manager-config.yaml
environment:
- OTEL_RESOURCE_ATTRIBUTES=host.name=signoz-host,os.type=linux
- OTEL_RESOURCE_ATTRIBUTES=host.name=observe-host,os.type=linux
- LOW_CARDINAL_EXCEPTION_GROUPING=false
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
ports:
# - "1777:1777" # pprof extension
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
signoz-telemetrystore-migrator:
o11y-telemetrystore-migrator:
!!merge <<: *db-depend
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-v0.144.2}
container_name: signoz-telemetrystore-migrator
image: ghcr.io/hanzoai/otel-collector:${OTELCOL_TAG:-v0.144.2}
container_name: o11y-telemetrystore-migrator
environment:
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- SIGNOZ_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- SIGNOZ_OTEL_COLLECTOR_TIMEOUT=10m
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_DSN=tcp://clickhouse:9000
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_CLUSTER=cluster
- O11Y_OTEL_COLLECTOR_CLICKHOUSE_REPLICATION=true
- O11Y_OTEL_COLLECTOR_TIMEOUT=10m
entrypoint:
- /bin/sh
command:
- -c
- |
/signoz-otel-collector migrate bootstrap &&
/signoz-otel-collector migrate sync up &&
/signoz-otel-collector migrate async up
/o11y-otel-collector migrate bootstrap &&
/o11y-otel-collector migrate sync up &&
/o11y-otel-collector migrate async up
restart: on-failure
networks:
signoz-net:
name: signoz-net
o11y-net:
name: o11y-net
volumes:
clickhouse:
name: signoz-clickhouse
name: o11y-datastore
sqlite:
name: signoz-sqlite
name: o11y-sqlite
zookeeper-1:
name: signoz-zookeeper-1
name: o11y-zookeeper-1
@@ -1,7 +1,7 @@
version: "3"
x-common: &common
networks:
- signoz-net
- o11y-net
extra_hosts:
- host.docker.internal:host-gateway
logging:
@@ -16,11 +16,11 @@ services:
container_name: hotrod
command: [ "all" ]
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://host.docker.internal:4318 # In case of external SigNoz or cloud, update the endpoint and access token
# - OTEL_OTLP_HEADERS=signoz-access-token=<your-access-token>
- OTEL_EXPORTER_OTLP_ENDPOINT=http://host.docker.internal:4318 # In case of external Hanzo O11y or cloud, update the endpoint and access token
# - OTEL_OTLP_HEADERS=observe-access-token=<your-access-token>
load-hotrod:
<<: *common
image: "signoz/locust:1.2.3"
image: "observe/locust:1.2.3"
container_name: load-hotrod
environment:
ATTACKED_HOST: http://hotrod:8080
@@ -34,6 +34,6 @@ services:
- ../../../common/locust-scripts:/locust
networks:
signoz-net:
name: signoz-net
o11y-net:
name: o11y-net
external: true
@@ -1,7 +1,7 @@
version: "3"
x-common: &common
networks:
- signoz-net
- o11y-net
extra_hosts:
- host.docker.internal:host-gateway
logging:
@@ -20,9 +20,9 @@ services:
- /:/hostfs:ro
- /var/run/docker.sock:/var/run/docker.sock
environment:
- SIGNOZ_COLLECTOR_ENDPOINT=http://host.docker.internal:4317 # In case of external SigNoz or cloud, update the endpoint and access token
- OTEL_RESOURCE_ATTRIBUTES=host.name=signoz-host,os.type=linux # Replace signoz-host with the actual hostname
# - SIGNOZ_ACCESS_TOKEN="<your-access-token>"
- O11Y_COLLECTOR_ENDPOINT=http://host.docker.internal:4317 # In case of external Hanzo O11y or cloud, update the endpoint and access token
- OTEL_RESOURCE_ATTRIBUTES=host.name=observe-host,os.type=linux # Replace observe-host with the actual hostname
# - O11Y_ACCESS_TOKEN="<your-access-token>"
# Before exposing the ports, make sure the ports are not used by other services
# ports:
# - "4317:4317"
@@ -38,6 +38,6 @@ services:
- otel-agent
networks:
signoz-net:
name: signoz-net
o11y-net:
name: o11y-net
external: true
@@ -41,26 +41,26 @@ receivers:
- action: keep
regex: true
source_labels:
- __meta_docker_container_label_signoz_io_scrape
- __meta_docker_container_label_observe_io_scrape
- regex: true
source_labels:
- __meta_docker_container_label_signoz_io_path
- __meta_docker_container_label_observe_io_path
target_label: __metrics_path__
- regex: (.+)
source_labels:
- __meta_docker_container_label_signoz_io_path
- __meta_docker_container_label_observe_io_path
target_label: __metrics_path__
- separator: ":"
source_labels:
- __meta_docker_network_ip
- __meta_docker_container_label_signoz_io_port
- __meta_docker_container_label_observe_io_port
target_label: __address__
- regex: '/(.*)'
replacement: '$1'
source_labels:
- __meta_docker_container_name
target_label: container_name
- regex: __meta_docker_container_label_signoz_io_(.+)
- regex: __meta_docker_container_label_observe_io_(.+)
action: labelmap
replacement: $1
tcplog/docker:
@@ -78,8 +78,8 @@ receivers:
field: attributes.timestamp
# please remove names from below if you want to collect logs from them
- type: filter
id: signoz_logs_filter
expr: 'attributes.container_name matches "^signoz|(signoz-(|otel-collector|clickhouse|zookeeper))|(infra-(logspout|otel-agent)-.*)"'
id: observe_logs_filter
expr: 'attributes.container_name matches "^observe|(observe-(|otel-collector|clickhouse|zookeeper))|(infra-(logspout|otel-agent)-.*)"'
processors:
batch:
send_batch_size: 10000
@@ -101,11 +101,11 @@ extensions:
endpoint: 0.0.0.0:1777
exporters:
otlp:
endpoint: ${env:SIGNOZ_COLLECTOR_ENDPOINT}
endpoint: ${env:O11Y_COLLECTOR_ENDPOINT}
tls:
insecure: true
headers:
signoz-access-token: ${env:SIGNOZ_ACCESS_TOKEN}
observe-access-token: ${env:O11Y_ACCESS_TOKEN}
# debug: {}
service:
telemetry:
+18 -18
View File
@@ -1,5 +1,5 @@
connectors:
signozmeter:
observemeter:
metrics_flush_interval: 1h
dimensions:
- name: service.name
@@ -36,8 +36,8 @@ processors:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors: [env, system]
timeout: 2s
signozspanmetrics/delta:
metrics_exporter: signozclickhousemetrics
observespanmetrics/delta:
metrics_exporter: observeclickhousemetrics
metrics_flush_interval: 60s
latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ]
dimensions_cache_size: 100000
@@ -51,7 +51,7 @@ processors:
# This is added to ensure the uniqueness of the timeseries
# Otherwise, identical timeseries produced by multiple replicas of
# collectors result in incorrect APM metrics
- name: signoz.collector.id
- name: observe.collector.id
- name: service.version
- name: browser.platform
- name: browser.mobile
@@ -68,24 +68,24 @@ extensions:
endpoint: 0.0.0.0:1777
exporters:
clickhousetraces:
datasource: tcp://clickhouse:9000/signoz_traces
datasource: tcp://clickhouse:9000/observe_traces
low_cardinal_exception_grouping: ${env:LOW_CARDINAL_EXCEPTION_GROUPING}
use_new_schema: true
signozclickhousemetrics:
dsn: tcp://clickhouse:9000/signoz_metrics
observeclickhousemetrics:
dsn: tcp://clickhouse:9000/observe_metrics
clickhouselogsexporter:
dsn: tcp://clickhouse:9000/signoz_logs
dsn: tcp://clickhouse:9000/observe_logs
timeout: 10s
use_new_schema: true
signozclickhousemeter:
dsn: tcp://clickhouse:9000/signoz_meter
observeclickhousemeter:
dsn: tcp://clickhouse:9000/observe_meter
timeout: 45s
sending_queue:
enabled: false
metadataexporter:
cache:
provider: in_memory
dsn: tcp://clickhouse:9000/signoz_metadata
dsn: tcp://clickhouse:9000/observe_metadata
enabled: true
timeout: 45s
service:
@@ -98,21 +98,21 @@ service:
pipelines:
traces:
receivers: [otlp]
processors: [signozspanmetrics/delta, batch]
exporters: [clickhousetraces, metadataexporter, signozmeter]
processors: [observespanmetrics/delta, batch]
exporters: [clickhousetraces, metadataexporter, observemeter]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [signozclickhousemetrics, metadataexporter, signozmeter]
exporters: [observeclickhousemetrics, metadataexporter, observemeter]
metrics/prometheus:
receivers: [prometheus]
processors: [batch]
exporters: [signozclickhousemetrics, metadataexporter, signozmeter]
exporters: [observeclickhousemetrics, metadataexporter, observemeter]
logs:
receivers: [otlp]
processors: [batch]
exporters: [clickhouselogsexporter, metadataexporter, signozmeter]
exporters: [clickhouselogsexporter, metadataexporter, observemeter]
metrics/meter:
receivers: [signozmeter]
receivers: [observemeter]
processors: [batch/meter]
exporters: [signozclickhousemeter]
exporters: [observeclickhousemeter]
+32 -23
View File
@@ -1229,7 +1229,7 @@ components:
$ref: '#/components/schemas/Querybuildertypesv5OrderBy'
type: array
type: object
Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5LogAggregation:
Querybuildertypesv5QueryBuilderQueryGithubComHanzo O11yObservePkgTypesQuerybuildertypesQuerybuildertypesv5LogAggregation:
properties:
aggregations:
items:
@@ -1280,7 +1280,7 @@ components:
stepInterval:
$ref: '#/components/schemas/Querybuildertypesv5Step'
type: object
Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregation:
Querybuildertypesv5QueryBuilderQueryGithubComHanzo O11yObservePkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregation:
properties:
aggregations:
items:
@@ -1331,7 +1331,7 @@ components:
stepInterval:
$ref: '#/components/schemas/Querybuildertypesv5Step'
type: object
Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregation:
Querybuildertypesv5QueryBuilderQueryGithubComHanzo O11yObservePkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregation:
properties:
aggregations:
items:
@@ -1455,21 +1455,21 @@ components:
Querybuildertypesv5QueryEnvelopeBuilderLog:
properties:
spec:
$ref: '#/components/schemas/Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5LogAggregation'
$ref: '#/components/schemas/Querybuildertypesv5QueryBuilderQueryGithubComHanzo O11yObservePkgTypesQuerybuildertypesQuerybuildertypesv5LogAggregation'
type:
$ref: '#/components/schemas/Querybuildertypesv5QueryType'
type: object
Querybuildertypesv5QueryEnvelopeBuilderMetric:
properties:
spec:
$ref: '#/components/schemas/Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregation'
$ref: '#/components/schemas/Querybuildertypesv5QueryBuilderQueryGithubComHanzo O11yObservePkgTypesQuerybuildertypesQuerybuildertypesv5MetricAggregation'
type:
$ref: '#/components/schemas/Querybuildertypesv5QueryType'
type: object
Querybuildertypesv5QueryEnvelopeBuilderTrace:
properties:
spec:
$ref: '#/components/schemas/Querybuildertypesv5QueryBuilderQueryGithubComSigNozSignozPkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregation'
$ref: '#/components/schemas/Querybuildertypesv5QueryBuilderQueryGithubComHanzo O11yObservePkgTypesQuerybuildertypesQuerybuildertypesv5TraceAggregation'
type:
$ref: '#/components/schemas/Querybuildertypesv5QueryType'
type: object
@@ -2108,6 +2108,15 @@ components:
token:
type: string
type: object
TypesPostableBulkInviteRequest:
properties:
invites:
items:
$ref: '#/components/schemas/TypesPostableInvite'
type: array
required:
- invites
type: object
TypesPostableForgotPassword:
properties:
email:
@@ -2196,6 +2205,8 @@ components:
type: string
role:
type: string
status:
type: string
updatedAt:
format: date-time
type: string
@@ -2256,33 +2267,33 @@ components:
number_of_services:
format: int64
type: integer
reasons_for_interest_in_signoz:
reasons_for_interest_in_observe:
items:
type: string
nullable: true
type: array
timeline_for_migrating_to_signoz:
timeline_for_migrating_to_observe:
type: string
uses_otel:
type: boolean
where_did_you_discover_signoz:
where_did_you_discover_observe:
type: string
required:
- uses_otel
- has_existing_observability_tool
- existing_observability_tool
- reasons_for_interest_in_signoz
- reasons_for_interest_in_observe
- logs_scale_per_day_in_gb
- number_of_services
- number_of_hosts
- where_did_you_discover_signoz
- timeline_for_migrating_to_signoz
- where_did_you_discover_observe
- timeline_for_migrating_to_observe
type: object
securitySchemes:
api_key:
description: API Keys
in: header
name: SigNoz-Api-Key
name: Hanzo O11y-Api-Key
type: apiKey
tokenizer:
bearerFormat: Tokenizer
@@ -2291,7 +2302,7 @@ components:
type: http
info:
description: OpenTelemetry-Native Logs, Metrics and Traces in a single pane
title: SigNoz
title: Hanzo O11y
version: ""
openapi: 3.0.3
paths:
@@ -3538,9 +3549,7 @@ paths:
content:
application/json:
schema:
items:
$ref: '#/components/schemas/TypesPostableInvite'
type: array
$ref: '#/components/schemas/TypesPostableBulkInviteRequest'
responses:
"201":
description: Created
@@ -7166,9 +7175,9 @@ paths:
- spec:
name: recent_errors
query: WITH __resource_filter AS ( SELECT fingerprint FROM
signoz_logs.distributed_logs_v2_resource WHERE seen_at_ts_bucket_start
observe_logs.distributed_logs_v2_resource WHERE seen_at_ts_bucket_start
>= $start_timestamp - 1800 AND seen_at_ts_bucket_start <=
$end_timestamp ) SELECT timestamp, body FROM signoz_logs.distributed_logs_v2
$end_timestamp ) SELECT timestamp, body FROM observe_logs.distributed_logs_v2
WHERE resource_fingerprint GLOBAL IN (SELECT fingerprint
FROM __resource_filter) AND timestamp >= $start_timestamp_nano
AND timestamp <= $end_timestamp_nano AND ts_bucket_start
@@ -7188,9 +7197,9 @@ paths:
- spec:
name: total_spans
query: WITH __resource_filter AS ( SELECT fingerprint FROM
signoz_traces.distributed_traces_v3_resource WHERE seen_at_ts_bucket_start
observe_traces.distributed_traces_v3_resource WHERE seen_at_ts_bucket_start
>= $start_timestamp - 1800 AND seen_at_ts_bucket_start <=
$end_timestamp ) SELECT count() AS value FROM signoz_traces.distributed_signoz_index_v3
$end_timestamp ) SELECT count() AS value FROM observe_traces.distributed_observe_index_v3
WHERE resource_fingerprint GLOBAL IN (SELECT fingerprint
FROM __resource_filter) AND timestamp >= $start_datetime
AND timestamp <= $end_datetime AND ts_bucket_start >= $start_timestamp
@@ -7208,10 +7217,10 @@ paths:
- spec:
name: span_rate
query: WITH __resource_filter AS ( SELECT fingerprint FROM
signoz_traces.distributed_traces_v3_resource WHERE seen_at_ts_bucket_start
observe_traces.distributed_traces_v3_resource WHERE seen_at_ts_bucket_start
>= $start_timestamp - 1800 AND seen_at_ts_bucket_start <=
$end_timestamp ) SELECT toStartOfInterval(timestamp, INTERVAL
60 SECOND) AS ts, count() AS value FROM signoz_traces.distributed_signoz_index_v3
60 SECOND) AS ts, count() AS value FROM observe_traces.distributed_observe_index_v3
WHERE resource_fingerprint GLOBAL IN (SELECT fingerprint
FROM __resource_filter) AND timestamp >= $start_datetime
AND timestamp <= $end_datetime AND ts_bucket_start >= $start_timestamp
+7 -7
View File
@@ -1,6 +1,6 @@
# Development Guide
Welcome! This guide will help you set up your local development environment for SigNoz. Let's get you started! 🚀
Welcome! This guide will help you set up your local development environment for Hanzo O11y. Let's get you started! 🚀
## What do I need?
@@ -31,7 +31,7 @@ Before diving in, make sure you have these tools installed:
1. Open your terminal
2. Clone the repository:
```bash
git clone https://github.com/SigNoz/signoz.git
git clone https://github.com/Hanzo O11y/signoz.git
```
3. Navigate to the project:
```bash
@@ -40,7 +40,7 @@ Before diving in, make sure you have these tools installed:
## How do I run it locally?
SigNoz has three main components: Clickhouse, Backend, and Frontend. Let's set them up one by one.
Hanzo O11y has three main components: Clickhouse, Backend, and Frontend. Let's set them up one by one.
### 1. Setting up ClickHouse
@@ -55,7 +55,7 @@ This command:
- Sets up Zookeeper
- Runs the latest schema migrations
### 2. Setting up SigNoz OpenTelemetry Collector
### 2. Setting up Hanzo O11y OpenTelemetry Collector
Next, start the OpenTelemetry Collector to receive telemetry data:
@@ -64,7 +64,7 @@ make devenv-signoz-otel-collector
```
This command:
- Starts the SigNoz OpenTelemetry Collector
- Starts the Hanzo O11y OpenTelemetry Collector
- Listens on port 4317 (gRPC) and 4318 (HTTP) for incoming telemetry data
- Forwards data to ClickHouse for storage
@@ -100,7 +100,7 @@ This command:
3. Create a `.env` file in this directory:
```env
FRONTEND_API_ENDPOINT=http://localhost:8080
VITE_FRONTEND_API_ENDPOINT=http://localhost:8080
```
4. Start the development server:
@@ -122,7 +122,7 @@ To verify everything is working correctly:
## How to send test data?
You can now send telemetry data to your local SigNoz instance:
You can now send telemetry data to your local Hanzo O11y instance:
- **OTLP gRPC**: `localhost:4317`
- **OTLP HTTP**: `localhost:4318`
+3 -3
View File
@@ -1,10 +1,10 @@
# Errors
SigNoz includes its own structured [errors](/pkg/errors/errors.go) package. It's built on top of Go's `error` interface, extending it to add additional context that helps provide more meaningful error messages throughout the application.
Hanzo O11y includes its own structured [errors](/pkg/errors/errors.go) package. It's built on top of Go's `error` interface, extending it to add additional context that helps provide more meaningful error messages throughout the application.
## How to use it?
To use the SigNoz structured errors package, use these functions instead of the standard library alternatives:
To use the Hanzo O11y structured errors package, use these functions instead of the standard library alternatives:
```go
// Instead of errors.New()
@@ -81,7 +81,7 @@ func GetUserSecurely(id string) (*User, error) {
## Why do we need this?
In a large codebase like SigNoz, error handling is critical for maintaining reliability, debuggability, and a good user experience. We believe that it is the **responsibility of a function** to return **well-defined** errors that **accurately describe what went wrong**. With our structured error system:
In a large codebase like Hanzo O11y, error handling is critical for maintaining reliability, debuggability, and a good user experience. We believe that it is the **responsibility of a function** to return **well-defined** errors that **accurately describe what went wrong**. With our structured error system:
- Functions can create precise errors with appropriate additional context
- Callers can make informed decisions based on the additional context
+3 -3
View File
@@ -1,6 +1,6 @@
# Flagger
Flagger is SigNoz's feature flagging system built on top of the [OpenFeature](https://openfeature.dev/) standard. It provides a unified interface for evaluating feature flags across the application, allowing features to be enabled, disabled, or configured dynamically without code changes.
Flagger is Hanzo O11y's feature flagging system built on top of the [OpenFeature](https://openfeature.dev/) standard. It provides a unified interface for evaluating feature flags across the application, allowing features to be enabled, disabled, or configured dynamically without code changes.
> 💡 **Note**: OpenFeature is a CNCF project that provides a vendor-agnostic feature flagging API, making it easy to switch providers without changing application code.
@@ -77,8 +77,8 @@ Use the `Flagger` interface to evaluate feature flags. The interface provides ty
```go
import (
"github.com/SigNoz/signoz/pkg/flagger"
"github.com/SigNoz/signoz/pkg/types/featuretypes"
"github.com/Hanzo O11y/signoz/pkg/flagger"
"github.com/Hanzo O11y/signoz/pkg/types/featuretypes"
)
func DoSomething(ctx context.Context, flagger flagger.Flagger) error {
+1 -1
View File
@@ -1,6 +1,6 @@
# Handler
Handlers in SigNoz are responsible for exposing module functionality over HTTP. They are thin adapters that:
Handlers in Hanzo O11y are responsible for exposing module functionality over HTTP. They are thin adapters that:
- Decode incoming HTTP requests
- Call the appropriate module layer
+4 -4
View File
@@ -1,6 +1,6 @@
# Integration Tests
SigNoz uses integration tests to verify that different components work together correctly in a real environment. These tests run against actual services (ClickHouse, PostgreSQL, etc.) to ensure end-to-end functionality.
Hanzo O11y uses integration tests to verify that different components work together correctly in a real environment. These tests run against actual services (ClickHouse, PostgreSQL, etc.) to ensure end-to-end functionality.
## How to set up the integration test environment?
@@ -92,7 +92,7 @@ Each test suite follows some important principles:
### Test Suite Design
Test suites should target functional domains or subsystems within SigNoz. When designing a test suite, consider these principles:
Test suites should target functional domains or subsystems within Hanzo O11y. When designing a test suite, consider these principles:
- **Functional Cohesion**: Group tests around a specific capability or service boundary
- **Data Flow**: Follow the path of data through related components
@@ -119,7 +119,7 @@ from fixtures.logger import setup_logger
logger = setup_logger(__name__)
def test_version(signoz: types.SigNoz) -> None:
def test_version(signoz: types.Hanzo O11y) -> None:
response = requests.get(signoz.self.host_config.get("/api/v1/version"), timeout=2)
logger.info(response)
```
@@ -142,7 +142,7 @@ from fixtures.logger import setup_logger
logger = setup_logger(__name__)
def test_user_registration(signoz: types.SigNoz) -> None:
def test_user_registration(signoz: types.Hanzo O11y) -> None:
"""Test user registration functionality."""
response = requests.post(
signoz.self.host_configs["8080"].get("/api/v1/register"),
+3 -3
View File
@@ -1,6 +1,6 @@
# Packages
All shared Go code in SigNoz lives under `pkg/`. Each package represents a distinct domain concept and exposes a clear public interface. This guide covers the conventions for creating, naming, and organising packages so the codebase stays consistent as it grows.
All shared Go code in Hanzo O11y lives under `pkg/`. Each package represents a distinct domain concept and exposes a clear public interface. This guide covers the conventions for creating, naming, and organising packages so the codebase stays consistent as it grows.
## How should I name a package?
@@ -81,8 +81,8 @@ import (
"github.com/gorilla/mux"
// 3. Internal
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/types"
"github.com/Hanzo O11y/signoz/pkg/errors"
"github.com/Hanzo O11y/signoz/pkg/types"
)
```
+6 -6
View File
@@ -1,6 +1,6 @@
# Provider
SigNoz is built on the provider pattern, a design approach where code is organized into providers that handle specific application responsibilities. Providers act as adapter components that integrate with external services and deliver required functionality to the application.
Hanzo O11y is built on the provider pattern, a design approach where code is organized into providers that handle specific application responsibilities. Providers act as adapter components that integrate with external services and deliver required functionality to the application.
> 💡 **Note**: Coming from a DDD background? Providers are similar (not exactly the same) to adapter/infrastructure services.
@@ -59,16 +59,16 @@ func NewMyProviderFactories() factory.NamedMap[factory.ProviderFactory[myprovide
}
```
3. Instantiate the provider by adding it to the `SigNoz` struct in `pkg/signoz/signoz.go`:
3. Instantiate the provider by adding it to the `Hanzo O11y` struct in `pkg/signoz/signoz.go`:
```go
type SigNoz struct {
type Hanzo O11y struct {
...
MyProvider myprovider.MyProvider
...
}
func New(...) (*SigNoz, error) {
func New(...) (*Hanzo O11y, error) {
...
myprovider, err := myproviderone.New(ctx, settings, config.MyProvider, "one/two")
if err != nil {
@@ -83,7 +83,7 @@ func New(...) (*SigNoz, error) {
To use a provider, import its interface. For example, to use the prometheus provider, import `pkg/prometheus/prometheus.go`:
```go
import "github.com/SigNoz/signoz/pkg/prometheus/prometheus"
import "github.com/Hanzo O11y/signoz/pkg/prometheus/prometheus"
func CreateSomething(ctx context.Context, prometheus prometheus.Prometheus) {
...
@@ -94,7 +94,7 @@ func CreateSomething(ctx context.Context, prometheus prometheus.Prometheus) {
## Why do we need this?
Like any dependency injection framework, providers decouple the codebase from implementation details. This is especially valuable in SigNoz's large codebase, where we need to swap implementations without changing dependent code. The provider pattern offers several benefits apart from the obvious one of decoupling:
Like any dependency injection framework, providers decouple the codebase from implementation details. This is especially valuable in Hanzo O11y's large codebase, where we need to swap implementations without changing dependent code. The provider pattern offers several benefits apart from the obvious one of decoupling:
- Configuration is **defined with each provider and centralized in one place**, making it easier to understand and manage through various methods (environment variables, config files, etc.)
- Provider mocking is **straightforward for unit testing**, with a consistent pattern for locating mocks
+1 -1
View File
@@ -1,6 +1,6 @@
# Go
This document provides an overview of contributing to the SigNoz backend written in Go. The SigNoz backend is built with Go, focusing on performance, maintainability, and developer experience. We strive for clean, idiomatic code that follows established Go practices while addressing the unique needs of an observability platform.
This document provides an overview of contributing to the Hanzo O11y backend written in Go. The Hanzo O11y backend is built with Go, focusing on performance, maintainability, and developer experience. We strive for clean, idiomatic code that follows established Go practices while addressing the unique needs of an observability platform.
We adhere to three primary style guides as our foundation:
+1 -1
View File
@@ -191,7 +191,7 @@ A standalone service only has the `factory.Service` lifecycle i.e it does not se
// ... dependencies ...
) user.Service {
return &service{
settings: factory.NewScopedProviderSettings(providerSettings, "go.signoz.io/pkg/modules/user"),
settings: factory.NewScopedProviderSettings(providerSettings, "go.o11y.hanzo.ai/pkg/modules/user"),
// ... dependencies ...
stopC: make(chan struct{}),
}
+3 -3
View File
@@ -1,9 +1,9 @@
# SQL
SigNoz utilizes a relational database to store metadata including organization information, user data and other settings.
Hanzo O11y utilizes a relational database to store metadata including organization information, user data and other settings.
## How to use it?
The database interface is defined in [SQLStore](/pkg/sqlstore/sqlstore.go). SigNoz leverages the Bun ORM to interact with the underlying database. To access the database instance, use the `BunDBCtx` function. For operations that require transactions across multiple database operations, use the `RunInTxCtx` function. This function embeds a transaction in the context, which propagates through various functions in the callback.
The database interface is defined in [SQLStore](/pkg/sqlstore/sqlstore.go). Hanzo O11y leverages the Bun ORM to interact with the underlying database. To access the database instance, use the `BunDBCtx` function. For operations that require transactions across multiple database operations, use the `RunInTxCtx` function. This function embeds a transaction in the context, which propagates through various functions in the callback.
```go
type Thing struct {
@@ -46,7 +46,7 @@ Hooks are user-defined functions that execute before and/or after specific datab
## How is the schema designed?
SigNoz implements a star schema design with the organizations table as the central entity. All other tables link to the organizations table via foreign key constraints on the `org_id` column. This design ensures that every entity within the system is either directly or indirectly associated with an organization.
Hanzo O11y implements a star schema design with the organizations table as the central entity. All other tables link to the organizations table via foreign key constraints on the `org_id` column. This design ensures that every entity within the system is either directly or indirectly associated with an organization.
```mermaid
erDiagram
+2 -1
View File
@@ -1,6 +1,6 @@
# Onboarding Configuration Guide
This guide explains how to add new data sources to the SigNoz onboarding flow. The onboarding configuration controls the "New Source" / "Get Started" experience in SigNoz Cloud.
This guide explains how to add new data sources to the Hanzo O11y onboarding flow. The onboarding configuration controls the "New Source" / "Get Started" experience in Hanzo O11y Cloud.
## Configuration File Location
@@ -273,6 +273,7 @@ Options can be simple (direct link) or nested (with another question):
- Place logo files in `public/Logos/`
- Use SVG format
- Reference as `"/Logos/your-logo.svg"`
- **Optimize new SVGs**: Run any newly downloaded SVGs through an optimizer like [SVGOMG (svgo)](https://svgomg.net/) or use `npx svgo public/Logos/your-logo.svg` to minimise their size before committing.
### 4. Links
+216
View File
@@ -0,0 +1,216 @@
# Query Range v5 — Design Principles & Architectural Contracts
## Purpose of This Document
This document defines the design principles, invariants, and architectural contracts of the Query Range v5 system. It is intended for the authors working on the querier and querier related parts codebase. Any change to the system must align with the principles described here. If a change would violate a principle, it must be flagged and discussed.
---
## Core Architectural Principle
**The user speaks OpenTelemetry. The storage speaks ClickHouse. The system translates between them. These two worlds must never leak into each other.**
Every design choice in Query Range flows from this separation. The user-facing API surface deals exclusively in `TelemetryFieldKey`: a representation of fields as they exist in the OpenTelemetry data model. The storage layer deals in ClickHouse column expressions, table names, and SQL fragments. The translation between them is mediated by a small set of composable abstractions with strict boundaries.
---
## The Central Type: `TelemetryFieldKey`
`TelemetryFieldKey` is the atomic unit of the entire query system. Every filter, aggregation, group-by, order-by, and select operation is expressed in terms of field keys. Understanding its design contracts is non-negotiable.
### Identity
A field key is identified by three dimensions:
- **Name** — the field name as the user knows it (`service.name`, `http.method`, `trace_id`)
- **FieldContext** — where the field lives in the OTel model (`resource`, `attribute`, `span`, `log`, `body`, `scope`, `event`, `metric`)
- **FieldDataType** — the data type (`string`, `bool`, `number`/`float64`/`int64`, array variants)
### Invariant: Same name does not mean same field
`status` as an attribute, `status` as a body JSON key, and `status` as a span-level field are **three different fields**. The context disambiguates. Code that resolves or compares field keys must always consider all three dimensions, never just the name.
### Invariant: Normalization happens once, at the boundary
`TelemetryFieldKey.Normalize()` is called during JSON unmarshaling. After normalization, the text representation `resource.service.name:string` and the programmatic construction `{Name: "service.name", FieldContext: Resource, FieldDataType: String}` are identical.
**Consequence:** Downstream code must never re-parse or re-normalize field keys. If you find yourself splitting on `.` or `:` deep in the pipeline, something is wrong — the normalization should have already happened.
### Invariant: The text format is `context.name:datatype`
Parsing rules (implemented in `GetFieldKeyFromKeyText` and `Normalize`):
1. Data type is extracted from the right, after the last `:`.
2. Field context is extracted from the left, before the first `.`, if it matches a known context prefix.
3. Everything remaining is the name.
Special case: `log.body.X` normalizes to `{FieldContext: body, Name: X}` — the `log.body.` prefix collapses because body fields under log are a nested context.
### Invariant: Historical aliases must be preserved
The `fieldContexts` map includes aliases (`tag` -> `attribute`, `spanfield` -> `span`, `logfield` -> `log`). These exist because older database entries use these names. Removing or changing these aliases will break existing saved queries and dashboard configurations.
---
## The Abstraction Stack
The query pipeline is built from four interfaces that compose vertically. Each layer has a single responsibility. Each layer depends only on the layers below it. This layering is intentional and must be preserved.
```
StatementBuilder <- Orchestrates everything into executable SQL
├── AggExprRewriter <- Rewrites aggregation expressions (maps field refs to columns)
├── ConditionBuilder <- Builds WHERE predicates (field + operator + value -> SQL)
└── FieldMapper <- Maps TelemetryFieldKey -> ClickHouse column expression
```
### FieldMapper
**Contract:** Given a `TelemetryFieldKey`, return a ClickHouse column expression that yields the value for that field when used in a SELECT.
**Principle:** This is the *only* place where field-to-column translation happens. No other layer should contain knowledge of how fields map to storage. If you need a column expression, go through the FieldMapper.
**Why:** The user says `http.request.method`. ClickHouse might store it as `attributes_string['http.request.method']`, or as a materialized column `` `attribute_string_http$$request$$method` ``, or via a JSON access path in a body column. This variation is entirely contained within the FieldMapper. Everything above it is storage-agnostic.
### ConditionBuilder
**Contract:** Given a field key, an operator, and a value, produce a valid SQL predicate for a WHERE clause.
**Dependency:** Uses FieldMapper for the left-hand side of the condition.
**Principle:** The ConditionBuilder owns all the complexity of operator semantics, i.e type casting, array operators (`hasAny`/`hasAll` vs `=`), existence checks, and negative operator behavior. This complexity must not leak upward into the StatementBuilder.
### AggExprRewriter
**Contract:** Given a user-facing aggregation expression like `sum(duration_nano)`, resolve field references within it and produce valid ClickHouse SQL.
**Dependency:** Uses FieldMapper to resolve field names within expressions.
**Principle:** Aggregation expressions are user-authored strings that contain field references. The rewriter parses them, identifies field references, resolves each through the FieldMapper, and reassembles the expression.
### StatementBuilder
**Contract:** Given a complete `QueryBuilderQuery`, a time range, and a request type, produces an executable SQL statement.
**Dependency:** Uses all three abstractions above.
**Principle:** This is the composition layer. It does not contain field mapping logic, condition building logic, or expression rewriting logic. It orchestrates the other abstractions. If you find storage-specific logic creeping into the StatementBuilder, push it down into the appropriate abstraction.
### Invariant: No layer skipping
The StatementBuilder must not call FieldMapper directly to build conditions, it goes through the ConditionBuilder. The AggExprRewriter must not hardcode column names, it goes through the FieldMapper. Skipping layers creates hidden coupling and makes the system fragile to storage changes.
---
## Design Decisions as Constraints
### Constraint: Formula evaluation happens in Go, not in ClickHouse
Formulas (`A + B`, `A / B`, `sqrt(A*A + B*B)`) are evaluated application-side by `FormulaEvaluator`, not via ClickHouse JOINs.
**Why this is a constraint, not just an implementation choice:** The original JOIN-based approach was abandoned because ClickHouse evaluates joins right-to-left, serializing execution unnecessarily. Running queries independently allows parallelism and caching of intermediate results. Any future optimization must not reintroduce the JOIN pattern without solving the serialization problem.
**Consequence:** Individual query results must be independently cacheable. Formula evaluation must handle label matching, timestamp alignment, and missing values without requiring the queries to coordinate at the SQL level.
### Constraint: Zero-defaulting is aggregation-dependent
Only additive/counting aggregations (`count`, `count_distinct`, `sum`, `rate`) default missing values to zero. Statistical aggregations (`avg`, `min`, `max`, percentiles) must show gaps.
**Why:** Absence of data has different meanings. No error requests in a time bucket means error count = 0. No requests at all means average latency is *unknown*, not 0. Conflating these is a correctness bug, not a display preference.
**Enforcement:** `GetQueriesSupportingZeroDefault` determines which queries can default to zero. The `FormulaEvaluator` consumes this via `canDefaultZero`. Changes to aggregation handling must preserve this distinction.
### Constraint: Existence semantics differ for positive vs negative operators
- **Positive operators** (`=`, `>`, `LIKE`, `IN`, etc.) implicitly assert field existence. `http.method = GET` means "the field exists AND equals GET".
- **Negative operators** (`!=`, `NOT IN`, `NOT LIKE`, etc.) do **not** add an existence check. `http.method != GET` includes records where the field doesn't exist at all.
**Why:** The user's intent with negative operators is ambiguous. Rather than guess, we take the broader interpretation. Users can add an explicit `EXISTS` filter if they want the narrower one. This is documented in `AddDefaultExistsFilter`.
**Consequence:** Any new operator must declare its existence behavior in `AddDefaultExistsFilter`. Do not add operators without considering this.
### Constraint: Post-processing functions operate on result sets, not in SQL
Functions like `cutOffMin`, `ewma`, `median`, `timeShift`, `fillZero`, `runningDiff`, and `cumulativeSum` are applied in Go on the returned time series, not pushed into ClickHouse SQL.
**Why:** These are sequential time-series transformations that require complete, ordered result sets. Pushing them into SQL would complicate query generation, prevent caching of raw results, and make the functions harder to test. They are applied via `ApplyFunctions` after query execution.
**Consequence:** New time-series transformation functions should follow this pattern i.e implement them as Go functions on `*TimeSeries`, not as SQL modifications.
### Constraint: The API surface rejects unknown fields with suggestions
All request types use custom `UnmarshalJSON` that calls `DisallowUnknownFields`. Unknown fields trigger error messages with Levenshtein-based suggestions ("did you mean: 'groupBy'?").
**Why:** Silent acceptance of unknown fields causes subtle bugs. A misspelled `groupBy` results in ungrouped data with no indication of what went wrong. Failing fast with suggestions turns errors into actionable feedback.
**Consequence:** Any new request type or query spec struct must implement custom unmarshaling with `UnmarshalJSONWithContext`. Do not use default `json.Unmarshal` for user-facing types.
### Constraint: Validation is context-sensitive to request type
What's valid depends on the `RequestType`. For aggregation requests (`time_series`, `scalar`, `distribution`), fields like `groupBy`, `aggregations`, `having`, and aggregation-referenced `orderBy` are validated. For non-aggregation requests (`raw`, `raw_stream`, `trace`), these fields are ignored.
**Why:** A raw log query doesn't have aggregations, so requiring `aggregations` would be wrong. But a time-series query without aggregations is meaningless. The validation rules are request-type-aware to avoid both false positives and false negatives.
**Consequence:** When adding new fields to query specs, consider which request types they apply to and gate validation accordingly.
---
## The Composite Query Model
### Structure
A `QueryRangeRequest` contains a `CompositeQuery` which holds `[]QueryEnvelope`. Each envelope is a discriminated union: a `Type` field determines how `Spec` is decoded.
### Invariant: Query names are unique within a composite query
Builder queries must have unique names. Formulas reference queries by name (`A`, `B`, `A.0`, `A.my_alias`). Duplicate names would make formula evaluation ambiguous.
### Invariant: Multi-aggregation uses indexed or aliased references
A single builder query can have multiple aggregations. They are accessed in formulas via:
- Index: `A.0`, `A.1` (zero-based)
- Alias: `A.total`, `A.error_count`
The default (just `A`) resolves to index 0. This is the formula evaluation contract and must be preserved.
### Invariant: Type-specific decoding through signal detection
Builder queries are decoded by first peeking at the `signal` field in the raw JSON, then unmarshaling into the appropriate generic type (`QueryBuilderQuery[TraceAggregation]`, `QueryBuilderQuery[LogAggregation]`, `QueryBuilderQuery[MetricAggregation]`). This two-pass decoding is intentional — it allows each signal to have its own aggregation schema while sharing the query structure.
---
## The Metadata Layer
### MetadataStore
The `MetadataStore` interface provides runtime field discovery and type resolution. It answers questions like "what fields exist for this signal?" and "what are the data types of field X?".
### Principle: Fields can be ambiguous until resolved
The same name can map to multiple `TelemetryFieldKey` variants (different contexts, different types). The metadata store returns *all* variants. Resolution to a single field happens during query building, using the query's signal and any explicit context/type hints from the user.
**Consequence:** Code that calls `GetKey` or `GetKeys` must handle multiple results. Do not assume a name maps to a single field.
### Principle: Materialized fields are a performance optimization, not a semantic distinction
A materialized field and its non-materialized equivalent represent the same logical field. The `Materialized` flag tells the FieldMapper to generate a simpler column expression. The user should never need to know whether a field is materialized.
### Principle: JSON body fields require access plans
Fields inside JSON body columns (`body.response.errors[].code`) need pre-computed `JSONAccessPlan` trees that encode the traversal path, including branching at array boundaries between `Array(JSON)` and `Array(Dynamic)` representations. These plans are computed during metadata resolution, not during query execution.
---
## Summary of Inviolable Rules
1. **User-facing types never contain ClickHouse column names or SQL fragments.**
2. **Field-to-column translation only happens in FieldMapper.**
3. **Normalization happens once at the API boundary, never deeper.**
4. **Historical aliases in fieldContexts and fieldDataTypes must not be removed.**
5. **Formula evaluation stays in Go — do not push it into ClickHouse JOINs.**
6. **Zero-defaulting is aggregation-type-dependent — do not universally default to zero.**
7. **Positive operators imply existence, negative operators do not.**
8. **Post-processing functions operate on Go result sets, not in SQL.**
9. **All user-facing types reject unknown JSON fields with suggestions.**
10. **Validation rules are gated by request type.**
11. **Query names must be unique within a composite query.**
12. **The four-layer abstraction stack (FieldMapper -> ConditionBuilder -> AggExprRewriter -> StatementBuilder) must not be bypassed or flattened.**
+31 -31
View File
@@ -1,28 +1,28 @@
# Configuring OpenTelemetry Demo App with SigNoz
# Configuring OpenTelemetry Demo App with Hanzo O11y
[The OpenTelemetry Astronomy Shop](https://github.com/open-telemetry/opentelemetry-demo) is an e-commerce web application, with **15 core microservices** in a **distributed system** which communicate over gRPC. Designed as a **polyglot** environment, it leverages a diverse set of programming languages, including Go, Python, .NET, Java, and others, showcasing cross-language instrumentation with OpenTelemetry. The intention is to get a quickstart application to send data and experience SigNoz firsthand.
[The OpenTelemetry Astronomy Shop](https://github.com/open-telemetry/opentelemetry-demo) is an e-commerce web application, with **15 core microservices** in a **distributed system** which communicate over gRPC. Designed as a **polyglot** environment, it leverages a diverse set of programming languages, including Go, Python, .NET, Java, and others, showcasing cross-language instrumentation with OpenTelemetry. The intention is to get a quickstart application to send data and experience Hanzo O11y firsthand.
This guide provides a step-by-step walkthrough for setting up the **OpenTelemetry Demo App** with **SigNoz** as backend for observability. It outlines steps to export telemetry data to **SigNoz self-hosted with Docker**, **SigNoz self-hosted with Kubernetes** and **SigNoz cloud**.
This guide provides a step-by-step walkthrough for setting up the **OpenTelemetry Demo App** with **Hanzo O11y** as backend for observability. It outlines steps to export telemetry data to **Hanzo O11y self-hosted with Docker**, **Hanzo O11y self-hosted with Kubernetes** and **Hanzo O11y cloud**.
<br/>
__Table of Contents__
- [Send data to SigNoz Self-hosted with Docker](#send-data-to-signoz-self-hosted-with-docker)
- [Send data to Hanzo O11y Self-hosted with Docker](#send-data-to-signoz-self-hosted-with-docker)
- [Prerequisites](#prerequisites)
- [Clone the OpenTelemetry Demo App Repository](#clone-the-opentelemetry-demo-app-repository)
- [Modify OpenTelemetry Collector Config](#modify-opentelemetry-collector-config)
- [Start the OpenTelemetry Demo App](#start-the-opentelemetry-demo-app)
- [Monitor with SigNoz (Docker)](#monitor-with-signoz-docker)
- [Send data to SigNoz Self-hosted with Kubernetes](#send-data-to-signoz-self-hosted-with-kubernetes)
- [Monitor with Hanzo O11y (Docker)](#monitor-with-signoz-docker)
- [Send data to Hanzo O11y Self-hosted with Kubernetes](#send-data-to-signoz-self-hosted-with-kubernetes)
- [Prerequisites](#prerequisites-1)
- [Install Helm Repo and Charts](#install-helm-repo-and-charts)
- [Start the OpenTelemetry Demo App](#start-the-opentelemetry-demo-app-1)
- [Monitor with SigNoz (Kubernetes)](#monitor-with-signoz-kubernetes)
- [Monitor with Hanzo O11y (Kubernetes)](#monitor-with-signoz-kubernetes)
- [What's next](#whats-next)
# Send data to SigNoz Self-hosted with Docker
# Send data to Hanzo O11y Self-hosted with Docker
In this guide you will install the OTel demo application using Docker and send telemetry data to SigNoz hosted with Docker, referred as SigNoz [Docker] from now.
In this guide you will install the OTel demo application using Docker and send telemetry data to Hanzo O11y hosted with Docker, referred as Hanzo O11y [Docker] from now.
## Prerequisites
@@ -46,7 +46,7 @@ By default, the collector in the demo application will merge the configuration f
1. otelcol-config.yml &nbsp;&nbsp;[we don't touch this]
2. otelcol-config-extras.yml &nbsp;&nbsp; [we modify this]
To add SigNoz [Docker] as the backend, open the file `src/otel-collector/otelcol-config-extras.yml` and add the following,
To add Hanzo O11y [Docker] as the backend, open the file `src/otel-collector/otelcol-config-extras.yml` and add the following,
```yaml
exporters:
otlp:
@@ -66,20 +66,20 @@ service:
exporters: [otlp]
```
The SigNoz OTel collector [sigNoz's otel-collector service] listens at 4317 port on localhost. When the OTel demo app is running within a Docker container and needs to transmit telemetry data to SigNoz, it cannot directly reference 'localhost' as this would refer to the container's own internal network. Instead, Docker provides a special DNS name, `host.docker.internal`, which resolves to the host machine's IP address from within containers. By configuring the OpenTelemetry Demo application to send data to `host.docker.internal:4317`, we establish a network path that allows the containerized application to transmit telemetry data across the container boundary to the SigNoz OTel collector running on the host machine's port 4317.
The Hanzo O11y OTel collector [sigNoz's otel-collector service] listens at 4317 port on localhost. When the OTel demo app is running within a Docker container and needs to transmit telemetry data to Hanzo O11y, it cannot directly reference 'localhost' as this would refer to the container's own internal network. Instead, Docker provides a special DNS name, `host.docker.internal`, which resolves to the host machine's IP address from within containers. By configuring the OpenTelemetry Demo application to send data to `host.docker.internal:4317`, we establish a network path that allows the containerized application to transmit telemetry data across the container boundary to the Hanzo O11y OTel collector running on the host machine's port 4317.
>
> Note: When merging extra configuration values with the existing collector config (`src/otel-collector/otelcol-config.yml`), objects are merged and arrays are replaced resulting in previous pipeline configurations getting overridden.
The spanmetrics exporter must be included in the array of exporters for the traces pipeline if overridden. Not including this exporter will result in an error.
>
<br>
<u>To send data to SigNoz Cloud</u>
<u>To send data to Hanzo O11y Cloud</u>
If you want to send data to cloud instead, open the file `src/otel-collector/otelcol-config-extras.yml` and add the following,
```yaml
exporters:
otlp:
endpoint: "https://ingest.{your-region}.signoz.cloud:443"
endpoint: "https://ingest.{your-region}.o11y.hanzo.ai:443"
tls:
insecure: false
headers:
@@ -101,9 +101,9 @@ Remember to replace the region and ingestion key with proper values as obtained
## Start the OpenTelemetry Demo App
Both SigNoz and OTel demo app [frontend-proxy service, to be accurate] share common port allocation at 8080. To prevent port allocation conflicts, modify the OTel demo application config to use port 8081 as the `ENVOY_PORT` value as shown below, and run docker compose command.
Both Hanzo O11y and OTel demo app [frontend-proxy service, to be accurate] share common port allocation at 8080. To prevent port allocation conflicts, modify the OTel demo application config to use port 8081 as the `ENVOY_PORT` value as shown below, and run docker compose command.
Also, both SigNoz and OTel Demo App have the same `PROMETHEUS_PORT` configured, by default both of them try to start at `9090`, which may cause either of them to fail depending upon which one acquires it first. To prevent this, we need to mofify the value of `PROMETHEUS_PORT` too.
Also, both Hanzo O11y and OTel Demo App have the same `PROMETHEUS_PORT` configured, by default both of them try to start at `9090`, which may cause either of them to fail depending upon which one acquires it first. To prevent this, we need to mofify the value of `PROMETHEUS_PORT` too.
```sh
@@ -125,20 +125,20 @@ The result should look similar to this,
Navigate to `http://localhost:8081/` where you can access OTel demo app UI. Generate some traffic to send to SigNoz [Docker].
Navigate to `http://localhost:8081/` where you can access OTel demo app UI. Generate some traffic to send to Hanzo O11y [Docker].
## Monitor with SigNoz [Docker]
## Monitor with Hanzo O11y [Docker]
Signoz exposes its UI at `http://localhost:8080/`. You should be able to see multiple services listed down as shown in the snapshot below.
![](/docs/img/otel-demo-services.png)
This verifies that your OTel demo app is successfully sending telemetry data to SigNoz [Docker] as expected.
This verifies that your OTel demo app is successfully sending telemetry data to Hanzo O11y [Docker] as expected.
# Send data to SigNoz Self-hosted with Kubernetes
# Send data to Hanzo O11y Self-hosted with Kubernetes
In this guide you will install the OTel demo application using Helm and send telemetry data to SigNoz hosted with Kubernetes, referred as SigNoz [Kubernetes] from now.
In this guide you will install the OTel demo application using Helm and send telemetry data to Hanzo O11y hosted with Kubernetes, referred as Hanzo O11y [Kubernetes] from now.
## Prerequisites
@@ -151,12 +151,12 @@ In this guide you will install the OTel demo application using Helm and send tel
## Install Helm Repo and Charts
Youll need to **install the Helm repository** to start sending data to SigNoz cloud.
Youll need to **install the Helm repository** to start sending data to Hanzo O11y cloud.
```sh
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
```
The OpenTelemetry Collectors configuration is exposed in the Helm chart. All additions made will be merged into the default configuration. We use this capability to add SigNoz as an exporter, and make pipelines as desired.
The OpenTelemetry Collectors configuration is exposed in the Helm chart. All additions made will be merged into the default configuration. We use this capability to add Hanzo O11y as an exporter, and make pipelines as desired.
For this we have to create a `values.yaml` which will override the existing configurations that comes with the Helm chart.
@@ -175,21 +175,21 @@ default:
- name: OTEL_COLLECTOR_NAME
value: signoz-otel-collector.<namespace>.svc.cluster.local
```
Replace namespace with your appropriate namespace. This file will replace the charts existing settings with our new ones, ensuring telemetry data is sent to SigNoz [Kubernetes].
Replace namespace with your appropriate namespace. This file will replace the charts existing settings with our new ones, ensuring telemetry data is sent to Hanzo O11y [Kubernetes].
> Note: When merging YAML values with Helm, objects are merged and arrays are replaced. The spanmetrics exporter must be included in the array of exporters for the traces pipeline if overridden. Not including this exporter will result in an error.
<br>
<u>To send data to SigNoz cloud</u>
<u>To send data to Hanzo O11y cloud</u>
If you wish to send data to cloud instance of SigNoz, we have to create a `values.yaml` which will override the existing configurations that comes with the Helm chart.
If you wish to send data to cloud instance of Hanzo O11y, we have to create a `values.yaml` which will override the existing configurations that comes with the Helm chart.
```sh
opentelemetry-collector:
config:
exporters:
otlp:
endpoint: "https://ingest.{your-region}.signoz.cloud:443"
endpoint: "https://ingest.{your-region}.o11y.hanzo.ai:443"
tls:
insecure: false
headers:
@@ -233,17 +233,17 @@ To expose the OTel demo app UI [frontend-proxy service] use the following comman
```sh
kubectl port-forward svc/my-otel-demo-frontend-proxy 8080:8081
```
Navigate to `http://localhost:8081/` where you can access OTel demo app UI. Generate some traffic to send to SigNoz [Kubernetes].
Navigate to `http://localhost:8081/` where you can access OTel demo app UI. Generate some traffic to send to Hanzo O11y [Kubernetes].
## Monitor with SigNoz [Kubernetes]
## Monitor with Hanzo O11y [Kubernetes]
Signoz exposes it's UI at `http://localhost:8080/`. You should be able to see multiple services listed down as shown in the snapshot below.
![](/docs/img/otel-demo-services.png)
This verifies that your OTel demo app is successfully sending telemetry data to SigNoz [Kubernetes] as expected.
This verifies that your OTel demo app is successfully sending telemetry data to Hanzo O11y [Kubernetes] as expected.
@@ -251,6 +251,6 @@ This verifies that your OTel demo app is successfully sending telemetry data to
Don't forget to check our OpenTelemetry [track](https://signoz.io/resource-center/opentelemetry/), guaranteed to take you from a newbie to sensei in no time!
Don't forget to check our OpenTelemetry [track](https://o11y.hanzo.ai/resource-center/opentelemetry/), guaranteed to take you from a newbie to sensei in no time!
Also from a fellow OTel fan to another, we at [SigNoz](https://signoz.io/) are building an open-source, OTel native, observability platform (one of its kind). So, show us love - star us on [GitHub](https://github.com/SigNoz/signoz), nitpick our [docs](https://signoz.io/docs/introduction/), or just tell your app were the ones wholl catch its crashes mid-flight and finally shush all the 3am panic calls!
Also from a fellow OTel fan to another, we at [Hanzo O11y](https://o11y.hanzo.ai/) are building an open-source, OTel native, observability platform (one of its kind). So, show us love - star us on [GitHub](https://github.com/Hanzo O11y/signoz), nitpick our [docs](https://o11y.hanzo.ai/docs/introduction/), or just tell your app were the ones wholl catch its crashes mid-flight and finally shush all the 3am panic calls!
-37
View File
@@ -1,37 +0,0 @@
The SigNoz Enterprise license (the "Enterprise License")
Copyright (c) 2020 - present SigNoz Inc.
With regard to the SigNoz Software:
This software and associated documentation files (the "Software") may only be
used in production, if you (and any entity that you represent) have agreed to,
and are in compliance with, the SigNoz Subscription Terms of Service, available
via email (hello@signoz.io) (the "Enterprise Terms"), or other
agreement governing the use of the Software, as agreed by you and SigNoz,
and otherwise have a valid SigNoz Enterprise license for the
correct number of user seats. Subject to the foregoing sentence, you are free to
modify this Software and publish patches to the Software. You agree that SigNoz
and/or its licensors (as applicable) retain all right, title and interest in and
to all such modifications and/or patches, and all such modifications and/or
patches may only be used, copied, modified, displayed, distributed, or otherwise
exploited with a valid SigNoz Enterprise license for the correct
number of user seats. Notwithstanding the foregoing, you may copy and modify
the Software for development and testing purposes, without requiring a
subscription. You agree that SigNoz and/or its licensors (as applicable) retain
all right, title and interest in and to all such modifications. You are not
granted any other rights beyond what is expressly stated herein. Subject to the
foregoing, it is forbidden to copy, merge, publish, distribute, sublicense,
and/or sell the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
For all third party components incorporated into the SigNoz Software, those
components are licensed under the original license provided by the owner of the
applicable component.
-34
View File
@@ -1,34 +0,0 @@
package anomaly
import (
"context"
"github.com/SigNoz/signoz/pkg/valuer"
)
type DailyProvider struct {
BaseSeasonalProvider
}
var _ BaseProvider = (*DailyProvider)(nil)
func (dp *DailyProvider) GetBaseSeasonalProvider() *BaseSeasonalProvider {
return &dp.BaseSeasonalProvider
}
func NewDailyProvider(opts ...GenericProviderOption[*DailyProvider]) *DailyProvider {
dp := &DailyProvider{
BaseSeasonalProvider: BaseSeasonalProvider{},
}
for _, opt := range opts {
opt(dp)
}
return dp
}
func (p *DailyProvider) GetAnomalies(ctx context.Context, orgID valuer.UUID, req *AnomaliesRequest) (*AnomaliesResponse, error) {
req.Seasonality = SeasonalityDaily
return p.getAnomalies(ctx, orgID, req)
}
-35
View File
@@ -1,35 +0,0 @@
package anomaly
import (
"context"
"github.com/SigNoz/signoz/pkg/valuer"
)
type HourlyProvider struct {
BaseSeasonalProvider
}
var _ BaseProvider = (*HourlyProvider)(nil)
func (hp *HourlyProvider) GetBaseSeasonalProvider() *BaseSeasonalProvider {
return &hp.BaseSeasonalProvider
}
// NewHourlyProvider now uses the generic option type
func NewHourlyProvider(opts ...GenericProviderOption[*HourlyProvider]) *HourlyProvider {
hp := &HourlyProvider{
BaseSeasonalProvider: BaseSeasonalProvider{},
}
for _, opt := range opts {
opt(hp)
}
return hp
}
func (p *HourlyProvider) GetAnomalies(ctx context.Context, orgID valuer.UUID, req *AnomaliesRequest) (*AnomaliesResponse, error) {
req.Seasonality = SeasonalityHourly
return p.getAnomalies(ctx, orgID, req)
}
-223
View File
@@ -1,223 +0,0 @@
package anomaly
import (
"time"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/valuer"
)
type Seasonality struct{ valuer.String }
var (
SeasonalityHourly = Seasonality{valuer.NewString("hourly")}
SeasonalityDaily = Seasonality{valuer.NewString("daily")}
SeasonalityWeekly = Seasonality{valuer.NewString("weekly")}
)
var (
oneWeekOffset = uint64(24 * 7 * time.Hour.Milliseconds())
oneDayOffset = uint64(24 * time.Hour.Milliseconds())
oneHourOffset = uint64(time.Hour.Milliseconds())
fiveMinOffset = uint64(5 * time.Minute.Milliseconds())
)
func (s Seasonality) IsValid() bool {
switch s {
case SeasonalityHourly, SeasonalityDaily, SeasonalityWeekly:
return true
default:
return false
}
}
type AnomaliesRequest struct {
Params qbtypes.QueryRangeRequest
Seasonality Seasonality
}
type AnomaliesResponse struct {
Results []*qbtypes.TimeSeriesData
}
// anomalyParams is the params for anomaly detection
// prediction = avg(past_period_query) + avg(current_season_query) - mean(past_season_query, past2_season_query, past3_season_query)
//
// ^ ^
// | |
// (rounded value for past peiod) + (seasonal growth)
//
// score = abs(value - prediction) / stddev (current_season_query)
type anomalyQueryParams struct {
// CurrentPeriodQuery is the query range params for period user is looking at or eval window
// Example: (now-5m, now), (now-30m, now), (now-1h, now)
// The results obtained from this query are used to compare with predicted values
// and to detect anomalies
CurrentPeriodQuery qbtypes.QueryRangeRequest
// PastPeriodQuery is the query range params for past period of seasonality
// Example: For weekly seasonality, (now-1w-5m, now-1w)
// : For daily seasonality, (now-1d-5m, now-1d)
// : For hourly seasonality, (now-1h-5m, now-1h)
PastPeriodQuery qbtypes.QueryRangeRequest
// CurrentSeasonQuery is the query range params for current period (seasonal)
// Example: For weekly seasonality, this is the query range params for the (now-1w-5m, now)
// : For daily seasonality, this is the query range params for the (now-1d-5m, now)
// : For hourly seasonality, this is the query range params for the (now-1h-5m, now)
CurrentSeasonQuery qbtypes.QueryRangeRequest
// PastSeasonQuery is the query range params for past seasonal period to the current season
// Example: For weekly seasonality, this is the query range params for the (now-2w-5m, now-1w)
// : For daily seasonality, this is the query range params for the (now-2d-5m, now-1d)
// : For hourly seasonality, this is the query range params for the (now-2h-5m, now-1h)
PastSeasonQuery qbtypes.QueryRangeRequest
// Past2SeasonQuery is the query range params for past 2 seasonal period to the current season
// Example: For weekly seasonality, this is the query range params for the (now-3w-5m, now-2w)
// : For daily seasonality, this is the query range params for the (now-3d-5m, now-2d)
// : For hourly seasonality, this is the query range params for the (now-3h-5m, now-2h)
Past2SeasonQuery qbtypes.QueryRangeRequest
// Past3SeasonQuery is the query range params for past 3 seasonal period to the current season
// Example: For weekly seasonality, this is the query range params for the (now-4w-5m, now-3w)
// : For daily seasonality, this is the query range params for the (now-4d-5m, now-3d)
// : For hourly seasonality, this is the query range params for the (now-4h-5m, now-3h)
Past3SeasonQuery qbtypes.QueryRangeRequest
}
func prepareAnomalyQueryParams(req qbtypes.QueryRangeRequest, seasonality Seasonality) *anomalyQueryParams {
start := req.Start
end := req.End
currentPeriodQuery := qbtypes.QueryRangeRequest{
Start: start,
End: end,
RequestType: qbtypes.RequestTypeTimeSeries,
CompositeQuery: req.CompositeQuery,
NoCache: false,
}
var pastPeriodStart, pastPeriodEnd uint64
switch seasonality {
// for one week period, we fetch the data from the past week with 5 min offset
case SeasonalityWeekly:
pastPeriodStart = start - oneWeekOffset - fiveMinOffset
pastPeriodEnd = end - oneWeekOffset
// for one day period, we fetch the data from the past day with 5 min offset
case SeasonalityDaily:
pastPeriodStart = start - oneDayOffset - fiveMinOffset
pastPeriodEnd = end - oneDayOffset
// for one hour period, we fetch the data from the past hour with 5 min offset
case SeasonalityHourly:
pastPeriodStart = start - oneHourOffset - fiveMinOffset
pastPeriodEnd = end - oneHourOffset
}
pastPeriodQuery := qbtypes.QueryRangeRequest{
Start: pastPeriodStart,
End: pastPeriodEnd,
RequestType: qbtypes.RequestTypeTimeSeries,
CompositeQuery: req.CompositeQuery,
NoCache: false,
}
// seasonality growth trend
var currentGrowthPeriodStart, currentGrowthPeriodEnd uint64
switch seasonality {
case SeasonalityWeekly:
currentGrowthPeriodStart = start - oneWeekOffset
currentGrowthPeriodEnd = start
case SeasonalityDaily:
currentGrowthPeriodStart = start - oneDayOffset
currentGrowthPeriodEnd = start
case SeasonalityHourly:
currentGrowthPeriodStart = start - oneHourOffset
currentGrowthPeriodEnd = start
}
currentGrowthQuery := qbtypes.QueryRangeRequest{
Start: currentGrowthPeriodStart,
End: currentGrowthPeriodEnd,
RequestType: qbtypes.RequestTypeTimeSeries,
CompositeQuery: req.CompositeQuery,
NoCache: false,
}
var pastGrowthPeriodStart, pastGrowthPeriodEnd uint64
switch seasonality {
case SeasonalityWeekly:
pastGrowthPeriodStart = start - 2*oneWeekOffset
pastGrowthPeriodEnd = start - 1*oneWeekOffset
case SeasonalityDaily:
pastGrowthPeriodStart = start - 2*oneDayOffset
pastGrowthPeriodEnd = start - 1*oneDayOffset
case SeasonalityHourly:
pastGrowthPeriodStart = start - 2*oneHourOffset
pastGrowthPeriodEnd = start - 1*oneHourOffset
}
pastGrowthQuery := qbtypes.QueryRangeRequest{
Start: pastGrowthPeriodStart,
End: pastGrowthPeriodEnd,
RequestType: qbtypes.RequestTypeTimeSeries,
CompositeQuery: req.CompositeQuery,
NoCache: false,
}
var past2GrowthPeriodStart, past2GrowthPeriodEnd uint64
switch seasonality {
case SeasonalityWeekly:
past2GrowthPeriodStart = start - 3*oneWeekOffset
past2GrowthPeriodEnd = start - 2*oneWeekOffset
case SeasonalityDaily:
past2GrowthPeriodStart = start - 3*oneDayOffset
past2GrowthPeriodEnd = start - 2*oneDayOffset
case SeasonalityHourly:
past2GrowthPeriodStart = start - 3*oneHourOffset
past2GrowthPeriodEnd = start - 2*oneHourOffset
}
past2GrowthQuery := qbtypes.QueryRangeRequest{
Start: past2GrowthPeriodStart,
End: past2GrowthPeriodEnd,
RequestType: qbtypes.RequestTypeTimeSeries,
CompositeQuery: req.CompositeQuery,
NoCache: false,
}
var past3GrowthPeriodStart, past3GrowthPeriodEnd uint64
switch seasonality {
case SeasonalityWeekly:
past3GrowthPeriodStart = start - 4*oneWeekOffset
past3GrowthPeriodEnd = start - 3*oneWeekOffset
case SeasonalityDaily:
past3GrowthPeriodStart = start - 4*oneDayOffset
past3GrowthPeriodEnd = start - 3*oneDayOffset
case SeasonalityHourly:
past3GrowthPeriodStart = start - 4*oneHourOffset
past3GrowthPeriodEnd = start - 3*oneHourOffset
}
past3GrowthQuery := qbtypes.QueryRangeRequest{
Start: past3GrowthPeriodStart,
End: past3GrowthPeriodEnd,
RequestType: qbtypes.RequestTypeTimeSeries,
CompositeQuery: req.CompositeQuery,
NoCache: false,
}
return &anomalyQueryParams{
CurrentPeriodQuery: currentPeriodQuery,
PastPeriodQuery: pastPeriodQuery,
CurrentSeasonQuery: currentGrowthQuery,
PastSeasonQuery: pastGrowthQuery,
Past2SeasonQuery: past2GrowthQuery,
Past3SeasonQuery: past3GrowthQuery,
}
}
type anomalyQueryResults struct {
CurrentPeriodResults []*qbtypes.TimeSeriesData
PastPeriodResults []*qbtypes.TimeSeriesData
CurrentSeasonResults []*qbtypes.TimeSeriesData
PastSeasonResults []*qbtypes.TimeSeriesData
Past2SeasonResults []*qbtypes.TimeSeriesData
Past3SeasonResults []*qbtypes.TimeSeriesData
}
-11
View File
@@ -1,11 +0,0 @@
package anomaly
import (
"context"
"github.com/SigNoz/signoz/pkg/valuer"
)
type Provider interface {
GetAnomalies(ctx context.Context, orgID valuer.UUID, req *AnomaliesRequest) (*AnomaliesResponse, error)
}
-465
View File
@@ -1,465 +0,0 @@
package anomaly
import (
"context"
"log/slog"
"math"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/valuer"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
)
var (
// TODO(srikanthccv): make this configurable?
movingAvgWindowSize = 7
)
// BaseProvider is an interface that includes common methods for all provider types
type BaseProvider interface {
GetBaseSeasonalProvider() *BaseSeasonalProvider
}
// GenericProviderOption is a generic type for provider options
type GenericProviderOption[T BaseProvider] func(T)
func WithQuerier[T BaseProvider](querier querier.Querier) GenericProviderOption[T] {
return func(p T) {
p.GetBaseSeasonalProvider().querier = querier
}
}
func WithLogger[T BaseProvider](logger *slog.Logger) GenericProviderOption[T] {
return func(p T) {
p.GetBaseSeasonalProvider().logger = logger
}
}
type BaseSeasonalProvider struct {
querier querier.Querier
logger *slog.Logger
}
func (p *BaseSeasonalProvider) getQueryParams(req *AnomaliesRequest) *anomalyQueryParams {
if !req.Seasonality.IsValid() {
req.Seasonality = SeasonalityDaily
}
return prepareAnomalyQueryParams(req.Params, req.Seasonality)
}
func (p *BaseSeasonalProvider) toTSResults(ctx context.Context, resp *qbtypes.QueryRangeResponse) []*qbtypes.TimeSeriesData {
tsData := []*qbtypes.TimeSeriesData{}
if resp == nil {
p.logger.InfoContext(ctx, "nil response from query range")
return tsData
}
for _, item := range resp.Data.Results {
if resultData, ok := item.(*qbtypes.TimeSeriesData); ok {
tsData = append(tsData, resultData)
}
}
return tsData
}
func (p *BaseSeasonalProvider) getResults(ctx context.Context, orgID valuer.UUID, params *anomalyQueryParams) (*anomalyQueryResults, error) {
// TODO(srikanthccv): parallelize this?
p.logger.InfoContext(ctx, "fetching results for current period", "anomaly_current_period_query", params.CurrentPeriodQuery)
currentPeriodResults, err := p.querier.QueryRange(ctx, orgID, &params.CurrentPeriodQuery)
if err != nil {
return nil, err
}
p.logger.InfoContext(ctx, "fetching results for past period", "anomaly_past_period_query", params.PastPeriodQuery)
pastPeriodResults, err := p.querier.QueryRange(ctx, orgID, &params.PastPeriodQuery)
if err != nil {
return nil, err
}
p.logger.InfoContext(ctx, "fetching results for current season", "anomaly_current_season_query", params.CurrentSeasonQuery)
currentSeasonResults, err := p.querier.QueryRange(ctx, orgID, &params.CurrentSeasonQuery)
if err != nil {
return nil, err
}
p.logger.InfoContext(ctx, "fetching results for past season", "anomaly_past_season_query", params.PastSeasonQuery)
pastSeasonResults, err := p.querier.QueryRange(ctx, orgID, &params.PastSeasonQuery)
if err != nil {
return nil, err
}
p.logger.InfoContext(ctx, "fetching results for past 2 season", "anomaly_past_2season_query", params.Past2SeasonQuery)
past2SeasonResults, err := p.querier.QueryRange(ctx, orgID, &params.Past2SeasonQuery)
if err != nil {
return nil, err
}
p.logger.InfoContext(ctx, "fetching results for past 3 season", "anomaly_past_3season_query", params.Past3SeasonQuery)
past3SeasonResults, err := p.querier.QueryRange(ctx, orgID, &params.Past3SeasonQuery)
if err != nil {
return nil, err
}
return &anomalyQueryResults{
CurrentPeriodResults: p.toTSResults(ctx, currentPeriodResults),
PastPeriodResults: p.toTSResults(ctx, pastPeriodResults),
CurrentSeasonResults: p.toTSResults(ctx, currentSeasonResults),
PastSeasonResults: p.toTSResults(ctx, pastSeasonResults),
Past2SeasonResults: p.toTSResults(ctx, past2SeasonResults),
Past3SeasonResults: p.toTSResults(ctx, past3SeasonResults),
}, nil
}
// getMatchingSeries gets the matching series from the query result
// for the given series
func (p *BaseSeasonalProvider) getMatchingSeries(_ context.Context, queryResult *qbtypes.TimeSeriesData, series *qbtypes.TimeSeries) *qbtypes.TimeSeries {
if queryResult == nil || len(queryResult.Aggregations) == 0 || len(queryResult.Aggregations[0].Series) == 0 {
return nil
}
for _, curr := range queryResult.Aggregations[0].Series {
currLabelsKey := qbtypes.GetUniqueSeriesKey(curr.Labels)
seriesLabelsKey := qbtypes.GetUniqueSeriesKey(series.Labels)
if currLabelsKey == seriesLabelsKey {
return curr
}
}
return nil
}
func (p *BaseSeasonalProvider) getAvg(series *qbtypes.TimeSeries) float64 {
if series == nil || len(series.Values) == 0 {
return 0
}
var sum float64
for _, smpl := range series.Values {
sum += smpl.Value
}
return sum / float64(len(series.Values))
}
func (p *BaseSeasonalProvider) getStdDev(series *qbtypes.TimeSeries) float64 {
if series == nil || len(series.Values) == 0 {
return 0
}
avg := p.getAvg(series)
var sum float64
for _, smpl := range series.Values {
sum += math.Pow(smpl.Value-avg, 2)
}
return math.Sqrt(sum / float64(len(series.Values)))
}
// getMovingAvg gets the moving average for the given series
// for the given window size and start index
func (p *BaseSeasonalProvider) getMovingAvg(series *qbtypes.TimeSeries, movingAvgWindowSize, startIdx int) float64 {
if series == nil || len(series.Values) == 0 {
return 0
}
if startIdx >= len(series.Values)-movingAvgWindowSize {
startIdx = int(math.Max(0, float64(len(series.Values)-movingAvgWindowSize)))
}
var sum float64
points := series.Values[startIdx:]
windowSize := int(math.Min(float64(movingAvgWindowSize), float64(len(points))))
for i := 0; i < windowSize; i++ {
sum += points[i].Value
}
avg := sum / float64(windowSize)
return avg
}
func (p *BaseSeasonalProvider) getMean(floats ...float64) float64 {
if len(floats) == 0 {
return 0
}
var sum float64
for _, f := range floats {
sum += f
}
return sum / float64(len(floats))
}
func (p *BaseSeasonalProvider) getPredictedSeries(
ctx context.Context,
series, prevSeries, currentSeasonSeries, pastSeasonSeries, past2SeasonSeries, past3SeasonSeries *qbtypes.TimeSeries,
) *qbtypes.TimeSeries {
predictedSeries := &qbtypes.TimeSeries{
Labels: series.Labels,
Values: make([]*qbtypes.TimeSeriesValue, 0),
}
// for each point in the series, get the predicted value
// the predicted value is the moving average (with window size = 7) of the previous period series
// plus the average of the current season series
// minus the mean of the past season series, past2 season series and past3 season series
for idx, curr := range series.Values {
movingAvg := p.getMovingAvg(prevSeries, movingAvgWindowSize, idx)
avg := p.getAvg(currentSeasonSeries)
mean := p.getMean(p.getAvg(pastSeasonSeries), p.getAvg(past2SeasonSeries), p.getAvg(past3SeasonSeries))
predictedValue := movingAvg + avg - mean
if predictedValue < 0 {
// this should not happen (except when the data has extreme outliers)
// we will use the moving avg of the previous period series in this case
p.logger.WarnContext(ctx, "predicted value is less than 0 for series", "anomaly_predicted_value", predictedValue, "anomaly_labels", series.Labels)
predictedValue = p.getMovingAvg(prevSeries, movingAvgWindowSize, idx)
}
p.logger.DebugContext(ctx, "predicted value for series",
"anomaly_moving_avg", movingAvg,
"anomaly_avg", avg,
"anomaly_mean", mean,
"anomaly_labels", series.Labels,
"anomaly_predicted_value", predictedValue,
"anomaly_curr", curr.Value,
)
predictedSeries.Values = append(predictedSeries.Values, &qbtypes.TimeSeriesValue{
Timestamp: curr.Timestamp,
Value: predictedValue,
})
}
return predictedSeries
}
// getBounds gets the upper and lower bounds for the given series
// for the given z score threshold
// moving avg of the previous period series + z score threshold * std dev of the series
// moving avg of the previous period series - z score threshold * std dev of the series
func (p *BaseSeasonalProvider) getBounds(
series, predictedSeries, weekSeries *qbtypes.TimeSeries,
zScoreThreshold float64,
) (*qbtypes.TimeSeries, *qbtypes.TimeSeries) {
upperBoundSeries := &qbtypes.TimeSeries{
Labels: series.Labels,
Values: make([]*qbtypes.TimeSeriesValue, 0),
}
lowerBoundSeries := &qbtypes.TimeSeries{
Labels: series.Labels,
Values: make([]*qbtypes.TimeSeriesValue, 0),
}
for idx, curr := range series.Values {
upperBound := p.getMovingAvg(predictedSeries, movingAvgWindowSize, idx) + zScoreThreshold*p.getStdDev(weekSeries)
lowerBound := p.getMovingAvg(predictedSeries, movingAvgWindowSize, idx) - zScoreThreshold*p.getStdDev(weekSeries)
upperBoundSeries.Values = append(upperBoundSeries.Values, &qbtypes.TimeSeriesValue{
Timestamp: curr.Timestamp,
Value: upperBound,
})
lowerBoundSeries.Values = append(lowerBoundSeries.Values, &qbtypes.TimeSeriesValue{
Timestamp: curr.Timestamp,
Value: math.Max(lowerBound, 0),
})
}
return upperBoundSeries, lowerBoundSeries
}
// getExpectedValue gets the expected value for the given series
// for the given index
// prevSeriesAvg + currentSeasonSeriesAvg - mean of past season series, past2 season series and past3 season series
func (p *BaseSeasonalProvider) getExpectedValue(
_, prevSeries, currentSeasonSeries, pastSeasonSeries, past2SeasonSeries, past3SeasonSeries *qbtypes.TimeSeries, idx int,
) float64 {
prevSeriesAvg := p.getMovingAvg(prevSeries, movingAvgWindowSize, idx)
currentSeasonSeriesAvg := p.getAvg(currentSeasonSeries)
pastSeasonSeriesAvg := p.getAvg(pastSeasonSeries)
past2SeasonSeriesAvg := p.getAvg(past2SeasonSeries)
past3SeasonSeriesAvg := p.getAvg(past3SeasonSeries)
return prevSeriesAvg + currentSeasonSeriesAvg - p.getMean(pastSeasonSeriesAvg, past2SeasonSeriesAvg, past3SeasonSeriesAvg)
}
// getScore gets the anomaly score for the given series
// for the given index
// (value - expectedValue) / std dev of the series
func (p *BaseSeasonalProvider) getScore(
series, prevSeries, weekSeries, weekPrevSeries, past2SeasonSeries, past3SeasonSeries *qbtypes.TimeSeries, value float64, idx int,
) float64 {
expectedValue := p.getExpectedValue(series, prevSeries, weekSeries, weekPrevSeries, past2SeasonSeries, past3SeasonSeries, idx)
if expectedValue < 0 {
expectedValue = p.getMovingAvg(prevSeries, movingAvgWindowSize, idx)
}
return (value - expectedValue) / p.getStdDev(weekSeries)
}
// getAnomalyScores gets the anomaly scores for the given series
// for the given index
// (value - expectedValue) / std dev of the series
func (p *BaseSeasonalProvider) getAnomalyScores(
series, prevSeries, currentSeasonSeries, pastSeasonSeries, past2SeasonSeries, past3SeasonSeries *qbtypes.TimeSeries,
) *qbtypes.TimeSeries {
anomalyScoreSeries := &qbtypes.TimeSeries{
Labels: series.Labels,
Values: make([]*qbtypes.TimeSeriesValue, 0),
}
for idx, curr := range series.Values {
anomalyScore := p.getScore(series, prevSeries, currentSeasonSeries, pastSeasonSeries, past2SeasonSeries, past3SeasonSeries, curr.Value, idx)
anomalyScoreSeries.Values = append(anomalyScoreSeries.Values, &qbtypes.TimeSeriesValue{
Timestamp: curr.Timestamp,
Value: anomalyScore,
})
}
return anomalyScoreSeries
}
func (p *BaseSeasonalProvider) getAnomalies(ctx context.Context, orgID valuer.UUID, req *AnomaliesRequest) (*AnomaliesResponse, error) {
anomalyParams := p.getQueryParams(req)
anomalyQueryResults, err := p.getResults(ctx, orgID, anomalyParams)
if err != nil {
return nil, err
}
currentPeriodResults := make(map[string]*qbtypes.TimeSeriesData)
for _, result := range anomalyQueryResults.CurrentPeriodResults {
currentPeriodResults[result.QueryName] = result
}
pastPeriodResults := make(map[string]*qbtypes.TimeSeriesData)
for _, result := range anomalyQueryResults.PastPeriodResults {
pastPeriodResults[result.QueryName] = result
}
currentSeasonResults := make(map[string]*qbtypes.TimeSeriesData)
for _, result := range anomalyQueryResults.CurrentSeasonResults {
currentSeasonResults[result.QueryName] = result
}
pastSeasonResults := make(map[string]*qbtypes.TimeSeriesData)
for _, result := range anomalyQueryResults.PastSeasonResults {
pastSeasonResults[result.QueryName] = result
}
past2SeasonResults := make(map[string]*qbtypes.TimeSeriesData)
for _, result := range anomalyQueryResults.Past2SeasonResults {
past2SeasonResults[result.QueryName] = result
}
past3SeasonResults := make(map[string]*qbtypes.TimeSeriesData)
for _, result := range anomalyQueryResults.Past3SeasonResults {
past3SeasonResults[result.QueryName] = result
}
for _, result := range currentPeriodResults {
funcs := req.Params.FuncsForQuery(result.QueryName)
var zScoreThreshold float64
for _, f := range funcs {
if f.Name == qbtypes.FunctionNameAnomaly {
for _, arg := range f.Args {
if arg.Name != "z_score_threshold" {
continue
}
value, ok := arg.Value.(float64)
if ok {
zScoreThreshold = value
} else {
p.logger.InfoContext(ctx, "z_score_threshold not provided, defaulting")
zScoreThreshold = 3
}
break
}
}
}
pastPeriodResult, ok := pastPeriodResults[result.QueryName]
if !ok {
continue
}
currentSeasonResult, ok := currentSeasonResults[result.QueryName]
if !ok {
continue
}
pastSeasonResult, ok := pastSeasonResults[result.QueryName]
if !ok {
continue
}
past2SeasonResult, ok := past2SeasonResults[result.QueryName]
if !ok {
continue
}
past3SeasonResult, ok := past3SeasonResults[result.QueryName]
if !ok {
continue
}
// no data;
if len(result.Aggregations) == 0 {
continue
}
aggOfInterest := result.Aggregations[0]
for _, series := range aggOfInterest.Series {
pastPeriodSeries := p.getMatchingSeries(ctx, pastPeriodResult, series)
currentSeasonSeries := p.getMatchingSeries(ctx, currentSeasonResult, series)
pastSeasonSeries := p.getMatchingSeries(ctx, pastSeasonResult, series)
past2SeasonSeries := p.getMatchingSeries(ctx, past2SeasonResult, series)
past3SeasonSeries := p.getMatchingSeries(ctx, past3SeasonResult, series)
stdDev := p.getStdDev(currentSeasonSeries)
p.logger.InfoContext(ctx, "calculated standard deviation for series", "anomaly_std_dev", stdDev, "anomaly_labels", series.Labels)
prevSeriesAvg := p.getAvg(pastPeriodSeries)
currentSeasonSeriesAvg := p.getAvg(currentSeasonSeries)
pastSeasonSeriesAvg := p.getAvg(pastSeasonSeries)
past2SeasonSeriesAvg := p.getAvg(past2SeasonSeries)
past3SeasonSeriesAvg := p.getAvg(past3SeasonSeries)
p.logger.InfoContext(ctx, "calculated mean for series",
"anomaly_prev_series_avg", prevSeriesAvg,
"anomaly_current_season_series_avg", currentSeasonSeriesAvg,
"anomaly_past_season_series_avg", pastSeasonSeriesAvg,
"anomaly_past_2season_series_avg", past2SeasonSeriesAvg,
"anomaly_past_3season_series_avg", past3SeasonSeriesAvg,
"anomaly_labels", series.Labels,
)
predictedSeries := p.getPredictedSeries(
ctx,
series,
pastPeriodSeries,
currentSeasonSeries,
pastSeasonSeries,
past2SeasonSeries,
past3SeasonSeries,
)
aggOfInterest.PredictedSeries = append(aggOfInterest.PredictedSeries, predictedSeries)
upperBoundSeries, lowerBoundSeries := p.getBounds(
series,
predictedSeries,
currentSeasonSeries,
zScoreThreshold,
)
aggOfInterest.UpperBoundSeries = append(aggOfInterest.UpperBoundSeries, upperBoundSeries)
aggOfInterest.LowerBoundSeries = append(aggOfInterest.LowerBoundSeries, lowerBoundSeries)
anomalyScoreSeries := p.getAnomalyScores(
series,
pastPeriodSeries,
currentSeasonSeries,
pastSeasonSeries,
past2SeasonSeries,
past3SeasonSeries,
)
aggOfInterest.AnomalyScores = append(aggOfInterest.AnomalyScores, anomalyScoreSeries)
}
}
results := make([]*qbtypes.TimeSeriesData, 0, len(currentPeriodResults))
for _, result := range currentPeriodResults {
results = append(results, result)
}
return &AnomaliesResponse{
Results: results,
}, nil
}

Some files were not shown because too many files have changed in this diff Show More