Compare commits

..

2 Commits

Author SHA1 Message Date
Aditya Singh
8715fc8b5a Merge branch 'main' into feat/table-escape-char-support 2026-04-10 15:04:27 +05:30
aks07
b68d36c4a2 feat: add support for \n and \t in table view logs 2026-04-10 14:54:51 +05:30
13 changed files with 1 additions and 996 deletions

View File

@@ -22,6 +22,7 @@ export const TableBodyContent = styled.div<TableBodyContentProps>`
-webkit-line-clamp: ${(props): number => props.linesPerRow};
line-clamp: ${(props): number => props.linesPerRow};
-webkit-box-orient: vertical;
white-space: pre-wrap;
${({ fontSize }): string =>
fontSize === FontSize.SMALL
? `font-size:11px; line-height:16px;`

View File

@@ -1,180 +0,0 @@
package signozapiserver
import (
"net/http"
"github.com/SigNoz/signoz/pkg/http/handler"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/aio11ymappingtypes"
"github.com/gorilla/mux"
)
func (provider *provider) addAIO11yMappingRoutes(router *mux.Router) error {
// --- Mapping Groups ---
if err := router.Handle("/api/v1/ai-o11y/mapping/groups", handler.New(
provider.authZ.ViewAccess(provider.aio11yMappingHandler.ListGroups),
handler.OpenAPIDef{
ID: "ListMappingGroups",
Tags: []string{"ai-o11y"},
Summary: "List mapping groups",
Description: "Returns all span attribute mapping groups for the authenticated org.",
Request: nil,
RequestContentType: "",
RequestQuery: new(aio11ymappingtypes.ListMappingGroupsQuery),
Response: new(aio11ymappingtypes.ListMappingGroupsResponse),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
},
)).Methods(http.MethodGet).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v1/ai-o11y/mapping/groups", handler.New(
provider.authZ.AdminAccess(provider.aio11yMappingHandler.CreateGroup),
handler.OpenAPIDef{
ID: "CreateMappingGroup",
Tags: []string{"ai-o11y"},
Summary: "Create a mapping group",
Description: "Creates a new span attribute mapping group for the org.",
Request: new(aio11ymappingtypes.PostableMappingGroup),
RequestContentType: "application/json",
Response: new(aio11ymappingtypes.GettableMappingGroup),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusCreated,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusConflict},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
},
)).Methods(http.MethodPost).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v1/ai-o11y/mapping/groups/{id}", handler.New(
provider.authZ.AdminAccess(provider.aio11yMappingHandler.UpdateGroup),
handler.OpenAPIDef{
ID: "UpdateMappingGroup",
Tags: []string{"ai-o11y"},
Summary: "Update a mapping group",
Description: "Partially updates an existing mapping group's name, condition, or enabled state.",
Request: new(aio11ymappingtypes.UpdatableMappingGroup),
RequestContentType: "application/json",
Response: new(aio11ymappingtypes.GettableMappingGroup),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
},
)).Methods(http.MethodPut).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v1/ai-o11y/mapping/groups/{id}", handler.New(
provider.authZ.AdminAccess(provider.aio11yMappingHandler.DeleteGroup),
handler.OpenAPIDef{
ID: "DeleteMappingGroup",
Tags: []string{"ai-o11y"},
Summary: "Delete a mapping group",
Description: "Hard-deletes a mapping group and cascades to all its mappers.",
Request: nil,
RequestContentType: "",
Response: nil,
ResponseContentType: "",
SuccessStatusCode: http.StatusNoContent,
ErrorStatusCodes: []int{http.StatusNotFound},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
},
)).Methods(http.MethodDelete).GetError(); err != nil {
return err
}
// --- Mappers ---
if err := router.Handle("/api/v1/ai-o11y/mapping/groups/{id}/mappers", handler.New(
provider.authZ.ViewAccess(provider.aio11yMappingHandler.ListMappers),
handler.OpenAPIDef{
ID: "ListMappers",
Tags: []string{"ai-o11y"},
Summary: "List mappers for a group",
Description: "Returns all attribute mappers belonging to a mapping group.",
Request: nil,
RequestContentType: "",
RequestQuery: new(aio11ymappingtypes.ListMappersQuery),
Response: new(aio11ymappingtypes.ListMappersResponse),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleViewer),
},
)).Methods(http.MethodGet).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v1/ai-o11y/mapping/groups/{id}/mappers", handler.New(
provider.authZ.AdminAccess(provider.aio11yMappingHandler.CreateMapper),
handler.OpenAPIDef{
ID: "CreateMapper",
Tags: []string{"ai-o11y"},
Summary: "Create a mapper",
Description: "Adds a new attribute mapper to the specified mapping group.",
Request: new(aio11ymappingtypes.PostableMapper),
RequestContentType: "application/json",
Response: new(aio11ymappingtypes.GettableMapper),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusCreated,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound, http.StatusConflict},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
},
)).Methods(http.MethodPost).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v1/ai-o11y/mapping/groups/{groupId}/mappers/{mapperId}", handler.New(
provider.authZ.AdminAccess(provider.aio11yMappingHandler.UpdateMapper),
handler.OpenAPIDef{
ID: "UpdateMapper",
Tags: []string{"ai-o11y"},
Summary: "Update a mapper",
Description: "Partially updates an existing mapper's field context, config, or enabled state.",
Request: new(aio11ymappingtypes.UpdatableMapper),
RequestContentType: "application/json",
Response: new(aio11ymappingtypes.GettableMapper),
ResponseContentType: "application/json",
SuccessStatusCode: http.StatusOK,
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
},
)).Methods(http.MethodPut).GetError(); err != nil {
return err
}
if err := router.Handle("/api/v1/ai-o11y/mapping/groups/{groupId}/mappers/{mapperId}", handler.New(
provider.authZ.AdminAccess(provider.aio11yMappingHandler.DeleteMapper),
handler.OpenAPIDef{
ID: "DeleteMapper",
Tags: []string{"ai-o11y"},
Summary: "Delete a mapper",
Description: "Hard-deletes a mapper from a mapping group.",
Request: nil,
RequestContentType: "",
Response: nil,
ResponseContentType: "",
SuccessStatusCode: http.StatusNoContent,
ErrorStatusCodes: []int{http.StatusNotFound},
Deprecated: false,
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
},
)).Methods(http.MethodDelete).GetError(); err != nil {
return err
}
return nil
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/http/handler"
"github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/modules/aio11ymapping"
"github.com/SigNoz/signoz/pkg/modules/authdomain"
"github.com/SigNoz/signoz/pkg/modules/cloudintegration"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
@@ -58,7 +57,6 @@ type provider struct {
factoryHandler factory.Handler
cloudIntegrationHandler cloudintegration.Handler
ruleStateHistoryHandler rulestatehistory.Handler
aio11yMappingHandler aio11ymapping.Handler
}
func NewFactory(
@@ -85,7 +83,6 @@ func NewFactory(
factoryHandler factory.Handler,
cloudIntegrationHandler cloudintegration.Handler,
ruleStateHistoryHandler rulestatehistory.Handler,
aio11yMappingHandler aio11ymapping.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(
@@ -115,7 +112,6 @@ func NewFactory(
factoryHandler,
cloudIntegrationHandler,
ruleStateHistoryHandler,
aio11yMappingHandler,
)
})
}
@@ -147,7 +143,6 @@ func newProvider(
factoryHandler factory.Handler,
cloudIntegrationHandler cloudintegration.Handler,
ruleStateHistoryHandler rulestatehistory.Handler,
aio11yMappingHandler aio11ymapping.Handler,
) (apiserver.APIServer, error) {
settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/apiserver/signozapiserver")
router := mux.NewRouter().UseEncodedPath()
@@ -177,7 +172,6 @@ func newProvider(
factoryHandler: factoryHandler,
cloudIntegrationHandler: cloudIntegrationHandler,
ruleStateHistoryHandler: ruleStateHistoryHandler,
aio11yMappingHandler: aio11yMappingHandler,
}
provider.authZ = middleware.NewAuthZ(settings.Logger(), orgGetter, authz)
@@ -278,10 +272,6 @@ func (provider *provider) AddToRouter(router *mux.Router) error {
return err
}
if err := provider.addAIO11yMappingRoutes(router); err != nil {
return err
}
return nil
}

View File

@@ -1,43 +0,0 @@
package aio11ymapping
import (
"context"
"net/http"
"github.com/SigNoz/signoz/pkg/types/aio11ymappingtypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
// Module defines the business logic for span attribute mapping groups and mappers.
type Module interface {
// Group operations
ListGroups(ctx context.Context, orgID valuer.UUID, q *aio11ymappingtypes.ListMappingGroupsQuery) ([]*aio11ymappingtypes.MappingGroup, error)
GetGroup(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*aio11ymappingtypes.MappingGroup, error)
CreateGroup(ctx context.Context, orgID valuer.UUID, createdBy string, req *aio11ymappingtypes.PostableMappingGroup) (*aio11ymappingtypes.MappingGroup, error)
UpdateGroup(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, req *aio11ymappingtypes.UpdatableMappingGroup) (*aio11ymappingtypes.MappingGroup, error)
DeleteGroup(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error
// Mapper operations
ListMappers(ctx context.Context, orgID valuer.UUID, groupID valuer.UUID, q *aio11ymappingtypes.ListMappersQuery) ([]*aio11ymappingtypes.Mapper, error)
GetMapper(ctx context.Context, orgID valuer.UUID, groupID valuer.UUID, id valuer.UUID) (*aio11ymappingtypes.Mapper, error)
CreateMapper(ctx context.Context, orgID valuer.UUID, groupID valuer.UUID, createdBy string, req *aio11ymappingtypes.PostableMapper) (*aio11ymappingtypes.Mapper, error)
UpdateMapper(ctx context.Context, orgID valuer.UUID, groupID valuer.UUID, id valuer.UUID, updatedBy string, req *aio11ymappingtypes.UpdatableMapper) (*aio11ymappingtypes.Mapper, error)
DeleteMapper(ctx context.Context, orgID valuer.UUID, groupID valuer.UUID, id valuer.UUID) error
}
// Handler defines the HTTP handler interface for mapping group and mapper endpoints.
type Handler interface {
// Group handlers
ListGroups(rw http.ResponseWriter, r *http.Request)
CreateGroup(rw http.ResponseWriter, r *http.Request)
UpdateGroup(rw http.ResponseWriter, r *http.Request)
DeleteGroup(rw http.ResponseWriter, r *http.Request)
// Mapper handlers
ListMappers(rw http.ResponseWriter, r *http.Request)
CreateMapper(rw http.ResponseWriter, r *http.Request)
UpdateMapper(rw http.ResponseWriter, r *http.Request)
DeleteMapper(rw http.ResponseWriter, r *http.Request)
}

View File

@@ -1,356 +0,0 @@
package impiaio11ymapping
import (
"context"
"net/http"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/http/binding"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/modules/aio11ymapping"
"github.com/SigNoz/signoz/pkg/types/aio11ymappingtypes"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/gorilla/mux"
)
type handler struct {
module aio11ymapping.Module
providerSettings factory.ProviderSettings
}
func NewHandler(module aio11ymapping.Module, providerSettings factory.ProviderSettings) aio11ymapping.Handler {
return &handler{module: module, providerSettings: providerSettings}
}
// ListGroups handles GET /api/v1/ai-o11y/mapping/groups.
func (h *handler) ListGroups(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
var q aio11ymappingtypes.ListMappingGroupsQuery
if err := binding.Query.BindQuery(r.URL.Query(), &q); err != nil {
render.Error(rw, err)
return
}
groups, err := h.module.ListGroups(ctx, orgID, &q)
if err != nil {
render.Error(rw, err)
return
}
items := make([]*aio11ymappingtypes.GettableMappingGroup, len(groups))
for i, g := range groups {
items[i] = aio11ymappingtypes.NewGettableMappingGroup(g)
}
render.Success(rw, http.StatusOK, &aio11ymappingtypes.ListMappingGroupsResponse{Items: items})
}
// CreateGroup handles POST /api/v1/ai-o11y/mapping/groups.
func (h *handler) CreateGroup(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
req := new(aio11ymappingtypes.PostableMappingGroup)
if err := binding.JSON.BindBody(r.Body, req); err != nil {
render.Error(rw, err)
return
}
group, err := h.module.CreateGroup(ctx, orgID, claims.Email, req)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusCreated, aio11ymappingtypes.NewGettableMappingGroup(group))
}
// UpdateGroup handles PUT /api/v1/ai-o11y/mapping/groups/{id}.
func (h *handler) UpdateGroup(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
id, err := groupIDFromPath(r)
if err != nil {
render.Error(rw, err)
return
}
req := new(aio11ymappingtypes.UpdatableMappingGroup)
if err := binding.JSON.BindBody(r.Body, req); err != nil {
render.Error(rw, err)
return
}
group, err := h.module.UpdateGroup(ctx, orgID, id, claims.Email, req)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, aio11ymappingtypes.NewGettableMappingGroup(group))
}
// DeleteGroup handles DELETE /api/v1/ai-o11y/mapping/groups/{id}.
func (h *handler) DeleteGroup(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
id, err := groupIDFromPath(r)
if err != nil {
render.Error(rw, err)
return
}
if err := h.module.DeleteGroup(ctx, orgID, id); err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusNoContent, nil)
}
// ListMappers handles GET /api/v1/ai-o11y/mapping/groups/{id}/mappers.
func (h *handler) ListMappers(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
groupID, err := groupIDFromPath(r)
if err != nil {
render.Error(rw, err)
return
}
var q aio11ymappingtypes.ListMappersQuery
if err := binding.Query.BindQuery(r.URL.Query(), &q); err != nil {
render.Error(rw, err)
return
}
mappers, err := h.module.ListMappers(ctx, orgID, groupID, &q)
if err != nil {
render.Error(rw, err)
return
}
items := make([]*aio11ymappingtypes.GettableMapper, len(mappers))
for i, m := range mappers {
items[i] = aio11ymappingtypes.NewGettableMapper(m)
}
render.Success(rw, http.StatusOK, &aio11ymappingtypes.ListMappersResponse{Items: items})
}
// CreateMapper handles POST /api/v1/ai-o11y/mapping/groups/{id}/mappers.
func (h *handler) CreateMapper(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
groupID, err := groupIDFromPath(r)
if err != nil {
render.Error(rw, err)
return
}
req := new(aio11ymappingtypes.PostableMapper)
if err := binding.JSON.BindBody(r.Body, req); err != nil {
render.Error(rw, err)
return
}
mapper, err := h.module.CreateMapper(ctx, orgID, groupID, claims.Email, req)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusCreated, aio11ymappingtypes.NewGettableMapper(mapper))
}
// UpdateMapper handles PUT /api/v1/ai-o11y/mapping/groups/{groupId}/mappers/{mapperId}.
func (h *handler) UpdateMapper(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
groupID, err := groupIDFromPath(r)
if err != nil {
render.Error(rw, err)
return
}
mapperID, err := mapperIDFromPath(r)
if err != nil {
render.Error(rw, err)
return
}
req := new(aio11ymappingtypes.UpdatableMapper)
if err := binding.JSON.BindBody(r.Body, req); err != nil {
render.Error(rw, err)
return
}
mapper, err := h.module.UpdateMapper(ctx, orgID, groupID, mapperID, claims.Email, req)
if err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusOK, aio11ymappingtypes.NewGettableMapper(mapper))
}
// DeleteMapper handles DELETE /api/v1/ai-o11y/mapping/groups/{groupId}/mappers/{mapperId}.
func (h *handler) DeleteMapper(rw http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
render.Error(rw, err)
return
}
orgID, err := valuer.NewUUID(claims.OrgID)
if err != nil {
render.Error(rw, err)
return
}
groupID, err := groupIDFromPath(r)
if err != nil {
render.Error(rw, err)
return
}
mapperID, err := mapperIDFromPath(r)
if err != nil {
render.Error(rw, err)
return
}
if err := h.module.DeleteMapper(ctx, orgID, groupID, mapperID); err != nil {
render.Error(rw, err)
return
}
render.Success(rw, http.StatusNoContent, nil)
}
// groupIDFromPath extracts and validates the {id} or {groupId} path variable.
func groupIDFromPath(r *http.Request) (valuer.UUID, error) {
vars := mux.Vars(r)
raw := vars["groupId"]
if raw == "" {
raw = vars["id"]
}
if raw == "" {
return valuer.UUID{}, errors.Newf(errors.TypeInvalidInput, aio11ymappingtypes.ErrCodeMappingInvalidInput, "group id is missing from the path")
}
id, err := valuer.NewUUID(raw)
if err != nil {
return valuer.UUID{}, errors.Wrapf(err, errors.TypeInvalidInput, aio11ymappingtypes.ErrCodeMappingInvalidInput, "group id is not a valid uuid")
}
return id, nil
}
// mapperIDFromPath extracts and validates the {mapperId} path variable.
func mapperIDFromPath(r *http.Request) (valuer.UUID, error) {
raw := mux.Vars(r)["mapperId"]
if raw == "" {
return valuer.UUID{}, errors.Newf(errors.TypeInvalidInput, aio11ymappingtypes.ErrCodeMappingInvalidInput, "mapper id is missing from the path")
}
id, err := valuer.NewUUID(raw)
if err != nil {
return valuer.UUID{}, errors.Wrapf(err, errors.TypeInvalidInput, aio11ymappingtypes.ErrCodeMappingInvalidInput, "mapper id is not a valid uuid")
}
return id, nil
}

View File

@@ -10,7 +10,6 @@ import (
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/global/signozglobal"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/modules/aio11ymapping"
"github.com/SigNoz/signoz/pkg/modules/apdex"
"github.com/SigNoz/signoz/pkg/modules/apdex/implapdex"
"github.com/SigNoz/signoz/pkg/modules/cloudintegration"
@@ -63,7 +62,6 @@ type Handlers struct {
RegistryHandler factory.Handler
CloudIntegrationHandler cloudintegration.Handler
RuleStateHistory rulestatehistory.Handler
AIO11yMappingHandler aio11ymapping.Handler
}
func NewHandlers(

View File

@@ -16,7 +16,6 @@ import (
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/http/handler"
"github.com/SigNoz/signoz/pkg/instrumentation"
"github.com/SigNoz/signoz/pkg/modules/aio11ymapping"
"github.com/SigNoz/signoz/pkg/modules/authdomain"
"github.com/SigNoz/signoz/pkg/modules/cloudintegration"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
@@ -70,7 +69,6 @@ func NewOpenAPI(ctx context.Context, instrumentation instrumentation.Instrumenta
struct{ factory.Handler }{},
struct{ cloudintegration.Handler }{},
struct{ rulestatehistory.Handler }{},
struct{ aio11ymapping.Handler }{},
).New(ctx, instrumentation.ToProviderSettings(), apiserver.Config{})
if err != nil {
return nil, err

View File

@@ -288,7 +288,6 @@ func NewAPIServerProviderFactories(orgGetter organization.Getter, authz authz.Au
handlers.RegistryHandler,
handlers.CloudIntegrationHandler,
handlers.RuleStateHistory,
handlers.AIO11yMappingHandler,
),
)
}

View File

@@ -1,11 +0,0 @@
package aio11ymappingtypes
import "github.com/SigNoz/signoz/pkg/errors"
var (
ErrCodeMappingGroupNotFound = errors.MustNewCode("mapping_group_not_found")
ErrCodeMappingGroupAlreadyExists = errors.MustNewCode("mapping_group_already_exists")
ErrCodeMapperNotFound = errors.MustNewCode("mapper_not_found")
ErrCodeMapperAlreadyExists = errors.MustNewCode("mapper_already_exists")
ErrCodeMappingInvalidInput = errors.MustNewCode("mapping_invalid_input")
)

View File

@@ -1,147 +0,0 @@
package aio11ymappingtypes
import (
"database/sql/driver"
"encoding/json"
"fmt"
"time"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/valuer"
)
type GroupCategory string
const (
GroupCategoryLLM GroupCategory = "llm"
GroupCategoryTool GroupCategory = "tool"
GroupCategoryAgent GroupCategory = "agent"
)
func (GroupCategory) Enum() []any {
return []any{GroupCategoryLLM, GroupCategoryTool, GroupCategoryAgent}
}
// Condition is the trigger condition for a mapping group.
// A group runs when any of the listed attribute/resource key patterns match.
// It implements driver.Valuer and sql.Scanner for JSON text column storage.
type Condition struct {
Attributes []string `json:"attributes"`
Resource []string `json:"resource"`
}
func (c Condition) Value() (driver.Value, error) {
b, err := json.Marshal(c)
if err != nil {
return nil, err
}
return string(b), nil
}
func (c *Condition) Scan(src any) error {
var raw []byte
switch v := src.(type) {
case string:
raw = []byte(v)
case []byte:
raw = v
case nil:
*c = Condition{}
return nil
default:
return fmt.Errorf("aio11ymappingtypes: cannot scan %T into Condition", src)
}
return json.Unmarshal(raw, c)
}
// MappingGroup is the domain model for a span attribute mapping group.
// It has no serialisation concerns — use GettableMappingGroup for HTTP responses.
type MappingGroup struct {
types.TimeAuditable
types.UserAuditable
ID string
OrgID valuer.UUID
Name string
Category GroupCategory
Condition Condition
Enabled bool
}
// NewMappingGroupFromStorable converts a StorableMappingGroup to a MappingGroup.
func NewMappingGroupFromStorable(s *StorableMappingGroup) *MappingGroup {
return &MappingGroup{
TimeAuditable: s.TimeAuditable,
UserAuditable: s.UserAuditable,
ID: s.ID.StringValue(),
OrgID: s.OrgID,
Name: s.Name,
Category: s.Category,
Condition: s.Condition,
Enabled: s.Enabled,
}
}
// NewMappingGroupsFromStorable converts a slice of StorableMappingGroup to a slice of MappingGroup.
func NewMappingGroupsFromStorable(ss []*StorableMappingGroup) []*MappingGroup {
groups := make([]*MappingGroup, len(ss))
for i, s := range ss {
groups[i] = NewMappingGroupFromStorable(s)
}
return groups
}
// GettableMappingGroup is the HTTP response representation of a mapping group.
type GettableMappingGroup struct {
ID string `json:"id" required:"true"`
Name string `json:"name" required:"true"`
Category GroupCategory `json:"category" required:"true"`
Condition Condition `json:"condition" required:"true"`
Enabled bool `json:"enabled" required:"true"`
CreatedAt time.Time `json:"created_at" required:"true"`
UpdatedAt time.Time `json:"updated_at" required:"true"`
CreatedBy string `json:"created_by" required:"true"`
UpdatedBy string `json:"updated_by" required:"true"`
}
// NewGettableMappingGroup converts a domain MappingGroup to a GettableMappingGroup.
func NewGettableMappingGroup(g *MappingGroup) *GettableMappingGroup {
return &GettableMappingGroup{
ID: g.ID,
Name: g.Name,
Category: g.Category,
Condition: g.Condition,
Enabled: g.Enabled,
CreatedAt: g.CreatedAt,
UpdatedAt: g.UpdatedAt,
CreatedBy: g.CreatedBy,
UpdatedBy: g.UpdatedBy,
}
}
// PostableMappingGroup is the HTTP request body for creating a mapping group.
type PostableMappingGroup struct {
Name string `json:"name" required:"true"`
Category GroupCategory `json:"category" required:"true"`
Condition Condition `json:"condition" required:"true"`
Enabled bool `json:"enabled"`
}
// UpdatableMappingGroup is the HTTP request body for updating a mapping group.
// All fields are optional; only non-nil fields are applied.
type UpdatableMappingGroup struct {
Name *string `json:"name,omitempty"`
Condition *Condition `json:"condition,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
}
// ListMappingGroupsQuery holds optional filter parameters for listing mapping groups.
type ListMappingGroupsQuery struct {
Category *GroupCategory `query:"category"`
Enabled *bool `query:"enabled"`
}
// ListMappingGroupsResponse is the response for listing mapping groups.
type ListMappingGroupsResponse struct {
Items []*GettableMappingGroup `json:"items" required:"true" nullable:"true"`
}

View File

@@ -1,183 +0,0 @@
package aio11ymappingtypes
import (
"database/sql/driver"
"encoding/json"
"fmt"
"time"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/valuer"
)
// FieldContext is where the target attribute is written.
type FieldContext string
const (
FieldContextSpanAttribute FieldContext = "span_attribute"
FieldContextResource FieldContext = "resource"
)
func (FieldContext) Enum() []any {
return []any{FieldContextSpanAttribute, FieldContextResource}
}
// MapperOperation determines whether the source attribute is moved (deleted) or copied.
type MapperOperation string
const (
MapperOperationMove MapperOperation = "move"
MapperOperationCopy MapperOperation = "copy"
)
func (MapperOperation) Enum() []any {
return []any{MapperOperationMove, MapperOperationCopy}
}
// SourceContext indicates whether the source key is read from span attributes or resource attributes.
type SourceContext string
const (
SourceContextAttribute SourceContext = "attribute"
SourceContextResource SourceContext = "resource"
)
func (SourceContext) Enum() []any {
return []any{SourceContextAttribute, SourceContextResource}
}
// MapperSource describes one candidate source for a target attribute.
type MapperSource struct {
// Key is the span/resource attribute key to read from.
Key string `json:"key"`
// Context indicates whether to read from span attributes or resource attributes.
Context SourceContext `json:"context"`
// Operation determines whether to move or copy the source value.
Operation MapperOperation `json:"operation"`
// Priority controls the evaluation order; lower value = higher priority.
Priority int `json:"priority"`
}
// MapperConfig holds the mapping logic for a single target attribute.
// It implements driver.Valuer and sql.Scanner for JSON text column storage.
type MapperConfig struct {
Sources []MapperSource `json:"sources"`
}
func (m MapperConfig) Value() (driver.Value, error) {
b, err := json.Marshal(m)
if err != nil {
return nil, err
}
return string(b), nil
}
func (m *MapperConfig) Scan(src any) error {
var raw []byte
switch v := src.(type) {
case string:
raw = []byte(v)
case []byte:
raw = v
case nil:
*m = MapperConfig{}
return nil
default:
return fmt.Errorf("aio11ymappingtypes: cannot scan %T into MapperConfig", src)
}
return json.Unmarshal(raw, m)
}
// Mapper is the domain model for a span attribute mapper.
type Mapper struct {
types.TimeAuditable
types.UserAuditable
ID string
OrgID valuer.UUID
GroupID valuer.UUID
Name string
FieldContext FieldContext
Config MapperConfig
Enabled bool
}
// NewMapperFromStorable converts a StorableMapper to a Mapper.
func NewMapperFromStorable(s *StorableMapper) *Mapper {
return &Mapper{
TimeAuditable: s.TimeAuditable,
UserAuditable: s.UserAuditable,
ID: s.ID.StringValue(),
OrgID: s.OrgID,
GroupID: s.GroupID,
Name: s.Name,
FieldContext: s.FieldContext,
Config: s.Config,
Enabled: s.Enabled,
}
}
// NewMappersFromStorable converts a slice of StorableMapper to a slice of Mapper.
func NewMappersFromStorable(ss []*StorableMapper) []*Mapper {
mappers := make([]*Mapper, len(ss))
for i, s := range ss {
mappers[i] = NewMapperFromStorable(s)
}
return mappers
}
// GettableMapper is the HTTP response representation of a mapper.
type GettableMapper struct {
ID string `json:"id" required:"true"`
GroupID string `json:"group_id" required:"true"`
Name string `json:"name" required:"true"`
FieldContext FieldContext `json:"field_context" required:"true"`
Config MapperConfig `json:"config" required:"true"`
Enabled bool `json:"enabled" required:"true"`
CreatedAt time.Time `json:"created_at" required:"true"`
UpdatedAt time.Time `json:"updated_at" required:"true"`
CreatedBy string `json:"created_by" required:"true"`
UpdatedBy string `json:"updated_by" required:"true"`
}
// NewGettableMapper converts a domain Mapper to a GettableMapper.
func NewGettableMapper(m *Mapper) *GettableMapper {
return &GettableMapper{
ID: m.ID,
GroupID: m.GroupID.StringValue(),
Name: m.Name,
FieldContext: m.FieldContext,
Config: m.Config,
Enabled: m.Enabled,
CreatedAt: m.CreatedAt,
UpdatedAt: m.UpdatedAt,
CreatedBy: m.CreatedBy,
UpdatedBy: m.UpdatedBy,
}
}
// PostableMapper is the HTTP request body for creating a mapper.
type PostableMapper struct {
Name string `json:"name" required:"true"`
FieldContext FieldContext `json:"field_context" required:"true"`
Config MapperConfig `json:"config" required:"true"`
Enabled bool `json:"enabled"`
}
// UpdatableMapper is the HTTP request body for updating a mapper.
// All fields are optional; only non-nil fields are applied.
type UpdatableMapper struct {
FieldContext *FieldContext `json:"field_context,omitempty"`
Config *MapperConfig `json:"config,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
}
// ListMappersQuery holds optional filter parameters for listing mappers in a group.
type ListMappersQuery struct {
Enabled *bool `query:"enabled"`
}
// ListMappersResponse is the response for listing mappers within a group.
type ListMappersResponse struct {
Items []*GettableMapper `json:"items" required:"true" nullable:"true"`
}

View File

@@ -1,38 +0,0 @@
package aio11ymappingtypes
import (
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/uptrace/bun"
)
// StorableMappingGroup is the bun/DB representation of a span attribute mapping group.
type StorableMappingGroup struct {
bun.BaseModel `bun:"table:span_attribute_mapping_group,alias:span_attribute_mapping_group"`
types.Identifiable
types.TimeAuditable
types.UserAuditable
OrgID valuer.UUID `bun:"org_id,type:text,notnull"`
Name string `bun:"name,type:text,notnull"`
Category GroupCategory `bun:"category,type:text,notnull"`
Condition Condition `bun:"condition,type:text,notnull"`
Enabled bool `bun:"enabled,notnull,default:true"`
}
// StorableMapper is the bun/DB representation of a span attribute mapper.
type StorableMapper struct {
bun.BaseModel `bun:"table:span_mapping_attribute,alias:span_mapping_attribute"`
types.Identifiable
types.TimeAuditable
types.UserAuditable
OrgID valuer.UUID `bun:"org_id,type:text,notnull"`
GroupID valuer.UUID `bun:"group_id,type:text,notnull"`
Name string `bun:"name,type:text,notnull"`
FieldContext FieldContext `bun:"field_context,type:text,notnull"`
Config MapperConfig `bun:"config,type:text,notnull"`
Enabled bool `bun:"enabled,notnull,default:true"`
}

View File

@@ -1,23 +0,0 @@
package aio11ymappingtypes
import (
"context"
"github.com/SigNoz/signoz/pkg/valuer"
)
type Store interface {
// Group operations
ListGroups(ctx context.Context, orgID valuer.UUID, q *ListMappingGroupsQuery) ([]*StorableMappingGroup, error)
GetGroup(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*StorableMappingGroup, error)
CreateGroup(ctx context.Context, group *StorableMappingGroup) error
UpdateGroup(ctx context.Context, group *StorableMappingGroup) error
DeleteGroup(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error
// Mapper operations
ListMappers(ctx context.Context, orgID valuer.UUID, groupID valuer.UUID, q *ListMappersQuery) ([]*StorableMapper, error)
GetMapper(ctx context.Context, orgID valuer.UUID, groupID valuer.UUID, id valuer.UUID) (*StorableMapper, error)
CreateMapper(ctx context.Context, mapper *StorableMapper) error
UpdateMapper(ctx context.Context, mapper *StorableMapper) error
DeleteMapper(ctx context.Context, orgID valuer.UUID, groupID valuer.UUID, id valuer.UUID) error
}