diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index e7123b8710..7fd0bb1828 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -57,6 +57,17 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + - name: Create .env file + run: | + echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env + echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env + echo 'SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> frontend/.env + echo 'SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> frontend/.env + echo 'SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> frontend/.env + echo 'SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> frontend/.env + echo 'TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> frontend/.env + echo 'TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> frontend/.env + echo 'POSTHOG_KEY="${{ secrets.POSTHOG_KEY }}"' >> frontend/.env - name: Setup golang uses: actions/setup-go@v4 with: diff --git a/Makefile b/Makefile index 2b2e47c9fa..c7dd0e4a9a 100644 --- a/Makefile +++ b/Makefile @@ -98,12 +98,12 @@ build-query-service-static-arm64: # Steps to build static binary of query service for all platforms .PHONY: build-query-service-static-all -build-query-service-static-all: build-query-service-static-amd64 build-query-service-static-arm64 +build-query-service-static-all: build-query-service-static-amd64 build-query-service-static-arm64 build-frontend-static # Steps to build and push docker image of query service .PHONY: build-query-service-amd64 build-push-query-service # Step to build docker image of query service in amd64 (used in build pipeline) -build-query-service-amd64: build-query-service-static-amd64 +build-query-service-amd64: build-query-service-static-amd64 build-frontend-static @echo "------------------" @echo "--> Building query-service docker image for amd64" @echo "------------------" diff --git a/conf/defaults.yaml b/conf/defaults.yaml new file mode 100644 index 0000000000..dd571e89fb --- /dev/null +++ b/conf/defaults.yaml @@ -0,0 +1,11 @@ +##################### SigNoz Configuration Defaults ##################### +# +# Do not modify this file +# + +##################### Web ##################### +web: + # The prefix to serve web on + prefix: / + # The directory containing the static build files. + directory: /etc/signoz/web \ No newline at end of file diff --git a/ee/query-service/Dockerfile b/ee/query-service/Dockerfile index 5c8f2f6f35..ae4b260f9a 100644 --- a/ee/query-service/Dockerfile +++ b/ee/query-service/Dockerfile @@ -23,6 +23,9 @@ COPY pkg/query-service/templates /root/templates # Make query-service executable for non-root users RUN chmod 755 /root /root/query-service +# Copy frontend +COPY frontend/build/ /etc/signoz/web/ + # run the binary ENTRYPOINT ["./query-service"] diff --git a/ee/query-service/app/server.go b/ee/query-service/app/server.go index 938b72b5a3..5f36aaaf66 100644 --- a/ee/query-service/app/server.go +++ b/ee/query-service/app/server.go @@ -32,6 +32,7 @@ import ( baseauth "go.signoz.io/signoz/pkg/query-service/auth" "go.signoz.io/signoz/pkg/query-service/migrate" v3 "go.signoz.io/signoz/pkg/query-service/model/v3" + "go.signoz.io/signoz/pkg/web" licensepkg "go.signoz.io/signoz/ee/query-service/license" "go.signoz.io/signoz/ee/query-service/usage" @@ -107,7 +108,7 @@ func (s Server) HealthCheckStatus() chan healthcheck.Status { } // NewServer creates and initializes Server -func NewServer(serverOptions *ServerOptions) (*Server, error) { +func NewServer(serverOptions *ServerOptions, web *web.Web) (*Server, error) { modelDao, err := dao.InitDao("sqlite", baseconst.RELATIONAL_DATASOURCE_PATH) if err != nil { @@ -289,7 +290,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) { usageManager: usageManager, } - httpServer, err := s.createPublicServer(apiHandler) + httpServer, err := s.createPublicServer(apiHandler, web) if err != nil { return nil, err @@ -338,7 +339,7 @@ func (s *Server) createPrivateServer(apiHandler *api.APIHandler) (*http.Server, }, nil } -func (s *Server) createPublicServer(apiHandler *api.APIHandler) (*http.Server, error) { +func (s *Server) createPublicServer(apiHandler *api.APIHandler, web *web.Web) (*http.Server, error) { r := baseapp.NewRouter() @@ -382,6 +383,11 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler) (*http.Server, e handler = handlers.CompressHandler(handler) + err := web.AddToRouter(r) + if err != nil { + return nil, err + } + return &http.Server{ Handler: handler, }, nil diff --git a/ee/query-service/main.go b/ee/query-service/main.go index a93a034f87..5fbbca1e18 100644 --- a/ee/query-service/main.go +++ b/ee/query-service/main.go @@ -10,13 +10,17 @@ import ( "syscall" "time" + "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/otel/sdk/resource" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "go.signoz.io/signoz/ee/query-service/app" + signozconfig "go.signoz.io/signoz/pkg/config" + "go.signoz.io/signoz/pkg/confmap/provider/signozenvprovider" "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" + signozweb "go.signoz.io/signoz/pkg/web" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -131,6 +135,23 @@ func main() { version.PrintVersion() + config, err := signozconfig.New(context.Background(), signozconfig.ProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: []string{"signozenv:"}, + ProviderFactories: []confmap.ProviderFactory{ + signozenvprovider.NewFactory(), + }, + }, + }) + if err != nil { + zap.L().Fatal("Failed to create config", zap.Error(err)) + } + + web, err := signozweb.New(zap.L(), config.Web) + if err != nil { + zap.L().Fatal("Failed to create web", zap.Error(err)) + } + serverOptions := &app.ServerOptions{ HTTPHostPort: baseconst.HTTPHostPort, PromConfigPath: promConfigPath, @@ -165,7 +186,7 @@ func main() { zap.L().Info("Migration successful") } - server, err := app.NewServer(serverOptions) + server, err := app.NewServer(serverOptions, web) if err != nil { zap.L().Fatal("Failed to create server", zap.Error(err)) } diff --git a/pkg/config/config.go b/pkg/config/config.go index 02cc7c37c2..6d88cacb61 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -3,10 +3,19 @@ package config import ( "context" + signozconfmap "go.signoz.io/signoz/pkg/confmap" "go.signoz.io/signoz/pkg/instrumentation" "go.signoz.io/signoz/pkg/web" ) +// This map contains the default values of all config structs +var ( + defaults = map[string]signozconfmap.Config{ + "instrumentation": &instrumentation.Config{}, + "web": &web.Config{}, + } +) + // Config defines the entire configuration of signoz. type Config struct { Instrumentation instrumentation.Config `mapstructure:"instrumentation"` @@ -21,15 +30,3 @@ 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 - } - -} diff --git a/pkg/config/unmarshaler.go b/pkg/config/unmarshaler.go index 8392f83462..69cec77193 100644 --- a/pkg/config/unmarshaler.go +++ b/pkg/config/unmarshaler.go @@ -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. @@ -19,22 +18,14 @@ func unmarshal(conf *confmap.Conf) (*Config, error) { 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) - } - + // To help the defaults kick in, we need iterate over the default map instead of the raw values + for k, v := range defaults { 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) } diff --git a/pkg/config/unmarshaler_test.go b/pkg/config/unmarshaler_test.go index 1627bbcf96..651510eba8 100644 --- a/pkg/config/unmarshaler_test.go +++ b/pkg/config/unmarshaler_test.go @@ -9,7 +9,7 @@ import ( "go.signoz.io/signoz/pkg/instrumentation" ) -func TestUnmarshal(t *testing.T) { +func TestUnmarshalForInstrumentation(t *testing.T) { input := confmap.NewFromStringMap( map[string]any{ "instrumentation": map[string]any{ @@ -29,6 +29,5 @@ 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) }