mirror of
https://github.com/hanzoai/o11y.git
synced 2026-10-30 14:56:15 +00:00
* 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.
196 lines
5.2 KiB
Go
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
|
|
}
|