chore(sqlmigration): drop the rule history and data migrations table (#8181)

This commit is contained in:
Vikrant Gupta 2025-06-09 15:46:22 +05:30 committed by GitHub
parent 0acbcf8322
commit decb660992
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 120 additions and 123 deletions

View File

@ -6,11 +6,7 @@ import { Filters } from 'components/AlertDetailsFilters/Filters';
import NotFound from 'components/NotFound';
import RouteTab from 'components/RouteTab';
import Spinner from 'components/Spinner';
import { QueryParams } from 'constants/query';
import ROUTES from 'constants/routes';
import { useNotifications } from 'hooks/useNotifications';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import history from 'lib/history';
import { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@ -74,9 +70,6 @@ BreadCrumbItem.defaultProps = {
function AlertDetails(): JSX.Element {
const { pathname } = useLocation();
const { routes } = useRouteTabUtils();
const urlQuery = useUrlQuery();
const { safeNavigate } = useSafeNavigate();
const { notifications } = useNotifications();
const {
isLoading,
@ -92,27 +85,6 @@ function AlertDetails(): JSX.Element {
document.title = alertTitle || document.title;
}, [alertDetailsResponse?.payload?.data.alert, isRefetching]);
useEffect(() => {
if (alertDetailsResponse?.payload?.data?.id) {
const ruleUUID = alertDetailsResponse.payload.data.id;
if (ruleId !== ruleUUID) {
urlQuery.set(QueryParams.ruleId, ruleUUID);
const generatedUrl = `${window.location.pathname}?${urlQuery}`;
notifications.info({
message:
"We're transitioning alert rule IDs from integers to UUIDs.Both old and new alert links will continue to work after this change - existing notifications using integer IDs will remain functional while new alerts will use the UUID format. Please use the updated link in the URL for future references",
});
safeNavigate(generatedUrl);
}
}
}, [
alertDetailsResponse?.payload?.data.id,
notifications,
ruleId,
safeNavigate,
urlQuery,
]);
if (
isError ||
!isValidRuleId ||

View File

@ -660,7 +660,13 @@ func Intersection(a, b []int) (c []int) {
}
func (aH *APIHandler) getRule(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"]
idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
ruleResponse, err := aH.ruleManager.GetRule(r.Context(), id)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
@ -990,9 +996,15 @@ func (aH *APIHandler) metaForLinks(ctx context.Context, rule *ruletypes.Gettable
}
func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request) {
ruleID := mux.Vars(r)["id"]
idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
params := model.QueryRuleStateHistory{}
err := json.NewDecoder(r.Body).Decode(&params)
err = json.NewDecoder(r.Body).Decode(&params)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
@ -1002,13 +1014,13 @@ func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request
return
}
res, err := aH.reader.ReadRuleStateHistoryByRuleID(r.Context(), ruleID, &params)
res, err := aH.reader.ReadRuleStateHistoryByRuleID(r.Context(), id.StringValue(), &params)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
return
}
rule, err := aH.ruleManager.GetRule(r.Context(), ruleID)
rule, err := aH.ruleManager.GetRule(r.Context(), id)
if err == nil {
for idx := range res.Items {
lbls := make(map[string]string)
@ -1036,21 +1048,27 @@ func (aH *APIHandler) getRuleStateHistory(w http.ResponseWriter, r *http.Request
}
func (aH *APIHandler) getRuleStateHistoryTopContributors(w http.ResponseWriter, r *http.Request) {
ruleID := mux.Vars(r)["id"]
params := model.QueryRuleStateHistory{}
err := json.NewDecoder(r.Body).Decode(&params)
idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
res, err := aH.reader.ReadRuleStateHistoryTopContributorsByRuleID(r.Context(), ruleID, &params)
params := model.QueryRuleStateHistory{}
err = json.NewDecoder(r.Body).Decode(&params)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
res, err := aH.reader.ReadRuleStateHistoryTopContributorsByRuleID(r.Context(), id.StringValue(), &params)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
return
}
rule, err := aH.ruleManager.GetRule(r.Context(), ruleID)
rule, err := aH.ruleManager.GetRule(r.Context(), id)
if err == nil {
for idx := range res {
lbls := make(map[string]string)
@ -1330,7 +1348,12 @@ func (aH *APIHandler) deleteRule(w http.ResponseWriter, r *http.Request) {
// patchRule updates only requested changes in the rule
func (aH *APIHandler) patchRule(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"]
idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
defer r.Body.Close()
body, err := io.ReadAll(r.Body)
@ -1351,7 +1374,12 @@ func (aH *APIHandler) patchRule(w http.ResponseWriter, r *http.Request) {
}
func (aH *APIHandler) editRule(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"]
idStr := mux.Vars(r)["id"]
id, err := valuer.NewUUID(idStr)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return
}
defer r.Body.Close()
body, err := io.ReadAll(r.Body)

View File

@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"sort"
"strconv"
"strings"
"sync"
"time"
@ -320,7 +319,7 @@ func (m *Manager) Stop(ctx context.Context) {
// EditRuleDefinition writes the rule definition to the
// datastore and also updates the rule executor
func (m *Manager) EditRule(ctx context.Context, ruleStr string, idStr string) error {
func (m *Manager) EditRule(ctx context.Context, ruleStr string, id valuer.UUID) error {
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
return err
@ -330,26 +329,12 @@ func (m *Manager) EditRule(ctx context.Context, ruleStr string, idStr string) er
return err
}
ruleUUID, err := valuer.NewUUID(idStr)
if err != nil {
id, err := strconv.Atoi(idStr)
if err != nil {
return err
}
ruleHistory, err := m.ruleStore.GetRuleUUID(ctx, id)
if err != nil {
return err
}
ruleUUID = ruleHistory.RuleUUID
}
parsedRule, err := ruletypes.ParsePostableRule([]byte(ruleStr))
if err != nil {
return err
}
existingRule, err := m.ruleStore.GetStoredRule(ctx, ruleUUID)
existingRule, err := m.ruleStore.GetStoredRule(ctx, id)
if err != nil {
return err
}
@ -378,7 +363,7 @@ func (m *Manager) EditRule(ctx context.Context, ruleStr string, idStr string) er
preferredChannels = parsedRule.PreferredChannels
}
err = cfg.UpdateRuleIDMatcher(ruleUUID.StringValue(), preferredChannels)
err = cfg.UpdateRuleIDMatcher(id.StringValue(), preferredChannels)
if err != nil {
return err
}
@ -826,22 +811,8 @@ func (m *Manager) ListRuleStates(ctx context.Context) (*ruletypes.GettableRules,
return &ruletypes.GettableRules{Rules: resp}, nil
}
func (m *Manager) GetRule(ctx context.Context, idStr string) (*ruletypes.GettableRule, error) {
ruleUUID, err := valuer.NewUUID(idStr)
if err != nil {
id, err := strconv.Atoi(idStr)
if err != nil {
return nil, err
}
ruleHistory, err := m.ruleStore.GetRuleUUID(ctx, id)
if err != nil {
return nil, err
}
ruleUUID = ruleHistory.RuleUUID
}
s, err := m.ruleStore.GetStoredRule(ctx, ruleUUID)
func (m *Manager) GetRule(ctx context.Context, id valuer.UUID) (*ruletypes.GettableRule, error) {
s, err := m.ruleStore.GetStoredRule(ctx, id)
if err != nil {
return nil, err
}
@ -849,7 +820,7 @@ func (m *Manager) GetRule(ctx context.Context, idStr string) (*ruletypes.Gettabl
if err := json.Unmarshal([]byte(s.Data), r); err != nil {
return nil, err
}
r.Id = ruleUUID.StringValue()
r.Id = id.StringValue()
// fetch state of rule from memory
if rm, ok := m.rules[r.Id]; !ok {
r.State = model.StateDisabled
@ -899,7 +870,7 @@ func (m *Manager) syncRuleStateWithTask(ctx context.Context, orgID valuer.UUID,
// - over write the patch attributes received in input (ruleStr)
// - re-deploy or undeploy task as necessary
// - update the patched rule in the DB
func (m *Manager) PatchRule(ctx context.Context, ruleStr string, ruleIdStr string) (*ruletypes.GettableRule, error) {
func (m *Manager) PatchRule(ctx context.Context, ruleStr string, id valuer.UUID) (*ruletypes.GettableRule, error) {
claims, err := authtypes.ClaimsFromContext(ctx)
if err != nil {
return nil, err
@ -910,24 +881,19 @@ func (m *Manager) PatchRule(ctx context.Context, ruleStr string, ruleIdStr strin
return nil, err
}
ruleID, err := valuer.NewUUID(ruleIdStr)
if err != nil {
return nil, errors.New(err.Error())
}
taskName := prepareTaskName(ruleID.StringValue())
taskName := prepareTaskName(id.StringValue())
// retrieve rule from DB
storedJSON, err := m.ruleStore.GetStoredRule(ctx, ruleID)
storedJSON, err := m.ruleStore.GetStoredRule(ctx, id)
if err != nil {
zap.L().Error("failed to get stored rule with given id", zap.String("id", ruleID.StringValue()), zap.Error(err))
zap.L().Error("failed to get stored rule with given id", zap.String("id", id.StringValue()), zap.Error(err))
return nil, err
}
// storedRule holds the current stored rule from DB
storedRule := ruletypes.PostableRule{}
if err := json.Unmarshal([]byte(storedJSON.Data), &storedRule); err != nil {
zap.L().Error("failed to unmarshal stored rule with given id", zap.String("id", ruleID.StringValue()), zap.Error(err))
zap.L().Error("failed to unmarshal stored rule with given id", zap.String("id", id.StringValue()), zap.Error(err))
return nil, err
}
@ -964,12 +930,12 @@ func (m *Manager) PatchRule(ctx context.Context, ruleStr string, ruleIdStr strin
// prepare http response
response := ruletypes.GettableRule{
Id: ruleID.StringValue(),
Id: id.StringValue(),
PostableRule: *patchedRule,
}
// fetch state of rule from memory
if rm, ok := m.rules[ruleID.StringValue()]; !ok {
if rm, ok := m.rules[id.StringValue()]; !ok {
response.State = model.StateDisabled
response.Disabled = true
} else {

View File

@ -103,17 +103,3 @@ func (r *rule) GetStoredRule(ctx context.Context, id valuer.UUID) (*ruletypes.Ru
}
return rule, nil
}
func (r *rule) GetRuleUUID(ctx context.Context, ruleID int) (*ruletypes.RuleHistory, error) {
ruleHistory := new(ruletypes.RuleHistory)
err := r.sqlstore.
BunDB().
NewSelect().
Model(ruleHistory).
Where("rule_id = ?", ruleID).
Scan(ctx)
if err != nil {
return nil, err
}
return ruleHistory, nil
}

View File

@ -91,6 +91,7 @@ func NewSQLMigrationProviderFactories(sqlstore sqlstore.SQLStore) factory.NamedM
sqlmigration.NewAddTraceFunnelsFactory(sqlstore),
sqlmigration.NewUpdateDashboardFactory(sqlstore),
sqlmigration.NewDropFeatureSetFactory(),
sqlmigration.NewDropDeprecatedTablesFactory(),
)
}

View File

@ -0,0 +1,66 @@
package sqlmigration
import (
"context"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/uptrace/bun"
"github.com/uptrace/bun/migrate"
)
type dropDeprecatedTables struct{}
func NewDropDeprecatedTablesFactory() factory.ProviderFactory[SQLMigration, Config] {
return factory.NewProviderFactory(factory.MustNewName("drop_deprecated_tables"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return newDropDeprecatedTables(ctx, ps, c)
})
}
func newDropDeprecatedTables(_ context.Context, _ factory.ProviderSettings, _ Config) (SQLMigration, error) {
return &dropDeprecatedTables{}, nil
}
func (migration *dropDeprecatedTables) Register(migrations *migrate.Migrations) error {
if err := migrations.Register(migration.Up, migration.Down); err != nil {
return err
}
return nil
}
func (migration *dropDeprecatedTables) Up(ctx context.Context, db *bun.DB) error {
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer func() {
_ = tx.Rollback()
}()
if _, err := tx.
NewDropTable().
IfExists().
Table("rule_history").
Exec(ctx); err != nil {
return err
}
if _, err := tx.
NewDropTable().
IfExists().
Table("data_migrations").
Exec(ctx); err != nil {
return err
}
if err := tx.Commit(); err != nil {
return err
}
return nil
}
func (migration *dropDeprecatedTables) Down(context.Context, *bun.DB) error {
return nil
}

View File

@ -1,15 +0,0 @@
package types
import (
"time"
"github.com/uptrace/bun"
)
type DataMigration struct {
bun.BaseModel `bun:"table:data_migrations"`
ID int `bun:"id,pk,autoincrement"`
Version string `bun:"version,unique,notnull,type:VARCHAR(255)"`
CreatedAt time.Time `bun:"created_at,notnull,default:current_timestamp"`
Succeeded bool `bun:"succeeded,notnull,default:false"`
}

View File

@ -18,17 +18,10 @@ type Rule struct {
OrgID string `bun:"org_id,type:text"`
}
type RuleHistory struct {
bun.BaseModel `bun:"table:rule_history"`
RuleID int `bun:"rule_id"`
RuleUUID valuer.UUID `bun:"rule_uuid"`
}
type RuleStore interface {
CreateRule(context.Context, *Rule, func(context.Context, valuer.UUID) error) (valuer.UUID, error)
EditRule(context.Context, *Rule, func(context.Context) error) error
DeleteRule(context.Context, valuer.UUID, func(context.Context) error) error
GetStoredRules(context.Context, string) ([]*Rule, error)
GetStoredRule(context.Context, valuer.UUID) (*Rule, error)
GetRuleUUID(context.Context, int) (*RuleHistory, error)
}