mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 11:19:11 +08:00
(feature): API - Implement receiver/channel test functionality (#993)
* (feature): Added test receiver/channel functionality
This commit is contained in:
parent
3c2173de9e
commit
508c6ced80
@ -39,6 +39,7 @@ type APIHandler struct {
|
|||||||
basePath string
|
basePath string
|
||||||
apiPrefix string
|
apiPrefix string
|
||||||
reader *Reader
|
reader *Reader
|
||||||
|
alertManager am.Manager
|
||||||
relationalDB *interfaces.ModelDao
|
relationalDB *interfaces.ModelDao
|
||||||
ready func(http.HandlerFunc) http.HandlerFunc
|
ready func(http.HandlerFunc) http.HandlerFunc
|
||||||
}
|
}
|
||||||
@ -46,9 +47,11 @@ type APIHandler struct {
|
|||||||
// NewAPIHandler returns an APIHandler
|
// NewAPIHandler returns an APIHandler
|
||||||
func NewAPIHandler(reader *Reader, relationalDB *interfaces.ModelDao) (*APIHandler, error) {
|
func NewAPIHandler(reader *Reader, relationalDB *interfaces.ModelDao) (*APIHandler, error) {
|
||||||
|
|
||||||
|
alertManager := am.New("")
|
||||||
aH := &APIHandler{
|
aH := &APIHandler{
|
||||||
reader: reader,
|
reader: reader,
|
||||||
relationalDB: relationalDB,
|
relationalDB: relationalDB,
|
||||||
|
alertManager: alertManager,
|
||||||
}
|
}
|
||||||
aH.ready = aH.testReady
|
aH.ready = aH.testReady
|
||||||
|
|
||||||
@ -172,6 +175,7 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router) {
|
|||||||
router.HandleFunc("/api/v1/channels/{id}", aH.editChannel).Methods(http.MethodPut)
|
router.HandleFunc("/api/v1/channels/{id}", aH.editChannel).Methods(http.MethodPut)
|
||||||
router.HandleFunc("/api/v1/channels/{id}", aH.deleteChannel).Methods(http.MethodDelete)
|
router.HandleFunc("/api/v1/channels/{id}", aH.deleteChannel).Methods(http.MethodDelete)
|
||||||
router.HandleFunc("/api/v1/channels", aH.createChannel).Methods(http.MethodPost)
|
router.HandleFunc("/api/v1/channels", aH.createChannel).Methods(http.MethodPost)
|
||||||
|
router.HandleFunc("/api/v1/testChannel", aH.testChannel).Methods(http.MethodPost)
|
||||||
router.HandleFunc("/api/v1/rules", aH.listRulesFromProm).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/rules", aH.listRulesFromProm).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/rules/{id}", aH.getRule).Methods(http.MethodGet)
|
router.HandleFunc("/api/v1/rules/{id}", aH.getRule).Methods(http.MethodGet)
|
||||||
router.HandleFunc("/api/v1/rules", aH.createRule).Methods(http.MethodPost)
|
router.HandleFunc("/api/v1/rules", aH.createRule).Methods(http.MethodPost)
|
||||||
@ -451,6 +455,33 @@ func (aH *APIHandler) listChannels(w http.ResponseWriter, r *http.Request) {
|
|||||||
aH.respond(w, channels)
|
aH.respond(w, channels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testChannels sends test alert to all registered channels
|
||||||
|
func (aH *APIHandler) testChannel(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
defer r.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Errorf("Error in getting req body of testChannel API\n", err)
|
||||||
|
aH.respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
receiver := &am.Receiver{}
|
||||||
|
if err := json.Unmarshal(body, receiver); err != nil { // Parse []byte to go struct pointer
|
||||||
|
zap.S().Errorf("Error in parsing req body of testChannel API\n", err)
|
||||||
|
aH.respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// send alert
|
||||||
|
apiErrorObj := aH.alertManager.TestReceiver(receiver)
|
||||||
|
if apiErrorObj != nil {
|
||||||
|
aH.respondError(w, apiErrorObj, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
aH.respond(w, "test alert sent")
|
||||||
|
}
|
||||||
|
|
||||||
func (aH *APIHandler) editChannel(w http.ResponseWriter, r *http.Request) {
|
func (aH *APIHandler) editChannel(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
id := mux.Vars(r)["id"]
|
id := mux.Vars(r)["id"]
|
||||||
|
@ -2,13 +2,14 @@ package alertManager
|
|||||||
|
|
||||||
// Wrapper to connect and process alert manager functions
|
// Wrapper to connect and process alert manager functions
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"encoding/json"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"go.uber.org/zap"
|
|
||||||
"go.signoz.io/query-service/constants"
|
"go.signoz.io/query-service/constants"
|
||||||
"go.signoz.io/query-service/model"
|
"go.signoz.io/query-service/model"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
const contentType = "application/json"
|
const contentType = "application/json"
|
||||||
@ -17,15 +18,16 @@ type Manager interface {
|
|||||||
AddRoute(receiver *Receiver) *model.ApiError
|
AddRoute(receiver *Receiver) *model.ApiError
|
||||||
EditRoute(receiver *Receiver) *model.ApiError
|
EditRoute(receiver *Receiver) *model.ApiError
|
||||||
DeleteRoute(name string) *model.ApiError
|
DeleteRoute(name string) *model.ApiError
|
||||||
|
TestReceiver(receiver *Receiver) *model.ApiError
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(url string) Manager{
|
func New(url string) Manager {
|
||||||
|
|
||||||
if url == ""{
|
if url == "" {
|
||||||
url = constants.GetAlertManagerApiPrefix()
|
url = constants.GetAlertManagerApiPrefix()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &manager {
|
return &manager{
|
||||||
url: url,
|
url: url,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +36,6 @@ type manager struct {
|
|||||||
url string
|
url string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func prepareAmChannelApiURL() string {
|
func prepareAmChannelApiURL() string {
|
||||||
basePath := constants.GetAlertManagerApiPrefix()
|
basePath := constants.GetAlertManagerApiPrefix()
|
||||||
AmChannelApiPath := constants.AmChannelApiPath
|
AmChannelApiPath := constants.AmChannelApiPath
|
||||||
@ -46,7 +47,12 @@ func prepareAmChannelApiURL() string {
|
|||||||
return fmt.Sprintf("%s%s", basePath, AmChannelApiPath)
|
return fmt.Sprintf("%s%s", basePath, AmChannelApiPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *manager) AddRoute(receiver *Receiver) (*model.ApiError) {
|
func prepareTestApiURL() string {
|
||||||
|
basePath := constants.GetAlertManagerApiPrefix()
|
||||||
|
return fmt.Sprintf("%s%s", basePath, "v1/testReceiver")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *manager) AddRoute(receiver *Receiver) *model.ApiError {
|
||||||
|
|
||||||
receiverString, _ := json.Marshal(receiver)
|
receiverString, _ := json.Marshal(receiver)
|
||||||
|
|
||||||
@ -125,5 +131,29 @@ func (m *manager) DeleteRoute(name string) *model.ApiError {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *manager) TestReceiver(receiver *Receiver) *model.ApiError {
|
||||||
|
|
||||||
|
receiverBytes, _ := json.Marshal(receiver)
|
||||||
|
|
||||||
|
amTestURL := prepareTestApiURL()
|
||||||
|
response, err := http.Post(amTestURL, contentType, bytes.NewBuffer(receiverBytes))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
zap.S().Errorf(fmt.Sprintf("Error in getting response of API call to alertmanager(POST %s)\n", amTestURL), err)
|
||||||
|
return &model.ApiError{Typ: model.ErrorInternal, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.StatusCode > 201 && response.StatusCode < 400 {
|
||||||
|
err := fmt.Errorf(fmt.Sprintf("Invalid parameters in test alert api for alertmanager(POST %s)\n", amTestURL), response.Status)
|
||||||
|
zap.S().Error(err)
|
||||||
|
return &model.ApiError{Typ: model.ErrorInternal, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
if response.StatusCode > 400 {
|
||||||
|
err := fmt.Errorf(fmt.Sprintf("Received Server Error response for API call to alertmanager(POST %s)\n", amTestURL), response.Status)
|
||||||
|
zap.S().Error(err)
|
||||||
|
return &model.ApiError{Typ: model.ErrorInternal, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user