Compare commits

...

40 Commits

Author SHA1 Message Date
grandwizard28
72c7fd3454 feat(signoz): add backwards compatibility function 2024-11-19 18:02:27 +05:30
grandwizard28
761eed7be8 feat(SIGNOZ_JWT_SECRET): add deprecation warning 2024-11-08 20:37:47 +05:30
grandwizard28
96bf51a951 feat(config): add a backwards compatibility function 2024-11-08 19:02:26 +05:30
grandwizard28
cd4085d134 chore(defaults): address comments 2024-11-08 17:23:18 +05:30
grandwizard28
1758c7b7be feat(go): run go-mod tidy 2024-11-08 17:09:54 +05:30
grandwizard28
1680fe1c96 Merge branch 'develop' into 176/coalesce
# Conflicts:
#	go.mod
2024-11-08 17:06:31 +05:30
grandwizard28
23db133b74 refactor(healthcheck): remove healthcheck 2024-08-23 15:43:47 +05:30
grandwizard28
d70e400605 refactor(dynamic_config): deprecate dynamic_config 2024-08-23 15:40:40 +05:30
grandwizard28
b6e2c26022 refactor(version): deprecate version 2024-08-23 15:38:28 +05:30
grandwizard28
f0c054f372 Merge branch 'develop' into 176/coalesce 2024-08-23 14:50:10 +05:30
grandwizard28
83b8c5ad2e feat(http): move config 2024-08-23 00:10:29 +05:30
grandwizard28
487935817a feat(opamp): move config 2024-08-23 00:04:14 +05:30
grandwizard28
c047abb951 feat(storage): move config 2024-08-22 23:59:35 +05:30
grandwizard28
633c5dbc83 feat(database): move config 2024-08-22 23:51:31 +05:30
grandwizard28
ed3180f84c feat(auth): move auth config 2024-08-22 23:41:56 +05:30
grandwizard28
6b6512c993 feat(cache): move cache config 2024-08-22 23:35:12 +05:30
grandwizard28
df4e5c043f feat(conf): add web, instrumentation to conf 2024-08-22 23:27:09 +05:30
grandwizard28
72c6d7c3d7 Merge branch '176/render' into 176/coalesce 2024-08-22 20:58:04 +05:30
grandwizard28
e827b6993d Merge branch 'develop' into 176/render 2024-08-22 20:58:02 +05:30
grandwizard28
77dd908fde feat(conf): create a default config file 2024-08-22 20:53:10 +05:30
grandwizard28
949b71837e feat(cmd): add cobra command for signoz entrypoint 2024-08-22 20:52:54 +05:30
grandwizard28
8a92a81416 fix(config): read defaults for config keys which do not exist 2024-08-22 20:52:34 +05:30
grandwizard28
3fd8c67999 feat(version): add pretty print 2024-08-22 20:52:12 +05:30
grandwizard28
0dccd20ea0 Merge branch '176/web' into 176/render 2024-08-22 17:51:34 +05:30
grandwizard28
fb78937956 feat(render): add render package 2024-08-22 17:13:10 +05:30
grandwizard28
f9aa333c4d Merge branch 'develop' into 176/web 2024-08-22 15:26:50 +05:30
grandwizard28
062b87c11d Merge branch '176/error' into 176/web 2024-08-22 14:33:01 +05:30
grandwizard28
3d61df370c Merge branch '176/registry' into 176/error 2024-08-22 14:33:00 +05:30
grandwizard28
22005f1561 Merge branch 'develop' into 176/registry 2024-08-22 14:32:59 +05:30
grandwizard28
ba0c896e87 ci(git): add git-town to .gitignore 2024-08-22 14:25:52 +05:30
grandwizard28
b74843c380 feat(errors): add the revamped error model 2024-08-22 14:25:52 +05:30
grandwizard28
3496ec2bb2 feat(web): add unit test for config 2024-08-22 14:25:52 +05:30
grandwizard28
9e4b3718ba feat(web): add config in master config package 2024-08-22 14:25:52 +05:30
grandwizard28
863c86d33f feat(web): add web package 2024-08-22 14:25:52 +05:30
grandwizard28
02d337da6b feat(middleware): add cache middleware 2024-08-22 14:25:52 +05:30
grandwizard28
dd0dd0167c feat(errors): add errors package 2024-08-22 14:25:51 +05:30
grandwizard28
b15db358cc feat(timeout): make max timeout configurable, move to a single log statement in logging 2024-08-22 13:28:54 +05:30
grandwizard28
dd06ad44d6 ci(git): add git-town to .gitignore 2024-08-21 21:02:28 +05:30
grandwizard28
29b33cf13c feat(registry): add registry and http package 2024-08-21 21:00:07 +05:30
grandwizard28
b06a24f2d6 feat(registry): add registry package 2024-08-21 21:00:06 +05:30
30 changed files with 624 additions and 283 deletions

29
cmd/signoz/config.go Normal file
View File

@@ -0,0 +1,29 @@
package main
import (
"flag"
"strings"
"github.com/spf13/cobra"
)
type config struct {
uris []string
}
func (c *config) Set(val string) error {
c.uris = append(c.uris, val)
return nil
}
func (c *config) String() string {
return "[" + strings.Join(c.uris, ", ") + "]"
}
func (c *config) registerFlags(cmd *cobra.Command) {
flagSet := new(flag.FlagSet)
flagSet.Var(c, "config", "Locations to the config file(s), note that only a"+
" single location can be set per flag entry e.g. `--config=file:/path/to/first --config=file:path/to/second`.")
cmd.Flags().AddGoFlagSet(flagSet)
}

101
cmd/signoz/main.go Normal file
View File

@@ -0,0 +1,101 @@
package main
import (
"context"
"os"
"slices"
"github.com/spf13/cobra"
"go.opentelemetry.io/collector/confmap"
"go.opentelemetry.io/collector/confmap/provider/fileprovider"
signozconfig "go.signoz.io/signoz/pkg/config"
"go.signoz.io/signoz/pkg/confmap/provider/signozenvprovider"
"go.signoz.io/signoz/pkg/instrumentation"
"go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/version"
"go.signoz.io/signoz/pkg/web"
"go.uber.org/zap"
)
func main() {
var config config
app := &cobra.Command{
Use: "signoz",
Short: "An open-source observability platform native to OpenTelemetry with logs, traces and metrics in a single application.",
Version: version.Info.Version,
SilenceUsage: true,
SilenceErrors: false,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
return run(ctx, config)
},
PostRunE: func(cmd *cobra.Command, args []string) error {
return nil
},
}
// register all flags
config.registerFlags(app)
// register the Name in version as per the command name
version.Info.Name = app.Use
if err := app.Execute(); err != nil {
os.Exit(1)
}
}
func run(
ctx context.Context,
cfg config,
) error {
// Create the master config first. The master config will be used to initialize/create
// all other components
if len(cfg.uris) == 0 || !slices.Contains(cfg.uris, "signozenv:") {
cfg.uris = append(cfg.uris, "signozenv:")
}
config, err := signozconfig.New(ctx, signozconfig.ProviderSettings{
ResolverSettings: confmap.ResolverSettings{
URIs: cfg.uris,
ProviderFactories: []confmap.ProviderFactory{
signozenvprovider.NewFactory(),
fileprovider.NewFactory(),
},
},
})
if err != nil {
return err
}
// Print the current environment
if config.Version.Banner.Enabled {
version.Info.PrettyPrint()
}
// Instrument the application, here we finally get the logger
instr, err := instrumentation.New(ctx, version.Info, config.Instrumentation)
if err != nil {
return err
}
// Remove this function once the new config is completely rolled out
signozconfig.EnsureBackwardsCompatibility(ctx, instr, config)
// To support backward compatibility, we are going to initialize the global zap logger
zap.ReplaceGlobals(instr.Logger.Named("go.signoz.io/signoz/cmd/signoz"))
_, err = web.New(instr.Logger, config.Web)
if err != nil {
return err
}
auth.JwtSecret = config.Auth.Jwt.Secret
if len(auth.JwtSecret) == 0 {
instr.Logger.Warn("no jwt secret key is specified", zap.Any("context", ctx))
}
return nil
}

125
conf/defaults.yaml Normal file
View File

@@ -0,0 +1,125 @@
##################### SigNoz Configuration Defaults #####################
#
# Do not modify this file
#
##################### Version #####################
version:
banner:
# Whether to show the banner on startup
enabled: true
##################### Instrumentation #####################
instrumentation:
logs:
# Whether to enable log exports to an otlp compatible backend
enabled: false
# the level of the logger
level: error
processors:
- batch:
exporter:
otlp:
# the otlp endpoint
endpoint:
# the otlp protocol
protocol:
traces:
# Whether to enable trace exports to an otlp compatible backend
enabled: false
processors:
- batch:
exporter:
otlp:
# the otlp endpoint
endpoint:
# the otlp protocol
protocol:
metrics:
# Whether to enable metric exports to an otlp compatible backend or in prometheus format
enabled: true
readers:
- periodic:
exporter:
otlp:
# the otlp endpoint
endpoint:
# the otlp protocol
protocol:
prometheus:
host: 0.0.0.0
port: 9090
##################### Web #####################
web:
# The prefix to serve web on
prefix: /
# The directory containing the static build files.
directory: /etc/signoz/web
##################### Cache #####################
cache:
# Memory provider
provider: memory
memory:
ttl: -1
cleanup_interval: 60
# Redis Provider
# provider: redis
# redis:
# host: localhost
# port: 6379
# password: password
# db: 0
##################### Auth #####################
auth:
jwt:
# The JWT secret for authentication
secret: secret
##################### Database #####################
database:
# Supported options are sqlite
provider: sqlite
# Path to the sqlite database
sqlite:
path: signoz.db
max_open_conn: 10
##################### Storage #####################
storage:
provider: clickhouse
clickhouse:
dsn: tcp://localhost:9000
cluster: cluster
max_idle_connections:
max_open_connections:
dial_timeout:
settings:
optimize_read_in_order_regex:
max_execution_time_leaf:
timeout_before_checking_execution_speed:
max_bytes_to_read:
##################### Opamp #####################
opamp:
address: 0.0.0.0:4320
##################### Http #####################
http:
address: 0.0.0.0:8000
timeout: 60s
max_timeout: 600s
##################### Prometheus #####################
prometheus:
remote_read:
config:
url: tcp://localhost:9000/signoz_metrics
##################### Alerting #####################
alerting:
rules:
enabled: true

View File

@@ -18,7 +18,7 @@ import (
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
rules "go.signoz.io/signoz/pkg/query-service/rules"
"go.signoz.io/signoz/pkg/query-service/version"
"go.signoz.io/signoz/pkg/version"
)
type APIHandlerOptions struct {
@@ -187,9 +187,8 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *baseapp.AuthMiddlew
}
func (ah *APIHandler) getVersion(w http.ResponseWriter, r *http.Request) {
version := version.GetVersion()
versionResponse := basemodel.GetVersionResponse{
Version: version,
Version: version.Info.Version,
EE: "Y",
SetupCompleted: ah.SetupCompleted,
}

View File

@@ -48,7 +48,6 @@ import (
"go.signoz.io/signoz/pkg/query-service/app/preferences"
"go.signoz.io/signoz/pkg/query-service/cache"
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/healthcheck"
basealm "go.signoz.io/signoz/pkg/query-service/integrations/alertManager"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
@@ -97,13 +96,6 @@ type Server struct {
usageManager *usage.Manager
opampServer *opamp.Server
unavailableChannel chan healthcheck.Status
}
// HealthCheckStatus returns health check status channel a client can subscribe to
func (s Server) HealthCheckStatus() chan healthcheck.Status {
return s.unavailableChannel
}
// NewServer creates and initializes Server
@@ -144,6 +136,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
readerReady := make(chan bool)
var reader interfaces.DataConnector
// todo(remove): read from config
storage := os.Getenv("STORAGE")
if storage == "clickhouse" {
zap.L().Info("Using ClickHouse as datastore ...")
@@ -280,10 +273,9 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
s := &Server{
// logger: logger,
// tracer: tracer,
ruleManager: rm,
serverOptions: serverOptions,
unavailableChannel: make(chan healthcheck.Status),
usageManager: usageManager,
ruleManager: rm,
serverOptions: serverOptions,
usageManager: usageManager,
}
httpServer, err := s.createPublicServer(apiHandler)
@@ -658,7 +650,6 @@ func (s *Server) Start() error {
default:
zap.L().Error("Could not start HTTP server", zap.Error(err))
}
s.unavailableChannel <- healthcheck.Unavailable
}()
go func() {
@@ -686,8 +677,6 @@ func (s *Server) Start() error {
zap.L().Error("Could not start private HTTP server", zap.Error(err))
}
s.unavailableChannel <- healthcheck.Unavailable
}()
go func() {
@@ -695,7 +684,6 @@ func (s *Server) Start() error {
err := s.opampServer.Start(baseconst.OpAmpWsEndpoint)
if err != nil {
zap.L().Error("opamp ws server failed to start", zap.Error(err))
s.unavailableChannel <- healthcheck.Unavailable
}
}()

View File

@@ -16,7 +16,6 @@ import (
"go.signoz.io/signoz/pkg/query-service/auth"
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/migrate"
"go.signoz.io/signoz/pkg/query-service/version"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
@@ -125,8 +124,6 @@ func main() {
zap.ReplaceGlobals(loggerMgr)
defer loggerMgr.Sync() // flushes buffer, if any
version.PrintVersion()
serverOptions := &app.ServerOptions{
HTTPHostPort: baseconst.HTTPHostPort,
PromConfigPath: promConfigPath,
@@ -178,8 +175,6 @@ func main() {
for {
select {
case status := <-server.HealthCheckStatus():
zap.L().Info("Received HealthCheck status: ", zap.Int("status", int(status)))
case <-signalsChannel:
zap.L().Fatal("Received OS Interrupt Signal ... ")
server.Stop()

View File

@@ -48,6 +48,7 @@ type Manager struct {
func New(dbType string, modelDao dao.ModelDao, licenseRepo *license.Repo, clickhouseConn clickhouse.Conn) (*Manager, error) {
hostNameRegex := regexp.MustCompile(`tcp://(?P<hostname>.*):`)
// todo(remove): read from config
hostNameRegexMatches := hostNameRegex.FindStringSubmatch(os.Getenv("ClickHouseUrl"))
tenantID := ""

2
go.mod
View File

@@ -47,6 +47,7 @@ require (
github.com/sethvargo/go-password v0.2.0
github.com/smartystreets/goconvey v1.8.1
github.com/soheilhy/cmux v0.1.5
github.com/spf13/cobra v1.8.1
github.com/srikanthccv/ClickHouse-go-mock v0.9.0
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/collector/component v0.111.0
@@ -169,7 +170,6 @@ require (
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smarty/assertions v1.15.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect

View File

@@ -2,15 +2,43 @@ package config
import (
"context"
"os"
signozconfmap "go.signoz.io/signoz/pkg/confmap"
"go.signoz.io/signoz/pkg/instrumentation"
"go.signoz.io/signoz/pkg/query-service/app/clickhouseReader"
"go.signoz.io/signoz/pkg/query-service/app/opamp"
"go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/query-service/cache"
"go.signoz.io/signoz/pkg/query-service/dao"
"go.signoz.io/signoz/pkg/version"
"go.signoz.io/signoz/pkg/web"
)
// This map contains the default values of all config structs
var (
defaultMap map[string]signozconfmap.Config = map[string]signozconfmap.Config{
"version": &version.Config{},
"instrumentation": &instrumentation.Config{},
"web": &web.Config{},
"cache": &cache.Config{},
"auth": &auth.Config{},
"database": &dao.Config{},
"storage": &clickhouseReader.Config{},
"opamp": &opamp.Config{},
}
)
// Config defines the entire configuration of signoz.
type Config struct {
Instrumentation instrumentation.Config `mapstructure:"instrumentation"`
Web web.Config `mapstructure:"web"`
Version version.Config `mapstructure:"version"`
Instrumentation instrumentation.Config `mapstructure:"instrumentation"`
Web web.Config `mapstructure:"web"`
Cache cache.Config `mapstructure:"cache"`
Auth auth.Config `mapstructure:"auth"`
Database dao.Config `mapstructure:"database"`
Storage clickhouseReader.Config `mapstructure:"storage"`
Opamp opamp.Config `mapstructure:"opamp"`
}
func New(ctx context.Context, settings ProviderSettings) (*Config, error) {
@@ -22,14 +50,13 @@ func New(ctx context.Context, settings ProviderSettings) (*Config, error) {
return provider.Get(ctx)
}
func byName(name string) (any, bool) {
switch name {
case "instrumentation":
return &instrumentation.Config{}, true
case "web":
return &web.Config{}, true
default:
return nil, false
// A backwards compatibility function to ensure signoz does not break for existing
// users. This will modify the input config in place
func EnsureBackwardsCompatibility(ctx context.Context, instrumentation *instrumentation.Instrumentation, cfg *Config) {
jwtSecret, ok := os.LookupEnv("SIGNOZ_JWT_SECRET")
if ok {
instrumentation.Logger.Warn("SIGNOZ_JWT_SECRET has been deprecated and will be removed in a future release")
cfg.Auth.Jwt.Secret = jwtSecret
}
}

View File

@@ -10,6 +10,7 @@ import (
contribsdkconfig "go.opentelemetry.io/contrib/config"
"go.signoz.io/signoz/pkg/confmap/provider/signozenvprovider"
"go.signoz.io/signoz/pkg/instrumentation"
"go.signoz.io/signoz/pkg/version"
"go.signoz.io/signoz/pkg/web"
)
@@ -32,6 +33,11 @@ func TestNewWithSignozEnvProvider(t *testing.T) {
i := 10
expected := &Config{
Version: version.Config{
Banner: version.Banner{
Enabled: true,
},
},
Instrumentation: instrumentation.Config{
Logs: instrumentation.LogsConfig{
Enabled: true,
@@ -57,5 +63,7 @@ func TestNewWithSignozEnvProvider(t *testing.T) {
},
}
assert.Equal(t, expected, config)
assert.Equal(t, expected.Instrumentation, config.Instrumentation)
assert.Equal(t, expected.Web, config.Web)
assert.Equal(t, expected.Version, config.Version)
}

View File

@@ -4,7 +4,6 @@ import (
"fmt"
"go.opentelemetry.io/collector/confmap"
signozconfmap "go.signoz.io/signoz/pkg/confmap"
)
// unmarshal converts a confmap.Conf into a Config struct.
@@ -17,24 +16,17 @@ func unmarshal(conf *confmap.Conf) (*Config, error) {
return nil, err
}
// To help the defaults kick in, we need to put keys into the raw map if the key is not present
parsed := make(map[string]any)
for k := range raw {
e, ok := byName(k)
if !ok {
return nil, fmt.Errorf("cannot find config with name %q", k)
}
i, ok := e.(signozconfmap.Config)
if !ok {
return nil, fmt.Errorf("config %q does not implement \"signozconfmap.Config\"", k)
}
for k, v := range defaultMap {
sub, err := conf.Sub(k)
if err != nil {
return nil, fmt.Errorf("cannot read config for %q: %w", k, err)
}
d := i.NewWithDefaults()
d := v.NewWithDefaults()
if err := sub.Unmarshal(&d); err != nil {
return nil, fmt.Errorf("cannot merge config for %q: %w", k, err)
}

View File

@@ -29,6 +29,6 @@ func TestUnmarshal(t *testing.T) {
cfg, err := unmarshal(input)
require.NoError(t, err)
assert.Equal(t, expected, cfg)
assert.Equal(t, expected.Instrumentation, cfg.Instrumentation)
}

View File

@@ -0,0 +1,41 @@
package clickhouseReader
import (
"time"
"go.signoz.io/signoz/pkg/confmap"
)
type Config struct {
Provider string `mapstructure:"provider"`
DSN string `mapstructure:"dsn"`
Cluster string `mapstructure:"cluster"`
PrometheusConfigPath string `mapstructure:"prometheus_config_path"`
MaxIdleConnections int `mapstructure:"max_idle_connections"`
MaxOpenConnections int `mapstructure:"max_open_connections"`
DialTimeout time.Duration `mapstructure:"dial_timeout"`
OptimizeReadInOrderRegex string `mapstructure:"optimize_read_in_order_regex"`
MaxExecutionTimeLeaf string `mapstructure:"max_execution_time_leaf"`
TimeoutBeforeCheckingExecutionSpeed string `mapstructure:"timeout_before_checking_execution_speed"`
MaxBytesToRead string `mapstructure:"max_bytes_to_read"`
}
func (c *Config) NewWithDefaults() confmap.Config {
return &Config{
Provider: "clickhouse",
DSN: "tcp://localhost:9000",
Cluster: "cluster",
PrometheusConfigPath: "/etc/signoz/config/prometheus.yml",
MaxIdleConnections: 50,
MaxOpenConnections: 100,
DialTimeout: 5 * time.Second,
OptimizeReadInOrderRegex: "",
MaxExecutionTimeLeaf: "",
TimeoutBeforeCheckingExecutionSpeed: "",
MaxBytesToRead: "",
}
}
func (c *Config) Validate() error {
return nil
}

View File

@@ -162,6 +162,7 @@ func NewReader(
useLogsNewSchema bool,
) *ClickHouseReader {
// todo(remove): read from config
datasource := os.Getenv("ClickHouseUrl")
options := NewOptions(datasource, maxIdleConns, maxOpenConns, dialTimeout, primaryNamespace, archiveNamespace)
db, err := initialize(options)

View File

@@ -46,6 +46,7 @@ import (
"go.signoz.io/signoz/pkg/query-service/contextlinks"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
"go.signoz.io/signoz/pkg/query-service/postprocess"
"go.signoz.io/signoz/pkg/version"
"go.uber.org/zap"
@@ -53,12 +54,10 @@ import (
"go.signoz.io/signoz/pkg/query-service/app/logparsingpipeline"
"go.signoz.io/signoz/pkg/query-service/dao"
am "go.signoz.io/signoz/pkg/query-service/integrations/alertManager"
signozio "go.signoz.io/signoz/pkg/query-service/integrations/signozio"
"go.signoz.io/signoz/pkg/query-service/interfaces"
"go.signoz.io/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/query-service/rules"
"go.signoz.io/signoz/pkg/query-service/telemetry"
"go.signoz.io/signoz/pkg/query-service/version"
)
type status string
@@ -483,7 +482,6 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *AuthMiddleware) {
router.HandleFunc("/api/v1/version", am.OpenAccess(aH.getVersion)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/featureFlags", am.OpenAccess(aH.getFeatureFlags)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/configs", am.OpenAccess(aH.getConfigs)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/health", am.OpenAccess(aH.getHealth)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/getSpanFilters", am.ViewAccess(aH.getSpanFilters)).Methods(http.MethodPost)
@@ -1932,9 +1930,8 @@ func (aH *APIHandler) getDisks(w http.ResponseWriter, r *http.Request) {
}
func (aH *APIHandler) getVersion(w http.ResponseWriter, r *http.Request) {
version := version.GetVersion()
versionResponse := model.GetVersionResponse{
Version: version,
Version: version.Info.Version,
EE: "Y",
SetupCompleted: aH.SetupCompleted,
}
@@ -1968,16 +1965,6 @@ func (aH *APIHandler) CheckFeature(f string) bool {
return err == nil
}
func (aH *APIHandler) getConfigs(w http.ResponseWriter, r *http.Request) {
configs, err := signozio.FetchDynamicConfigs()
if err != nil {
aH.HandleError(w, err, http.StatusInternalServerError)
return
}
aH.Respond(w, configs)
}
// getHealth is used to check the health of the service.
// 'live' query param can be used to check liveliness of
// the service by checking the database connection.

View File

@@ -0,0 +1,25 @@
package opamp
import "go.signoz.io/signoz/pkg/confmap"
// Config satisfies the confmap.Config interface
var _ confmap.Config = (*Config)(nil)
// Config holds the configuration for http.
type Config struct {
//Address specifies the TCP address for the server to listen on, in the form "host:port".
// If empty, ":http" (port 80) is used. The service names are defined in RFC 6335 and assigned by IANA.
// See net.Dial for details of the address format.
Address string `mapstructure:"address"`
}
func (c *Config) NewWithDefaults() confmap.Config {
return &Config{
Address: "0.0.0.0:4320",
}
}
func (c *Config) Validate() error {
return nil
}

View File

@@ -40,7 +40,6 @@ import (
"go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/dao"
"go.signoz.io/signoz/pkg/query-service/featureManager"
"go.signoz.io/signoz/pkg/query-service/healthcheck"
am "go.signoz.io/signoz/pkg/query-service/integrations/alertManager"
"go.signoz.io/signoz/pkg/query-service/interfaces"
"go.signoz.io/signoz/pkg/query-service/model"
@@ -83,13 +82,6 @@ type Server struct {
privateHTTP *http.Server
opampServer *opamp.Server
unavailableChannel chan healthcheck.Status
}
// HealthCheckStatus returns health check status channel a client can subscribe to
func (s Server) HealthCheckStatus() chan healthcheck.Status {
return s.unavailableChannel
}
// NewServer creates and initializes Server
@@ -118,6 +110,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
readerReady := make(chan bool)
var reader interfaces.Reader
// todo(remove): read from config
storage := os.Getenv("STORAGE")
if storage == "clickhouse" {
zap.L().Info("Using ClickHouse as datastore ...")
@@ -210,9 +203,8 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
s := &Server{
// logger: logger,
// tracer: tracer,
ruleManager: rm,
serverOptions: serverOptions,
unavailableChannel: make(chan healthcheck.Status),
ruleManager: rm,
serverOptions: serverOptions,
}
httpServer, err := s.createPublicServer(apiHandler)
@@ -646,7 +638,6 @@ func (s *Server) Start() error {
default:
zap.L().Error("Could not start HTTP server", zap.Error(err))
}
s.unavailableChannel <- healthcheck.Unavailable
}()
go func() {
@@ -673,9 +664,6 @@ func (s *Server) Start() error {
default:
zap.L().Error("Could not start private HTTP server", zap.Error(err))
}
s.unavailableChannel <- healthcheck.Unavailable
}()
go func() {
@@ -683,7 +671,6 @@ func (s *Server) Start() error {
err := s.opampServer.Start(constants.OpAmpWsEndpoint)
if err != nil {
zap.L().Info("opamp ws server failed to start", zap.Error(err))
s.unavailableChannel <- healthcheck.Unavailable
}
}()

View File

@@ -0,0 +1,23 @@
package auth
import "go.signoz.io/signoz/pkg/confmap"
type Config struct {
Jwt Secret `mapstructure:"jwt"`
}
type Secret struct {
Secret string `mapstructure:"secret"`
}
func (c *Config) NewWithDefaults() confmap.Config {
return &Config{
Jwt: Secret{
Secret: "",
},
}
}
func (c *Config) Validate() error {
return nil
}

32
pkg/query-service/cache/config.go vendored Normal file
View File

@@ -0,0 +1,32 @@
package cache
import (
"time"
"go.signoz.io/signoz/pkg/confmap"
inmemory "go.signoz.io/signoz/pkg/query-service/cache/inmemory"
redis "go.signoz.io/signoz/pkg/query-service/cache/redis"
)
// Config satisfies the confmap.Config interface
var _ confmap.Config = (*Config)(nil)
type Config struct {
Provider string `mapstructure:"provider"`
Redis *redis.Options `yaml:"redis,omitempty"`
Memory *inmemory.Options `yaml:"memory,omitempty"`
}
func (c *Config) NewWithDefaults() confmap.Config {
return &Config{
Provider: "memory",
Memory: &inmemory.Options{
TTL: -1,
CleanupInterval: 1 * time.Minute,
},
}
}
func (c *Config) Validate() error {
return nil
}

View File

@@ -69,9 +69,13 @@ var InviteEmailTemplate = GetOrDefaultEnv("INVITE_EMAIL_TEMPLATE", "/root/templa
// Alert manager channel subpath
var AmChannelApiPath = GetOrDefaultEnv("ALERTMANAGER_API_CHANNEL_PATH", "v1/routes")
// todo(remove): read from config
var OTLPTarget = GetOrDefaultEnv("OTEL_EXPORTER_OTLP_ENDPOINT", "")
// todo(remove): read from config
var LogExportBatchSize = GetOrDefaultEnv("OTEL_BLRP_MAX_EXPORT_BATCH_SIZE", "512")
// todo(remove): read from config
var RELATIONAL_DATASOURCE_PATH = GetOrDefaultEnv("SIGNOZ_LOCAL_DB_PATH", "/var/lib/signoz/signoz.db")
var DurationSortFeature = GetOrDefaultEnv("DURATION_SORT_FEATURE", "true")
@@ -148,6 +152,7 @@ var DEFAULT_FEATURE_SET = model.FeatureSet{
},
}
// todo(remove): read from config
func GetContextTimeout() time.Duration {
contextTimeoutStr := GetOrDefaultEnv("CONTEXT_TIMEOUT", "60")
contextTimeoutDuration, err := time.ParseDuration(contextTimeoutStr + "s")
@@ -157,8 +162,10 @@ func GetContextTimeout() time.Duration {
return contextTimeoutDuration
}
// todo(remove): read from config
var ContextTimeout = GetContextTimeout()
// todo(remove): read from config
func GetContextTimeoutMaxAllowed() time.Duration {
contextTimeoutStr := GetOrDefaultEnv("CONTEXT_TIMEOUT_MAX_ALLOWED", "600")
contextTimeoutDuration, err := time.ParseDuration(contextTimeoutStr + "s")
@@ -177,6 +184,7 @@ func GetEvalDelay() time.Duration {
return evalDelayDuration
}
// todo(remove): read from config
var ContextTimeoutMaxAllowed = GetContextTimeoutMaxAllowed()
const (

View File

@@ -0,0 +1,19 @@
package dao
import "go.signoz.io/signoz/pkg/confmap"
type Config struct {
Provider string `mapstructure:"provider"`
Path string `mapstructure:"path"`
}
func (c *Config) NewWithDefaults() confmap.Config {
return &Config{
Provider: "sqlite",
Path: "/var/lib/signoz.db",
}
}
func (c *Config) Validate() error {
return nil
}

View File

@@ -1,12 +0,0 @@
package healthcheck
const (
// Unavailable indicates the service is not able to handle requests
Unavailable Status = iota
// Ready indicates the service is ready to handle requests
Ready
// Broken indicates that the healthcheck itself is broken, not serving HTTP
Broken
)
type Status int

View File

@@ -1,75 +0,0 @@
package signozio
import (
"encoding/json"
"io"
"net/http"
"time"
"go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/model"
)
var C *Client
const (
POST = "POST"
APPLICATION_JSON = "application/json"
)
type Client struct {
Prefix string
}
func New() *Client {
return &Client{
Prefix: constants.ConfigSignozIo,
}
}
func init() {
C = New()
}
// FetchDynamicConfigs fetches configs from config server
func FetchDynamicConfigs() (map[string]Config, *model.ApiError) {
client := http.Client{Timeout: 5 * time.Second}
req, err := http.NewRequest(http.MethodGet, C.Prefix+"/configs", http.NoBody)
if err != nil {
return DefaultConfig, nil
}
req.SetBasicAuth("admin", "SigNoz@adm1n")
httpResponse, err := client.Do(req)
if err != nil {
return DefaultConfig, nil
}
defer httpResponse.Body.Close()
if err != nil {
return DefaultConfig, nil
}
httpBody, err := io.ReadAll(httpResponse.Body)
if err != nil {
return DefaultConfig, nil
}
// read api request result
result := ConfigResult{}
err = json.Unmarshal(httpBody, &result)
if err != nil {
return DefaultConfig, nil
}
switch httpResponse.StatusCode {
case 200, 201:
return result.Data, nil
case 400, 401:
return DefaultConfig, nil
default:
return DefaultConfig, nil
}
}

View File

@@ -1,54 +0,0 @@
package signozio
type status string
type ConfigResult struct {
Status status `json:"status"`
Data map[string]Config `json:"data,omitempty"`
ErrorType string `json:"errorType,omitempty"`
Error string `json:"error,omitempty"`
}
type Config struct {
Enabled bool `json:"enabled"`
FrontendPositionId string `json:"frontendPositionId"`
Components []ComponentProps `json:"components"`
}
type ComponentProps struct {
Text string `json:"text"`
Position int `json:"position"`
DarkIcon string `json:"darkIcon"`
LightIcon string `json:"lightIcon"`
Href string `json:"href"`
}
var DefaultConfig = map[string]Config{
"helpConfig": {
Enabled: true,
FrontendPositionId: "tooltip",
Components: []ComponentProps{
{
Text: "How to use SigNoz in production",
Position: 1,
LightIcon: "RiseOutlined",
DarkIcon: "RiseOutlined",
Href: "https://signoz.io/docs/production-readiness",
},
{
Text: "Create an issue in GitHub",
Position: 2,
LightIcon: "GithubFilled",
DarkIcon: "GithubOutlined",
Href: "https://github.com/SigNoz/signoz/issues/new/choose",
},
{
Text: "Read the docs",
Position: 3,
LightIcon: "FileTextFilled",
DarkIcon: "FileTextOutlined",
Href: "https://signoz.io/docs",
},
},
},
}

View File

@@ -13,7 +13,6 @@ import (
"go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/migrate"
"go.signoz.io/signoz/pkg/query-service/version"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
@@ -70,7 +69,6 @@ func main() {
defer loggerMgr.Sync() // flushes buffer, if any
logger := loggerMgr.Sugar()
version.PrintVersion()
serverOptions := &app.ServerOptions{
HTTPHostPort: constants.HTTPHostPort,
@@ -89,15 +87,6 @@ func main() {
UseLogsNewSchema: useLogsNewSchema,
}
// Read the jwt secret key
auth.JwtSecret = os.Getenv("SIGNOZ_JWT_SECRET")
if len(auth.JwtSecret) == 0 {
zap.L().Warn("No JWT secret key is specified.")
} else {
zap.L().Info("JWT secret key set successfully.")
}
if err := migrate.Migrate(constants.RELATIONAL_DATASOURCE_PATH); err != nil {
zap.L().Error("Failed to migrate", zap.Error(err))
} else {
@@ -122,8 +111,6 @@ func main() {
for {
select {
case status := <-server.HealthCheckStatus():
logger.Info("Received HealthCheck status: ", zap.Int("status", int(status)))
case <-signalsChannel:
logger.Info("Received OS Interrupt Signal ... ")
err := server.Stop()

View File

@@ -19,7 +19,7 @@ import (
"go.signoz.io/signoz/pkg/query-service/interfaces"
"go.signoz.io/signoz/pkg/query-service/model"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
"go.signoz.io/signoz/pkg/query-service/version"
"go.signoz.io/signoz/pkg/version"
)
const (
@@ -591,7 +591,7 @@ func (a *Telemetry) SendEvent(event string, data map[string]interface{}, userEma
// zap.L().Info(data)
properties := analytics.NewProperties()
properties.Set("version", version.GetVersion())
properties.Set("version", version.Info.Version)
properties.Set("deploymentType", getDeploymentType())
properties.Set("companyDomain", a.getCompanyDomain())

View File

@@ -1,46 +0,0 @@
package version
import (
"fmt"
"runtime"
)
// These fields are set during an official build
// Global vars set from command-line arguments
var (
buildVersion = "--"
buildHash = "--"
buildTime = "--"
gitBranch = "--"
)
// BuildDetails returns a string containing details about the SigNoz query-service binary.
func BuildDetails() string {
licenseInfo := `Check SigNoz Github repo for license details`
return fmt.Sprintf(`
SigNoz version : %v
Commit SHA-1 : %v
Commit timestamp : %v
Branch : %v
Go version : %v
For SigNoz Official Documentation, visit https://signoz.io/docs/
For SigNoz Community Slack, visit http://signoz.io/slack/
For archive of discussions about SigNoz, visit https://knowledgebase.signoz.io/
%s.
Copyright 2024 SigNoz
`,
buildVersion, buildHash, buildTime, gitBranch,
runtime.Version(), licenseInfo)
}
// PrintVersion prints version and other helpful information.
func PrintVersion() {
fmt.Println(BuildDetails())
}
func GetVersion() string {
return buildVersion
}

27
pkg/version/config.go Normal file
View File

@@ -0,0 +1,27 @@
package version
import "go.signoz.io/signoz/pkg/confmap"
// Config satisfies the confmap.Config interface
var _ confmap.Config = (*Config)(nil)
// Config holds the configuration for all instrumentation components.
type Config struct {
Banner Banner `mapstructure:"banner"`
}
type Banner struct {
Enabled bool `mapstructure:"enabled"`
}
func (c *Config) NewWithDefaults() confmap.Config {
return &Config{
Banner: Banner{
Enabled: true,
},
}
}
func (c *Config) Validate() error {
return nil
}

View File

@@ -1,4 +1,3 @@
// Package version is used to track the build information of the application.
// This is typically set via ldflags at build time.
// Eg: -ldflags="-X 'pkg/version.Build.Version=v1.0.0'"
package version

View File

@@ -1,9 +1,136 @@
package version
import (
"fmt"
"runtime"
"strings"
)
// This is set via ldflags at build time.
var (
name string = "-------"
version string = "-------"
hash string = "-------"
time string = "-------"
branch string = "-------"
Info Build = Build{
Name: name,
Version: version,
Hash: hash,
Time: time,
Branch: branch,
GoVersion: runtime.Version(),
}
)
// Build contains information about the build environment.
type Build struct {
// The name of the current build.
Name string
// The version of the current build.
Version string
// The git hash of the current build.
Hash string
// The time of the current build.
Time string
// The branch of the current build.
Branch string
// The version of go.
GoVersion string
}
func (b Build) PrettyPrint() {
ascii := []string{
" -**********= ",
" .::-=+**********+=--:. ",
" .-=*******++=-----==+******=-. ",
" :-+*******=:. :-+******=: ",
" .-********+: .=*******=. ",
" :+********+: .=*******+: ",
" .+*********+ :+***+. -********+: ",
" -**********+. .****= =*********= ",
" .************: +**** +**********: ",
".************+ .----: -***********- ",
"*************= :************.",
":************+ ----: -***********= ",
" :************. ***** +**********: ",
" .=**********+ :****= -*********+. ",
" :+*********+ :+***+ -********+: ",
" :+********+. =*******+- ",
" :=********=. -*******=: ",
" :=*******+-. .-+******=-. ",
" :-+*******+=--:::--=+******+=: ",
" .:-==+***********+=-:: ",
" :**********= ",
}
fields := []struct {
key string
value string
}{
{"Name", b.Name},
{"Version", b.Version},
{"Commit Hash", b.Hash},
{"Commit Time", b.Time},
{"Branch", b.Branch},
{"Go Version", b.GoVersion},
}
maxKeyLength := 0
for _, field := range fields {
if len(field.key) > maxKeyLength {
maxKeyLength = len(field.key)
}
}
maxAsciiWidth := 0
for _, line := range ascii {
if len(line) > maxAsciiWidth {
maxAsciiWidth = len(line)
}
}
panelWidth := maxKeyLength + 30 // Adjust this value to change panel width
fmt.Println()
for i, line := range ascii {
fmt.Print(line)
fmt.Print(" ")
if i == 0 || i == 2 {
fmt.Printf("%s\n", strings.Repeat("-", panelWidth))
continue
}
if i == 1 {
txt := "Starting SigNoz"
fmt.Printf("| %-*s |\n", panelWidth-4, txt)
continue
}
if i-3 >= 0 && i-3 < len(fields) {
field := fields[i-3]
fmt.Printf("| %-*s : %-*s |", maxKeyLength, field.key, panelWidth-maxKeyLength-7, field.value)
} else if i == len(fields)+3 {
fmt.Print(strings.Repeat("-", panelWidth))
} else if i > 2 && i < len(fields)+4 {
fmt.Printf("|%-*s|", panelWidth-2, "")
}
fmt.Println()
}
fmt.Println()
// for i := 0; i < len(ascii); i++ {
// if i < len(fields) {
// fmt.Printf("%-9s %-*s : %s\n", ascii[i], maxKeyLength, fields[i].key, fields[i].value)
// } else {
// fmt.Printf("%-9s\n", ascii[i])
// }
// }
// // Print remaining fields if any
// for i := len(ascii); i < len(fields); i++ {
// fmt.Printf("%9s %-*s : %s\n", "", maxKeyLength, fields[i].key, fields[i].value)
// }
// fmt.Printf("\n")
}