chore: enable forbidigo and noerrors in depguard (#9047)

* chore: enable forbidgo

* chore: enable forbidgo
This commit is contained in:
Vibhu Pandey 2025-09-09 15:44:27 +05:30 committed by GitHub
parent 57013e1c4f
commit c83eaf3d50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 186 additions and 141 deletions

View File

@ -8,6 +8,7 @@ linters:
- depguard - depguard
- iface - iface
- unparam - unparam
- forbidigo
linters-settings: linters-settings:
sloglint: sloglint:
@ -24,6 +25,10 @@ linters-settings:
deny: deny:
- pkg: "go.uber.org/zap" - pkg: "go.uber.org/zap"
desc: "Do not use zap logger. Use slog instead." desc: "Do not use zap logger. Use slog instead."
noerrors:
deny:
- pkg: "errors"
desc: "Do not use errors package. Use github.com/SigNoz/signoz/pkg/errors instead."
iface: iface:
enable: enable:
- identical - identical

View File

@ -32,7 +32,7 @@ func registerServer(parentCmd *cobra.Command, logger *slog.Logger) {
Short: "Run the SigNoz server", Short: "Run the SigNoz server",
FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true}, FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
RunE: func(currCmd *cobra.Command, args []string) error { RunE: func(currCmd *cobra.Command, args []string) error {
config, err := cmd.NewSigNozConfig(currCmd.Context(), flags) config, err := cmd.NewSigNozConfig(currCmd.Context(), logger, flags)
if err != nil { if err != nil {
return err return err
} }

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"context" "context"
"fmt"
"log/slog" "log/slog"
"os" "os"
@ -12,9 +11,10 @@ import (
"github.com/SigNoz/signoz/pkg/signoz" "github.com/SigNoz/signoz/pkg/signoz"
) )
func NewSigNozConfig(ctx context.Context, flags signoz.DeprecatedFlags) (signoz.Config, error) { func NewSigNozConfig(ctx context.Context, logger *slog.Logger, flags signoz.DeprecatedFlags) (signoz.Config, error) {
config, err := signoz.NewConfig( config, err := signoz.NewConfig(
ctx, ctx,
logger,
config.ResolverConfig{ config.ResolverConfig{
Uris: []string{"env:"}, Uris: []string{"env:"},
ProviderFactories: []config.ProviderFactory{ ProviderFactories: []config.ProviderFactory{
@ -31,14 +31,10 @@ func NewSigNozConfig(ctx context.Context, flags signoz.DeprecatedFlags) (signoz.
return config, nil return config, nil
} }
func NewJWTSecret(_ context.Context, _ *slog.Logger) string { func NewJWTSecret(ctx context.Context, logger *slog.Logger) string {
jwtSecret := os.Getenv("SIGNOZ_JWT_SECRET") jwtSecret := os.Getenv("SIGNOZ_JWT_SECRET")
if len(jwtSecret) == 0 { if len(jwtSecret) == 0 {
fmt.Println("🚨 CRITICAL SECURITY ISSUE: No JWT secret key specified!") logger.ErrorContext(ctx, "🚨 CRITICAL SECURITY ISSUE: No JWT secret key specified!", "error", "SIGNOZ_JWT_SECRET environment variable is not set. This has dire consequences for the security of the application. Without a JWT secret, user sessions are vulnerable to tampering and unauthorized access. Please set the SIGNOZ_JWT_SECRET environment variable immediately. For more information, please refer to https://github.com/SigNoz/signoz/issues/8400.")
fmt.Println("SIGNOZ_JWT_SECRET environment variable is not set. This has dire consequences for the security of the application.")
fmt.Println("Without a JWT secret, user sessions are vulnerable to tampering and unauthorized access.")
fmt.Println("Please set the SIGNOZ_JWT_SECRET environment variable immediately.")
fmt.Println("For more information, please refer to https://github.com/SigNoz/signoz/issues/8400.")
} }
return jwtSecret return jwtSecret

View File

@ -35,7 +35,7 @@ func registerServer(parentCmd *cobra.Command, logger *slog.Logger) {
Short: "Run the SigNoz server", Short: "Run the SigNoz server",
FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true}, FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
RunE: func(currCmd *cobra.Command, args []string) error { RunE: func(currCmd *cobra.Command, args []string) error {
config, err := cmd.NewSigNozConfig(currCmd.Context(), flags) config, err := cmd.NewSigNozConfig(currCmd.Context(), logger, flags)
if err != nil { if err != nil {
return err return err
} }

View File

@ -2,8 +2,12 @@ package config
import ( import (
"context" "context"
"errors"
"fmt" "github.com/SigNoz/signoz/pkg/errors"
)
var (
ErrCodeInvalidResolver = errors.MustNewCode("invalid_resolver")
) )
type ResolverConfig struct { type ResolverConfig struct {
@ -24,11 +28,11 @@ type Resolver struct {
func NewResolver(config ResolverConfig) (*Resolver, error) { func NewResolver(config ResolverConfig) (*Resolver, error) {
if len(config.Uris) == 0 { if len(config.Uris) == 0 {
return nil, errors.New("cannot build resolver, no uris have been provided") return nil, errors.New(errors.TypeInvalidInput, ErrCodeInvalidResolver, "cannot build resolver, no uris have been provided")
} }
if len(config.ProviderFactories) == 0 { if len(config.ProviderFactories) == 0 {
return nil, errors.New("cannot build resolver, no providers have been provided") return nil, errors.New(errors.TypeInvalidInput, ErrCodeInvalidResolver, "cannot build resolver, no providers have been provided")
} }
uris := make([]Uri, len(config.Uris)) uris := make([]Uri, len(config.Uris))
@ -48,7 +52,7 @@ func NewResolver(config ResolverConfig) (*Resolver, error) {
scheme := provider.Scheme() scheme := provider.Scheme()
// Check that the scheme is unique. // Check that the scheme is unique.
if _, ok := providers[scheme]; ok { if _, ok := providers[scheme]; ok {
return nil, fmt.Errorf("cannot build resolver, duplicate scheme %q found", scheme) return nil, errors.Newf(errors.TypeInvalidInput, ErrCodeInvalidResolver, "cannot build resolver, duplicate scheme %q found", scheme)
} }
providers[provider.Scheme()] = provider providers[provider.Scheme()] = provider
@ -70,7 +74,7 @@ func (resolver *Resolver) Do(ctx context.Context) (*Conf, error) {
} }
if err = conf.Merge(currentConf); err != nil { if err = conf.Merge(currentConf); err != nil {
return nil, fmt.Errorf("cannot merge config: %w", err) return nil, errors.Newf(errors.TypeInternal, ErrCodeInvalidResolver, "cannot merge config: %s", err.Error())
} }
} }
@ -80,7 +84,7 @@ func (resolver *Resolver) Do(ctx context.Context) (*Conf, error) {
func (resolver *Resolver) get(ctx context.Context, uri Uri) (*Conf, error) { func (resolver *Resolver) get(ctx context.Context, uri Uri) (*Conf, error) {
provider, ok := resolver.providers[uri.scheme] provider, ok := resolver.providers[uri.scheme]
if !ok { if !ok {
return nil, fmt.Errorf("cannot find provider with schema %q", uri.scheme) return nil, errors.Newf(errors.TypeInternal, ErrCodeInvalidResolver, "cannot find provider with schema %q", uri.scheme)
} }
return provider.Get(ctx, uri) return provider.Get(ctx, uri)

View File

@ -16,6 +16,7 @@ var (
CodeForbidden = Code{"forbidden"} CodeForbidden = Code{"forbidden"}
CodeCanceled = Code{"canceled"} CodeCanceled = Code{"canceled"}
CodeTimeout = Code{"timeout"} CodeTimeout = Code{"timeout"}
CodeUnknown = Code{"unknown"}
) )
var ( var (

View File

@ -1,15 +1,11 @@
package errors package errors
import ( import (
"errors" "errors" //nolint:depguard
"fmt" "fmt"
"log/slog" "log/slog"
) )
var (
codeUnknown Code = MustNewCode("unknown")
)
// base is the fundamental struct that implements the error interface. // base is the fundamental struct that implements the error interface.
// The order of the struct is 'TCMEUA'. // The order of the struct is 'TCMEUA'.
type base struct { type base struct {
@ -59,7 +55,7 @@ func New(t typ, code Code, message string) *base {
} }
// Newf returns a new base by formatting the error message with the supplied format specifier. // Newf returns a new base by formatting the error message with the supplied format specifier.
func Newf(t typ, code Code, format string, args ...interface{}) *base { func Newf(t typ, code Code, format string, args ...any) *base {
return &base{ return &base{
t: t, t: t,
c: code, c: code,
@ -70,7 +66,7 @@ func Newf(t typ, code Code, format string, args ...interface{}) *base {
// Wrapf returns a new error by formatting the error message with the supplied format specifier // Wrapf returns a new error by formatting the error message with the supplied format specifier
// and wrapping another error with base. // and wrapping another error with base.
func Wrapf(cause error, t typ, code Code, format string, args ...interface{}) *base { func Wrapf(cause error, t typ, code Code, format string, args ...any) *base {
return &base{ return &base{
t: t, t: t,
c: code, c: code,
@ -91,7 +87,7 @@ func Wrap(cause error, t typ, code Code, message string) *base {
// WithAdditional wraps an existing base error with a new formatted message. // WithAdditional wraps an existing base error with a new formatted message.
// It is used when the original error already contains type and code. // It is used when the original error already contains type and code.
func WithAdditional(cause error, format string, args ...interface{}) *base { func WithAdditional(cause error, format string, args ...any) *base {
t, c, m, e, u, a := Unwrapb(cause) t, c, m, e, u, a := Unwrapb(cause)
b := &base{ b := &base{
t: t, t: t,
@ -142,7 +138,7 @@ func Unwrapb(cause error) (typ, Code, string, error, string, []string) {
return base.t, base.c, base.m, base.e, base.u, base.a return base.t, base.c, base.m, base.e, base.u, base.a
} }
return TypeInternal, codeUnknown, cause.Error(), cause, "", []string{} return TypeInternal, CodeUnknown, cause.Error(), cause, "", []string{}
} }
// Ast checks if the provided error matches the specified custom error type. // Ast checks if the provided error matches the specified custom error type.
@ -164,42 +160,52 @@ func Join(errs ...error) error {
return errors.Join(errs...) return errors.Join(errs...)
} }
// As is a wrapper around errors.As.
func As(err error, target any) bool { func As(err error, target any) bool {
return errors.As(err, target) return errors.As(err, target)
} }
// Is is a wrapper around errors.Is.
func Is(err error, target error) bool { func Is(err error, target error) bool {
return errors.Is(err, target) return errors.Is(err, target)
} }
func WrapNotFoundf(cause error, code Code, format string, args ...interface{}) *base { // WrapNotFoundf is a wrapper around Wrapf with TypeNotFound.
func WrapNotFoundf(cause error, code Code, format string, args ...any) *base {
return Wrapf(cause, TypeNotFound, code, format, args...) return Wrapf(cause, TypeNotFound, code, format, args...)
} }
func NewNotFoundf(code Code, format string, args ...interface{}) *base { // NewNotFoundf is a wrapper around Newf with TypeNotFound.
func NewNotFoundf(code Code, format string, args ...any) *base {
return Newf(TypeNotFound, code, format, args...) return Newf(TypeNotFound, code, format, args...)
} }
func WrapInternalf(cause error, code Code, format string, args ...interface{}) *base { // WrapInternalf is a wrapper around Wrapf with TypeInternal.
func WrapInternalf(cause error, code Code, format string, args ...any) *base {
return Wrapf(cause, TypeInternal, code, format, args...) return Wrapf(cause, TypeInternal, code, format, args...)
} }
func NewInternalf(code Code, format string, args ...interface{}) *base { // NewInternalf is a wrapper around Newf with TypeInternal.
func NewInternalf(code Code, format string, args ...any) *base {
return Newf(TypeInternal, code, format, args...) return Newf(TypeInternal, code, format, args...)
} }
func WrapInvalidInputf(cause error, code Code, format string, args ...interface{}) *base { // WrapInvalidInputf is a wrapper around Wrapf with TypeInvalidInput.
func WrapInvalidInputf(cause error, code Code, format string, args ...any) *base {
return Wrapf(cause, TypeInvalidInput, code, format, args...) return Wrapf(cause, TypeInvalidInput, code, format, args...)
} }
func NewInvalidInputf(code Code, format string, args ...interface{}) *base { // NewInvalidInputf is a wrapper around Newf with TypeInvalidInput.
func NewInvalidInputf(code Code, format string, args ...any) *base {
return Newf(TypeInvalidInput, code, format, args...) return Newf(TypeInvalidInput, code, format, args...)
} }
func WrapUnexpectedf(cause error, code Code, format string, args ...interface{}) *base { // WrapUnexpectedf is a wrapper around Wrapf with TypeUnexpected.
func WrapUnexpectedf(cause error, code Code, format string, args ...any) *base {
return Wrapf(cause, TypeInvalidInput, code, format, args...) return Wrapf(cause, TypeInvalidInput, code, format, args...)
} }
func NewUnexpectedf(code Code, format string, args ...interface{}) *base { // NewUnexpectedf is a wrapper around Newf with TypeUnexpected.
func NewUnexpectedf(code Code, format string, args ...any) *base {
return Newf(TypeInvalidInput, code, format, args...) return Newf(TypeInvalidInput, code, format, args...)
} }

View File

@ -1,7 +1,7 @@
package errors package errors
import ( import (
"errors" "errors" //nolint:depguard
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"

View File

@ -2,12 +2,16 @@ package factory
import ( import (
"context" "context"
"errors"
"fmt"
"log/slog" "log/slog"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"github.com/SigNoz/signoz/pkg/errors"
)
var (
ErrCodeInvalidRegistry = errors.MustNewCode("invalid_registry")
) )
type Registry struct { type Registry struct {
@ -20,11 +24,11 @@ type Registry struct {
// New creates a new registry of services. It needs at least one service in the input. // New creates a new registry of services. It needs at least one service in the input.
func NewRegistry(logger *slog.Logger, services ...NamedService) (*Registry, error) { func NewRegistry(logger *slog.Logger, services ...NamedService) (*Registry, error) {
if logger == nil { if logger == nil {
return nil, fmt.Errorf("cannot build registry, logger is required") return nil, errors.Newf(errors.TypeInvalidInput, ErrCodeInvalidRegistry, "cannot build registry, logger is required")
} }
if len(services) == 0 { if len(services) == 0 {
return nil, fmt.Errorf("cannot build registry, at least one service is required") return nil, errors.Newf(errors.TypeInvalidInput, ErrCodeInvalidRegistry, "cannot build registry, at least one service is required")
} }
m, err := NewNamedMap(services...) m, err := NewNamedMap(services...)

View File

@ -1,12 +1,17 @@
package gateway package gateway
import ( import (
"errors"
"net/url" "net/url"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/factory"
) )
var (
ErrCodeInvalidGatewayConfig = errors.MustNewCode("invalid_gateway_config")
)
type Config struct { type Config struct {
URL *url.URL `mapstructure:"url"` URL *url.URL `mapstructure:"url"`
} }
@ -27,7 +32,8 @@ func newConfig() factory.Config {
func (c Config) Validate() error { func (c Config) Validate() error {
if c.URL == nil { if c.URL == nil {
return errors.New("url is required") return errors.New(errors.TypeInvalidInput, ErrCodeInvalidGatewayConfig, "url is required")
} }
return nil return nil
} }

View File

@ -2,12 +2,13 @@ package instrumentation
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"time" "time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
contribsdkconfig "go.opentelemetry.io/contrib/config" contribsdkconfig "go.opentelemetry.io/contrib/config"
@ -87,19 +88,19 @@ func prometheusReaderWithCustomRegistry(ctx context.Context, prometheusConfig *c
reader, err := otelprom.New(opts...) reader, err := otelprom.New(opts...)
if err != nil { if err != nil {
return nil, fmt.Errorf("error creating otel prometheus exporter: %w", err) return nil, errors.Newf(errors.TypeInternal, errors.CodeInternal, "error creating otel prometheus exporter: %s", err.Error())
} }
lis, err := net.Listen("tcp", addr) lis, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
return nil, errors.Join( return nil, errors.Join(
fmt.Errorf("binding address %s for Prometheus exporter: %w", addr, err), errors.Newf(errors.TypeInternal, errors.CodeInternal, "binding address %s for Prometheus exporter: %s", addr, err.Error()),
reader.Shutdown(ctx), reader.Shutdown(ctx),
) )
} }
go func() { go func() {
if err := server.Serve(lis); err != nil && !errors.Is(err, http.ErrServerClosed) { if err := server.Serve(lis); err != nil && !errors.Is(err, http.ErrServerClosed) {
otel.Handle(fmt.Errorf("the Prometheus HTTP server exited unexpectedly: %w", err)) otel.Handle(errors.Newf(errors.TypeInternal, errors.CodeInternal, "the Prometheus HTTP server exited unexpectedly: %s", err.Error()))
} }
}() }()
@ -142,13 +143,13 @@ func meterProviderWithCustomRegistry(ctx context.Context, meterProviderConfig *c
// metricReaderWithCustomRegistry creates metric readers with custom Prometheus registry support // metricReaderWithCustomRegistry creates metric readers with custom Prometheus registry support
func metricReaderWithCustomRegistry(ctx context.Context, r contribsdkconfig.MetricReader, customRegistry *prometheus.Registry) (sdkmetric.Reader, error) { func metricReaderWithCustomRegistry(ctx context.Context, r contribsdkconfig.MetricReader, customRegistry *prometheus.Registry) (sdkmetric.Reader, error) {
if r.Periodic != nil && r.Pull != nil { if r.Periodic != nil && r.Pull != nil {
return nil, errors.New("must not specify multiple metric reader type") return nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "must not specify multiple metric reader type")
} }
if r.Pull != nil { if r.Pull != nil {
return pullReaderWithCustomRegistry(ctx, r.Pull.Exporter, customRegistry) return pullReaderWithCustomRegistry(ctx, r.Pull.Exporter, customRegistry)
} }
return nil, errors.New("no valid metric reader") return nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "no valid metric reader")
} }
// pullReaderWithCustomRegistry creates pull readers with custom Prometheus registry support // pullReaderWithCustomRegistry creates pull readers with custom Prometheus registry support
@ -156,5 +157,6 @@ func pullReaderWithCustomRegistry(ctx context.Context, exporter contribsdkconfig
if exporter.Prometheus != nil { if exporter.Prometheus != nil {
return prometheusReaderWithCustomRegistry(ctx, exporter.Prometheus, customRegistry) return prometheusReaderWithCustomRegistry(ctx, exporter.Prometheus, customRegistry)
} }
return nil, errors.New("no valid metric exporter")
return nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "no valid metric exporter")
} }

View File

@ -3,6 +3,7 @@ package signoz
import ( import (
"context" "context"
"fmt" "fmt"
"log/slog"
"net/url" "net/url"
"os" "os"
"path" "path"
@ -129,7 +130,7 @@ func (df *DeprecatedFlags) RegisterFlags(cmd *cobra.Command) {
_ = cmd.Flags().MarkDeprecated("gateway-url", "use SIGNOZ_GATEWAY_URL instead") _ = cmd.Flags().MarkDeprecated("gateway-url", "use SIGNOZ_GATEWAY_URL instead")
} }
func NewConfig(ctx context.Context, resolverConfig config.ResolverConfig, deprecatedFlags DeprecatedFlags) (Config, error) { func NewConfig(ctx context.Context, logger *slog.Logger, resolverConfig config.ResolverConfig, deprecatedFlags DeprecatedFlags) (Config, error) {
configFactories := []factory.ConfigFactory{ configFactories := []factory.ConfigFactory{
version.NewConfigFactory(), version.NewConfigFactory(),
instrumentation.NewConfigFactory(), instrumentation.NewConfigFactory(),
@ -161,7 +162,7 @@ func NewConfig(ctx context.Context, resolverConfig config.ResolverConfig, deprec
return Config{}, err return Config{}, err
} }
mergeAndEnsureBackwardCompatibility(&config, deprecatedFlags) mergeAndEnsureBackwardCompatibility(ctx, logger, &config, deprecatedFlags)
if err := validateConfig(config); err != nil { if err := validateConfig(config); err != nil {
return Config{}, err return Config{}, err
@ -186,88 +187,88 @@ func validateConfig(config Config) error {
return nil return nil
} }
func mergeAndEnsureBackwardCompatibility(config *Config, deprecatedFlags DeprecatedFlags) { func mergeAndEnsureBackwardCompatibility(ctx context.Context, logger *slog.Logger, config *Config, deprecatedFlags DeprecatedFlags) {
if os.Getenv("SIGNOZ_LOCAL_DB_PATH") != "" { if os.Getenv("SIGNOZ_LOCAL_DB_PATH") != "" {
fmt.Println("[Deprecated] env SIGNOZ_LOCAL_DB_PATH is deprecated and scheduled for removal. Please use SIGNOZ_SQLSTORE_SQLITE_PATH instead.") 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") config.SQLStore.Sqlite.Path = os.Getenv("SIGNOZ_LOCAL_DB_PATH")
} }
if os.Getenv("CONTEXT_TIMEOUT") != "" { if os.Getenv("CONTEXT_TIMEOUT") != "" {
fmt.Println("[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 SIGNOZ_APISERVER_TIMEOUT_DEFAULT instead.")
contextTimeoutDuration, err := time.ParseDuration(os.Getenv("CONTEXT_TIMEOUT") + "s") contextTimeoutDuration, err := time.ParseDuration(os.Getenv("CONTEXT_TIMEOUT") + "s")
if err == nil { if err == nil {
config.APIServer.Timeout.Default = contextTimeoutDuration config.APIServer.Timeout.Default = contextTimeoutDuration
} else { } else {
fmt.Println("Error parsing CONTEXT_TIMEOUT, using default value of 60s") logger.WarnContext(ctx, "Error parsing CONTEXT_TIMEOUT, using default value of 60s")
} }
} }
if os.Getenv("CONTEXT_TIMEOUT_MAX_ALLOWED") != "" { if os.Getenv("CONTEXT_TIMEOUT_MAX_ALLOWED") != "" {
fmt.Println("[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 SIGNOZ_APISERVER_TIMEOUT_MAX instead.")
contextTimeoutDuration, err := time.ParseDuration(os.Getenv("CONTEXT_TIMEOUT_MAX_ALLOWED") + "s") contextTimeoutDuration, err := time.ParseDuration(os.Getenv("CONTEXT_TIMEOUT_MAX_ALLOWED") + "s")
if err == nil { if err == nil {
config.APIServer.Timeout.Max = contextTimeoutDuration config.APIServer.Timeout.Max = contextTimeoutDuration
} else { } else {
fmt.Println("Error parsing CONTEXT_TIMEOUT_MAX_ALLOWED, using default value of 600s") logger.WarnContext(ctx, "Error parsing CONTEXT_TIMEOUT_MAX_ALLOWED, using default value of 600s")
} }
} }
if os.Getenv("STORAGE") != "" { if os.Getenv("STORAGE") != "" {
fmt.Println("[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 SIGNOZ_TELEMETRYSTORE_PROVIDER instead.")
config.TelemetryStore.Provider = os.Getenv("STORAGE") config.TelemetryStore.Provider = os.Getenv("STORAGE")
} }
if os.Getenv("ClickHouseUrl") != "" { if os.Getenv("ClickHouseUrl") != "" {
fmt.Println("[Deprecated] env ClickHouseUrl is deprecated and scheduled for removal. Please use SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN instead.") 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") config.TelemetryStore.Clickhouse.DSN = os.Getenv("ClickHouseUrl")
} }
if deprecatedFlags.MaxIdleConns != 50 { if deprecatedFlags.MaxIdleConns != 50 {
fmt.Println("[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 SIGNOZ_TELEMETRYSTORE_MAX__IDLE__CONNS instead.")
config.TelemetryStore.Connection.MaxIdleConns = deprecatedFlags.MaxIdleConns config.TelemetryStore.Connection.MaxIdleConns = deprecatedFlags.MaxIdleConns
} }
if deprecatedFlags.MaxOpenConns != 100 { if deprecatedFlags.MaxOpenConns != 100 {
fmt.Println("[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 SIGNOZ_TELEMETRYSTORE_MAX__OPEN__CONNS instead.")
config.TelemetryStore.Connection.MaxOpenConns = deprecatedFlags.MaxOpenConns config.TelemetryStore.Connection.MaxOpenConns = deprecatedFlags.MaxOpenConns
} }
if deprecatedFlags.DialTimeout != 5*time.Second { if deprecatedFlags.DialTimeout != 5*time.Second {
fmt.Println("[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 SIGNOZ_TELEMETRYSTORE_DIAL__TIMEOUT instead.")
config.TelemetryStore.Connection.DialTimeout = deprecatedFlags.DialTimeout config.TelemetryStore.Connection.DialTimeout = deprecatedFlags.DialTimeout
} }
if os.Getenv("ALERTMANAGER_API_PREFIX") != "" { if os.Getenv("ALERTMANAGER_API_PREFIX") != "" {
fmt.Println("[Deprecated] env ALERTMANAGER_API_PREFIX is deprecated and scheduled for removal. Please use SIGNOZ_ALERTMANAGER_LEGACY_API__URL instead.") logger.WarnContext(ctx, "[Deprecated] env ALERTMANAGER_API_PREFIX is deprecated and scheduled for removal. Please use SIGNOZ_ALERTMANAGER_LEGACY_API__URL instead.")
u, err := url.Parse(os.Getenv("ALERTMANAGER_API_PREFIX")) u, err := url.Parse(os.Getenv("ALERTMANAGER_API_PREFIX"))
if err != nil { if err != nil {
fmt.Println("Error parsing ALERTMANAGER_API_PREFIX, using default value") logger.WarnContext(ctx, "Error parsing ALERTMANAGER_API_PREFIX, using default value")
} else { } else {
config.Alertmanager.Legacy.ApiURL = u config.Alertmanager.Legacy.ApiURL = u
} }
} }
if os.Getenv("ALERTMANAGER_API_CHANNEL_PATH") != "" { if os.Getenv("ALERTMANAGER_API_CHANNEL_PATH") != "" {
fmt.Println("[Deprecated] env ALERTMANAGER_API_CHANNEL_PATH is deprecated and scheduled for complete removal.") logger.WarnContext(ctx, "[Deprecated] env ALERTMANAGER_API_CHANNEL_PATH is deprecated and scheduled for complete removal.")
} }
if deprecatedFlags.Config != "" { if deprecatedFlags.Config != "" {
fmt.Println("[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 SigNoz config. More details can be found at https://github.com/SigNoz/signoz/issues/6805.")
} }
if os.Getenv("INVITE_EMAIL_TEMPLATE") != "" { if os.Getenv("INVITE_EMAIL_TEMPLATE") != "" {
fmt.Println("[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 SIGNOZ_EMAILING_TEMPLATES_DIRECTORY instead.")
config.Emailing.Templates.Directory = path.Dir(os.Getenv("INVITE_EMAIL_TEMPLATE")) config.Emailing.Templates.Directory = path.Dir(os.Getenv("INVITE_EMAIL_TEMPLATE"))
} }
if os.Getenv("SMTP_ENABLED") != "" { if os.Getenv("SMTP_ENABLED") != "" {
fmt.Println("[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 SIGNOZ_EMAILING_ENABLED instead.")
config.Emailing.Enabled = os.Getenv("SMTP_ENABLED") == "true" config.Emailing.Enabled = os.Getenv("SMTP_ENABLED") == "true"
} }
if os.Getenv("SMTP_HOST") != "" { if os.Getenv("SMTP_HOST") != "" {
fmt.Println("[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 SIGNOZ_EMAILING_ADDRESS instead.")
if os.Getenv("SMTP_PORT") != "" { if os.Getenv("SMTP_PORT") != "" {
config.Emailing.SMTP.Address = os.Getenv("SMTP_HOST") + ":" + os.Getenv("SMTP_PORT") config.Emailing.SMTP.Address = os.Getenv("SMTP_HOST") + ":" + os.Getenv("SMTP_PORT")
} else { } else {
@ -276,62 +277,62 @@ func mergeAndEnsureBackwardCompatibility(config *Config, deprecatedFlags Depreca
} }
if os.Getenv("SMTP_PORT") != "" { if os.Getenv("SMTP_PORT") != "" {
fmt.Println("[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 SIGNOZ_EMAILING_ADDRESS instead.")
} }
if os.Getenv("SMTP_USERNAME") != "" { if os.Getenv("SMTP_USERNAME") != "" {
fmt.Println("[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 SIGNOZ_EMAILING_AUTH_USERNAME instead.")
config.Emailing.SMTP.Auth.Username = os.Getenv("SMTP_USERNAME") config.Emailing.SMTP.Auth.Username = os.Getenv("SMTP_USERNAME")
} }
if os.Getenv("SMTP_PASSWORD") != "" { if os.Getenv("SMTP_PASSWORD") != "" {
fmt.Println("[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 SIGNOZ_EMAILING_AUTH_PASSWORD instead.")
config.Emailing.SMTP.Auth.Password = os.Getenv("SMTP_PASSWORD") config.Emailing.SMTP.Auth.Password = os.Getenv("SMTP_PASSWORD")
} }
if os.Getenv("SMTP_FROM") != "" { if os.Getenv("SMTP_FROM") != "" {
fmt.Println("[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 SIGNOZ_EMAILING_FROM instead.")
config.Emailing.SMTP.From = os.Getenv("SMTP_FROM") config.Emailing.SMTP.From = os.Getenv("SMTP_FROM")
} }
if os.Getenv("SIGNOZ_SAAS_SEGMENT_KEY") != "" { if os.Getenv("SIGNOZ_SAAS_SEGMENT_KEY") != "" {
fmt.Println("[Deprecated] env SIGNOZ_SAAS_SEGMENT_KEY is deprecated and scheduled for removal. Please use SIGNOZ_ANALYTICS_SEGMENT_KEY instead.") 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") config.Analytics.Segment.Key = os.Getenv("SIGNOZ_SAAS_SEGMENT_KEY")
} }
if os.Getenv("TELEMETRY_ENABLED") != "" { if os.Getenv("TELEMETRY_ENABLED") != "" {
fmt.Println("[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 SIGNOZ_ANALYTICS_ENABLED instead.")
config.Analytics.Enabled = os.Getenv("TELEMETRY_ENABLED") == "true" config.Analytics.Enabled = os.Getenv("TELEMETRY_ENABLED") == "true"
} }
if deprecatedFlags.FluxInterval != "" { if deprecatedFlags.FluxInterval != "" {
fmt.Println("[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 SIGNOZ_QUERIER_FLUX__INTERVAL instead.")
fluxInterval, err := time.ParseDuration(deprecatedFlags.FluxInterval) fluxInterval, err := time.ParseDuration(deprecatedFlags.FluxInterval)
if err != nil { if err != nil {
fmt.Println("Error parsing --flux-interval, using default value.") logger.WarnContext(ctx, "Error parsing --flux-interval, using default value.")
} else { } else {
config.Querier.FluxInterval = fluxInterval config.Querier.FluxInterval = fluxInterval
} }
} }
if deprecatedFlags.FluxIntervalForTraceDetail != "" { if deprecatedFlags.FluxIntervalForTraceDetail != "" {
fmt.Println("[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 SIGNOZ_QUERIER_FLUX__INTERVAL instead.")
} }
if deprecatedFlags.Cluster != "" { if deprecatedFlags.Cluster != "" {
fmt.Println("[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 SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_CLUSTER instead.")
config.TelemetryStore.Clickhouse.Cluster = deprecatedFlags.Cluster config.TelemetryStore.Clickhouse.Cluster = deprecatedFlags.Cluster
} }
if deprecatedFlags.PreferSpanMetrics { if deprecatedFlags.PreferSpanMetrics {
fmt.Println("[Deprecated] flag --prefer-span-metrics is deprecated and scheduled for removal. Please use USE_SPAN_METRICS instead.") logger.WarnContext(ctx, "[Deprecated] flag --prefer-span-metrics is deprecated and scheduled for removal. Please use USE_SPAN_METRICS instead.")
} }
if deprecatedFlags.GatewayUrl != "" { if deprecatedFlags.GatewayUrl != "" {
fmt.Println("[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 SIGNOZ_GATEWAY_URL instead.")
u, err := url.Parse(deprecatedFlags.GatewayUrl) u, err := url.Parse(deprecatedFlags.GatewayUrl)
if err != nil { if err != nil {
fmt.Println("Error parsing --gateway-url, using default value.") logger.WarnContext(ctx, "Error parsing --gateway-url, using default value.")
} else { } else {
config.Gateway.URL = u config.Gateway.URL = u
} }

View File

@ -2,6 +2,8 @@ package signoz
import ( import (
"context" "context"
"io"
"log/slog"
"testing" "testing"
"github.com/SigNoz/signoz/pkg/config/configtest" "github.com/SigNoz/signoz/pkg/config/configtest"
@ -11,6 +13,7 @@ import (
// This is a test to ensure that all fields of config implement the factory.Config interface and are valid with // This is a test to ensure that all fields of config implement the factory.Config interface and are valid with
// their default values. // their default values.
func TestValidateConfig(t *testing.T) { func TestValidateConfig(t *testing.T) {
_, err := NewConfig(context.Background(), configtest.NewResolverConfig(), DeprecatedFlags{}) logger := slog.New(slog.NewTextHandler(io.Discard, nil))
_, err := NewConfig(context.Background(), logger, configtest.NewResolverConfig(), DeprecatedFlags{})
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@ -1,9 +1,10 @@
package client package client
import ( import (
"errors"
"net/smtp" "net/smtp"
"strings" "strings"
"github.com/SigNoz/signoz/pkg/errors"
) )
type loginAuth struct { type loginAuth struct {
@ -27,7 +28,7 @@ func (auth *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
case "password:": case "password:":
return []byte(auth.password), nil return []byte(auth.password), nil
default: default:
return nil, errors.New("unexpected server challenge") return nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "unexpected server challenge")
} }
} }
return nil, nil return nil, nil

View File

@ -5,7 +5,6 @@ import (
"context" "context"
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"errors"
"fmt" "fmt"
"log/slog" "log/slog"
"math/rand" "math/rand"
@ -20,6 +19,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/SigNoz/signoz/pkg/errors"
) )
type Client struct { type Client struct {
@ -52,12 +53,12 @@ func New(address string, logger *slog.Logger, opts ...Option) (*Client, error) {
from, err := mail.ParseAddress(clientOpts.from) from, err := mail.ParseAddress(clientOpts.from)
if err != nil { if err != nil {
return nil, fmt.Errorf("parse 'from' address: %w", err) return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "parse 'from' address: %s", err.Error())
} }
host, port, err := net.SplitHostPort(address) host, port, err := net.SplitHostPort(address)
if err != nil { if err != nil {
return nil, fmt.Errorf("parse 'address': %w", err) return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "parse 'address': %s", err.Error())
} }
if clientOpts.headers == nil { if clientOpts.headers == nil {
@ -67,7 +68,7 @@ func New(address string, logger *slog.Logger, opts ...Option) (*Client, error) {
tls, err := newTLSConfig(clientOpts.tls, host) tls, err := newTLSConfig(clientOpts.tls, host)
if err != nil { if err != nil {
return nil, fmt.Errorf("create TLS config: %w", err) return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "create TLS config: %s", err.Error())
} }
return &Client{ return &Client{
@ -102,7 +103,7 @@ func (c *Client) Do(ctx context.Context, tos []*mail.Address, subject string, co
smtpClient, err = smtp.NewClient(conn, c.host) smtpClient, err = smtp.NewClient(conn, c.host)
if err != nil { if err != nil {
conn.Close() conn.Close()
return fmt.Errorf("failed to create SMTP client: %w", err) return errors.Newf(errors.TypeInternal, errors.CodeInternal, "failed to create SMTP client: %s", err.Error())
} }
// Try to clean up after ourselves but don't log anything if something has failed. // Try to clean up after ourselves but don't log anything if something has failed.
@ -275,7 +276,7 @@ func (c *Client) smtpAuth(_ context.Context, mechs string) (smtp.Auth, error) {
case "CRAM-MD5": case "CRAM-MD5":
secret := c.auth.Secret secret := c.auth.Secret
if secret == "" { if secret == "" {
errs = append(errs, errors.New("missing secret for CRAM-MD5 auth mechanism")) errs = append(errs, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "missing secret for CRAM-MD5 auth mechanism"))
continue continue
} }
return smtp.CRAMMD5Auth(username, secret), nil return smtp.CRAMMD5Auth(username, secret), nil
@ -283,7 +284,7 @@ func (c *Client) smtpAuth(_ context.Context, mechs string) (smtp.Auth, error) {
case "PLAIN": case "PLAIN":
password := c.auth.Password password := c.auth.Password
if password == "" { if password == "" {
errs = append(errs, errors.New("missing password for PLAIN auth mechanism")) errs = append(errs, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "missing password for PLAIN auth mechanism"))
continue continue
} }
identity := c.auth.Identity identity := c.auth.Identity
@ -292,7 +293,7 @@ func (c *Client) smtpAuth(_ context.Context, mechs string) (smtp.Auth, error) {
case "LOGIN": case "LOGIN":
password := c.auth.Password password := c.auth.Password
if password == "" { if password == "" {
errs = append(errs, errors.New("missing password for LOGIN auth mechanism")) errs = append(errs, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "missing password for LOGIN auth mechanism"))
continue continue
} }
@ -301,7 +302,7 @@ func (c *Client) smtpAuth(_ context.Context, mechs string) (smtp.Auth, error) {
} }
if len(errs) == 0 { if len(errs) == 0 {
errs = append(errs, errors.New("unknown auth mechanism: "+mechs)) errs = append(errs, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "unknown auth mechanism: "+mechs))
} }
return nil, errors.Join(errs...) return nil, errors.Join(errs...)

View File

@ -3,7 +3,8 @@ package sqlmigration
import ( import (
"context" "context"
"database/sql" "database/sql"
"errors"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"

View File

@ -70,7 +70,7 @@ func (migration *addAlertmanager) Up(ctx context.Context, db *bun.DB) error {
NewAddColumn(). NewAddColumn().
Table("notification_channels"). Table("notification_channels").
ColumnExpr("org_id TEXT REFERENCES organizations(id) ON DELETE CASCADE"). ColumnExpr("org_id TEXT REFERENCES organizations(id) ON DELETE CASCADE").
Exec(ctx); err != nil && err != ErrNoExecute { Exec(ctx); err != nil {
return err return err
} }
} }

View File

@ -279,7 +279,6 @@ func (migration *queryBuilderV5Migration) migrateRules(
updated := alertsMigrator.Migrate(ctx, rule.Data) updated := alertsMigrator.Migrate(ctx, rule.Data)
if updated { if updated {
fmt.Println("updated rule", rule.ID)
dataJSON, err := json.Marshal(rule.Data) dataJSON, err := json.Marshal(rule.Data)
if err != nil { if err != nil {
return err return err

View File

@ -2,7 +2,6 @@ package sqlmigration
import ( import (
"context" "context"
"errors"
"github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/factory"
"github.com/uptrace/bun" "github.com/uptrace/bun"
@ -22,10 +21,6 @@ type SQLMigration interface {
Down(context.Context, *bun.DB) error Down(context.Context, *bun.DB) error
} }
var (
ErrNoExecute = errors.New("no execute")
)
var ( var (
OrgReference = "org" OrgReference = "org"
UserReference = "user" UserReference = "user"

View File

@ -1,12 +1,17 @@
package sqlmigrator package sqlmigrator
import ( import (
"errors"
"time" "time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/factory"
) )
var (
ErrCodeInvalidSQLMigratorConfig = errors.MustNewCode("invalid_sqlmigrator_config")
)
type Config struct { type Config struct {
// Lock is the lock configuration. // Lock is the lock configuration.
Lock Lock `mapstructure:"lock"` Lock Lock `mapstructure:"lock"`
@ -34,7 +39,7 @@ func newConfig() factory.Config {
func (c Config) Validate() error { func (c Config) Validate() error {
if c.Lock.Timeout <= c.Lock.Interval { if c.Lock.Timeout <= c.Lock.Interval {
return errors.New("lock::timeout must be greater than lock::interval") return errors.New(errors.TypeInvalidInput, ErrCodeInvalidSQLMigratorConfig, "lock::timeout must be greater than lock::interval")
} }
return nil return nil

View File

@ -2,9 +2,10 @@ package sqlmigrator
import ( import (
"context" "context"
"errors"
"time" "time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/uptrace/bun/migrate" "github.com/uptrace/bun/migrate"
@ -100,7 +101,7 @@ func (migrator *migrator) Lock(ctx context.Context) error {
for { for {
select { select {
case <-timer.C: case <-timer.C:
err := errors.New("timed out waiting for lock") err := errors.New(errors.TypeTimeout, errors.CodeTimeout, "timed out waiting for lock")
migrator.settings.Logger().ErrorContext(ctx, "cannot acquire lock", "error", err, "lock_timeout", migrator.config.Lock.Timeout.String(), "dialect", migrator.dialect) migrator.settings.Logger().ErrorContext(ctx, "cannot acquire lock", "error", err, "lock_timeout", migrator.config.Lock.Timeout.String(), "dialect", migrator.dialect)
return err return err
case <-ticker.C: case <-ticker.C:

View File

@ -1,17 +1,19 @@
package sqlitesqlschema package sqlitesqlschema
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
"strings" "strings"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/sqlschema" "github.com/SigNoz/signoz/pkg/sqlschema"
) )
// Inspired by https://github.com/go-gorm/sqlite // Inspired by https://github.com/go-gorm/sqlite
var ( var (
ErrCodeInvalidDDL = errors.MustNewCode("invalid_ddl")
sqliteSeparator = "`|\"|'|\t" sqliteSeparator = "`|\"|'|\t"
sqliteIdentQuote = "`|\"|'" sqliteIdentQuote = "`|\"|'"
uniqueRegexp = regexp.MustCompile(fmt.Sprintf(`^(?:CONSTRAINT [%v]?[\w-]+[%v]? )?UNIQUE (.*)$`, sqliteSeparator, sqliteSeparator)) uniqueRegexp = regexp.MustCompile(fmt.Sprintf(`^(?:CONSTRAINT [%v]?[\w-]+[%v]? )?UNIQUE (.*)$`, sqliteSeparator, sqliteSeparator))
@ -40,12 +42,12 @@ const (
func parseCreateTable(str string, fmter sqlschema.SQLFormatter) (*sqlschema.Table, []*sqlschema.UniqueConstraint, error) { func parseCreateTable(str string, fmter sqlschema.SQLFormatter) (*sqlschema.Table, []*sqlschema.UniqueConstraint, error) {
sections := tableRegexp.FindStringSubmatch(str) sections := tableRegexp.FindStringSubmatch(str)
if len(sections) == 0 { if len(sections) == 0 {
return nil, nil, errors.New("invalid DDL") return nil, nil, errors.New(errors.TypeInternal, ErrCodeInvalidDDL, "invalid DDL")
} }
tableNameSections := tableNameRegexp.FindStringSubmatch(str) tableNameSections := tableNameRegexp.FindStringSubmatch(str)
if len(tableNameSections) == 0 { if len(tableNameSections) == 0 {
return nil, nil, errors.New("invalid DDL") return nil, nil, errors.New(errors.TypeInternal, ErrCodeInvalidDDL, "invalid DDL")
} }
tableName := sqlschema.TableName(tableNameSections[1]) tableName := sqlschema.TableName(tableNameSections[1])
@ -97,14 +99,14 @@ func parseCreateTable(str string, fmter sqlschema.SQLFormatter) (*sqlschema.Tabl
} }
if bracketLevel < 0 { if bracketLevel < 0 {
return nil, nil, errors.New("invalid DDL, unbalanced brackets") return nil, nil, errors.New(errors.TypeInternal, ErrCodeInvalidDDL, "invalid DDL, unbalanced brackets")
} }
buf += string(c) buf += string(c)
} }
if bracketLevel != 0 { if bracketLevel != 0 {
return nil, nil, errors.New("invalid DDL, unbalanced brackets") return nil, nil, errors.New(errors.TypeInternal, ErrCodeInvalidDDL, "invalid DDL, unbalanced brackets")
} }
if buf != "" { if buf != "" {
@ -300,14 +302,14 @@ func parseAllColumns(in string) ([]sqlschema.ColumnName, error) {
state = parseAllColumnsState_State_End state = parseAllColumnsState_State_End
continue continue
} }
return nil, fmt.Errorf("unexpected token: %s", string(s[i])) return nil, errors.Newf(errors.TypeInternal, ErrCodeInvalidDDL, "unexpected token: %s", string(s[i]))
case parseAllColumnsState_State_End: case parseAllColumnsState_State_End:
// break is automatic in Go switch statements // break is automatic in Go switch statements
} }
} }
if state != parseAllColumnsState_State_End { if state != parseAllColumnsState_State_End {
return nil, errors.New("unexpected end") return nil, errors.New(errors.TypeInternal, ErrCodeInvalidDDL, "unexpected end")
} }
return columns, nil return columns, nil

View File

@ -3,10 +3,11 @@ package telemetrystorehook
import ( import (
"context" "context"
"database/sql" "database/sql"
"errors"
"log/slog" "log/slog"
"time" "time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/telemetrystore" "github.com/SigNoz/signoz/pkg/telemetrystore"
) )

View File

@ -2,7 +2,8 @@ package authtypes
import ( import (
"context" "context"
"errors"
"github.com/SigNoz/signoz/pkg/errors"
) )
type uuidKey struct{} type uuidKey struct{}
@ -24,7 +25,7 @@ func (u *UUID) ContextFromRequest(ctx context.Context, values ...string) (contex
} }
if value == "" { if value == "" {
return ctx, errors.New("missing Authorization header") return ctx, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "missing Authorization header")
} }
return NewContextWithUUID(ctx, value), nil return NewContextWithUUID(ctx, value), nil

View File

@ -1,10 +1,11 @@
package pipelinetypes package pipelinetypes
import ( import (
"errors"
"fmt" "fmt"
"regexp" "regexp"
"strings" "strings"
"github.com/SigNoz/signoz/pkg/errors"
) )
// Regex for strptime format placeholders supported by the time parser. // Regex for strptime format placeholders supported by the time parser.
@ -106,7 +107,7 @@ func RegexForStrptimeLayout(layout string) (string, error) {
if regex, ok := ctimeRegex[directive]; ok { if regex, ok := ctimeRegex[directive]; ok {
return regex return regex
} }
errs = append(errs, errors.New("unsupported ctimefmt directive: "+directive)) errs = append(errs, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "unsupported ctimefmt directive: "+directive))
return "" return ""
} }

View File

@ -3,8 +3,9 @@ package ruletypes
import ( import (
"database/sql/driver" "database/sql/driver"
"encoding/json" "encoding/json"
"errors"
"time" "time"
"github.com/SigNoz/signoz/pkg/errors"
) )
type RepeatType string type RepeatType string
@ -61,7 +62,7 @@ func (d *Duration) UnmarshalJSON(b []byte) error {
return nil return nil
default: default:
return errors.New("invalid duration") return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "invalid duration")
} }
} }

View File

@ -3,7 +3,6 @@ package ruletypes
import ( import (
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
"math" "math"
"net/url" "net/url"
@ -11,6 +10,8 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/SigNoz/signoz/pkg/errors"
html_template "html/template" html_template "html/template"
text_template "text/template" text_template "text/template"
@ -73,7 +74,7 @@ func NewTemplateExpander(
if len(v) > 0 { if len(v) > 0 {
return v[0], nil return v[0], nil
} }
return nil, errors.New("first() called on vector with no elements") return nil, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "first() called on vector with no elements")
}, },
"label": func(label string, s *tmplQueryRecord) string { "label": func(label string, s *tmplQueryRecord) string {
return s.Labels[label] return s.Labels[label]

View File

@ -2,10 +2,10 @@ package ssotypes
import ( import (
"context" "context"
"errors"
"fmt"
"net/http" "net/http"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/coreos/go-oidc/v3/oidc" "github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2" "golang.org/x/oauth2"
) )
@ -48,7 +48,7 @@ func (g *GoogleOAuthProvider) HandleCallback(r *http.Request) (identity *SSOIden
token, err := g.OAuth2Config.Exchange(r.Context(), q.Get("code")) token, err := g.OAuth2Config.Exchange(r.Context(), q.Get("code"))
if err != nil { if err != nil {
return identity, fmt.Errorf("google: failed to get token: %v", err) return identity, errors.Newf(errors.TypeInternal, errors.CodeInternal, "google: failed to get token: %v", err)
} }
return g.createIdentity(r.Context(), token) return g.createIdentity(r.Context(), token)
@ -57,11 +57,11 @@ func (g *GoogleOAuthProvider) HandleCallback(r *http.Request) (identity *SSOIden
func (g *GoogleOAuthProvider) createIdentity(ctx context.Context, token *oauth2.Token) (identity *SSOIdentity, err error) { func (g *GoogleOAuthProvider) createIdentity(ctx context.Context, token *oauth2.Token) (identity *SSOIdentity, err error) {
rawIDToken, ok := token.Extra("id_token").(string) rawIDToken, ok := token.Extra("id_token").(string)
if !ok { if !ok {
return identity, errors.New("google: no id_token in token response") return identity, errors.New(errors.TypeInternal, errors.CodeInternal, "google: no id_token in token response")
} }
idToken, err := g.Verifier.Verify(ctx, rawIDToken) idToken, err := g.Verifier.Verify(ctx, rawIDToken)
if err != nil { if err != nil {
return identity, fmt.Errorf("google: failed to verify ID Token: %v", err) return identity, errors.Newf(errors.TypeInternal, errors.CodeInternal, "google: failed to verify ID Token: %v", err)
} }
var claims struct { var claims struct {
@ -71,11 +71,11 @@ func (g *GoogleOAuthProvider) createIdentity(ctx context.Context, token *oauth2.
HostedDomain string `json:"hd"` HostedDomain string `json:"hd"`
} }
if err := idToken.Claims(&claims); err != nil { if err := idToken.Claims(&claims); err != nil {
return identity, fmt.Errorf("oidc: failed to decode claims: %v", err) return identity, errors.Newf(errors.TypeInternal, errors.CodeInternal, "oidc: failed to decode claims: %v", err)
} }
if claims.HostedDomain != g.HostedDomain { if claims.HostedDomain != g.HostedDomain {
return identity, fmt.Errorf("oidc: unexpected hd claim %v", claims.HostedDomain) return identity, errors.Newf(errors.TypeInternal, errors.CodeInternal, "oidc: unexpected hd claim %v", claims.HostedDomain)
} }
identity = &SSOIdentity{ identity = &SSOIdentity{

View File

@ -3,9 +3,10 @@ package valuer
import ( import (
"database/sql/driver" "database/sql/driver"
"encoding/json" "encoding/json"
"fmt"
"reflect" "reflect"
"strings" "strings"
"github.com/SigNoz/signoz/pkg/errors"
) )
var _ Valuer = (*String)(nil) var _ Valuer = (*String)(nil)
@ -50,7 +51,7 @@ func (enum String) Value() (driver.Value, error) {
func (enum *String) Scan(val interface{}) error { func (enum *String) Scan(val interface{}) error {
if enum == nil { if enum == nil {
return fmt.Errorf("string: (nil \"%s\")", reflect.TypeOf(enum).String()) return errors.Newf(errors.TypeInternal, ErrCodeUnknownValuerScan, "string: (nil \"%s\")", reflect.TypeOf(enum).String())
} }
if val == nil { if val == nil {
@ -61,7 +62,7 @@ func (enum *String) Scan(val interface{}) error {
str, ok := val.(string) str, ok := val.(string)
if !ok { if !ok {
return fmt.Errorf("string: (non-string \"%s\")", reflect.TypeOf(val).String()) return errors.Newf(errors.TypeInternal, ErrCodeUnknownValuerScan, "string: (non-string \"%s\")", reflect.TypeOf(val).String())
} }
*enum = NewString(str) *enum = NewString(str)

View File

@ -3,9 +3,9 @@ package valuer
import ( import (
"database/sql/driver" "database/sql/driver"
"encoding/json" "encoding/json"
"fmt"
"reflect" "reflect"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/google/uuid" "github.com/google/uuid"
) )
@ -98,11 +98,11 @@ func (enum UUID) Value() (driver.Value, error) {
func (enum *UUID) Scan(val interface{}) error { func (enum *UUID) Scan(val interface{}) error {
if enum == nil { if enum == nil {
return fmt.Errorf("uuid: (nil \"%s\")", reflect.TypeOf(enum).String()) return errors.Newf(errors.TypeInternal, ErrCodeUnknownValuerScan, "uuid: (nil \"%s\")", reflect.TypeOf(enum).String())
} }
if val == nil { if val == nil {
return fmt.Errorf("uuid: (nil \"%s\")", reflect.TypeOf(val).String()) return errors.Newf(errors.TypeInternal, ErrCodeUnknownValuerScan, "uuid: (nil \"%s\")", reflect.TypeOf(val).String())
} }
var enumVal UUID var enumVal UUID
@ -110,17 +110,17 @@ func (enum *UUID) Scan(val interface{}) error {
case string: case string:
_enumVal, err := NewUUID(val) _enumVal, err := NewUUID(val)
if err != nil { if err != nil {
return fmt.Errorf("uuid: (invalid-uuid \"%s\")", err.Error()) return errors.Newf(errors.TypeInternal, ErrCodeUnknownValuerScan, "uuid: (invalid-uuid \"%s\")", err.Error())
} }
enumVal = _enumVal enumVal = _enumVal
case []byte: case []byte:
_enumVal, err := NewUUIDFromBytes(val) _enumVal, err := NewUUIDFromBytes(val)
if err != nil { if err != nil {
return fmt.Errorf("uuid: (invalid-uuid \"%s\")", err.Error()) return errors.Newf(errors.TypeInternal, ErrCodeUnknownValuerScan, "uuid: (invalid-uuid \"%s\")", err.Error())
} }
enumVal = _enumVal enumVal = _enumVal
default: default:
return fmt.Errorf("uuid: (non-uuid \"%s\")", reflect.TypeOf(val).String()) return errors.Newf(errors.TypeInternal, ErrCodeUnknownValuerScan, "uuid: (non-uuid \"%s\")", reflect.TypeOf(val).String())
} }
*enum = enumVal *enum = enumVal

View File

@ -6,6 +6,12 @@ import (
"encoding" "encoding"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/SigNoz/signoz/pkg/errors"
)
var (
ErrCodeUnknownValuerScan = errors.MustNewCode("unknown_valuer_scan")
) )
type Valuer interface { type Valuer interface {

View File

@ -102,10 +102,10 @@ func (b Build) PrettyPrint(cfg Config) {
" :**********= ", " :**********= ",
} }
fmt.Println() fmt.Println() //nolint:forbidigo
for _, line := range ascii { for _, line := range ascii {
fmt.Print(line) fmt.Print(line) //nolint:forbidigo
fmt.Println() fmt.Println() //nolint:forbidigo
} }
fmt.Println() fmt.Println() //nolint:forbidigo
} }