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

5.9 KiB
Raw Permalink Blame History

Packages

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?

Use short, lowercase, single-word names. No underscores or camelCase (querier, cache, authz, not query_builder or dataStore).

Names must be domain-specific. A package name should tell you what problem domain it deals with, not what data structure it wraps. Prefer alertmanager over manager, licensing over checker.

Avoid generic names like util, helpers, common, misc, or base. If you can't name it, the code probably belongs in an existing package.

When should I create a new package?

Create a new package when:

  • The functionality represents a distinct domain concept (e.g., authz, licensing, cache).
  • Two or more other packages would import it; it serves as shared infrastructure.
  • The code has a clear public interface that can stand on its own.

Do not create a new package when:

  • There is already a package that covers the same domain. Extend the existing package instead.
  • The code is only used in one place. Keep it local to the caller.
  • You are splitting purely for file size. Use multiple files within the same package instead.

How should I lay out a package?

A typical package looks like:

pkg/cache/
├── cache.go            # Public interface + exported types
├── config.go           # Configuration types if needed
├── memorycache/        # Implementation sub-package
├── rediscache/         # Another implementation
└── cachetest/          # Test helpers for consumers

Follow these rules:

  1. Interface-first file: The file matching the package name (e.g., cache.go in pkg/cache/) should define the public interface and core exported types. Keep implementation details out of this file.

  2. One responsibility per file: Name files after what they contain (config.go, handler.go, service.go), not after the package name. If a package merges two concerns, prefix files to group them (e.g., memory_store.go, redis_store.go in a storage package).

  3. Sub-packages for implementations: When a package defines an interface with multiple implementations, put each implementation in its own sub-package (memorycache/, rediscache/). This keeps the parent package import-free of implementation dependencies.

  4. Test helpers in {pkg}test/: If consumers need test mocks or builders, put them in a {pkg}test/ sub-package (e.g., cachetest/, sqlstoretest/). This avoids polluting the main package with test-only code.

  5. Test files stay alongside source: Unit tests go in _test.go files next to the code they test, in the same package.

How should I name symbols?

Exported symbols

  • Interfaces: For single-method interfaces, follow the standard -er suffix convention (Reader, Writer, Closer). For multi-method interfaces, use clear nouns (Cache, Store, Provider).
  • Constructors: New<Type>(...) (e.g., NewMemoryCache()).
  • Avoid stutter: Since callers qualify with the package name, don't repeat it. Write cache.Cache, not cache.CacheInterface. Write authz.FromRole, not authz.AuthzFromRole.

Unexported symbols

  • Struct receivers: one or two characters (c, f, br).
  • Helper functions: descriptive lowercase names (parseToken, buildQuery).

Constants

  • Use PascalCase for exported constants.
  • When merging files from different origins into one package, watch out for name collisions across files. Prefix to disambiguate when two types share a natural name.

How should I organise imports?

Group imports in three blocks separated by blank lines:

import (
    // 1. Standard library
    "fmt"
    "net/http"

    // 2. External dependencies
    "github.com/gorilla/mux"

    // 3. Internal
    "github.com/Hanzo O11y/o11y/pkg/errors"
    "github.com/Hanzo O11y/o11y/pkg/types"
)

Never introduce circular imports. If package A needs package B and B needs A, extract the shared types into a third package (often under pkg/types/).

Where do shared types go?

Most types belong in pkg/types/ under a domain-specific sub-package (e.g., pkg/types/ruletypes, pkg/types/authtypes).

Do not put domain logic in pkg/types/. Only data structures, constants, and simple methods.

How do I merge or move packages?

When two packages are tightly coupled (one imports the other's constants, they cover the same domain), merge them:

  1. Pick a domain-specific name for the combined package.
  2. Prefix files to preserve origin (e.g., memory_store.go, redis_store.go).
  3. Resolve symbol conflicts explicitly; rename with a prefix rather than silently shadowing.
  4. Update all consumers in a single change.
  5. Delete the old packages. Do not leave behind re-export shims.
  6. Verify with go build ./..., go test ./<new-pkg>/..., and go vet ./....

When should I add documentation?

Add a doc.go with a package-level comment for any package that is non-trivial or has multiple consumers. Keep it to 1–3 sentences:

// Package cache provides a caching interface with pluggable backends
// for in-memory and Redis-based storage.
package cache

What should I remember?

  • Package names are domain-specific and lowercase. Never generic names like util or common.
  • The file matching the package name (e.g., cache.go) defines the public interface. Implementation details go elsewhere.
  • Never introduce circular imports. Extract shared types into pkg/types/ when needed.
  • Watch for symbol name collisions when merging packages, prefix to disambiguate.
  • Put test helpers in a {pkg}test/ sub-package, not in the main package.
  • Before submitting, verify with go build ./..., go test ./<your-pkg>/..., and go vet ./....
  • Update all consumers when you rename or move symbols.