Files
zeekayandGitHub babbdec4b8 debrand: SigNoz -> O11y across the tree (+ otel-collector v0.144.7, schema cutover migration) (#28)
* debrand: signoz/SigNoz/SIGNOZ -> o11y/O11y/O11Y across the tree

Rename all SigNoz *branding* to O11y in file contents, file/dir names,
package names, env vars, config keys, comments, docs, SDK code, and the
ClickHouse schema identifiers the querier reads.

Collector dependency:
- Repoint github.com/hanzoai/signoz-otel-collector ->
  github.com/hanzoai/otel-collector and bump v0.144.6 -> v0.144.7
  (go.mod + go.sum reconciled via go mod tidy). Internal package paths
  also debranded upstream: signozschemamigrator -> o11yschemamigrator,
  signozlogspipelineprocessor -> o11ylogspipelineprocessor.
- Fix: v0.144.7 dropped otelconst.DistributedFieldKeysTable from the
  collector's public constants; pin FieldKeysTable = "distributed_field_keys"
  locally in pkg/telemetrymetadata/tables.go.

Package/dir renames (package decl + all importers):
  pkg/apiserver/signozapiserver -> o11yapiserver, plus signozalertmanager,
  signozauthzapi, signozglobal, signozquerier, signozruler, and pkg/signoz -> pkg/o11y.

Schema (read plane): signoz_traces/metrics/logs/metadata/analytics/meter and
signoz_index_v3/index_v2/error_index_v2/spans (+ distributed_*) -> o11y_*.
Data-preserving cutover migration added:
  deploy/clickhouse/migrations/0001_rename_signoz_to_o11y.sql
  (metadata-only RENAME DATABASE/TABLE, no drop/recreate).

Preserved (attribution / external / wire contracts):
- LICENSE + NOTICE verbatim (incl. "software from SigNoz", "Copyright ... SigNoz Inc.").
- Upstream github.com/SigNoz/* repo URLs + @SigNoz/* CODEOWNERS teams.
- Billing resource-attribute regex "signoz.workspace.*" (external wire contract).

go build ./pkg/... ./cmd/... = 0; gofmt clean; renamed+schema pkg tests pass.

* o11y: bump collector to v0.144.8 (o11y_* physical schema writer) + lockstep deploy plan

Collector v0.144.8's schema-migrator + exporters now CREATE/WRITE the same
o11y_* physical databases/tables the querier reads and the RENAME migration
(0001_rename_signoz_to_o11y.sql) targets.

Cross-checked byte-identical: writer DB set == migration target DB set (6);
writer prefixed-table set == migration target table set (8); o11y querier
reads and cloud reads are subsets of that set. Zero table-name mismatches
between writer, readers, and migration.

Collector go.mod unchanged between v0.144.7 and v0.144.8 (identical go.mod
hash) — pure source rename, no module-graph change.

Adds deploy/clickhouse/DEPLOY_signoz_to_o11y_cutover.md: the lockstep order
(collector v0.144.8 -> RENAME migration -> o11y+cloud readers) with a
fresh/scratch-ClickHouse pre-flight (create via migrator, emit trace+metric,
query back) and rollback. Ships together or telemetry blackholes.

go build ./pkg/... ./cmd/community = 0.
2026-07-09 13:08:55 -07:00

196 lines
5.2 KiB
Go

package opamp
import (
"fmt"
"log/slog"
"sync"
)
var lockTracesPipelineSpec sync.RWMutex
var lockMetricsPipelineSpec sync.RWMutex
type pipelineStatus struct {
Name string
Enabled bool
}
var tracesPipelineSpec = map[int]pipelineStatus{
0: {
Name: "o11y_tail_sampling",
Enabled: false,
},
1: {
Name: "batch",
Enabled: true,
},
}
var metricsPipelineSpec = map[int]pipelineStatus{
0: {
Name: "filter",
Enabled: false,
},
1: {
Name: "batch",
Enabled: true,
},
}
func updatePipelineSpec(signal string, name string, enabled bool) {
switch signal {
case "metrics":
lockMetricsPipelineSpec.Lock()
defer lockMetricsPipelineSpec.Unlock()
for i := 0; i < len(metricsPipelineSpec); i++ {
p := metricsPipelineSpec[i]
if p.Name == name {
p.Enabled = enabled
metricsPipelineSpec[i] = p
}
}
case "traces":
lockTracesPipelineSpec.Lock()
defer lockTracesPipelineSpec.Unlock()
for i := 0; i < len(tracesPipelineSpec); i++ {
p := tracesPipelineSpec[i]
if p.Name == name {
p.Enabled = enabled
tracesPipelineSpec[i] = p
}
}
default:
return
}
}
// AddToTracePipeline to enable processor in traces pipeline
func AddToTracePipelineSpec(processor string) {
updatePipelineSpec("traces", processor, true)
}
// RemoveFromTracePipeline to remove processor from traces pipeline
func RemoveFromTracePipelineSpec(name string) {
updatePipelineSpec("traces", name, false)
}
// AddToMetricsPipeline to enable processor in traces pipeline
func AddToMetricsPipelineSpec(processor string) {
updatePipelineSpec("metrics", processor, true)
}
// RemoveFromMetricsPipeline to remove processor from traces pipeline
func RemoveFromMetricsPipelineSpec(name string) {
updatePipelineSpec("metrics", name, false)
}
func checkDuplicates(pipeline []interface{}) bool {
exists := make(map[string]bool, len(pipeline))
slog.Debug("checking duplicate processors in the pipeline", "pipeline", pipeline)
for _, processor := range pipeline {
name := processor.(string)
if _, ok := exists[name]; ok {
return true
}
exists[name] = true
}
return false
}
func buildPipeline(signal Signal, current []interface{}) ([]interface{}, error) {
var spec map[int]pipelineStatus
switch signal {
case Metrics:
spec = metricsPipelineSpec
lockMetricsPipelineSpec.Lock()
defer lockMetricsPipelineSpec.Unlock()
case Traces:
spec = tracesPipelineSpec
lockTracesPipelineSpec.Lock()
defer lockTracesPipelineSpec.Unlock()
default:
return nil, fmt.Errorf("invalid signal")
}
pipeline := current
// create a reverse map of existing config processors and their position
existing := map[string]int{}
for i, p := range current {
name := p.(string)
existing[name] = i
}
// create mapping from our tracesPipelinePlan (processors managed by us) to position in existing processors (from current config)
// this means, if "batch" holds position 3 in the current effective config, and 2 in our config, the map will be [2]: 3
specVsExistingMap := map[int]int{}
// go through plan and map its elements to current positions in effective config
for i, m := range spec {
if loc, ok := existing[m.Name]; ok {
specVsExistingMap[i] = loc
}
}
lastMatched := -1
inserts := 0
// go through plan again in the increasing order
for i := 0; i < len(spec); i++ {
m := spec[i]
if loc, ok := specVsExistingMap[i]; ok {
// element from plan already exists in current effective config.
currentPos := loc + inserts
// if disabled then remove from the pipeline
if !m.Enabled {
slog.Debug("build_pipeline: found a disabled item, removing from pipeline at position", "position", currentPos-1, "processor", m.Name)
if currentPos-1 <= 0 {
pipeline = pipeline[currentPos+1:]
} else {
pipeline = append(pipeline[:currentPos-1], pipeline[currentPos+1:]...)
}
}
// capture last position where match was found, this will be used
// to insert missing elements next to it
lastMatched = currentPos
} else {
if m.Enabled {
// track inserts as they shift the elements in pipeline
inserts++
// we use last matched to insert new item. This means, we keep inserting missing processors
// right after last matched processsor (e.g. insert filters after tail_sampling for existing list of [batch, tail_sampling])
if lastMatched <= 0 {
slog.Debug("build_pipeline: found a new item to be inserted, inserting at position 0", "processor", m.Name)
pipeline = append([]interface{}{m.Name}, pipeline[lastMatched+1:]...)
} else {
slog.Debug("build_pipeline: found a new item to be inserted, inserting at position", "position", lastMatched, "processor", m.Name)
prior := make([]interface{}, len(pipeline[:lastMatched]))
next := make([]interface{}, len(pipeline[lastMatched:]))
copy(prior, pipeline[:lastMatched])
copy(next, pipeline[lastMatched:])
pipeline = append(prior, m.Name)
pipeline = append(pipeline, next...)
}
}
}
}
if checkDuplicates(pipeline) {
// duplicates are most likely because the processor sequence in effective config conflicts
// with the planned sequence as per planned pipeline
return pipeline, fmt.Errorf("the effective config has an unexpected processor sequence: %v", pipeline)
}
return pipeline, nil
}