Compare commits
40 Commits
variables-
...
176/coales
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72c7fd3454 | ||
|
|
761eed7be8 | ||
|
|
96bf51a951 | ||
|
|
cd4085d134 | ||
|
|
1758c7b7be | ||
|
|
1680fe1c96 | ||
|
|
23db133b74 | ||
|
|
d70e400605 | ||
|
|
b6e2c26022 | ||
|
|
f0c054f372 | ||
|
|
83b8c5ad2e | ||
|
|
487935817a | ||
|
|
c047abb951 | ||
|
|
633c5dbc83 | ||
|
|
ed3180f84c | ||
|
|
6b6512c993 | ||
|
|
df4e5c043f | ||
|
|
72c6d7c3d7 | ||
|
|
e827b6993d | ||
|
|
77dd908fde | ||
|
|
949b71837e | ||
|
|
8a92a81416 | ||
|
|
3fd8c67999 | ||
|
|
0dccd20ea0 | ||
|
|
fb78937956 | ||
|
|
f9aa333c4d | ||
|
|
062b87c11d | ||
|
|
3d61df370c | ||
|
|
22005f1561 | ||
|
|
ba0c896e87 | ||
|
|
b74843c380 | ||
|
|
3496ec2bb2 | ||
|
|
9e4b3718ba | ||
|
|
863c86d33f | ||
|
|
02d337da6b | ||
|
|
dd0dd0167c | ||
|
|
b15db358cc | ||
|
|
dd06ad44d6 | ||
|
|
29b33cf13c | ||
|
|
b06a24f2d6 |
29
cmd/signoz/config.go
Normal file
29
cmd/signoz/config.go
Normal 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
101
cmd/signoz/main.go
Normal 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
125
conf/defaults.yaml
Normal 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
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
2
go.mod
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
41
pkg/query-service/app/clickhouseReader/config.go
Normal file
41
pkg/query-service/app/clickhouseReader/config.go
Normal 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
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
25
pkg/query-service/app/opamp/config.go
Normal file
25
pkg/query-service/app/opamp/config.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
23
pkg/query-service/auth/config.go
Normal file
23
pkg/query-service/auth/config.go
Normal 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
32
pkg/query-service/cache/config.go
vendored
Normal 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
|
||||
}
|
||||
@@ -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 (
|
||||
|
||||
19
pkg/query-service/dao/config.go
Normal file
19
pkg/query-service/dao/config.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
@@ -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
27
pkg/version/config.go
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user