Compare commits

...

4 Commits

Author SHA1 Message Date
vikrantgupta25
c5daa4e0c1 feat(ingestion): use consistent naming for handler instead of API 2025-12-16 14:27:14 +05:30
vikrantgupta25
4b930a3288 feat(ingestion): update apiserver config tests 2025-12-16 14:15:19 +05:30
vikrantgupta25
de4699644d feat(ingestion): update the openapi spec 2025-12-16 14:05:03 +05:30
vikrantgupta25
034260e974 feat(ingestion): add ingestion and api server url to config 2025-12-16 14:01:10 +05:30
17 changed files with 264 additions and 6 deletions

View File

@@ -473,6 +473,49 @@ paths:
summary: Get reset password token
tags:
- users
/api/v1/ingestion:
get:
deprecated: false
description: This endpoints returns ingestion details
operationId: GetIngestion
responses:
"200":
content:
application/json:
schema:
properties:
data:
$ref: '#/components/schemas/IngestiontypesGettableIngestion'
status:
type: string
type: object
description: OK
"401":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Unauthorized
"403":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Forbidden
"500":
content:
application/json:
schema:
$ref: '#/components/schemas/RenderErrorResponse'
description: Internal Server Error
security:
- api_key:
- EDITOR
- tokenizer:
- EDITOR
summary: Get ingestion details
tags:
- ingestion
/api/v1/invite:
get:
deprecated: false
@@ -2065,6 +2108,11 @@ components:
message:
type: string
type: object
IngestiontypesGettableIngestion:
properties:
url:
type: string
type: object
PreferencetypesPreference:
properties:
allowedScopes:

View File

@@ -1,6 +1,7 @@
package apiserver
import (
"net/url"
"time"
"github.com/SigNoz/signoz/pkg/factory"
@@ -10,6 +11,7 @@ import (
type Config struct {
Timeout Timeout `mapstructure:"timeout"`
Logging Logging `mapstructure:"logging"`
Web Web `mapstructure:"web"`
}
type Timeout struct {
@@ -26,6 +28,11 @@ type Logging struct {
ExcludedRoutes []string `mapstructure:"excluded_routes"`
}
type Web struct {
// the url under which apiserver is externally reachable (for example, if apiserver is served via a reverse proxy).
ExternalURL *url.URL `mapstructure:"external_url"`
}
func NewConfigFactory() factory.ConfigFactory {
return factory.NewConfigFactory(factory.MustNewName("apiserver"), newConfig)
}
@@ -48,6 +55,12 @@ func newConfig() factory.Config {
"/",
},
},
Web: Web{
ExternalURL: &url.URL{
Scheme: "http",
Host: "localhost:8080",
},
},
}
}

View File

@@ -2,6 +2,7 @@ package apiserver
import (
"context"
"net/url"
"testing"
"time"
@@ -17,6 +18,7 @@ func TestNewWithEnvProvider(t *testing.T) {
t.Setenv("SIGNOZ_APISERVER_TIMEOUT_MAX", "700s")
t.Setenv("SIGNOZ_APISERVER_TIMEOUT_EXCLUDED__ROUTES", "/excluded1,/excluded2")
t.Setenv("SIGNOZ_APISERVER_LOGGING_EXCLUDED__ROUTES", "/api/v1/health1")
t.Setenv("SIGNOZ_APISERVER_WEB_EXTERNAL__URL", "https://test.com")
conf, err := config.New(
context.Background(),
@@ -51,6 +53,12 @@ func TestNewWithEnvProvider(t *testing.T) {
"/api/v1/health1",
},
},
Web: Web{
ExternalURL: &url.URL{
Scheme: "https",
Host: "test.com",
},
},
}
assert.Equal(t, expected, actual)

View File

@@ -0,0 +1,31 @@
package signozapiserver
import (
"net/http"
"github.com/SigNoz/signoz/pkg/http/handler"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/ingestiontypes"
"github.com/gorilla/mux"
)
func (provider *provider) addIngestionRoutes(router *mux.Router) error {
if err := router.Handle("/api/v1/ingestion", handler.New(provider.authZ.EditAccess(provider.ingestionHandler.Get), handler.OpenAPIDef{
ID: "GetIngestion",
Tags: []string{"ingestion"},
Summary: "Get ingestion details",
Description: "This endpoints returns ingestion details",
Request: nil,
RequestContentType: "",
Response: new(ingestiontypes.GettableIngestion),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleEditor),
})).Methods(http.MethodGet).GetError(); err != nil {
return err
}
return nil
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/http/handler"
"github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/ingestion"
"github.com/SigNoz/signoz/pkg/modules/authdomain"
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/preference"
@@ -28,6 +29,7 @@ type provider struct {
sessionHandler session.Handler
authDomainHandler authdomain.Handler
preferenceHandler preference.Handler
ingestionHandler ingestion.Handler
}
func NewFactory(
@@ -38,9 +40,10 @@ func NewFactory(
sessionHandler session.Handler,
authDomainHandler authdomain.Handler,
preferenceHandler preference.Handler,
ingestionHandler ingestion.Handler,
) factory.ProviderFactory[apiserver.APIServer, apiserver.Config] {
return factory.NewProviderFactory(factory.MustNewName("signoz"), func(ctx context.Context, providerSettings factory.ProviderSettings, config apiserver.Config) (apiserver.APIServer, error) {
return newProvider(ctx, providerSettings, config, orgGetter, authz, orgHandler, userHandler, sessionHandler, authDomainHandler, preferenceHandler)
return newProvider(ctx, providerSettings, config, orgGetter, authz, orgHandler, userHandler, sessionHandler, authDomainHandler, preferenceHandler, ingestionHandler)
})
}
@@ -55,6 +58,7 @@ func newProvider(
sessionHandler session.Handler,
authDomainHandler authdomain.Handler,
preferenceHandler preference.Handler,
ingestionHandler ingestion.Handler,
) (apiserver.APIServer, error) {
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/apiserver/signozapiserver")
router := mux.NewRouter().UseEncodedPath()
@@ -68,6 +72,7 @@ func newProvider(
sessionHandler: sessionHandler,
authDomainHandler: authDomainHandler,
preferenceHandler: preferenceHandler,
ingestionHandler: ingestionHandler,
}
provider.authZ = middleware.NewAuthZ(settings.Logger(), orgGetter, authz)
@@ -104,6 +109,10 @@ func (provider *provider) AddToRouter(router *mux.Router) error {
return err
}
if err := provider.addIngestionRoutes(router); err != nil {
return err
}
return nil
}

39
pkg/ingestion/config.go Normal file
View File

@@ -0,0 +1,39 @@
package ingestion
import (
"net/url"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
)
var (
ErrCodeInvalidIngestionConfig = errors.MustNewCode("invalid_ingestion_config")
)
type Config struct {
URL *url.URL `mapstructure:"url"`
}
func NewConfigFactory() factory.ConfigFactory {
return factory.NewConfigFactory(factory.MustNewName("ingestion"), newConfig)
}
func newConfig() factory.Config {
return &Config{
URL: &url.URL{
Scheme: "http",
Host: "localhost:8080",
Path: "/",
},
}
}
func (c Config) Validate() error {
if c.URL == nil {
return errors.New(errors.TypeInvalidInput, ErrCodeInvalidIngestionConfig, "url is required")
}
return nil
}

View File

@@ -0,0 +1,13 @@
package ingestion
import (
"net/http"
)
type Ingestion interface {
GetConfig() Config
}
type Handler interface {
Get(http.ResponseWriter, *http.Request)
}

View File

@@ -0,0 +1,23 @@
package signozingestion
import (
"net/http"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/ingestion"
"github.com/SigNoz/signoz/pkg/types/ingestiontypes"
)
type signozapi struct {
ingestion ingestion.Ingestion
}
func NewHandler(ingestion ingestion.Ingestion) ingestion.Handler {
return &signozapi{ingestion: ingestion}
}
func (api *signozapi) Get(rw http.ResponseWriter, r *http.Request) {
cfg := api.ingestion.GetConfig()
render.Success(rw, http.StatusOK, ingestiontypes.NewGettableIngestion(cfg.URL))
}

View File

@@ -0,0 +1,31 @@
package signozingestion
import (
"context"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/ingestion"
)
type provider struct {
config ingestion.Config
settings factory.ScopedProviderSettings
}
func NewFactory() factory.ProviderFactory[ingestion.Ingestion, ingestion.Config] {
return factory.NewProviderFactory(factory.MustNewName("signoz"), func(ctx context.Context, providerSettings factory.ProviderSettings, config ingestion.Config) (ingestion.Ingestion, error) {
return newProvider(ctx, providerSettings, config)
})
}
func newProvider(_ context.Context, providerSettings factory.ProviderSettings, config ingestion.Config) (ingestion.Ingestion, error) {
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/ingestion/signozingestion")
return &provider{
config: config,
settings: settings,
}, nil
}
func (provider *provider) GetConfig() ingestion.Config {
return provider.config
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/gateway"
"github.com/SigNoz/signoz/pkg/ingestion"
"github.com/SigNoz/signoz/pkg/instrumentation"
"github.com/SigNoz/signoz/pkg/modules/metricsexplorer"
"github.com/SigNoz/signoz/pkg/prometheus"
@@ -101,6 +102,9 @@ type Config struct {
// MetricsExplorer config
MetricsExplorer metricsexplorer.Config `mapstructure:"metricsexplorer"`
// Ingestion config
Ingestion ingestion.Config `mapstructure:"ingestion"`
}
// DeprecatedFlags are the flags that are deprecated and scheduled for removal.
@@ -161,6 +165,7 @@ func NewConfig(ctx context.Context, logger *slog.Logger, resolverConfig config.R
gateway.NewConfigFactory(),
tokenizer.NewConfigFactory(),
metricsexplorer.NewConfigFactory(),
ingestion.NewConfigFactory(),
}
conf, err := config.New(ctx, resolverConfig, configFactories)

View File

@@ -2,6 +2,8 @@ package signoz
import (
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/ingestion"
"github.com/SigNoz/signoz/pkg/ingestion/signozingestion"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/modules/apdex"
"github.com/SigNoz/signoz/pkg/modules/apdex/implapdex"
@@ -34,9 +36,10 @@ type Handlers struct {
SpanPercentile spanpercentile.Handler
Services services.Handler
MetricsExplorer metricsexplorer.Handler
Ingestion ingestion.Handler
}
func NewHandlers(modules Modules, providerSettings factory.ProviderSettings, querier querier.Querier, licensing licensing.Licensing) Handlers {
func NewHandlers(modules Modules, providerSettings factory.ProviderSettings, querier querier.Querier, licensing licensing.Licensing, ingestion ingestion.Ingestion) Handlers {
return Handlers{
SavedView: implsavedview.NewHandler(modules.SavedView),
Apdex: implapdex.NewHandler(modules.Apdex),
@@ -47,5 +50,6 @@ func NewHandlers(modules Modules, providerSettings factory.ProviderSettings, que
Services: implservices.NewHandler(modules.Services),
MetricsExplorer: implmetricsexplorer.NewHandler(modules.MetricsExplorer),
SpanPercentile: implspanpercentile.NewHandler(modules.SpanPercentile),
Ingestion: signozingestion.NewHandler(ingestion),
}
}

View File

@@ -38,7 +38,7 @@ func TestNewHandlers(t *testing.T) {
require.NoError(t, err)
modules := NewModules(sqlstore, tokenizer, emailing, providerSettings, orgGetter, alertmanager, nil, nil, nil, nil, nil, nil, nil, Config{})
handlers := NewHandlers(modules, providerSettings, nil, nil)
handlers := NewHandlers(modules, providerSettings, nil, nil, nil)
reflectVal := reflect.ValueOf(handlers)
for i := 0; i < reflectVal.NumField(); i++ {

View File

@@ -9,6 +9,7 @@ import (
"github.com/SigNoz/signoz/pkg/apiserver/signozapiserver"
"github.com/SigNoz/signoz/pkg/authz"
"github.com/SigNoz/signoz/pkg/http/handler"
"github.com/SigNoz/signoz/pkg/ingestion"
"github.com/SigNoz/signoz/pkg/instrumentation"
"github.com/SigNoz/signoz/pkg/modules/authdomain"
"github.com/SigNoz/signoz/pkg/modules/organization"
@@ -36,6 +37,7 @@ func NewOpenAPI(ctx context.Context, instrumentation instrumentation.Instrumenta
struct{ session.Handler }{},
struct{ authdomain.Handler }{},
struct{ preference.Handler }{},
struct{ ingestion.Handler }{},
).New(ctx, instrumentation.ToProviderSettings(), apiserver.Config{})
if err != nil {
return nil, err

View File

@@ -18,6 +18,8 @@ import (
"github.com/SigNoz/signoz/pkg/emailing/noopemailing"
"github.com/SigNoz/signoz/pkg/emailing/smtpemailing"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/ingestion"
"github.com/SigNoz/signoz/pkg/ingestion/signozingestion"
"github.com/SigNoz/signoz/pkg/modules/authdomain/implauthdomain"
"github.com/SigNoz/signoz/pkg/modules/organization"
"github.com/SigNoz/signoz/pkg/modules/organization/implorganization"
@@ -221,7 +223,7 @@ func NewQuerierProviderFactories(telemetryStore telemetrystore.TelemetryStore, p
)
}
func NewAPIServerProviderFactories(orgGetter organization.Getter, authz authz.AuthZ, modules Modules, handlers Handlers) factory.NamedMap[factory.ProviderFactory[apiserver.APIServer, apiserver.Config]] {
func NewAPIServerProviderFactories(orgGetter organization.Getter, authz authz.AuthZ, ingestion ingestion.Ingestion, modules Modules, handlers Handlers) factory.NamedMap[factory.ProviderFactory[apiserver.APIServer, apiserver.Config]] {
return factory.MustNewNamedMap(
signozapiserver.NewFactory(
orgGetter,
@@ -231,6 +233,7 @@ func NewAPIServerProviderFactories(orgGetter organization.Getter, authz authz.Au
implsession.NewHandler(modules.Session),
implauthdomain.NewHandler(modules.AuthDomain),
implpreference.NewHandler(modules.Preference),
signozingestion.NewHandler(ingestion),
),
)
}
@@ -242,3 +245,9 @@ func NewTokenizerProviderFactories(cache cache.Cache, sqlstore sqlstore.SQLStore
jwttokenizer.NewFactory(cache, tokenStore),
)
}
func NewIngestionProviderFactories() factory.NamedMap[factory.ProviderFactory[ingestion.Ingestion, ingestion.Config]] {
return factory.MustNewNamedMap(
signozingestion.NewFactory(),
)
}

View File

@@ -83,6 +83,7 @@ func TestNewProviderFactories(t *testing.T) {
NewAPIServerProviderFactories(
implorganization.NewGetter(implorganization.NewStore(sqlstoretest.New(sqlstore.Config{Provider: "sqlite"}, sqlmock.QueryMatcherEqual)), nil),
nil,
nil,
Modules{},
Handlers{},
)

View File

@@ -345,18 +345,29 @@ func New(
telemetrymetadata.AttributesMetadataLocalTableName,
)
ingestion, err := factory.NewProviderFromNamedMap(
ctx,
providerSettings,
config.Ingestion,
NewIngestionProviderFactories(),
"signoz",
)
if err != nil {
return nil, err
}
// Initialize all modules
modules := NewModules(sqlstore, tokenizer, emailing, providerSettings, orgGetter, alertmanager, analytics, querier, telemetrystore, telemetryMetadataStore, authNs, authz, cache, config)
// Initialize all handlers for the modules
handlers := NewHandlers(modules, providerSettings, querier, licensing)
handlers := NewHandlers(modules, providerSettings, querier, licensing, ingestion)
// Initialize the API server
apiserver, err := factory.NewProviderFromNamedMap(
ctx,
providerSettings,
config.APIServer,
NewAPIServerProviderFactories(orgGetter, authz, modules, handlers),
NewAPIServerProviderFactories(orgGetter, authz, ingestion, modules, handlers),
"signoz",
)
if err != nil {

View File

@@ -0,0 +1,11 @@
package ingestiontypes
import "net/url"
type GettableIngestion struct {
URL string `json:"url"`
}
func NewGettableIngestion(url *url.URL) *GettableIngestion {
return &GettableIngestion{URL: url.String()}
}