Compare commits

...

2 Commits

Author SHA1 Message Date
nityanandagohain
eb9d1d25be chore: add search and override filters in pricing model list api 2026-06-16 17:16:58 +05:30
Srikanth Chekuri
e1e9d516ac chore: add firing alert count and system/k8s metric existance status (#11730)
Some checks are pending
build-staging / prepare (push) Waiting to run
build-staging / js-build (push) Blocked by required conditions
build-staging / go-build (push) Blocked by required conditions
build-staging / staging (push) Blocked by required conditions
Release Drafter / update_release_draft (push) Waiting to run
2026-06-16 10:28:22 +00:00
13 changed files with 114 additions and 12 deletions

View File

@@ -10191,6 +10191,15 @@ paths:
name: limit
schema:
type: integer
- in: query
name: q
schema:
type: string
- in: query
name: isOverride
schema:
nullable: true
type: boolean
responses:
"200":
content:

View File

@@ -9388,6 +9388,16 @@ export type ListLLMPricingRulesParams = {
* @description undefined
*/
limit?: number;
/**
* @type string
* @description undefined
*/
q?: string;
/**
* @type boolean,null
* @description undefined
*/
isOverride?: boolean | null;
};
export type ListLLMPricingRules200 = {

View File

@@ -0,0 +1,32 @@
package implinframonitoring
import (
"context"
"fmt"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/telemetrymetrics"
"github.com/SigNoz/signoz/pkg/valuer"
)
func (m *module) Collect(ctx context.Context, _ valuer.UUID) (map[string]any, error) {
stats := make(map[string]any)
metadataTable := fmt.Sprintf("%s.%s", telemetrymetrics.DBName, telemetrymetrics.AttributesMetadataTableName)
var (
systemMetricCount uint64
k8sMetricCount uint64
)
query := fmt.Sprintf(
"SELECT (SELECT count() FROM (SELECT 1 FROM %s WHERE metric_name LIKE 'system.%%' LIMIT 1)), (SELECT count() FROM (SELECT 1 FROM %s WHERE metric_name LIKE 'k8s.%%' LIMIT 1))",
metadataTable, metadataTable,
)
if err := m.telemetryStore.ClickhouseDB().QueryRow(ctx, query).Scan(&systemMetricCount, &k8sMetricCount); err == nil {
stats["telemetry.metrics.system.exists"] = systemMetricCount > 0
stats["telemetry.metrics.k8s.exists"] = k8sMetricCount > 0
} else {
m.logger.DebugContext(ctx, "failed to collect metrics namespace existence stats", errors.Attr(err))
}
return stats, nil
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"net/http"
"github.com/SigNoz/signoz/pkg/statsreporter"
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
@@ -22,6 +23,7 @@ type Handler interface {
}
type Module interface {
statsreporter.StatsCollector
ListHosts(ctx context.Context, orgID valuer.UUID, req *inframonitoringtypes.PostableHosts) (*inframonitoringtypes.Hosts, error)
ListPods(ctx context.Context, orgID valuer.UUID, req *inframonitoringtypes.PostablePods) (*inframonitoringtypes.Pods, error)
ListNodes(ctx context.Context, orgID valuer.UUID, req *inframonitoringtypes.PostableNodes) (*inframonitoringtypes.Nodes, error)

View File

@@ -54,7 +54,7 @@ func (h *handler) List(rw http.ResponseWriter, r *http.Request) {
return
}
rules, total, err := h.module.List(ctx, orgID, q.Offset, q.Limit)
rules, total, err := h.module.List(ctx, orgID, q.Offset, q.Limit, q.Search, q.IsOverride)
if err != nil {
render.Error(rw, err)
return

View File

@@ -21,8 +21,8 @@ func NewModule(store llmpricingruletypes.Store) llmpricingrule.Module {
return &module{store: store}
}
func (module *module) List(ctx context.Context, orgID valuer.UUID, offset, limit int) ([]*llmpricingruletypes.LLMPricingRule, int, error) {
return module.store.List(ctx, orgID, offset, limit)
func (module *module) List(ctx context.Context, orgID valuer.UUID, offset, limit int, search string, isOverride *bool) ([]*llmpricingruletypes.LLMPricingRule, int, error) {
return module.store.List(ctx, orgID, offset, limit, search, isOverride)
}
func (module *module) Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*llmpricingruletypes.LLMPricingRule, error) {
@@ -108,7 +108,7 @@ func (module *module) RecommendAgentConfig(orgID valuer.UUID, currentConfYaml []
}
func (module *module) getEnabledRules(ctx context.Context, orgID valuer.UUID) ([]*llmpricingruletypes.LLMPricingRule, error) {
rules, _, err := module.List(ctx, orgID, 0, 10000)
rules, _, err := module.List(ctx, orgID, 0, 10000, "", nil)
if err != nil {
return nil, err
}

View File

@@ -17,14 +17,25 @@ func NewStore(sqlstore sqlstore.SQLStore) llmpricingruletypes.Store {
return &store{sqlstore: sqlstore}
}
func (store *store) List(ctx context.Context, orgID valuer.UUID, offset, limit int) ([]*llmpricingruletypes.LLMPricingRule, int, error) {
func (store *store) List(ctx context.Context, orgID valuer.UUID, offset, limit int, search string, isOverride *bool) ([]*llmpricingruletypes.LLMPricingRule, int, error) {
rules := make([]*llmpricingruletypes.LLMPricingRule, 0)
count, err := store.sqlstore.
query := store.sqlstore.
BunDBCtx(ctx).
NewSelect().
Model(&rules).
Where("org_id = ?", orgID).
Where("org_id = ?", orgID)
if search != "" {
like := "%" + search + "%"
query = query.Where("(LOWER(model) LIKE LOWER(?) OR LOWER(provider) LIKE LOWER(?))", like, like)
}
if isOverride != nil {
query = query.Where("is_override = ?", *isOverride)
}
count, err := query.
Order("created_at DESC").
Offset(offset).
Limit(limit).

View File

@@ -13,7 +13,7 @@ type Module interface {
// Since this module interacts with OpAMP, it must implement the AgentFeature interface.
agentConf.AgentFeature
List(ctx context.Context, orgID valuer.UUID, offset, limit int) ([]*llmpricingruletypes.LLMPricingRule, int, error)
List(ctx context.Context, orgID valuer.UUID, offset, limit int, search string, isOverride *bool) ([]*llmpricingruletypes.LLMPricingRule, int, error)
Get(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*llmpricingruletypes.LLMPricingRule, error)
CreateOrUpdate(ctx context.Context, orgID valuer.UUID, userEmail string, rules []*llmpricingruletypes.UpdatableLLMPricingRule) (err error)
Delete(ctx context.Context, orgID, id valuer.UUID) error

View File

@@ -744,6 +744,32 @@ func (m *Manager) TriggeredAlerts() []*ruletypes.NamedAlert {
return namedAlerts
}
type AlertStats struct {
FiringRules int64
LastFiredAt time.Time
}
func (m *Manager) AlertStats(ctx context.Context) AlertStats {
m.mtx.RLock()
defer m.mtx.RUnlock()
// TODO(therealpandey): scope these stats per org; rules for all orgs are aggregated here.
stats := AlertStats{}
for _, r := range m.rules {
if r.State() == ruletypes.StateFiring {
stats.FiringRules++
}
for _, alert := range r.ActiveAlerts() {
if alert.FiredAt.After(stats.LastFiredAt) {
stats.LastFiredAt = alert.FiredAt
}
}
}
return stats
}
// NotifyFunc sends notifications about a set of alerts generated by the given expression.
type NotifyFunc func(ctx context.Context, orgID string, alerts ...*ruletypes.Alert)

View File

@@ -100,7 +100,16 @@ func (provider *provider) Collect(ctx context.Context, orgID valuer.UUID) (map[s
return nil, err
}
return ruletypes.NewStatsFromRules(rules), nil
stats := ruletypes.NewStatsFromRules(rules)
alertStats := provider.manager.AlertStats(ctx)
stats["alert.firing.count"] = alertStats.FiringRules
if !alertStats.LastFiredAt.IsZero() {
stats["alert.last_fired.time"] = alertStats.LastFiredAt.UTC()
stats["alert.last_fired.time_unix"] = alertStats.LastFiredAt.Unix()
}
return stats, nil
}
func (provider *provider) ListRuleStates(ctx context.Context) (*ruletypes.GettableRules, error) {

View File

@@ -499,6 +499,7 @@ func New(
serviceAccount,
cloudIntegrationModule,
modules.LogsPipeline,
modules.InfraMonitoring,
querier,
}

View File

@@ -125,8 +125,10 @@ type UpdatableLLMPricingRules struct {
}
type ListPricingRulesQuery struct {
Offset int `query:"offset" json:"offset"`
Limit int `query:"limit" json:"limit"`
Offset int `query:"offset" json:"offset"`
Limit int `query:"limit" json:"limit"`
Search string `query:"q" json:"q"`
IsOverride *bool `query:"isOverride" json:"isOverride"`
}
type GettablePricingRules struct {

View File

@@ -7,7 +7,7 @@ import (
)
type Store interface {
List(ctx context.Context, orgID valuer.UUID, offset, limit int) ([]*LLMPricingRule, int, error)
List(ctx context.Context, orgID valuer.UUID, offset, limit int, search string, isOverride *bool) ([]*LLMPricingRule, int, error)
Get(ctx context.Context, orgID, id valuer.UUID) (*LLMPricingRule, error)
GetBySourceID(ctx context.Context, orgID, sourceID valuer.UUID) (*LLMPricingRule, error)
Create(ctx context.Context, rule *LLMPricingRule) error