Skip to content

Commit

Permalink
feat(alertmanager): add service for alertmanager (#7136)
Browse files Browse the repository at this point in the history
### Summary

- adds an alertmanager service
  • Loading branch information
grandwizard28 authored Feb 18, 2025
1 parent 7e1301b commit 918c894
Show file tree
Hide file tree
Showing 13 changed files with 884 additions and 57 deletions.
25 changes: 25 additions & 0 deletions pkg/alertmanager/alertmanager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package alertmanager

import (
"context"

"go.signoz.io/signoz/pkg/errors"
"go.signoz.io/signoz/pkg/factory"
"go.signoz.io/signoz/pkg/types/alertmanagertypes"
)

var (
ErrCodeAlertmanagerNotFound = errors.MustNewCode("alertmanager_not_found")
)

type Alertmanager interface {
factory.Service
// GetAlerts gets the alerts from the alertmanager per organization.
GetAlerts(context.Context, string, alertmanagertypes.GettableAlertsParams) (alertmanagertypes.GettableAlerts, error)

// PutAlerts puts the alerts into the alertmanager per organization.
PutAlerts(context.Context, string, alertmanagertypes.PostableAlerts) error

// TestReceiver sends a test alert to a receiver.
TestReceiver(context.Context, string, alertmanagertypes.Receiver) error
}
100 changes: 100 additions & 0 deletions pkg/alertmanager/alertmanagerstore/sqlalertmanagerstore/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package sqlalertmanagerstore

import (
"context"
"database/sql"

"go.signoz.io/signoz/pkg/errors"
"go.signoz.io/signoz/pkg/sqlstore"
"go.signoz.io/signoz/pkg/types/alertmanagertypes"
)

type config struct {
sqlstore sqlstore.SQLStore
}

func NewConfigStore(sqlstore sqlstore.SQLStore) alertmanagertypes.ConfigStore {
return &config{sqlstore: sqlstore}
}

// Get implements alertmanagertypes.ConfigStore.
func (store *config) Get(ctx context.Context, orgID string) (*alertmanagertypes.Config, error) {
storeableConfig := new(alertmanagertypes.StoreableConfig)

err := store.
sqlstore.
BunDB().
NewSelect().
Model(storeableConfig).
Where("org_id = ?", orgID).
Scan(ctx)
if err != nil {
if err == sql.ErrNoRows {
return nil, errors.Newf(errors.TypeNotFound, alertmanagertypes.ErrCodeAlertmanagerConfigNotFound, "cannot find alertmanager config for orgID %s", orgID)
}

return nil, err
}

cfg, err := alertmanagertypes.NewConfigFromStoreableConfig(storeableConfig)
if err != nil {
return nil, err
}

return cfg, nil
}

// Set implements alertmanagertypes.ConfigStore.
func (store *config) Set(ctx context.Context, config *alertmanagertypes.Config) error {
tx, err := store.sqlstore.BunDB().BeginTx(ctx, nil)
if err != nil {
return err
}

defer tx.Rollback() //nolint:errcheck

if _, err = tx.
NewInsert().
Model(config.StoreableConfig()).
On("CONFLICT (org_id) DO UPDATE").
Set("config = ?", string(config.StoreableConfig().Config)).
Set("updated_at = ?", config.StoreableConfig().UpdatedAt).
Exec(ctx); err != nil {
return err
}

channels := config.Channels()
if len(channels) != 0 {
if _, err = tx.NewInsert().
Model(&channels).
On("CONFLICT (name) DO UPDATE").
Set("data = EXCLUDED.data").
Set("updated_at = EXCLUDED.updated_at").
Exec(ctx); err != nil {
return err
}
}

if err = tx.Commit(); err != nil {
return err
}

return nil
}

func (store *config) ListOrgs(ctx context.Context) ([]string, error) {
var orgIDs []string

err := store.
sqlstore.
BunDB().
NewSelect().
Table("organizations").
ColumnExpr("id").
Scan(ctx, &orgIDs)
if err != nil {
return nil, err
}

return orgIDs, nil
}
69 changes: 69 additions & 0 deletions pkg/alertmanager/alertmanagerstore/sqlalertmanagerstore/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package sqlalertmanagerstore

import (
"context"
"database/sql"

"go.signoz.io/signoz/pkg/errors"
"go.signoz.io/signoz/pkg/sqlstore"
"go.signoz.io/signoz/pkg/types/alertmanagertypes"
)

type state struct {
sqlstore sqlstore.SQLStore
}

func NewStateStore(sqlstore sqlstore.SQLStore) alertmanagertypes.StateStore {
return &state{sqlstore: sqlstore}
}

// Get implements alertmanagertypes.StateStore.
func (store *state) Get(ctx context.Context, orgID string) (*alertmanagertypes.StoreableState, error) {
storeableState := new(alertmanagertypes.StoreableState)

err := store.
sqlstore.
BunDB().
NewSelect().
Model(storeableState).
Where("org_id = ?", orgID).
Scan(ctx)
if err != nil {
if err == sql.ErrNoRows {
return nil, errors.Newf(errors.TypeNotFound, alertmanagertypes.ErrCodeAlertmanagerStateNotFound, "cannot find alertmanager state for org %s", orgID)
}

return nil, err
}

return storeableState, nil
}

// Set implements alertmanagertypes.StateStore.
func (store *state) Set(ctx context.Context, orgID string, storeableState *alertmanagertypes.StoreableState) error {
tx, err := store.sqlstore.BunDB().BeginTx(ctx, nil)
if err != nil {
return err
}

defer tx.Rollback() //nolint:errcheck

_, err = tx.
NewInsert().
Model(storeableState).
On("CONFLICT (org_id) DO UPDATE").
Set("silences = EXCLUDED.silences").
Set("nflog = EXCLUDED.nflog").
Set("updated_at = EXCLUDED.updated_at").
Where("org_id = ?", orgID).
Exec(ctx)
if err != nil {
return err
}

if err := tx.Commit(); err != nil {
return err
}

return nil
}
Loading

0 comments on commit 918c894

Please # to comment.