Compare commits

...

23 Commits

Author SHA1 Message Date
Abhishek Kumar Singh
629d94ffc2 chore: updated license header with short notation 2026-04-15 15:58:40 +05:30
Abhishek Kumar Singh
e26ad63de9 Merge branch 'main' into chore/am_custom_notifiers 2026-04-15 15:57:03 +05:30
primus-bot[bot]
be1a0fa3a5 chore(release): bump to v0.119.0 (#10936)
Some checks are pending
build-staging / js-build (push) Blocked by required conditions
build-staging / prepare (push) Waiting to run
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
Co-authored-by: primus-bot[bot] <171087277+primus-bot[bot]@users.noreply.github.com>
Co-authored-by: Priyanshu Shrivastava <priyanshu@signoz.io>
2026-04-15 08:35:52 +00:00
Nikhil Mantri
6ad2711c7a feat(/fields/*) : introduce a new param metricNamespace in the APIs for prefix match (#10779)
* chore: initial commit

* chore: added metricNamespace as a new param

* chore: go generate openapi, update spec

* chore: frontend yarn generate:api

* chore: added metricnamespace support in /fields/values as well as added integration tests

* chore: corrected comment

* chore: added unit tests for getMetricsKeys and getMeterSourceMetricKeys

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-04-15 07:26:42 +00:00
Srikanth Chekuri
569b413843 Merge branch 'main' into chore/am_custom_notifiers 2026-04-15 10:39:07 +05:30
swapnil-signoz
4f59cb0de3 chore: updating cloud integration agent version (#10933)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-04-15 05:01:26 +00:00
Srikanth Chekuri
304c39e08c fix(route-policy): allow undefined variables for expression (#10934)
* fix(route-policy): allow undefined variables for expression

* chore: fix lint
2026-04-15 04:55:21 +00:00
swapnil-signoz
3df0da3a4e chore: removing underscore attribute based cloud integration dashboards (#10929)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-04-14 13:08:07 +00:00
Abhishek Kumar Singh
41ded342a1 Merge branch 'main' into chore/am_custom_notifiers 2026-04-14 17:50:27 +05:30
Tushar Vats
381966adcd fix: flaky integration tests (#10927) 2026-04-14 10:52:16 +00:00
Abhishek Kumar Singh
2e2dd4c42b Merge branch 'main' into chore/am_custom_notifiers 2026-04-13 22:04:08 +05:30
Abhishek Kumar Singh
46ae74ced5 chore: updated email notifier from upstream 2026-03-31 11:52:08 +05:30
Abhishek Kumar Singh
2d8c1b7c86 chore: updated licenses for notifiers 2026-03-31 11:51:45 +05:30
Abhishek Kumar Singh
6602c8c523 refactor: lint fixes 2026-03-31 10:46:52 +05:30
Abhishek Kumar Singh
c22dbcbf74 refactor: review comments 2026-03-31 10:44:37 +05:30
Abhishek Kumar Singh
250bd9abeb Merge branch 'main' into chore/am_custom_notifiers 2026-03-31 10:15:39 +05:30
Abhishek Kumar Singh
e6a9f49cec Merge branch 'main' into chore/am_custom_notifiers 2026-03-17 20:14:30 +05:30
Abhishek Kumar Singh
01a09cf6d2 chore: updated test name + code for timeout errors 2026-03-12 10:22:42 +05:30
Abhishek Kumar Singh
d07a833574 chore: added tracing to msteamsv2 notifier 2026-03-11 16:05:00 +05:30
Abhishek Kumar Singh
b39bec7245 Merge branch 'main' into chore/am_custom_notifiers 2026-03-10 22:37:24 +05:30
Abhishek Kumar Singh
6ff55c48be chore: fix email linter 2026-03-10 22:19:05 +05:30
Abhishek Kumar Singh
b15fa0f88f chore: lint fixs 2026-03-10 21:57:53 +05:30
Abhishek Kumar Singh
19fe4f860e chore: custom notifiers in alert manager 2026-03-10 13:20:04 +05:30
62 changed files with 5804 additions and 27397 deletions

View File

@@ -190,7 +190,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:v0.118.0
image: signoz/signoz:v0.119.0
ports:
- "8080:8080" # signoz port
# - "6060:6060" # pprof port

View File

@@ -117,7 +117,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:v0.118.0
image: signoz/signoz:v0.119.0
ports:
- "8080:8080" # signoz port
volumes:

View File

@@ -181,7 +181,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.118.0}
image: signoz/signoz:${VERSION:-v0.119.0}
container_name: signoz
ports:
- "8080:8080" # signoz port

View File

@@ -109,7 +109,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.118.0}
image: signoz/signoz:${VERSION:-v0.119.0}
container_name: signoz
ports:
- "8080:8080" # signoz port

View File

@@ -4465,6 +4465,10 @@ paths:
name: metricName
schema:
type: string
- in: query
name: metricNamespace
schema:
type: string
- in: query
name: searchText
schema:
@@ -4550,6 +4554,10 @@ paths:
name: metricName
schema:
type: string
- in: query
name: metricNamespace
schema:
type: string
- in: query
name: searchText
schema:
@@ -8312,6 +8320,10 @@ paths:
name: metricName
schema:
type: string
- in: query
name: metricNamespace
schema:
type: string
- in: query
name: searchText
schema:
@@ -8409,6 +8421,10 @@ paths:
name: metricName
schema:
type: string
- in: query
name: metricNamespace
schema:
type: string
- in: query
name: searchText
schema:

View File

@@ -3836,6 +3836,11 @@ export type GetFieldsKeysParams = {
* @description undefined
*/
metricName?: string;
/**
* @type string
* @description undefined
*/
metricNamespace?: string;
/**
* @type string
* @description undefined
@@ -3890,6 +3895,11 @@ export type GetFieldsValuesParams = {
* @description undefined
*/
metricName?: string;
/**
* @type string
* @description undefined
*/
metricNamespace?: string;
/**
* @type string
* @description undefined
@@ -4569,6 +4579,11 @@ export type GetRuleHistoryFilterKeysParams = {
* @description undefined
*/
metricName?: string;
/**
* @type string
* @description undefined
*/
metricNamespace?: string;
/**
* @type string
* @description undefined
@@ -4626,6 +4641,11 @@ export type GetRuleHistoryFilterValuesParams = {
* @description undefined
*/
metricName?: string;
/**
* @type string
* @description undefined
*/
metricNamespace?: string;
/**
* @type string
* @description undefined

4
go.mod
View File

@@ -15,6 +15,7 @@ require (
github.com/coreos/go-oidc/v3 v3.17.0
github.com/dgraph-io/ristretto/v2 v2.3.0
github.com/dustin/go-humanize v1.0.1
github.com/emersion/go-smtp v0.24.0
github.com/gin-gonic/gin v1.11.0
github.com/go-co-op/gocron v1.30.1
github.com/go-openapi/runtime v0.29.2
@@ -111,6 +112,7 @@ require (
github.com/bytedance/sonic v1.14.1 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
github.com/go-openapi/swag/conv v0.25.4 // indirect
@@ -164,7 +166,7 @@ require (
github.com/ClickHouse/ch-go v0.67.0 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/Yiling-J/theine-go v0.6.2 // indirect
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/beevik/etree v1.1.0 // indirect

View File

@@ -0,0 +1,431 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package email
import (
"bytes"
"context"
"crypto/tls"
"fmt"
"log/slog"
"math/rand"
"mime"
"mime/multipart"
"mime/quotedprintable"
"net"
"net/mail"
"net/smtp"
"net/textproto"
"os"
"strings"
"sync"
"time"
"github.com/SigNoz/signoz/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
)
const (
Integration = "email"
)
// Email implements a Notifier for email notifications.
type Email struct {
conf *config.EmailConfig
tmpl *template.Template
logger *slog.Logger
hostname string
}
var errNoAuthUsernameConfigured = errors.NewInternalf(errors.CodeInternal, "no auth username configured")
// New returns a new Email notifier.
func New(c *config.EmailConfig, t *template.Template, l *slog.Logger) *Email {
if _, ok := c.Headers["Subject"]; !ok {
c.Headers["Subject"] = config.DefaultEmailSubject
}
if _, ok := c.Headers["To"]; !ok {
c.Headers["To"] = c.To
}
if _, ok := c.Headers["From"]; !ok {
c.Headers["From"] = c.From
}
h, err := os.Hostname()
// If we can't get the hostname, we'll use localhost
if err != nil {
h = "localhost.localdomain"
}
return &Email{conf: c, tmpl: t, logger: l, hostname: h}
}
// auth resolves a string of authentication mechanisms.
func (n *Email) auth(mechs string) (smtp.Auth, error) {
username := n.conf.AuthUsername
// If no username is set, return custom error which can be ignored if needed.
if strings.TrimSpace(username) == "" {
return nil, errNoAuthUsernameConfigured
}
var errs error
for mech := range strings.SplitSeq(mechs, " ") {
switch mech {
case "CRAM-MD5":
secret, secretErr := n.getAuthSecret()
if secretErr != nil {
errs = errors.Join(errs, secretErr)
continue
}
if secret == "" {
errs = errors.Join(errs, errors.NewInternalf(errors.CodeInternal, "missing secret for CRAM-MD5 auth mechanism"))
continue
}
return smtp.CRAMMD5Auth(username, secret), nil
case "PLAIN":
password, passwordErr := n.getPassword()
if passwordErr != nil {
errs = errors.Join(errs, passwordErr)
continue
}
if password == "" {
errs = errors.Join(errs, errors.NewInternalf(errors.CodeInternal, "missing password for PLAIN auth mechanism"))
continue
}
return smtp.PlainAuth(n.conf.AuthIdentity, username, password, n.conf.Smarthost.Host), nil
case "LOGIN":
password, passwordErr := n.getPassword()
if passwordErr != nil {
errs = errors.Join(errs, passwordErr)
continue
}
if password == "" {
errs = errors.Join(errs, errors.NewInternalf(errors.CodeInternal, "missing password for LOGIN auth mechanism"))
continue
}
return LoginAuth(username, password), nil
default:
errs = errors.Join(errs, errors.NewInternalf(errors.CodeUnsupported, "unknown auth mechanism: %s", mech))
}
}
return nil, errs
}
// Notify implements the Notifier interface.
func (n *Email) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
var (
c *smtp.Client
conn net.Conn
err error
success = false
)
// Determine whether to use Implicit TLS
var useImplicitTLS bool
if n.conf.ForceImplicitTLS != nil {
useImplicitTLS = *n.conf.ForceImplicitTLS
} else {
// Default logic: port 465 uses implicit TLS (backward compatibility)
useImplicitTLS = n.conf.Smarthost.Port == "465"
}
if useImplicitTLS {
tlsConfig, err := commoncfg.NewTLSConfig(n.conf.TLSConfig)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "parse TLS configuration")
}
if tlsConfig.ServerName == "" {
tlsConfig.ServerName = n.conf.Smarthost.Host
}
conn, err = tls.Dial("tcp", n.conf.Smarthost.String(), tlsConfig)
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "establish TLS connection to server")
}
} else {
var (
d = net.Dialer{}
err error
)
conn, err = d.DialContext(ctx, "tcp", n.conf.Smarthost.String())
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "establish connection to server")
}
}
c, err = smtp.NewClient(conn, n.conf.Smarthost.Host)
if err != nil {
conn.Close()
return true, errors.WrapInternalf(err, errors.CodeInternal, "create SMTP client")
}
defer func() {
// Try to clean up after ourselves but don't log anything if something has failed.
if err := c.Quit(); success && err != nil {
n.logger.WarnContext(ctx, "failed to close SMTP connection", slog.Any("err", err))
}
}()
if n.conf.Hello != "" {
err = c.Hello(n.conf.Hello)
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "send EHLO command")
}
}
// Global Config guarantees RequireTLS is not nil.
if *n.conf.RequireTLS && !useImplicitTLS {
if ok, _ := c.Extension("STARTTLS"); !ok {
return true, errors.WrapInternalf(err, errors.CodeInternal, "'require_tls' is true (default) but %q does not advertise the STARTTLS extension", n.conf.Smarthost)
}
tlsConf, err := commoncfg.NewTLSConfig(n.conf.TLSConfig)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "parse TLS configuration")
}
if tlsConf.ServerName == "" {
tlsConf.ServerName = n.conf.Smarthost.Host
}
if err := c.StartTLS(tlsConf); err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "send STARTTLS command")
}
}
if ok, mech := c.Extension("AUTH"); ok {
auth, err := n.auth(mech)
if err != nil && err != errNoAuthUsernameConfigured {
return true, errors.WrapInternalf(err, errors.CodeInternal, "find auth mechanism")
} else if err == errNoAuthUsernameConfigured {
n.logger.DebugContext(ctx, "no auth username configured. Attempting to send email without authenticating")
}
if auth != nil {
if err := c.Auth(auth); err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "%T auth", auth)
}
}
}
var (
tmplErr error
data = notify.GetTemplateData(ctx, n.tmpl, as, n.logger)
tmpl = notify.TmplText(n.tmpl, data, &tmplErr)
)
from := tmpl(n.conf.From)
if tmplErr != nil {
return false, errors.WrapInternalf(tmplErr, errors.CodeInternal, "execute 'from' template")
}
to := tmpl(n.conf.To)
if tmplErr != nil {
return false, errors.WrapInternalf(tmplErr, errors.CodeInternal, "execute 'to' template")
}
addrs, err := mail.ParseAddressList(from)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "parse 'from' addresses")
}
if len(addrs) != 1 {
return false, errors.NewInternalf(errors.CodeInternal, "must be exactly one 'from' address (got: %d)", len(addrs))
}
if err = c.Mail(addrs[0].Address); err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "send MAIL command")
}
addrs, err = mail.ParseAddressList(to)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "parse 'to' addresses")
}
for _, addr := range addrs {
if err = c.Rcpt(addr.Address); err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "send RCPT command")
}
}
// Send the email headers and body.
message, err := c.Data()
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "send DATA command")
}
closeOnce := sync.OnceValue(func() error {
return message.Close()
})
// Close the message when this method exits in order to not leak resources. Even though we're calling this explicitly
// further down, the method may exit before then.
defer func() {
// If we try close an already-closed writer, it'll send a subsequent request to the server which is invalid.
_ = closeOnce()
}()
buffer := &bytes.Buffer{}
for header, t := range n.conf.Headers {
value, err := n.tmpl.ExecuteTextString(t, data)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "execute %q header template", header)
}
fmt.Fprintf(buffer, "%s: %s\r\n", header, mime.QEncoding.Encode("utf-8", value))
}
if _, ok := n.conf.Headers["Message-Id"]; !ok {
fmt.Fprintf(buffer, "Message-Id: %s\r\n", fmt.Sprintf("<%d.%d@%s>", time.Now().UnixNano(), rand.Uint64(), n.hostname))
}
if n.conf.Threading.Enabled {
key, err := notify.ExtractGroupKey(ctx)
if err != nil {
return false, err
}
// Add threading headers. All notifications for the same alert group
// (identified by key hash) are threaded together.
threadBy := ""
if n.conf.Threading.ThreadByDate != "none" {
// ThreadByDate is 'daily':
// Use current date so all mails for this alert today thread together.
threadBy = time.Now().Format("2006-01-02")
}
keyHash := key.Hash()
if len(keyHash) > 16 {
keyHash = keyHash[:16]
}
// The thread root ID is a Message-ID that doesn't correspond to
// any actual email. Email clients following the (commonly used) JWZ
// algorithm will create a dummy container to group these messages.
threadRootID := fmt.Sprintf("<alert-%s-%s@alertmanager>", keyHash, threadBy)
fmt.Fprintf(buffer, "References: %s\r\n", threadRootID)
fmt.Fprintf(buffer, "In-Reply-To: %s\r\n", threadRootID)
}
multipartBuffer := &bytes.Buffer{}
multipartWriter := multipart.NewWriter(multipartBuffer)
fmt.Fprintf(buffer, "Date: %s\r\n", time.Now().Format(time.RFC1123Z))
fmt.Fprintf(buffer, "Content-Type: multipart/alternative; boundary=%s\r\n", multipartWriter.Boundary())
fmt.Fprintf(buffer, "MIME-Version: 1.0\r\n\r\n")
// TODO: Add some useful headers here, such as URL of the alertmanager
// and active/resolved.
_, err = message.Write(buffer.Bytes())
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "write headers")
}
if len(n.conf.Text) > 0 {
// Text template
w, err := multipartWriter.CreatePart(textproto.MIMEHeader{
"Content-Transfer-Encoding": {"quoted-printable"},
"Content-Type": {"text/plain; charset=UTF-8"},
})
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "create part for text template")
}
body, err := n.tmpl.ExecuteTextString(n.conf.Text, data)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "execute text template")
}
qw := quotedprintable.NewWriter(w)
_, err = qw.Write([]byte(body))
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "write text part")
}
err = qw.Close()
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "close text part")
}
}
if len(n.conf.HTML) > 0 {
// Html template
// Preferred alternative placed last per section 5.1.4 of RFC 2046
// https://www.ietf.org/rfc/rfc2046.txt
w, err := multipartWriter.CreatePart(textproto.MIMEHeader{
"Content-Transfer-Encoding": {"quoted-printable"},
"Content-Type": {"text/html; charset=UTF-8"},
})
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "create part for html template")
}
body, err := n.tmpl.ExecuteHTMLString(n.conf.HTML, data)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "execute html template")
}
qw := quotedprintable.NewWriter(w)
_, err = qw.Write([]byte(body))
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "write HTML part")
}
err = qw.Close()
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "close HTML part")
}
}
err = multipartWriter.Close()
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "close multipartWriter")
}
_, err = message.Write(multipartBuffer.Bytes())
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "write body buffer")
}
// Complete the message and await response.
if err = closeOnce(); err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "delivery failure")
}
success = true
return false, nil
}
type loginAuth struct {
username, password string
}
func LoginAuth(username, password string) smtp.Auth {
return &loginAuth{username, password}
}
func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
return "LOGIN", []byte{}, nil
}
// Used for AUTH LOGIN. (Maybe password should be encrypted).
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
switch strings.ToLower(string(fromServer)) {
case "username:":
return []byte(a.username), nil
case "password:":
return []byte(a.password), nil
default:
return nil, errors.NewInternalf(errors.CodeInternal, "unexpected server challenge")
}
}
return nil, nil
}
func (n *Email) getPassword() (string, error) {
if len(n.conf.AuthPasswordFile) > 0 {
content, err := os.ReadFile(n.conf.AuthPasswordFile)
if err != nil {
return "", errors.NewInternalf(errors.CodeInternal, "could not read %s: %v", n.conf.AuthPasswordFile, err)
}
return strings.TrimSpace(string(content)), nil
}
return string(n.conf.AuthPassword), nil
}
func (n *Email) getAuthSecret() (string, error) {
if len(n.conf.AuthSecretFile) > 0 {
content, err := os.ReadFile(n.conf.AuthSecretFile)
if err != nil {
return "", errors.NewInternalf(errors.CodeInternal, "could not read %s: %v", n.conf.AuthSecretFile, err)
}
return string(content), nil
}
return string(n.conf.AuthSecret), nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,7 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package msteamsv2
import (
@@ -27,6 +31,10 @@ const (
colorGrey = "Warning"
)
const (
Integration = "msteamsv2"
)
type Notifier struct {
conf *config.MSTeamsV2Config
titleLink string
@@ -87,7 +95,7 @@ type teamsMessage struct {
// New returns a new notifier that uses the Microsoft Teams Power Platform connector.
func New(c *config.MSTeamsV2Config, t *template.Template, titleLink string, l *slog.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
client, err := commoncfg.NewClientFromConfig(*c.HTTPConfig, "msteamsv2", httpOpts...)
client, err := notify.NewClientWithTracing(*c.HTTPConfig, Integration, httpOpts...)
if err != nil {
return nil, err
}

View File

@@ -1,3 +1,7 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package msteamsv2
import (

View File

@@ -0,0 +1,2 @@
my_secret_api_key

View File

@@ -0,0 +1,294 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package opsgenie
import (
"bytes"
"context"
"encoding/json"
"fmt"
"log/slog"
"maps"
"net/http"
"os"
"strings"
"github.com/SigNoz/signoz/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
)
const (
Integration = "opsgenie"
)
// https://docs.opsgenie.com/docs/alert-api - 130 characters meaning runes.
const maxMessageLenRunes = 130
// Notifier implements a Notifier for OpsGenie notifications.
type Notifier struct {
conf *config.OpsGenieConfig
tmpl *template.Template
logger *slog.Logger
client *http.Client
retrier *notify.Retrier
}
// New returns a new OpsGenie notifier.
func New(c *config.OpsGenieConfig, t *template.Template, l *slog.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
client, err := notify.NewClientWithTracing(*c.HTTPConfig, Integration, httpOpts...)
if err != nil {
return nil, err
}
return &Notifier{
conf: c,
tmpl: t,
logger: l,
client: client,
retrier: &notify.Retrier{RetryCodes: []int{http.StatusTooManyRequests}},
}, nil
}
type opsGenieCreateMessage struct {
Alias string `json:"alias"`
Message string `json:"message"`
Description string `json:"description,omitempty"`
Details map[string]string `json:"details"`
Source string `json:"source"`
Responders []opsGenieCreateMessageResponder `json:"responders,omitempty"`
Tags []string `json:"tags,omitempty"`
Note string `json:"note,omitempty"`
Priority string `json:"priority,omitempty"`
Entity string `json:"entity,omitempty"`
Actions []string `json:"actions,omitempty"`
}
type opsGenieCreateMessageResponder struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Username string `json:"username,omitempty"`
Type string `json:"type"` // team, user, escalation, schedule etc.
}
type opsGenieCloseMessage struct {
Source string `json:"source"`
}
type opsGenieUpdateMessageMessage struct {
Message string `json:"message,omitempty"`
}
type opsGenieUpdateDescriptionMessage struct {
Description string `json:"description,omitempty"`
}
// Notify implements the Notifier interface.
func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
requests, retry, err := n.createRequests(ctx, as...)
if err != nil {
return retry, err
}
for _, req := range requests {
req.Header.Set("User-Agent", notify.UserAgentHeader)
resp, err := n.client.Do(req) //nolint:bodyclose
if err != nil {
return true, err
}
shouldRetry, err := n.retrier.Check(resp.StatusCode, resp.Body)
notify.Drain(resp)
if err != nil {
return shouldRetry, notify.NewErrorWithReason(notify.GetFailureReasonFromStatusCode(resp.StatusCode), err)
}
}
return true, nil
}
// Like Split but filter out empty strings.
func safeSplit(s, sep string) []string {
a := strings.Split(strings.TrimSpace(s), sep)
b := a[:0]
for _, x := range a {
if x != "" {
b = append(b, x)
}
}
return b
}
// Create requests for a list of alerts.
func (n *Notifier) createRequests(ctx context.Context, as ...*types.Alert) ([]*http.Request, bool, error) {
key, err := notify.ExtractGroupKey(ctx)
if err != nil {
return nil, false, err
}
logger := n.logger.With(slog.Any("group_key", key))
logger.DebugContext(ctx, "extracted group key")
data := notify.GetTemplateData(ctx, n.tmpl, as, logger)
tmpl := notify.TmplText(n.tmpl, data, &err)
details := make(map[string]string)
maps.Copy(details, data.CommonLabels)
for k, v := range n.conf.Details {
details[k] = tmpl(v)
}
requests := []*http.Request{}
var (
alias = key.Hash()
alerts = types.Alerts(as...)
)
switch alerts.Status() {
case model.AlertResolved:
resolvedEndpointURL := n.conf.APIURL.Copy()
resolvedEndpointURL.Path += fmt.Sprintf("v2/alerts/%s/close", alias)
q := resolvedEndpointURL.Query()
q.Set("identifierType", "alias")
resolvedEndpointURL.RawQuery = q.Encode()
msg := &opsGenieCloseMessage{Source: tmpl(n.conf.Source)}
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(msg); err != nil {
return nil, false, err
}
req, err := http.NewRequest("POST", resolvedEndpointURL.String(), &buf)
if err != nil {
return nil, true, err
}
requests = append(requests, req.WithContext(ctx))
default:
message, truncated := notify.TruncateInRunes(tmpl(n.conf.Message), maxMessageLenRunes)
if truncated {
logger.WarnContext(ctx, "Truncated message", slog.Any("alert", key), slog.Int("max_runes", maxMessageLenRunes))
}
createEndpointURL := n.conf.APIURL.Copy()
createEndpointURL.Path += "v2/alerts"
var responders []opsGenieCreateMessageResponder
for _, r := range n.conf.Responders {
responder := opsGenieCreateMessageResponder{
ID: tmpl(r.ID),
Name: tmpl(r.Name),
Username: tmpl(r.Username),
Type: tmpl(r.Type),
}
if responder == (opsGenieCreateMessageResponder{}) {
// Filter out empty responders. This is useful if you want to fill
// responders dynamically from alert's common labels.
continue
}
if responder.Type == "teams" {
teams := safeSplit(responder.Name, ",")
for _, team := range teams {
newResponder := opsGenieCreateMessageResponder{
Name: tmpl(team),
Type: tmpl("team"),
}
responders = append(responders, newResponder)
}
continue
}
responders = append(responders, responder)
}
msg := &opsGenieCreateMessage{
Alias: alias,
Message: message,
Description: tmpl(n.conf.Description),
Details: details,
Source: tmpl(n.conf.Source),
Responders: responders,
Tags: safeSplit(tmpl(n.conf.Tags), ","),
Note: tmpl(n.conf.Note),
Priority: tmpl(n.conf.Priority),
Entity: tmpl(n.conf.Entity),
Actions: safeSplit(tmpl(n.conf.Actions), ","),
}
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(msg); err != nil {
return nil, false, err
}
req, err := http.NewRequest("POST", createEndpointURL.String(), &buf)
if err != nil {
return nil, true, err
}
requests = append(requests, req.WithContext(ctx))
if n.conf.UpdateAlerts {
updateMessageEndpointURL := n.conf.APIURL.Copy()
updateMessageEndpointURL.Path += fmt.Sprintf("v2/alerts/%s/message", alias)
q := updateMessageEndpointURL.Query()
q.Set("identifierType", "alias")
updateMessageEndpointURL.RawQuery = q.Encode()
updateMsgMsg := &opsGenieUpdateMessageMessage{
Message: msg.Message,
}
var updateMessageBuf bytes.Buffer
if err := json.NewEncoder(&updateMessageBuf).Encode(updateMsgMsg); err != nil {
return nil, false, err
}
req, err := http.NewRequest("PUT", updateMessageEndpointURL.String(), &updateMessageBuf)
if err != nil {
return nil, true, err
}
requests = append(requests, req)
updateDescriptionEndpointURL := n.conf.APIURL.Copy()
updateDescriptionEndpointURL.Path += fmt.Sprintf("v2/alerts/%s/description", alias)
q = updateDescriptionEndpointURL.Query()
q.Set("identifierType", "alias")
updateDescriptionEndpointURL.RawQuery = q.Encode()
updateDescMsg := &opsGenieUpdateDescriptionMessage{
Description: msg.Description,
}
var updateDescriptionBuf bytes.Buffer
if err := json.NewEncoder(&updateDescriptionBuf).Encode(updateDescMsg); err != nil {
return nil, false, err
}
req, err = http.NewRequest("PUT", updateDescriptionEndpointURL.String(), &updateDescriptionBuf)
if err != nil {
return nil, true, err
}
requests = append(requests, req.WithContext(ctx))
}
}
var apiKey string
if n.conf.APIKey != "" {
apiKey = tmpl(string(n.conf.APIKey))
} else {
content, err := os.ReadFile(n.conf.APIKeyFile)
if err != nil {
return nil, false, errors.WrapInternalf(err, errors.CodeInternal, "read key_file error")
}
apiKey = tmpl(string(content))
apiKey = strings.TrimSpace(string(apiKey))
}
if err != nil {
return nil, false, errors.WrapInternalf(err, errors.CodeInternal, "templating error")
}
for _, req := range requests {
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", fmt.Sprintf("GenieKey %s", apiKey))
}
return requests, true, nil
}

View File

@@ -0,0 +1,337 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package opsgenie
import (
"context"
"fmt"
"io"
"net/http"
"net/url"
"os"
"testing"
"time"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/require"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/notify/test"
"github.com/prometheus/alertmanager/types"
)
func TestOpsGenieRetry(t *testing.T) {
notifier, err := New(
&config.OpsGenieConfig{
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
retryCodes := append(test.DefaultRetryCodes(), http.StatusTooManyRequests)
for statusCode, expected := range test.RetryTests(retryCodes) {
actual, _ := notifier.retrier.Check(statusCode, nil)
require.Equal(t, expected, actual, "error on status %d", statusCode)
}
}
func TestOpsGenieRedactedURL(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
key := "key"
notifier, err := New(
&config.OpsGenieConfig{
APIURL: &config.URL{URL: u},
APIKey: config.Secret(key),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, key)
}
func TestGettingOpsGegineApikeyFromFile(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
key := "key"
f, err := os.CreateTemp(t.TempDir(), "opsgenie_test")
require.NoError(t, err, "creating temp file failed")
_, err = f.WriteString(key)
require.NoError(t, err, "writing to temp file failed")
notifier, err := New(
&config.OpsGenieConfig{
APIURL: &config.URL{URL: u},
APIKeyFile: f.Name(),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, key)
}
func TestOpsGenie(t *testing.T) {
u, err := url.Parse("https://opsgenie/api")
if err != nil {
t.Fatalf("failed to parse URL: %v", err)
}
logger := promslog.NewNopLogger()
tmpl := test.CreateTmpl(t)
for _, tc := range []struct {
title string
cfg *config.OpsGenieConfig
expectedEmptyAlertBody string
expectedBody string
}{
{
title: "config without details",
cfg: &config.OpsGenieConfig{
NotifierConfig: config.NotifierConfig{
VSendResolved: true,
},
Message: `{{ .CommonLabels.Message }}`,
Description: `{{ .CommonLabels.Description }}`,
Source: `{{ .CommonLabels.Source }}`,
Responders: []config.OpsGenieConfigResponder{
{
Name: `{{ .CommonLabels.ResponderName1 }}`,
Type: `{{ .CommonLabels.ResponderType1 }}`,
},
{
Name: `{{ .CommonLabels.ResponderName2 }}`,
Type: `{{ .CommonLabels.ResponderType2 }}`,
},
},
Tags: `{{ .CommonLabels.Tags }}`,
Note: `{{ .CommonLabels.Note }}`,
Priority: `{{ .CommonLabels.Priority }}`,
Entity: `{{ .CommonLabels.Entity }}`,
Actions: `{{ .CommonLabels.Actions }}`,
APIKey: `{{ .ExternalURL }}`,
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
expectedEmptyAlertBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"","details":{},"source":""}
`,
expectedBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"message","description":"description","details":{"Actions":"doThis,doThat","Description":"description","Entity":"test-domain","Message":"message","Note":"this is a note","Priority":"P1","ResponderName1":"TeamA","ResponderName2":"EscalationA","ResponderName3":"TeamA,TeamB","ResponderType1":"team","ResponderType2":"escalation","ResponderType3":"teams","Source":"http://prometheus","Tags":"tag1,tag2"},"source":"http://prometheus","responders":[{"name":"TeamA","type":"team"},{"name":"EscalationA","type":"escalation"}],"tags":["tag1","tag2"],"note":"this is a note","priority":"P1","entity":"test-domain","actions":["doThis","doThat"]}
`,
},
{
title: "config with details",
cfg: &config.OpsGenieConfig{
NotifierConfig: config.NotifierConfig{
VSendResolved: true,
},
Message: `{{ .CommonLabels.Message }}`,
Description: `{{ .CommonLabels.Description }}`,
Source: `{{ .CommonLabels.Source }}`,
Details: map[string]string{
"Description": `adjusted {{ .CommonLabels.Description }}`,
},
Responders: []config.OpsGenieConfigResponder{
{
Name: `{{ .CommonLabels.ResponderName1 }}`,
Type: `{{ .CommonLabels.ResponderType1 }}`,
},
{
Name: `{{ .CommonLabels.ResponderName2 }}`,
Type: `{{ .CommonLabels.ResponderType2 }}`,
},
},
Tags: `{{ .CommonLabels.Tags }}`,
Note: `{{ .CommonLabels.Note }}`,
Priority: `{{ .CommonLabels.Priority }}`,
Entity: `{{ .CommonLabels.Entity }}`,
Actions: `{{ .CommonLabels.Actions }}`,
APIKey: `{{ .ExternalURL }}`,
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
expectedEmptyAlertBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"","details":{"Description":"adjusted "},"source":""}
`,
expectedBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"message","description":"description","details":{"Actions":"doThis,doThat","Description":"adjusted description","Entity":"test-domain","Message":"message","Note":"this is a note","Priority":"P1","ResponderName1":"TeamA","ResponderName2":"EscalationA","ResponderName3":"TeamA,TeamB","ResponderType1":"team","ResponderType2":"escalation","ResponderType3":"teams","Source":"http://prometheus","Tags":"tag1,tag2"},"source":"http://prometheus","responders":[{"name":"TeamA","type":"team"},{"name":"EscalationA","type":"escalation"}],"tags":["tag1","tag2"],"note":"this is a note","priority":"P1","entity":"test-domain","actions":["doThis","doThat"]}
`,
},
{
title: "config with multiple teams",
cfg: &config.OpsGenieConfig{
NotifierConfig: config.NotifierConfig{
VSendResolved: true,
},
Message: `{{ .CommonLabels.Message }}`,
Description: `{{ .CommonLabels.Description }}`,
Source: `{{ .CommonLabels.Source }}`,
Details: map[string]string{
"Description": `adjusted {{ .CommonLabels.Description }}`,
},
Responders: []config.OpsGenieConfigResponder{
{
Name: `{{ .CommonLabels.ResponderName3 }}`,
Type: `{{ .CommonLabels.ResponderType3 }}`,
},
},
Tags: `{{ .CommonLabels.Tags }}`,
Note: `{{ .CommonLabels.Note }}`,
Priority: `{{ .CommonLabels.Priority }}`,
APIKey: `{{ .ExternalURL }}`,
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
expectedEmptyAlertBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"","details":{"Description":"adjusted "},"source":""}
`,
expectedBody: `{"alias":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","message":"message","description":"description","details":{"Actions":"doThis,doThat","Description":"adjusted description","Entity":"test-domain","Message":"message","Note":"this is a note","Priority":"P1","ResponderName1":"TeamA","ResponderName2":"EscalationA","ResponderName3":"TeamA,TeamB","ResponderType1":"team","ResponderType2":"escalation","ResponderType3":"teams","Source":"http://prometheus","Tags":"tag1,tag2"},"source":"http://prometheus","responders":[{"name":"TeamA","type":"team"},{"name":"TeamB","type":"team"}],"tags":["tag1","tag2"],"note":"this is a note","priority":"P1"}
`,
},
} {
t.Run(tc.title, func(t *testing.T) {
notifier, err := New(tc.cfg, tmpl, logger)
require.NoError(t, err)
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")
expectedURL, _ := url.Parse("https://opsgenie/apiv2/alerts")
// Empty alert.
alert1 := &types.Alert{
Alert: model.Alert{
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
}
req, retry, err := notifier.createRequests(ctx, alert1)
require.NoError(t, err)
require.Len(t, req, 1)
require.True(t, retry)
require.Equal(t, expectedURL, req[0].URL)
require.Equal(t, "GenieKey http://am", req[0].Header.Get("Authorization"))
require.Equal(t, tc.expectedEmptyAlertBody, readBody(t, req[0]))
// Fully defined alert.
alert2 := &types.Alert{
Alert: model.Alert{
Labels: model.LabelSet{
"Message": "message",
"Description": "description",
"Source": "http://prometheus",
"ResponderName1": "TeamA",
"ResponderType1": "team",
"ResponderName2": "EscalationA",
"ResponderType2": "escalation",
"ResponderName3": "TeamA,TeamB",
"ResponderType3": "teams",
"Tags": "tag1,tag2",
"Note": "this is a note",
"Priority": "P1",
"Entity": "test-domain",
"Actions": "doThis,doThat",
},
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
}
req, retry, err = notifier.createRequests(ctx, alert2)
require.NoError(t, err)
require.True(t, retry)
require.Len(t, req, 1)
require.Equal(t, tc.expectedBody, readBody(t, req[0]))
// Broken API Key Template.
tc.cfg.APIKey = "{{ kaput "
_, _, err = notifier.createRequests(ctx, alert2)
require.Error(t, err)
require.Equal(t, "template: :1: function \"kaput\" not defined", err.Error())
})
}
}
func TestOpsGenieWithUpdate(t *testing.T) {
u, err := url.Parse("https://test-opsgenie-url")
require.NoError(t, err)
tmpl := test.CreateTmpl(t)
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")
opsGenieConfigWithUpdate := config.OpsGenieConfig{
Message: `{{ .CommonLabels.Message }}`,
Description: `{{ .CommonLabels.Description }}`,
UpdateAlerts: true,
APIKey: "test-api-key",
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
}
notifierWithUpdate, err := New(&opsGenieConfigWithUpdate, tmpl, promslog.NewNopLogger())
alert := &types.Alert{
Alert: model.Alert{
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
Labels: model.LabelSet{
"Message": "new message",
"Description": "new description",
},
},
}
require.NoError(t, err)
requests, retry, err := notifierWithUpdate.createRequests(ctx, alert)
require.NoError(t, err)
require.True(t, retry)
require.Len(t, requests, 3)
body0 := readBody(t, requests[0])
body1 := readBody(t, requests[1])
body2 := readBody(t, requests[2])
key, _ := notify.ExtractGroupKey(ctx)
alias := key.Hash()
require.Equal(t, "https://test-opsgenie-url/v2/alerts", requests[0].URL.String())
require.NotEmpty(t, body0)
require.Equal(t, requests[1].URL.String(), fmt.Sprintf("https://test-opsgenie-url/v2/alerts/%s/message?identifierType=alias", alias))
require.JSONEq(t, `{"message":"new message"}`, body1)
require.Equal(t, requests[2].URL.String(), fmt.Sprintf("https://test-opsgenie-url/v2/alerts/%s/description?identifierType=alias", alias))
require.JSONEq(t, `{"description":"new description"}`, body2)
}
func TestOpsGenieApiKeyFile(t *testing.T) {
u, err := url.Parse("https://test-opsgenie-url")
require.NoError(t, err)
tmpl := test.CreateTmpl(t)
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")
opsGenieConfigWithUpdate := config.OpsGenieConfig{
APIKeyFile: `./api_key_file`,
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
}
notifierWithUpdate, err := New(&opsGenieConfigWithUpdate, tmpl, promslog.NewNopLogger())
require.NoError(t, err)
requests, _, err := notifierWithUpdate.createRequests(ctx)
require.NoError(t, err)
require.Equal(t, "GenieKey my_secret_api_key", requests[0].Header.Get("Authorization"))
}
func readBody(t *testing.T, r *http.Request) string {
t.Helper()
body, err := io.ReadAll(r.Body)
require.NoError(t, err)
return string(body)
}

View File

@@ -0,0 +1,378 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package pagerduty
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"os"
"strings"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/alecthomas/units"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
)
const (
Integration = "pagerduty"
)
const (
maxEventSize int = 512000
// https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTc4-send-a-v1-event - 1024 characters or runes.
maxV1DescriptionLenRunes = 1024
// https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTgx-send-an-alert-event - 1024 characters or runes.
maxV2SummaryLenRunes = 1024
)
// Notifier implements a Notifier for PagerDuty notifications.
type Notifier struct {
conf *config.PagerdutyConfig
tmpl *template.Template
logger *slog.Logger
apiV1 string // for tests.
client *http.Client
retrier *notify.Retrier
}
// New returns a new PagerDuty notifier.
func New(c *config.PagerdutyConfig, t *template.Template, l *slog.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
client, err := notify.NewClientWithTracing(*c.HTTPConfig, Integration, httpOpts...)
if err != nil {
return nil, err
}
n := &Notifier{conf: c, tmpl: t, logger: l, client: client}
if c.ServiceKey != "" || c.ServiceKeyFile != "" {
n.apiV1 = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
// Retrying can solve the issue on 403 (rate limiting) and 5xx response codes.
// https://developer.pagerduty.com/docs/events-api-v1-overview#api-response-codes--retry-logic
n.retrier = &notify.Retrier{RetryCodes: []int{http.StatusForbidden}, CustomDetailsFunc: errDetails}
} else {
// Retrying can solve the issue on 429 (rate limiting) and 5xx response codes.
// https://developer.pagerduty.com/docs/events-api-v2-overview#response-codes--retry-logic
n.retrier = &notify.Retrier{RetryCodes: []int{http.StatusTooManyRequests}, CustomDetailsFunc: errDetails}
}
return n, nil
}
const (
pagerDutyEventTrigger = "trigger"
pagerDutyEventResolve = "resolve"
)
type pagerDutyMessage struct {
RoutingKey string `json:"routing_key,omitempty"`
ServiceKey string `json:"service_key,omitempty"`
DedupKey string `json:"dedup_key,omitempty"`
IncidentKey string `json:"incident_key,omitempty"`
EventType string `json:"event_type,omitempty"`
Description string `json:"description,omitempty"`
EventAction string `json:"event_action"`
Payload *pagerDutyPayload `json:"payload"`
Client string `json:"client,omitempty"`
ClientURL string `json:"client_url,omitempty"`
Details map[string]any `json:"details,omitempty"`
Images []pagerDutyImage `json:"images,omitempty"`
Links []pagerDutyLink `json:"links,omitempty"`
}
type pagerDutyLink struct {
HRef string `json:"href"`
Text string `json:"text"`
}
type pagerDutyImage struct {
Src string `json:"src"`
Alt string `json:"alt"`
Href string `json:"href"`
}
type pagerDutyPayload struct {
Summary string `json:"summary"`
Source string `json:"source"`
Severity string `json:"severity"`
Timestamp string `json:"timestamp,omitempty"`
Class string `json:"class,omitempty"`
Component string `json:"component,omitempty"`
Group string `json:"group,omitempty"`
CustomDetails map[string]any `json:"custom_details,omitempty"`
}
func (n *Notifier) encodeMessage(ctx context.Context, msg *pagerDutyMessage) (bytes.Buffer, error) {
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(msg); err != nil {
return buf, errors.WrapInternalf(err, errors.CodeInternal, "failed to encode PagerDuty message")
}
if buf.Len() > maxEventSize {
truncatedMsg := fmt.Sprintf("Custom details have been removed because the original event exceeds the maximum size of %s", units.MetricBytes(maxEventSize).String())
if n.apiV1 != "" {
msg.Details = map[string]any{"error": truncatedMsg}
} else {
msg.Payload.CustomDetails = map[string]any{"error": truncatedMsg}
}
n.logger.WarnContext(ctx, "Truncated Details because message of size exceeds limit", slog.String("message_size", units.MetricBytes(buf.Len()).String()), slog.String("max_size", units.MetricBytes(maxEventSize).String()))
buf.Reset()
if err := json.NewEncoder(&buf).Encode(msg); err != nil {
return buf, errors.WrapInternalf(err, errors.CodeInternal, "failed to encode PagerDuty message")
}
}
return buf, nil
}
func (n *Notifier) notifyV1(
ctx context.Context,
eventType string,
key notify.Key,
data *template.Data,
details map[string]any,
) (bool, error) {
var tmplErr error
tmpl := notify.TmplText(n.tmpl, data, &tmplErr)
description, truncated := notify.TruncateInRunes(tmpl(n.conf.Description), maxV1DescriptionLenRunes)
if truncated {
n.logger.WarnContext(ctx, "Truncated description", slog.Any("key", key), slog.Int("max_runes", maxV1DescriptionLenRunes))
}
serviceKey := string(n.conf.ServiceKey)
if serviceKey == "" {
content, fileErr := os.ReadFile(n.conf.ServiceKeyFile)
if fileErr != nil {
return false, errors.WrapInternalf(fileErr, errors.CodeInternal, "failed to read service key from file")
}
serviceKey = strings.TrimSpace(string(content))
}
msg := &pagerDutyMessage{
ServiceKey: tmpl(serviceKey),
EventType: eventType,
IncidentKey: key.Hash(),
Description: description,
Details: details,
}
if eventType == pagerDutyEventTrigger {
msg.Client = tmpl(n.conf.Client)
msg.ClientURL = tmpl(n.conf.ClientURL)
}
if tmplErr != nil {
return false, errors.WrapInternalf(tmplErr, errors.CodeInternal, "failed to template PagerDuty v1 message")
}
// Ensure that the service key isn't empty after templating.
if msg.ServiceKey == "" {
return false, errors.NewInternalf(errors.CodeInternal, "service key cannot be empty")
}
encodedMsg, err := n.encodeMessage(ctx, msg)
if err != nil {
return false, err
}
resp, err := notify.PostJSON(ctx, n.client, n.apiV1, &encodedMsg) //nolint:bodyclose
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "failed to post message to PagerDuty v1")
}
defer notify.Drain(resp)
return n.retrier.Check(resp.StatusCode, resp.Body)
}
func (n *Notifier) notifyV2(
ctx context.Context,
eventType string,
key notify.Key,
data *template.Data,
details map[string]any,
) (bool, error) {
var tmplErr error
tmpl := notify.TmplText(n.tmpl, data, &tmplErr)
if n.conf.Severity == "" {
n.conf.Severity = "error"
}
summary, truncated := notify.TruncateInRunes(tmpl(n.conf.Description), maxV2SummaryLenRunes)
if truncated {
n.logger.WarnContext(ctx, "Truncated summary", slog.Any("key", key), slog.Int("max_runes", maxV2SummaryLenRunes))
}
routingKey := string(n.conf.RoutingKey)
if routingKey == "" {
content, fileErr := os.ReadFile(n.conf.RoutingKeyFile)
if fileErr != nil {
return false, errors.WrapInternalf(fileErr, errors.CodeInternal, "failed to read routing key from file")
}
routingKey = strings.TrimSpace(string(content))
}
msg := &pagerDutyMessage{
Client: tmpl(n.conf.Client),
ClientURL: tmpl(n.conf.ClientURL),
RoutingKey: tmpl(routingKey),
EventAction: eventType,
DedupKey: key.Hash(),
Images: make([]pagerDutyImage, 0, len(n.conf.Images)),
Links: make([]pagerDutyLink, 0, len(n.conf.Links)),
Payload: &pagerDutyPayload{
Summary: summary,
Source: tmpl(n.conf.Source),
Severity: tmpl(n.conf.Severity),
CustomDetails: details,
Class: tmpl(n.conf.Class),
Component: tmpl(n.conf.Component),
Group: tmpl(n.conf.Group),
},
}
for _, item := range n.conf.Images {
image := pagerDutyImage{
Src: tmpl(item.Src),
Alt: tmpl(item.Alt),
Href: tmpl(item.Href),
}
if image.Src != "" {
msg.Images = append(msg.Images, image)
}
}
for _, item := range n.conf.Links {
link := pagerDutyLink{
HRef: tmpl(item.Href),
Text: tmpl(item.Text),
}
if link.HRef != "" {
msg.Links = append(msg.Links, link)
}
}
if tmplErr != nil {
return false, errors.WrapInternalf(tmplErr, errors.CodeInternal, "failed to template PagerDuty v2 message")
}
// Ensure that the routing key isn't empty after templating.
if msg.RoutingKey == "" {
return false, errors.NewInternalf(errors.CodeInternal, "routing key cannot be empty")
}
encodedMsg, err := n.encodeMessage(ctx, msg)
if err != nil {
return false, err
}
resp, err := notify.PostJSON(ctx, n.client, n.conf.URL.String(), &encodedMsg) //nolint:bodyclose
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "failed to post message to PagerDuty")
}
defer notify.Drain(resp)
retry, err := n.retrier.Check(resp.StatusCode, resp.Body)
if err != nil {
return retry, notify.NewErrorWithReason(notify.GetFailureReasonFromStatusCode(resp.StatusCode), err)
}
return retry, err
}
// Notify implements the Notifier interface.
func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
key, err := notify.ExtractGroupKey(ctx)
if err != nil {
return false, err
}
logger := n.logger.With(slog.Any("group_key", key))
var (
alerts = types.Alerts(as...)
data = notify.GetTemplateData(ctx, n.tmpl, as, logger)
eventType = pagerDutyEventTrigger
)
if alerts.Status() == model.AlertResolved {
eventType = pagerDutyEventResolve
}
logger.DebugContext(ctx, "extracted group key", slog.String("event_type", eventType))
details, err := n.renderDetails(data)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "failed to render details: %v", err)
}
if n.conf.Timeout > 0 {
nfCtx, cancel := context.WithTimeoutCause(ctx, n.conf.Timeout, errors.NewInternalf(errors.CodeTimeout, "configured pagerduty timeout reached (%s)", n.conf.Timeout))
defer cancel()
ctx = nfCtx
}
nf := n.notifyV2
if n.apiV1 != "" {
nf = n.notifyV1
}
retry, err := nf(ctx, eventType, key, data, details)
if err != nil {
if ctx.Err() != nil {
err = errors.WrapInternalf(err, errors.CodeInternal, "failed to notify PagerDuty: %v", context.Cause(ctx))
}
return retry, err
}
return retry, nil
}
func errDetails(status int, body io.Reader) string {
// See https://v2.developer.pagerduty.com/docs/trigger-events for the v1 events API.
// See https://v2.developer.pagerduty.com/docs/send-an-event-events-api-v2 for the v2 events API.
if status != http.StatusBadRequest || body == nil {
return ""
}
var pgr struct {
Status string `json:"status"`
Message string `json:"message"`
Errors []string `json:"errors"`
}
if err := json.NewDecoder(body).Decode(&pgr); err != nil {
return ""
}
return fmt.Sprintf("%s: %s", pgr.Message, strings.Join(pgr.Errors, ","))
}
func (n *Notifier) renderDetails(
data *template.Data,
) (map[string]any, error) {
var (
tmplTextErr error
tmplText = notify.TmplText(n.tmpl, data, &tmplTextErr)
tmplTextFunc = func(tmpl string) (string, error) {
return tmplText(tmpl), tmplTextErr
}
)
var err error
rendered := make(map[string]any, len(n.conf.Details))
for k, v := range n.conf.Details {
rendered[k], err = template.DeepCopyWithTemplate(v, tmplTextFunc)
if err != nil {
return nil, err
}
}
return rendered, nil
}

View File

@@ -0,0 +1,883 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package pagerduty
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"net/url"
"os"
"strings"
"testing"
"time"
"github.com/SigNoz/signoz/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/require"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/notify/test"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
)
func TestPagerDutyRetryV1(t *testing.T) {
notifier, err := New(
&config.PagerdutyConfig{
ServiceKey: config.Secret("01234567890123456789012345678901"),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
retryCodes := append(test.DefaultRetryCodes(), http.StatusForbidden)
for statusCode, expected := range test.RetryTests(retryCodes) {
actual, _ := notifier.retrier.Check(statusCode, nil)
require.Equal(t, expected, actual, "retryv1 - error on status %d", statusCode)
}
}
func TestPagerDutyRetryV2(t *testing.T) {
notifier, err := New(
&config.PagerdutyConfig{
RoutingKey: config.Secret("01234567890123456789012345678901"),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
retryCodes := append(test.DefaultRetryCodes(), http.StatusTooManyRequests)
for statusCode, expected := range test.RetryTests(retryCodes) {
actual, _ := notifier.retrier.Check(statusCode, nil)
require.Equal(t, expected, actual, "retryv2 - error on status %d", statusCode)
}
}
func TestPagerDutyRedactedURLV1(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
key := "01234567890123456789012345678901"
notifier, err := New(
&config.PagerdutyConfig{
ServiceKey: config.Secret(key),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
notifier.apiV1 = u.String()
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, key)
}
func TestPagerDutyRedactedURLV2(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
key := "01234567890123456789012345678901"
notifier, err := New(
&config.PagerdutyConfig{
URL: &config.URL{URL: u},
RoutingKey: config.Secret(key),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, key)
}
func TestPagerDutyV1ServiceKeyFromFile(t *testing.T) {
key := "01234567890123456789012345678901"
f, err := os.CreateTemp(t.TempDir(), "pagerduty_test")
require.NoError(t, err, "creating temp file failed")
_, err = f.WriteString(key)
require.NoError(t, err, "writing to temp file failed")
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
notifier, err := New(
&config.PagerdutyConfig{
ServiceKeyFile: f.Name(),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
notifier.apiV1 = u.String()
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, key)
}
func TestPagerDutyV2RoutingKeyFromFile(t *testing.T) {
key := "01234567890123456789012345678901"
f, err := os.CreateTemp(t.TempDir(), "pagerduty_test")
require.NoError(t, err, "creating temp file failed")
_, err = f.WriteString(key)
require.NoError(t, err, "writing to temp file failed")
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
notifier, err := New(
&config.PagerdutyConfig{
URL: &config.URL{URL: u},
RoutingKeyFile: f.Name(),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, key)
}
func TestPagerDutyTemplating(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dec := json.NewDecoder(r.Body)
out := make(map[string]any)
err := dec.Decode(&out)
if err != nil {
panic(err)
}
}))
defer srv.Close()
u, _ := url.Parse(srv.URL)
for _, tc := range []struct {
title string
cfg *config.PagerdutyConfig
retry bool
errMsg string
}{
{
title: "full-blown legacy message",
cfg: &config.PagerdutyConfig{
RoutingKey: config.Secret("01234567890123456789012345678901"),
Images: []config.PagerdutyImage{
{
Src: "{{ .Status }}",
Alt: "{{ .Status }}",
Href: "{{ .Status }}",
},
},
Links: []config.PagerdutyLink{
{
Href: "{{ .Status }}",
Text: "{{ .Status }}",
},
},
Details: map[string]any{
"firing": `{{ .Alerts.Firing | toJson }}`,
"resolved": `{{ .Alerts.Resolved | toJson }}`,
"num_firing": `{{ .Alerts.Firing | len }}`,
"num_resolved": `{{ .Alerts.Resolved | len }}`,
},
},
},
{
title: "full-blown legacy message",
cfg: &config.PagerdutyConfig{
RoutingKey: config.Secret("01234567890123456789012345678901"),
Images: []config.PagerdutyImage{
{
Src: "{{ .Status }}",
Alt: "{{ .Status }}",
Href: "{{ .Status }}",
},
},
Links: []config.PagerdutyLink{
{
Href: "{{ .Status }}",
Text: "{{ .Status }}",
},
},
Details: map[string]any{
"firing": `{{ template "pagerduty.default.instances" .Alerts.Firing }}`,
"resolved": `{{ template "pagerduty.default.instances" .Alerts.Resolved }}`,
"num_firing": `{{ .Alerts.Firing | len }}`,
"num_resolved": `{{ .Alerts.Resolved | len }}`,
},
},
},
{
title: "nested details",
cfg: &config.PagerdutyConfig{
RoutingKey: config.Secret("01234567890123456789012345678901"),
Details: map[string]any{
"a": map[string]any{
"b": map[string]any{
"c": map[string]any{
"firing": `{{ .Alerts.Firing | toJson }}`,
"resolved": `{{ .Alerts.Resolved | toJson }}`,
"num_firing": `{{ .Alerts.Firing | len }}`,
"num_resolved": `{{ .Alerts.Resolved | len }}`,
},
},
},
},
},
},
{
title: "nested details with template error",
cfg: &config.PagerdutyConfig{
RoutingKey: config.Secret("01234567890123456789012345678901"),
Details: map[string]any{
"a": map[string]any{
"b": map[string]any{
"c": map[string]any{
"firing": `{{ template "pagerduty.default.instances" .Alerts.Firing`,
},
},
},
},
},
errMsg: "failed to render details: template: :1: unclosed action",
},
{
title: "details with templating errors",
cfg: &config.PagerdutyConfig{
RoutingKey: config.Secret("01234567890123456789012345678901"),
Details: map[string]any{
"firing": `{{ .Alerts.Firing | toJson`,
"resolved": `{{ .Alerts.Resolved | toJson }}`,
"num_firing": `{{ .Alerts.Firing | len }}`,
"num_resolved": `{{ .Alerts.Resolved | len }}`,
},
},
errMsg: "failed to render details: template: :1: unclosed action",
},
{
title: "v2 message with templating errors",
cfg: &config.PagerdutyConfig{
RoutingKey: config.Secret("01234567890123456789012345678901"),
Severity: "{{ ",
},
errMsg: "failed to template",
},
{
title: "v1 message with templating errors",
cfg: &config.PagerdutyConfig{
ServiceKey: config.Secret("01234567890123456789012345678901"),
Client: "{{ ",
},
errMsg: "failed to template",
},
{
title: "routing key cannot be empty",
cfg: &config.PagerdutyConfig{
RoutingKey: config.Secret(`{{ "" }}`),
},
errMsg: "routing key cannot be empty",
},
{
title: "service_key cannot be empty",
cfg: &config.PagerdutyConfig{
ServiceKey: config.Secret(`{{ "" }}`),
},
errMsg: "service key cannot be empty",
},
} {
t.Run(tc.title, func(t *testing.T) {
tc.cfg.URL = &config.URL{URL: u}
tc.cfg.HTTPConfig = &commoncfg.HTTPClientConfig{}
pd, err := New(tc.cfg, test.CreateTmpl(t), promslog.NewNopLogger())
require.NoError(t, err)
if pd.apiV1 != "" {
pd.apiV1 = u.String()
}
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")
ok, err := pd.Notify(ctx, []*types.Alert{
{
Alert: model.Alert{
Labels: model.LabelSet{
"lbl1": "val1",
},
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
},
}...)
if tc.errMsg == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
if errors.Asc(err, errors.CodeInternal) {
_, _, errMsg, _, _, _ := errors.Unwrapb(err)
require.Contains(t, errMsg, tc.errMsg)
} else {
require.Contains(t, err.Error(), tc.errMsg)
}
}
require.Equal(t, tc.retry, ok)
})
}
}
func TestErrDetails(t *testing.T) {
for _, tc := range []struct {
status int
body io.Reader
exp string
}{
{
status: http.StatusBadRequest,
body: bytes.NewBuffer([]byte(
`{"status":"invalid event","message":"Event object is invalid","errors":["Length of 'routing_key' is incorrect (should be 32 characters)"]}`,
)),
exp: "Length of 'routing_key' is incorrect",
},
{
status: http.StatusBadRequest,
body: bytes.NewBuffer([]byte(`{"status"}`)),
exp: "",
},
{
status: http.StatusBadRequest,
exp: "",
},
{
status: http.StatusTooManyRequests,
exp: "",
},
} {
t.Run("", func(t *testing.T) {
err := errDetails(tc.status, tc.body)
require.Contains(t, err, tc.exp)
})
}
}
func TestEventSizeEnforcement(t *testing.T) {
bigDetailsV1 := map[string]any{
"firing": strings.Repeat("a", 513000),
}
bigDetailsV2 := map[string]any{
"firing": strings.Repeat("a", 513000),
}
// V1 Messages
msgV1 := &pagerDutyMessage{
ServiceKey: "01234567890123456789012345678901",
EventType: "trigger",
Details: bigDetailsV1,
}
notifierV1, err := New(
&config.PagerdutyConfig{
ServiceKey: config.Secret("01234567890123456789012345678901"),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
encodedV1, err := notifierV1.encodeMessage(context.Background(), msgV1)
require.NoError(t, err)
require.Contains(t, encodedV1.String(), `"details":{"error":"Custom details have been removed because the original event exceeds the maximum size of 512KB"}`)
// V2 Messages
msgV2 := &pagerDutyMessage{
RoutingKey: "01234567890123456789012345678901",
EventAction: "trigger",
Payload: &pagerDutyPayload{
CustomDetails: bigDetailsV2,
},
}
notifierV2, err := New(
&config.PagerdutyConfig{
RoutingKey: config.Secret("01234567890123456789012345678901"),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
encodedV2, err := notifierV2.encodeMessage(context.Background(), msgV2)
require.NoError(t, err)
require.Contains(t, encodedV2.String(), `"custom_details":{"error":"Custom details have been removed because the original event exceeds the maximum size of 512KB"}`)
}
func TestPagerDutyEmptySrcHref(t *testing.T) {
type pagerDutyEvent struct {
RoutingKey string `json:"routing_key"`
EventAction string `json:"event_action"`
DedupKey string `json:"dedup_key"`
Payload pagerDutyPayload `json:"payload"`
Images []pagerDutyImage
Links []pagerDutyLink
}
images := []config.PagerdutyImage{
{
Src: "",
Alt: "Empty src",
Href: "https://example.com/",
},
{
Src: "https://example.com/cat.jpg",
Alt: "Empty href",
Href: "",
},
{
Src: "https://example.com/cat.jpg",
Alt: "",
Href: "https://example.com/",
},
}
links := []config.PagerdutyLink{
{
Href: "",
Text: "Empty href",
},
{
Href: "https://example.com/",
Text: "",
},
}
expectedImages := make([]pagerDutyImage, 0, len(images))
for _, image := range images {
if image.Src == "" {
continue
}
expectedImages = append(expectedImages, pagerDutyImage{
Src: image.Src,
Alt: image.Alt,
Href: image.Href,
})
}
expectedLinks := make([]pagerDutyLink, 0, len(links))
for _, link := range links {
if link.Href == "" {
continue
}
expectedLinks = append(expectedLinks, pagerDutyLink{
HRef: link.Href,
Text: link.Text,
})
}
server := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var event pagerDutyEvent
if err := decoder.Decode(&event); err != nil {
panic(err)
}
if event.RoutingKey == "" || event.EventAction == "" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
for _, image := range event.Images {
if image.Src == "" {
http.Error(w, "Event object is invalid: 'image src' is missing or blank", http.StatusBadRequest)
return
}
}
for _, link := range event.Links {
if link.HRef == "" {
http.Error(w, "Event object is invalid: 'link href' is missing or blank", http.StatusBadRequest)
return
}
}
require.Equal(t, expectedImages, event.Images)
require.Equal(t, expectedLinks, event.Links)
},
))
defer server.Close()
url, err := url.Parse(server.URL)
require.NoError(t, err)
pagerDutyConfig := config.PagerdutyConfig{
HTTPConfig: &commoncfg.HTTPClientConfig{},
RoutingKey: config.Secret("01234567890123456789012345678901"),
URL: &config.URL{URL: url},
Images: images,
Links: links,
}
pagerDuty, err := New(&pagerDutyConfig, test.CreateTmpl(t), promslog.NewNopLogger())
require.NoError(t, err)
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")
_, err = pagerDuty.Notify(ctx, []*types.Alert{
{
Alert: model.Alert{
Labels: model.LabelSet{
"lbl1": "val1",
},
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
},
}...)
require.NoError(t, err)
}
func TestPagerDutyTimeout(t *testing.T) {
type pagerDutyEvent struct {
RoutingKey string `json:"routing_key"`
EventAction string `json:"event_action"`
DedupKey string `json:"dedup_key"`
Payload pagerDutyPayload `json:"payload"`
Images []pagerDutyImage
Links []pagerDutyLink
}
tests := map[string]struct {
latency time.Duration
timeout time.Duration
wantErr bool
}{
"success": {latency: 100 * time.Millisecond, timeout: 120 * time.Millisecond, wantErr: false},
"error": {latency: 100 * time.Millisecond, timeout: 80 * time.Millisecond, wantErr: true},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var event pagerDutyEvent
if err := decoder.Decode(&event); err != nil {
panic(err)
}
if event.RoutingKey == "" || event.EventAction == "" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
time.Sleep(tt.latency)
},
))
defer srv.Close()
u, err := url.Parse(srv.URL)
require.NoError(t, err)
cfg := config.PagerdutyConfig{
HTTPConfig: &commoncfg.HTTPClientConfig{},
RoutingKey: config.Secret("01234567890123456789012345678901"),
URL: &config.URL{URL: u},
Timeout: tt.timeout,
}
pd, err := New(&cfg, test.CreateTmpl(t), promslog.NewNopLogger())
require.NoError(t, err)
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")
alert := &types.Alert{
Alert: model.Alert{
Labels: model.LabelSet{
"lbl1": "val1",
},
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
}
_, err = pd.Notify(ctx, alert)
require.Equal(t, tt.wantErr, err != nil)
})
}
}
func TestRenderDetails(t *testing.T) {
type args struct {
details map[string]any
data *template.Data
}
tests := []struct {
name string
args args
want map[string]any
wantErr bool
}{
{
name: "flat",
args: args{
details: map[string]any{
"a": "{{ .Status }}",
"b": "String",
},
data: &template.Data{
Status: "Flat",
},
},
want: map[string]any{
"a": "Flat",
"b": "String",
},
wantErr: false,
},
{
name: "flat error",
args: args{
details: map[string]any{
"a": "{{ .Status",
},
data: &template.Data{
Status: "Error",
},
},
want: nil,
wantErr: true,
},
{
name: "nested",
args: args{
details: map[string]any{
"a": map[string]any{
"b": map[string]any{
"c": "{{ .Status }}",
"d": "String",
},
},
},
data: &template.Data{
Status: "Nested",
},
},
want: map[string]any{
"a": map[string]any{
"b": map[string]any{
"c": "Nested",
"d": "String",
},
},
},
wantErr: false,
},
{
name: "nested error",
args: args{
details: map[string]any{
"a": map[string]any{
"b": map[string]any{
"c": "{{ .Status",
},
},
},
data: &template.Data{
Status: "Error",
},
},
want: nil,
wantErr: true,
},
{
name: "alerts",
args: args{
details: map[string]any{
"alerts": map[string]any{
"firing": "{{ .Alerts.Firing | toJson }}",
"resolved": "{{ .Alerts.Resolved | toJson }}",
"num_firing": "{{ len .Alerts.Firing }}",
"num_resolved": "{{ len .Alerts.Resolved }}",
},
},
data: &template.Data{
Alerts: template.Alerts{
{
Status: "firing",
Annotations: template.KV{
"annotation1": "value1",
"annotation2": "value2",
},
Labels: template.KV{
"alertname": "Firing1",
"label1": "value1",
"label2": "value2",
},
Fingerprint: "fingerprint1",
GeneratorURL: "http://generator1",
StartsAt: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC),
EndsAt: time.Date(2001, time.January, 1, 1, 0, 0, 0, time.UTC),
},
{
Status: "firing",
Annotations: template.KV{
"annotation1": "value1",
"annotation2": "value2",
},
Labels: template.KV{
"alertname": "Firing2",
"label1": "value1",
"label2": "value2",
},
Fingerprint: "fingerprint2",
GeneratorURL: "http://generator2",
StartsAt: time.Date(2002, time.January, 1, 0, 0, 0, 0, time.UTC),
EndsAt: time.Date(2002, time.January, 1, 1, 0, 0, 0, time.UTC),
},
{
Status: "resolved",
Annotations: template.KV{
"annotation1": "value1",
"annotation2": "value2",
},
Labels: template.KV{
"alertname": "Resolved1",
"label1": "value1",
"label2": "value2",
},
Fingerprint: "fingerprint3",
GeneratorURL: "http://generator3",
StartsAt: time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC),
EndsAt: time.Date(2001, time.January, 1, 1, 0, 0, 0, time.UTC),
},
{
Status: "resolved",
Annotations: template.KV{
"annotation1": "value1",
"annotation2": "value2",
},
Labels: template.KV{
"alertname": "Resolved2",
"label1": "value1",
"label2": "value2",
},
Fingerprint: "fingerprint4",
GeneratorURL: "http://generator4",
StartsAt: time.Date(2002, time.January, 1, 0, 0, 0, 0, time.UTC),
EndsAt: time.Date(2002, time.January, 1, 1, 0, 0, 0, time.UTC),
},
},
},
},
want: map[string]any{
"alerts": map[string]any{
"firing": []any{
map[string]any{
"status": "firing",
"labels": map[string]any{
"alertname": "Firing1",
"label1": "value1",
"label2": "value2",
},
"annotations": map[string]any{
"annotation1": "value1",
"annotation2": "value2",
},
"startsAt": time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC).Format(time.RFC3339),
"endsAt": time.Date(2001, time.January, 1, 1, 0, 0, 0, time.UTC).Format(time.RFC3339),
"fingerprint": "fingerprint1",
"generatorURL": "http://generator1",
},
map[string]any{
"status": "firing",
"labels": map[string]any{
"alertname": "Firing2",
"label1": "value1",
"label2": "value2",
},
"annotations": map[string]any{
"annotation1": "value1",
"annotation2": "value2",
},
"startsAt": time.Date(2002, time.January, 1, 0, 0, 0, 0, time.UTC).Format(time.RFC3339),
"endsAt": time.Date(2002, time.January, 1, 1, 0, 0, 0, time.UTC).Format(time.RFC3339),
"fingerprint": "fingerprint2",
"generatorURL": "http://generator2",
},
},
"resolved": []any{
map[string]any{
"status": "resolved",
"labels": map[string]any{
"alertname": "Resolved1",
"label1": "value1",
"label2": "value2",
},
"annotations": map[string]any{
"annotation1": "value1",
"annotation2": "value2",
},
"startsAt": time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC).Format(time.RFC3339),
"endsAt": time.Date(2001, time.January, 1, 1, 0, 0, 0, time.UTC).Format(time.RFC3339),
"fingerprint": "fingerprint3",
"generatorURL": "http://generator3",
},
map[string]any{
"status": "resolved",
"labels": map[string]any{
"alertname": "Resolved2",
"label1": "value1",
"label2": "value2",
},
"annotations": map[string]any{
"annotation1": "value1",
"annotation2": "value2",
},
"startsAt": time.Date(2002, time.January, 1, 0, 0, 0, 0, time.UTC).Format(time.RFC3339),
"endsAt": time.Date(2002, time.January, 1, 1, 0, 0, 0, time.UTC).Format(time.RFC3339),
"fingerprint": "fingerprint4",
"generatorURL": "http://generator4",
},
},
"num_firing": 2,
"num_resolved": 2,
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
n := &Notifier{
conf: &config.PagerdutyConfig{
Details: tt.args.details,
},
tmpl: test.CreateTmpl(t),
}
got, err := n.renderDetails(tt.args.data)
if (err != nil) != tt.wantErr {
t.Errorf("renderDetails() error = %v, wantErr %v", err, tt.wantErr)
return
}
require.Equal(t, tt.want, got)
})
}
}

View File

@@ -2,8 +2,14 @@ package alertmanagernotify
import (
"log/slog"
"slices"
"github.com/SigNoz/signoz/pkg/alertmanager/alertmanagernotify/email"
"github.com/SigNoz/signoz/pkg/alertmanager/alertmanagernotify/msteamsv2"
"github.com/SigNoz/signoz/pkg/alertmanager/alertmanagernotify/opsgenie"
"github.com/SigNoz/signoz/pkg/alertmanager/alertmanagernotify/pagerduty"
"github.com/SigNoz/signoz/pkg/alertmanager/alertmanagernotify/slack"
"github.com/SigNoz/signoz/pkg/alertmanager/alertmanagernotify/webhook"
"github.com/SigNoz/signoz/pkg/types/alertmanagertypes"
"github.com/prometheus/alertmanager/config/receiver"
"github.com/prometheus/alertmanager/notify"
@@ -11,6 +17,15 @@ import (
"github.com/prometheus/alertmanager/types"
)
var customNotifierIntegrations = []string{
webhook.Integration,
email.Integration,
pagerduty.Integration,
opsgenie.Integration,
slack.Integration,
msteamsv2.Integration,
}
func NewReceiverIntegrations(nc alertmanagertypes.Receiver, tmpl *template.Template, logger *slog.Logger) ([]notify.Integration, error) {
upstreamIntegrations, err := receiver.BuildReceiverIntegrations(nc, tmpl, logger)
if err != nil {
@@ -31,14 +46,29 @@ func NewReceiverIntegrations(nc alertmanagertypes.Receiver, tmpl *template.Templ
)
for _, integration := range upstreamIntegrations {
// skip upstream msteamsv2 integration
if integration.Name() != "msteamsv2" {
// skip upstream integration if we support custom integration for it
if !slices.Contains(customNotifierIntegrations, integration.Name()) {
integrations = append(integrations, integration)
}
}
for i, c := range nc.WebhookConfigs {
add(webhook.Integration, i, c, func(l *slog.Logger) (notify.Notifier, error) { return webhook.New(c, tmpl, l) })
}
for i, c := range nc.EmailConfigs {
add(email.Integration, i, c, func(l *slog.Logger) (notify.Notifier, error) { return email.New(c, tmpl, l), nil })
}
for i, c := range nc.PagerdutyConfigs {
add(pagerduty.Integration, i, c, func(l *slog.Logger) (notify.Notifier, error) { return pagerduty.New(c, tmpl, l) })
}
for i, c := range nc.OpsGenieConfigs {
add(opsgenie.Integration, i, c, func(l *slog.Logger) (notify.Notifier, error) { return opsgenie.New(c, tmpl, l) })
}
for i, c := range nc.SlackConfigs {
add(slack.Integration, i, c, func(l *slog.Logger) (notify.Notifier, error) { return slack.New(c, tmpl, l) })
}
for i, c := range nc.MSTeamsV2Configs {
add("msteamsv2", i, c, func(l *slog.Logger) (notify.Notifier, error) {
add(msteamsv2.Integration, i, c, func(l *slog.Logger) (notify.Notifier, error) {
return msteamsv2.New(c, tmpl, `{{ template "msteamsv2.default.titleLink" . }}`, l)
})
}

View File

@@ -0,0 +1,281 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package slack
import (
"bytes"
"context"
"encoding/json"
"io"
"log/slog"
"net/http"
"os"
"strings"
"github.com/SigNoz/signoz/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
)
const (
Integration = "slack"
)
// https://api.slack.com/reference/messaging/attachments#legacy_fields - 1024, no units given, assuming runes or characters.
const maxTitleLenRunes = 1024
// Notifier implements a Notifier for Slack notifications.
type Notifier struct {
conf *config.SlackConfig
tmpl *template.Template
logger *slog.Logger
client *http.Client
retrier *notify.Retrier
postJSONFunc func(ctx context.Context, client *http.Client, url string, body io.Reader) (*http.Response, error)
}
// New returns a new Slack notification handler.
func New(c *config.SlackConfig, t *template.Template, l *slog.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
client, err := notify.NewClientWithTracing(*c.HTTPConfig, Integration, httpOpts...)
if err != nil {
return nil, err
}
return &Notifier{
conf: c,
tmpl: t,
logger: l,
client: client,
retrier: &notify.Retrier{},
postJSONFunc: notify.PostJSON,
}, nil
}
// request is the request for sending a slack notification.
type request struct {
Channel string `json:"channel,omitempty"`
Username string `json:"username,omitempty"`
IconEmoji string `json:"icon_emoji,omitempty"`
IconURL string `json:"icon_url,omitempty"`
LinkNames bool `json:"link_names,omitempty"`
Text string `json:"text,omitempty"`
Attachments []attachment `json:"attachments"`
}
// attachment is used to display a richly-formatted message block.
type attachment struct {
Title string `json:"title,omitempty"`
TitleLink string `json:"title_link,omitempty"`
Pretext string `json:"pretext,omitempty"`
Text string `json:"text"`
Fallback string `json:"fallback"`
CallbackID string `json:"callback_id"`
Fields []config.SlackField `json:"fields,omitempty"`
Actions []config.SlackAction `json:"actions,omitempty"`
ImageURL string `json:"image_url,omitempty"`
ThumbURL string `json:"thumb_url,omitempty"`
Footer string `json:"footer"`
Color string `json:"color,omitempty"`
MrkdwnIn []string `json:"mrkdwn_in,omitempty"`
}
// Notify implements the Notifier interface.
func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
key, err := notify.ExtractGroupKey(ctx)
if err != nil {
return false, err
}
logger := n.logger.With(slog.Any("group_key", key))
logger.DebugContext(ctx, "extracted group key")
var (
data = notify.GetTemplateData(ctx, n.tmpl, as, logger)
tmplText = notify.TmplText(n.tmpl, data, &err)
)
var markdownIn []string
if len(n.conf.MrkdwnIn) == 0 {
markdownIn = []string{"fallback", "pretext", "text"}
} else {
markdownIn = n.conf.MrkdwnIn
}
title, truncated := notify.TruncateInRunes(tmplText(n.conf.Title), maxTitleLenRunes)
if truncated {
logger.WarnContext(ctx, "Truncated title", slog.Int("max_runes", maxTitleLenRunes))
}
att := &attachment{
Title: title,
TitleLink: tmplText(n.conf.TitleLink),
Pretext: tmplText(n.conf.Pretext),
Text: tmplText(n.conf.Text),
Fallback: tmplText(n.conf.Fallback),
CallbackID: tmplText(n.conf.CallbackID),
ImageURL: tmplText(n.conf.ImageURL),
ThumbURL: tmplText(n.conf.ThumbURL),
Footer: tmplText(n.conf.Footer),
Color: tmplText(n.conf.Color),
MrkdwnIn: markdownIn,
}
numFields := len(n.conf.Fields)
if numFields > 0 {
fields := make([]config.SlackField, numFields)
for index, field := range n.conf.Fields {
// Check if short was defined for the field otherwise fallback to the global setting
var short bool
if field.Short != nil {
short = *field.Short
} else {
short = n.conf.ShortFields
}
// Rebuild the field by executing any templates and setting the new value for short
fields[index] = config.SlackField{
Title: tmplText(field.Title),
Value: tmplText(field.Value),
Short: &short,
}
}
att.Fields = fields
}
numActions := len(n.conf.Actions)
if numActions > 0 {
actions := make([]config.SlackAction, numActions)
for index, action := range n.conf.Actions {
slackAction := config.SlackAction{
Type: tmplText(action.Type),
Text: tmplText(action.Text),
URL: tmplText(action.URL),
Style: tmplText(action.Style),
Name: tmplText(action.Name),
Value: tmplText(action.Value),
}
if action.ConfirmField != nil {
slackAction.ConfirmField = &config.SlackConfirmationField{
Title: tmplText(action.ConfirmField.Title),
Text: tmplText(action.ConfirmField.Text),
OkText: tmplText(action.ConfirmField.OkText),
DismissText: tmplText(action.ConfirmField.DismissText),
}
}
actions[index] = slackAction
}
att.Actions = actions
}
req := &request{
Channel: tmplText(n.conf.Channel),
Username: tmplText(n.conf.Username),
IconEmoji: tmplText(n.conf.IconEmoji),
IconURL: tmplText(n.conf.IconURL),
LinkNames: n.conf.LinkNames,
Text: tmplText(n.conf.MessageText),
Attachments: []attachment{*att},
}
if err != nil {
return false, err
}
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(req); err != nil {
return false, err
}
var u string
if n.conf.APIURL != nil {
u = n.conf.APIURL.String()
} else {
content, err := os.ReadFile(n.conf.APIURLFile)
if err != nil {
return false, err
}
u = strings.TrimSpace(string(content))
}
if n.conf.Timeout > 0 {
postCtx, cancel := context.WithTimeoutCause(ctx, n.conf.Timeout, errors.NewInternalf(errors.CodeTimeout, "configured slack timeout reached (%s)", n.conf.Timeout))
defer cancel()
ctx = postCtx
}
resp, err := n.postJSONFunc(ctx, n.client, u, &buf) //nolint:bodyclose
if err != nil {
if ctx.Err() != nil {
err = errors.NewInternalf(errors.CodeInternal, "failed to post JSON to slack: %v", context.Cause(ctx))
}
return true, notify.RedactURL(err)
}
defer notify.Drain(resp)
// Use a retrier to generate an error message for non-200 responses and
// classify them as retriable or not.
retry, err := n.retrier.Check(resp.StatusCode, resp.Body)
if err != nil {
err = errors.NewInternalf(errors.CodeInternal, "channel %q: %v", req.Channel, err)
return retry, notify.NewErrorWithReason(notify.GetFailureReasonFromStatusCode(resp.StatusCode), err)
}
// Slack web API might return errors with a 200 response code.
// https://docs.slack.dev/tools/node-slack-sdk/web-api/#handle-errors
retry, err = checkResponseError(resp)
if err != nil {
err = errors.NewInternalf(errors.CodeInternal, "channel %q: %v", req.Channel, err)
return retry, notify.NewErrorWithReason(notify.ClientErrorReason, err)
}
return retry, nil
}
// checkResponseError parses out the error message from Slack API response.
func checkResponseError(resp *http.Response) (bool, error) {
body, err := io.ReadAll(resp.Body)
if err != nil {
return true, errors.WrapInternalf(err, errors.CodeInternal, "could not read response body")
}
if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") {
return checkJSONResponseError(body)
}
return checkTextResponseError(body)
}
// checkTextResponseError classifies plaintext responses from Slack.
// A plaintext (non-JSON) response is successful if it's a string "ok".
// This is typically a response for an Incoming Webhook
// (https://api.slack.com/messaging/webhooks#handling_errors)
func checkTextResponseError(body []byte) (bool, error) {
if !bytes.Equal(body, []byte("ok")) {
return false, errors.NewInternalf(errors.CodeInternal, "received an error response from Slack: %s", string(body))
}
return false, nil
}
// checkJSONResponseError classifies JSON responses from Slack.
func checkJSONResponseError(body []byte) (bool, error) {
// response is for parsing out errors from the JSON response.
type response struct {
OK bool `json:"ok"`
Error string `json:"error"`
}
var data response
if err := json.Unmarshal(body, &data); err != nil {
return true, errors.NewInternalf(errors.CodeInternal, "could not unmarshal JSON response %q: %v", string(body), err)
}
if !data.OK {
return false, errors.NewInternalf(errors.CodeInternal, "error response from Slack: %s", data.Error)
}
return false, nil
}

View File

@@ -0,0 +1,343 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package slack
import (
"context"
"encoding/json"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"net/url"
"os"
"strings"
"testing"
"time"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/require"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/notify/test"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
)
func TestSlackRetry(t *testing.T) {
notifier, err := New(
&config.SlackConfig{
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
for statusCode, expected := range test.RetryTests(test.DefaultRetryCodes()) {
actual, _ := notifier.retrier.Check(statusCode, nil)
require.Equal(t, expected, actual, "error on status %d", statusCode)
}
}
func TestSlackRedactedURL(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
notifier, err := New(
&config.SlackConfig{
APIURL: &config.SecretURL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, u.String())
}
func TestGettingSlackURLFromFile(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
f, err := os.CreateTemp(t.TempDir(), "slack_test")
require.NoError(t, err, "creating temp file failed")
_, err = f.WriteString(u.String())
require.NoError(t, err, "writing to temp file failed")
notifier, err := New(
&config.SlackConfig{
APIURLFile: f.Name(),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, u.String())
}
func TestTrimmingSlackURLFromFile(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
f, err := os.CreateTemp(t.TempDir(), "slack_test_newline")
require.NoError(t, err, "creating temp file failed")
_, err = f.WriteString(u.String() + "\n\n")
require.NoError(t, err, "writing to temp file failed")
notifier, err := New(
&config.SlackConfig{
APIURLFile: f.Name(),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, u.String())
}
func TestNotifier_Notify_WithReason(t *testing.T) {
tests := []struct {
name string
statusCode int
responseBody string
expectedReason notify.Reason
expectedErr string
expectedRetry bool
noError bool
}{
{
name: "with a 4xx status code",
statusCode: http.StatusUnauthorized,
expectedReason: notify.ClientErrorReason,
expectedRetry: false,
expectedErr: "unexpected status code 401",
},
{
name: "with a 5xx status code",
statusCode: http.StatusInternalServerError,
expectedReason: notify.ServerErrorReason,
expectedRetry: true,
expectedErr: "unexpected status code 500",
},
{
name: "with a 3xx status code",
statusCode: http.StatusTemporaryRedirect,
expectedReason: notify.DefaultReason,
expectedRetry: false,
expectedErr: "unexpected status code 307",
},
{
name: "with a 1xx status code",
statusCode: http.StatusSwitchingProtocols,
expectedReason: notify.DefaultReason,
expectedRetry: false,
expectedErr: "unexpected status code 101",
},
{
name: "2xx response with invalid JSON",
statusCode: http.StatusOK,
responseBody: `{"not valid json"}`,
expectedReason: notify.ClientErrorReason,
expectedRetry: true,
expectedErr: "could not unmarshal",
},
{
name: "2xx response with a JSON error",
statusCode: http.StatusOK,
responseBody: `{"ok":false,"error":"error_message"}`,
expectedReason: notify.ClientErrorReason,
expectedRetry: false,
expectedErr: "error response from Slack: error_message",
},
{
name: "2xx response with a plaintext error",
statusCode: http.StatusOK,
responseBody: "no_channel",
expectedReason: notify.ClientErrorReason,
expectedRetry: false,
expectedErr: "error response from Slack: no_channel",
},
{
name: "successful JSON response",
statusCode: http.StatusOK,
responseBody: `{"ok":true}`,
noError: true,
},
{
name: "successful plaintext response",
statusCode: http.StatusOK,
responseBody: "ok",
noError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
apiurl, _ := url.Parse("https://slack.com/post.Message")
notifier, err := New(
&config.SlackConfig{
NotifierConfig: config.NotifierConfig{},
HTTPConfig: &commoncfg.HTTPClientConfig{},
APIURL: &config.SecretURL{URL: apiurl},
Channel: "channelname",
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
notifier.postJSONFunc = func(ctx context.Context, client *http.Client, url string, body io.Reader) (*http.Response, error) {
resp := httptest.NewRecorder()
if strings.HasPrefix(tt.responseBody, "{") {
resp.Header().Add("Content-Type", "application/json; charset=utf-8")
}
resp.WriteHeader(tt.statusCode)
_, _ = resp.WriteString(tt.responseBody)
return resp.Result(), nil
}
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")
alert1 := &types.Alert{
Alert: model.Alert{
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
}
retry, err := notifier.Notify(ctx, alert1)
require.Equal(t, tt.expectedRetry, retry)
if tt.noError {
require.NoError(t, err)
} else {
var reasonError *notify.ErrorWithReason
require.ErrorAs(t, err, &reasonError)
require.Equal(t, tt.expectedReason, reasonError.Reason)
require.Contains(t, err.Error(), tt.expectedErr)
require.Contains(t, err.Error(), "channelname")
}
})
}
}
func TestSlackTimeout(t *testing.T) {
tests := map[string]struct {
latency time.Duration
timeout time.Duration
wantErr bool
}{
"success": {latency: 100 * time.Millisecond, timeout: 120 * time.Millisecond, wantErr: false},
"error": {latency: 100 * time.Millisecond, timeout: 80 * time.Millisecond, wantErr: true},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
u, _ := url.Parse("https://slack.com/post.Message")
notifier, err := New(
&config.SlackConfig{
NotifierConfig: config.NotifierConfig{},
HTTPConfig: &commoncfg.HTTPClientConfig{},
APIURL: &config.SecretURL{URL: u},
Channel: "channelname",
Timeout: tt.timeout,
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
notifier.postJSONFunc = func(ctx context.Context, client *http.Client, url string, body io.Reader) (*http.Response, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-time.After(tt.latency):
resp := httptest.NewRecorder()
resp.Header().Set("Content-Type", "application/json; charset=utf-8")
resp.WriteHeader(http.StatusOK)
_, _ = resp.WriteString(`{"ok":true}`)
return resp.Result(), nil
}
}
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "1")
alert := &types.Alert{
Alert: model.Alert{
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
}
_, err = notifier.Notify(ctx, alert)
require.Equal(t, tt.wantErr, err != nil)
})
}
}
func TestSlackMessageField(t *testing.T) {
// 1. Setup a fake Slack server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var body map[string]any
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
t.Fatal(err)
}
// 2. VERIFY: Top-level text exists
if body["text"] != "My Top Level Message" {
t.Errorf("Expected top-level 'text' to be 'My Top Level Message', got %v", body["text"])
}
// 3. VERIFY: Old attachments still exist
attachments, ok := body["attachments"].([]any)
if !ok || len(attachments) == 0 {
t.Errorf("Expected attachments to exist")
} else {
first := attachments[0].(map[string]any)
if first["title"] != "Old Attachment Title" {
t.Errorf("Expected attachment title 'Old Attachment Title', got %v", first["title"])
}
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"ok": true}`))
}))
defer server.Close()
// 4. Configure Notifier with BOTH new and old fields
u, _ := url.Parse(server.URL)
conf := &config.SlackConfig{
APIURL: &config.SecretURL{URL: u},
MessageText: "My Top Level Message", // Your NEW field
Title: "Old Attachment Title", // An OLD field
Channel: "#test-channel",
HTTPConfig: &commoncfg.HTTPClientConfig{},
}
tmpl, err := template.FromGlobs([]string{})
if err != nil {
t.Fatal(err)
}
tmpl.ExternalURL = u
logger := slog.New(slog.DiscardHandler)
notifier, err := New(conf, tmpl, logger)
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "test-group-key")
if _, err := notifier.Notify(ctx); err != nil {
t.Fatal("Notify failed:", err)
}
}

View File

@@ -0,0 +1,140 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package webhook
import (
"bytes"
"context"
"encoding/json"
"log/slog"
"net/http"
"os"
"strings"
"github.com/SigNoz/signoz/pkg/errors"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/types"
)
const (
Integration = "webhook"
)
// Notifier implements a Notifier for generic webhooks.
type Notifier struct {
conf *config.WebhookConfig
tmpl *template.Template
logger *slog.Logger
client *http.Client
retrier *notify.Retrier
}
// New returns a new Webhook.
func New(conf *config.WebhookConfig, t *template.Template, l *slog.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
client, err := notify.NewClientWithTracing(*conf.HTTPConfig, Integration, httpOpts...)
if err != nil {
return nil, err
}
return &Notifier{
conf: conf,
tmpl: t,
logger: l,
client: client,
// Webhooks are assumed to respond with 2xx response codes on a successful
// request and 5xx response codes are assumed to be recoverable.
retrier: &notify.Retrier{},
}, nil
}
// Message defines the JSON object send to webhook endpoints.
type Message struct {
*template.Data
// The protocol version.
Version string `json:"version"`
GroupKey string `json:"groupKey"`
TruncatedAlerts uint64 `json:"truncatedAlerts"`
}
func truncateAlerts(maxAlerts uint64, alerts []*types.Alert) ([]*types.Alert, uint64) {
if maxAlerts != 0 && uint64(len(alerts)) > maxAlerts {
return alerts[:maxAlerts], uint64(len(alerts)) - maxAlerts
}
return alerts, 0
}
// Notify implements the Notifier interface.
func (n *Notifier) Notify(ctx context.Context, alerts ...*types.Alert) (bool, error) {
alerts, numTruncated := truncateAlerts(n.conf.MaxAlerts, alerts)
data := notify.GetTemplateData(ctx, n.tmpl, alerts, n.logger)
groupKey, err := notify.ExtractGroupKey(ctx)
if err != nil {
return false, err
}
logger := n.logger.With(slog.Any("group_key", groupKey))
logger.DebugContext(ctx, "extracted group key")
msg := &Message{
Version: "4",
Data: data,
GroupKey: groupKey.String(),
TruncatedAlerts: numTruncated,
}
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(msg); err != nil {
return false, err
}
var url string
var tmplErr error
tmpl := notify.TmplText(n.tmpl, data, &tmplErr)
if n.conf.URL != "" {
url = tmpl(string(n.conf.URL))
} else {
content, err := os.ReadFile(n.conf.URLFile)
if err != nil {
return false, errors.WrapInternalf(err, errors.CodeInternal, "read url_file")
}
url = tmpl(strings.TrimSpace(string(content)))
}
if tmplErr != nil {
return false, errors.NewInternalf(errors.CodeInternal, "failed to template webhook URL: %v", tmplErr)
}
if url == "" {
return false, errors.NewInternalf(errors.CodeInternal, "webhook URL is empty after templating")
}
if n.conf.Timeout > 0 {
postCtx, cancel := context.WithTimeoutCause(ctx, n.conf.Timeout, errors.NewInternalf(errors.CodeTimeout, "configured webhook timeout reached (%s)", n.conf.Timeout))
defer cancel()
ctx = postCtx
}
resp, err := notify.PostJSON(ctx, n.client, url, &buf) //nolint:bodyclose
if err != nil {
if ctx.Err() != nil {
err = errors.NewInternalf(errors.CodeInternal, "failed to post JSON to webhook: %v", context.Cause(ctx))
}
return true, notify.RedactURL(err)
}
defer notify.Drain(resp)
shouldRetry, err := n.retrier.Check(resp.StatusCode, resp.Body)
if err != nil {
return shouldRetry, notify.NewErrorWithReason(notify.GetFailureReasonFromStatusCode(resp.StatusCode), err)
}
return shouldRetry, err
}

View File

@@ -0,0 +1,218 @@
// Copyright (c) 2026 SigNoz, Inc.
// Copyright 2019 Prometheus Team
// SPDX-License-Identifier: Apache-2.0
package webhook
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"
commoncfg "github.com/prometheus/common/config"
"github.com/prometheus/common/model"
"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/require"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/notify/test"
"github.com/prometheus/alertmanager/types"
)
func TestWebhookRetry(t *testing.T) {
notifier, err := New(
&config.WebhookConfig{
URL: config.SecretTemplateURL("http://example.com"),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
if err != nil {
require.NoError(t, err)
}
t.Run("test retry status code", func(t *testing.T) {
for statusCode, expected := range test.RetryTests(test.DefaultRetryCodes()) {
actual, _ := notifier.retrier.Check(statusCode, nil)
require.Equal(t, expected, actual, "error on status %d", statusCode)
}
})
t.Run("test retry error details", func(t *testing.T) {
for _, tc := range []struct {
status int
body io.Reader
exp string
}{
{
status: http.StatusBadRequest,
body: bytes.NewBuffer([]byte(
`{"status":"invalid event"}`,
)),
exp: fmt.Sprintf(`unexpected status code %d: {"status":"invalid event"}`, http.StatusBadRequest),
},
{
status: http.StatusBadRequest,
exp: fmt.Sprintf(`unexpected status code %d`, http.StatusBadRequest),
},
} {
t.Run("", func(t *testing.T) {
_, err = notifier.retrier.Check(tc.status, tc.body)
require.Equal(t, tc.exp, err.Error())
})
}
})
}
func TestWebhookTruncateAlerts(t *testing.T) {
alerts := make([]*types.Alert, 10)
truncatedAlerts, numTruncated := truncateAlerts(0, alerts)
require.Len(t, truncatedAlerts, 10)
require.EqualValues(t, 0, numTruncated)
truncatedAlerts, numTruncated = truncateAlerts(4, alerts)
require.Len(t, truncatedAlerts, 4)
require.EqualValues(t, 6, numTruncated)
truncatedAlerts, numTruncated = truncateAlerts(100, alerts)
require.Len(t, truncatedAlerts, 10)
require.EqualValues(t, 0, numTruncated)
}
func TestWebhookRedactedURL(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
secret := "secret"
notifier, err := New(
&config.WebhookConfig{
URL: config.SecretTemplateURL(u.String()),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, secret)
}
func TestWebhookReadingURLFromFile(t *testing.T) {
ctx, u, fn := test.GetContextWithCancelingURL()
defer fn()
f, err := os.CreateTemp(t.TempDir(), "webhook_url")
require.NoError(t, err, "creating temp file failed")
_, err = f.WriteString(u.String() + "\n")
require.NoError(t, err, "writing to temp file failed")
notifier, err := New(
&config.WebhookConfig{
URLFile: f.Name(),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
test.AssertNotifyLeaksNoSecret(ctx, t, notifier, u.String())
}
func TestWebhookURLTemplating(t *testing.T) {
var calledURL string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
calledURL = r.URL.Path
w.WriteHeader(http.StatusOK)
}))
defer srv.Close()
tests := []struct {
name string
url string
groupLabels model.LabelSet
alertLabels model.LabelSet
expectError bool
expectedErrMsg string
expectedPath string
}{
{
name: "templating with alert labels",
url: srv.URL + "/{{ .GroupLabels.alertname }}/{{ .CommonLabels.severity }}",
groupLabels: model.LabelSet{"alertname": "TestAlert"},
alertLabels: model.LabelSet{"alertname": "TestAlert", "severity": "critical"},
expectError: false,
expectedPath: "/TestAlert/critical",
},
{
name: "invalid template field",
url: srv.URL + "/{{ .InvalidField }}",
groupLabels: model.LabelSet{"alertname": "TestAlert"},
alertLabels: model.LabelSet{"alertname": "TestAlert"},
expectError: true,
expectedErrMsg: "failed to template webhook URL",
},
{
name: "template renders to empty string",
url: "{{ if .CommonLabels.nonexistent }}http://example.com{{ end }}",
groupLabels: model.LabelSet{"alertname": "TestAlert"},
alertLabels: model.LabelSet{"alertname": "TestAlert"},
expectError: true,
expectedErrMsg: "webhook URL is empty after templating",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
calledURL = "" // Reset for each test
notifier, err := New(
&config.WebhookConfig{
URL: config.SecretTemplateURL(tc.url),
HTTPConfig: &commoncfg.HTTPClientConfig{},
},
test.CreateTmpl(t),
promslog.NewNopLogger(),
)
require.NoError(t, err)
ctx := context.Background()
ctx = notify.WithGroupKey(ctx, "test-group")
if tc.groupLabels != nil {
ctx = notify.WithGroupLabels(ctx, tc.groupLabels)
}
alerts := []*types.Alert{
{
Alert: model.Alert{
Labels: tc.alertLabels,
StartsAt: time.Now(),
EndsAt: time.Now().Add(time.Hour),
},
},
}
_, err = notifier.Notify(ctx, alerts...)
if tc.expectError {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expectedErrMsg)
} else {
require.NoError(t, err)
require.Equal(t, tc.expectedPath, calledURL)
}
})
}
}

View File

@@ -223,6 +223,8 @@ func (r *provider) Match(ctx context.Context, orgID string, ruleID string, set m
for _, route := range expressionRoutes {
evaluateExpr, err := r.evaluateExpr(ctx, route.Expression, set)
if err != nil {
//nolint:sloglint
r.settings.Logger().WarnContext(ctx, "failed to evaluate route policy expression", errors.Attr(err), slog.String("rule.id", ruleID))
continue
}
if evaluateExpr {
@@ -298,7 +300,7 @@ func (r *provider) convertLabelSetToEnv(ctx context.Context, labelSet model.Labe
func (r *provider) evaluateExpr(ctx context.Context, expression string, labelSet model.LabelSet) (bool, error) {
env := r.convertLabelSetToEnv(ctx, labelSet)
program, err := expr.Compile(expression, expr.Env(env))
program, err := expr.Compile(expression, expr.Env(env), expr.AllowUndefinedVariables())
if err != nil {
return false, errors.NewInternalf(errors.CodeInternal, "error compiling route policy %s: %v", expression, err)
}

View File

@@ -644,6 +644,22 @@ func TestProvider_EvaluateExpression(t *testing.T) {
},
expected: true,
},
{
name: "nonexistent key OR check",
expression: `threshold.name = 'warning' OR ruleId = 'rule1'`,
labelSet: model.LabelSet{
"threshold.name": "warning",
},
expected: true,
},
{
name: "nonexistent key && check",
expression: `threshold.name = 'warning' && nonexistent = 'auth'`,
labelSet: model.LabelSet{
"threshold.name": "warning",
},
expected: false,
},
}
for _, tt := range tests {

View File

@@ -172,7 +172,7 @@ func Ast(cause error, typ typ) bool {
return t == typ
}
// Ast checks if the provided error matches the specified custom error code.
// Asc checks if the provided error matches the specified custom error code.
func Asc(cause error, code Code) bool {
_, c, _, _, _, _ := Unwrapb(cause)

View File

@@ -22,7 +22,7 @@ func newConfig() factory.Config {
Agent: AgentConfig{
// we will maintain the latest version of cloud integration agent from here,
// till we automate it externally or figure out a way to validate it.
Version: "v0.0.8",
Version: "v0.0.9",
},
}
}

View File

@@ -99,7 +99,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_account_id') as cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_ApplicationELB_ConsumedLCUs_max'\nGROUP BY cloud_account_id",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.account.id') as `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_ApplicationELB_ConsumedLCUs_max'\nGROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -115,7 +115,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_region') as cloud_region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_ApplicationELB_ConsumedLCUs_max'\n and JSONExtractString(labels, 'cloud_account_id') IN {{.Account}}\nGROUP BY cloud_region\n",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.region') as `cloud.region`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_ApplicationELB_ConsumedLCUs_max'\n and JSONExtractString(labels, 'cloud.account.id') IN {{.Account}}\nGROUP BY `cloud.region`\n",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -158,10 +158,10 @@
"id": "b282d9f1",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -171,10 +171,10 @@
"id": "71837c70",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -221,18 +221,18 @@
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
@@ -364,10 +364,10 @@
"id": "448b551a",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -377,10 +377,10 @@
"id": "a8821216",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -427,18 +427,18 @@
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
@@ -570,10 +570,10 @@
"id": "702a8765",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -583,10 +583,10 @@
"id": "32985f2d",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -625,18 +625,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -776,10 +776,10 @@
"id": "5807a1e3",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -789,10 +789,10 @@
"id": "0dd63d0c",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -826,18 +826,18 @@
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
@@ -969,10 +969,10 @@
"id": "72c256c0",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -982,10 +982,10 @@
"id": "b433c2a1",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1019,18 +1019,18 @@
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
@@ -1162,10 +1162,10 @@
"id": "9226a37c",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1175,10 +1175,10 @@
"id": "c3ff0c8f",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1221,18 +1221,18 @@
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
@@ -1364,10 +1364,10 @@
"id": "20627274",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1377,10 +1377,10 @@
"id": "cd861e27",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1401,18 +1401,18 @@
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
@@ -1544,10 +1544,10 @@
"id": "7d4a3494",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1557,10 +1557,10 @@
"id": "3c307858",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1594,18 +1594,18 @@
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
@@ -1737,10 +1737,10 @@
"id": "a416e862",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1750,10 +1750,10 @@
"id": "ed7d0a39",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1774,18 +1774,18 @@
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],

View File

@@ -393,7 +393,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_account_id') as `cloud_account_id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like '%aws_ApiGateway%'\nGROUP BY `cloud_account_id`",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.account.id') as `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like '%aws_ApiGateway%'\nGROUP BY `cloud.account.id`\n\n",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -409,7 +409,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_region') as `cloud_region`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like '%aws_ApiGateway%'\n and JSONExtractString(labels, 'cloud_account_id') IN {{.Account}}\nGROUP BY `cloud_region`",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.region') as `cloud.region`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like '%aws_ApiGateway%'\n and JSONExtractString(labels, 'cloud.account.id') IN {{.Account}}\nGROUP BY `cloud.region`\n",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -471,10 +471,10 @@
"id": "81918ce2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -484,10 +484,10 @@
"id": "114c7ff4",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -522,6 +522,7 @@
"id": "rest-requests-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -577,10 +578,10 @@
"id": "3c67d1fc",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -590,10 +591,10 @@
"id": "e2a96f23",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -628,6 +629,7 @@
"id": "rest-latency-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -683,10 +685,10 @@
"id": "b3ebaf28",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -696,10 +698,10 @@
"id": "f2030d94",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -734,6 +736,7 @@
"id": "rest-5xx-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -789,10 +792,10 @@
"id": "5f2f2892",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -802,10 +805,10 @@
"id": "960ee6d2",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -840,6 +843,7 @@
"id": "rest-integ-latency-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -895,10 +899,10 @@
"id": "8ec09e30",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -908,10 +912,10 @@
"id": "d1622884",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -946,6 +950,7 @@
"id": "rest-cache-hit-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1001,10 +1006,10 @@
"id": "f02d484d",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1014,10 +1019,10 @@
"id": "4d8ddc75",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1052,6 +1057,7 @@
"id": "rest-cache-miss-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1113,10 +1119,10 @@
"id": "http2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1126,10 +1132,10 @@
"id": "http3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1164,6 +1170,7 @@
"id": "http-count-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1219,10 +1226,10 @@
"id": "http4xx2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1232,10 +1239,10 @@
"id": "http4xx3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1270,6 +1277,7 @@
"id": "http-4xx-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1325,10 +1333,10 @@
"id": "http5xx2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1338,10 +1346,10 @@
"id": "http5xx3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1376,6 +1384,7 @@
"id": "http-5xx-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1431,10 +1440,10 @@
"id": "httplat2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1444,10 +1453,10 @@
"id": "httplat3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1482,6 +1491,7 @@
"id": "http-latency-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1537,10 +1547,10 @@
"id": "httpdata2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1550,10 +1560,10 @@
"id": "httpdata3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1588,6 +1598,7 @@
"id": "http-data-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1649,10 +1660,10 @@
"id": "wscon2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1662,10 +1673,10 @@
"id": "wscon3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1700,6 +1711,7 @@
"id": "ws-connect-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1755,10 +1767,10 @@
"id": "wsmsg2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1768,10 +1780,10 @@
"id": "wsmsg3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1806,6 +1818,7 @@
"id": "ws-message-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1861,10 +1874,10 @@
"id": "wscli2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1874,10 +1887,10 @@
"id": "wscli3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1912,6 +1925,7 @@
"id": "ws-client-error-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -1967,10 +1981,10 @@
"id": "wsexec2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1980,10 +1994,10 @@
"id": "wsexec3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2018,6 +2032,7 @@
"id": "ws-exec-error-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -2073,10 +2088,10 @@
"id": "wsint2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2086,10 +2101,10 @@
"id": "wsint3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2124,6 +2139,7 @@
"id": "ws-integ-error-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
@@ -2185,10 +2201,10 @@
"id": "commonintlat2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2198,10 +2214,10 @@
"id": "commonintlat3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2257,6 +2273,7 @@
"id": "common-integ-latency-query",
"queryType": "builder"
},
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,

View File

@@ -153,7 +153,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_DynamoDB%' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_DynamoDB%' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -169,7 +169,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_DynamoDB%' GROUP BY cloud_account_id",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_DynamoDB%' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -184,7 +184,7 @@
"multiSelect": true,
"name": "Table",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'TableName') AS table FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name like '%aws_DynamoDB%' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} AND JSONExtractString(labels, 'cloud_region') IN {{.Region}} and table != '' GROUP BY table\n",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'TableName') AS table FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name like '%aws_DynamoDB%' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}} and table != '' GROUP BY table\n",
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
@@ -228,10 +228,10 @@
"id": "fc55895c",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -241,10 +241,10 @@
"id": "8b3f3e0b",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -384,10 +384,10 @@
"id": "f7b176f8",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -397,10 +397,10 @@
"id": "9a023ab7",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -540,10 +540,10 @@
"id": "ec5ebf95",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -553,10 +553,10 @@
"id": "5b2fb00e",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -696,10 +696,10 @@
"id": "3815cf09",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -709,10 +709,10 @@
"id": "a783bd91",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -852,10 +852,10 @@
"id": "edcbcb83",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -865,10 +865,10 @@
"id": "224766cb",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1008,10 +1008,10 @@
"id": "c237482a",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1021,10 +1021,10 @@
"id": "e3a117d5",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1164,10 +1164,10 @@
"id": "b867513b",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1177,10 +1177,10 @@
"id": "9c10cbaa",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1344,10 +1344,10 @@
"id": "7e2aa806",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1357,10 +1357,10 @@
"id": "dd49e062",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1524,10 +1524,10 @@
"id": "b3e029fa",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1537,10 +1537,10 @@
"id": "e6764d50",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1680,10 +1680,10 @@
"id": "80ba9142",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1693,10 +1693,10 @@
"id": "9c802cf0",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1836,10 +1836,10 @@
"id": "db6edb77",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1849,10 +1849,10 @@
"id": "8b86de4a",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2016,10 +2016,10 @@
"id": "93bef7f0",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2029,10 +2029,10 @@
"id": "4a293ec8",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2196,10 +2196,10 @@
"id": "28fcd3cd",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2209,10 +2209,10 @@
"id": "619578e5",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2376,10 +2376,10 @@
"id": "5a060b5e",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2389,10 +2389,10 @@
"id": "3a1cb5ff",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2532,10 +2532,10 @@
"id": "58bc06b3",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2545,10 +2545,10 @@
"id": "d6d7a8fb",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2654,4 +2654,4 @@
"yAxisUnit": "none"
}
]
}
}

View File

@@ -72,7 +72,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_account_id') as cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_EC2_CPUUtilization_sum'\nGROUP BY cloud_account_id",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.account.id') as `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_EC2_CPUUtilization_sum'\nGROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -87,7 +87,7 @@
"multiSelect": false,
"name": "Region",
"order": 0,
"queryValue": "\nSELECT JSONExtractString(labels, 'cloud_region') as cloud_region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_EC2_CPUUtilization_sum'\n and JSONExtractString(labels, 'cloud_account_id') IN {{.Account}}\nGROUP BY cloud_region",
"queryValue": "\nSELECT JSONExtractString(labels, 'cloud.region') as `cloud.region`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_EC2_CPUUtilization_sum'\n and JSONExtractString(labels, 'cloud.account.id') IN {{.Account}}\nGROUP BY `cloud.region`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -130,10 +130,10 @@
"id": "d302d50d",
"key": {
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
@@ -143,10 +143,10 @@
"id": "e6c54e87",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -156,10 +156,10 @@
"id": "7907211a",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -172,31 +172,31 @@
"groupBy": [
{
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
"having": [],
"legend": "{{service_instance_id}}",
"legend": "{{service.instance.id}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -323,10 +323,10 @@
"id": "30ded0dc",
"key": {
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
@@ -336,10 +336,10 @@
"id": "c935f6ec",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -349,10 +349,10 @@
"id": "d092fef8",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -365,31 +365,31 @@
"groupBy": [
{
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
"having": [],
"legend": "{{service_instance_id}}",
"legend": "{{service.instance.id}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -516,10 +516,10 @@
"id": "a5fbfa4a",
"key": {
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
@@ -529,10 +529,10 @@
"id": "87071f13",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -542,10 +542,10 @@
"id": "c84a88c4",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -558,31 +558,31 @@
"groupBy": [
{
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
"having": [],
"legend": "{{service_instance_id}} - Reads",
"legend": "{{service.instance.id}} - Reads",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -610,10 +610,10 @@
"id": "4d10ca4b",
"key": {
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
@@ -623,10 +623,10 @@
"id": "fc2db932",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -636,10 +636,10 @@
"id": "a3fd74c0",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -652,31 +652,31 @@
"groupBy": [
{
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
"having": [],
"legend": "{{service_instance_id}} - Writes",
"legend": "{{service.instance.id}} - Writes",
"limit": null,
"orderBy": [],
"queryName": "B",
@@ -803,10 +803,10 @@
"id": "85d84806",
"key": {
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
@@ -816,10 +816,10 @@
"id": "f2074606",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -829,10 +829,10 @@
"id": "134c7ca9",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -845,31 +845,31 @@
"groupBy": [
{
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
"having": [],
"legend": "{{service_instance_id}} - Reads",
"legend": "{{service.instance.id}} - Reads",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -897,10 +897,10 @@
"id": "47e0c00f",
"key": {
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
@@ -910,10 +910,10 @@
"id": "0a157dfe",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -923,10 +923,10 @@
"id": "a7d1e8df",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -939,31 +939,31 @@
"groupBy": [
{
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
"having": [],
"legend": "{{service_instance_id}} - Writes",
"legend": "{{service.instance.id}} - Writes",
"limit": null,
"orderBy": [],
"queryName": "B",
@@ -1090,10 +1090,10 @@
"id": "12d6748d",
"key": {
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
@@ -1103,10 +1103,10 @@
"id": "df3a8da1",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1116,10 +1116,10 @@
"id": "81ec53f4",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1132,31 +1132,31 @@
"groupBy": [
{
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
"having": [],
"legend": "{{service_instance_id}}",
"legend": "{{service.instance.id}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -1283,10 +1283,10 @@
"id": "d301aaa7",
"key": {
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
"op": "!=",
@@ -1296,10 +1296,10 @@
"id": "e8afaa3b",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1309,10 +1309,10 @@
"id": "d67487ab",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1325,31 +1325,31 @@
"groupBy": [
{
"dataType": "string",
"id": "service_instance_id--string--tag--false",
"id": "service.instance.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "service_instance_id",
"key": "service.instance.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
}
],
"having": [],
"legend": "{{service_instance_id}}",
"legend": "{{service.instance.id}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -1443,4 +1443,4 @@
"yAxisUnit": "binBps"
}
]
}
}

View File

@@ -100,7 +100,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' GROUP BY cloud_account_id",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -116,7 +116,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -132,7 +132,7 @@
"multiSelect": false,
"name": "Cluster",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS cluster\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_ECS%' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} AND JSONExtractString(labels, 'cloud_region') IN {{.Region}}\nGROUP BY cluster",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS cluster\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_ECS%' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}}\nGROUP BY cluster",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -178,10 +178,10 @@
"id": "c002d3ea",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -191,10 +191,10 @@
"id": "d95dc93f",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -358,10 +358,10 @@
"id": "8ae50256",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -371,10 +371,10 @@
"id": "dada2be4",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -538,10 +538,10 @@
"id": "840f6a82",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -551,10 +551,10 @@
"id": "e494eace",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -711,10 +711,10 @@
"id": "98cf55a2",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -724,10 +724,10 @@
"id": "dc2591e8",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -880,10 +880,10 @@
"id": "6d3fb70d",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -893,10 +893,10 @@
"id": "763ec68f",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1049,10 +1049,10 @@
"id": "4cabe614",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1062,10 +1062,10 @@
"id": "077e09db",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1218,10 +1218,10 @@
"id": "8e15b10c",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1231,10 +1231,10 @@
"id": "92d56544",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1411,10 +1411,10 @@
"id": "6a1059e5",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1424,10 +1424,10 @@
"id": "fe0d40de",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1604,10 +1604,10 @@
"id": "89f0e499",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1617,10 +1617,10 @@
"id": "91ce3091",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1805,10 +1805,10 @@
"id": "edef4331",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1818,10 +1818,10 @@
"id": "d6081c36",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1962,4 +1962,4 @@
"yAxisUnit": "Bps"
}
]
}
}

View File

@@ -121,7 +121,7 @@
"customValue": "",
"defaultValue": "",
"description": "",
"dynamicVariablesAttribute": "cloud_region",
"dynamicVariablesAttribute": "cloud.region",
"dynamicVariablesSource": "Metrics",
"id": "3e37f808-da29-4f42-b9fd-ed0c5a9f55af",
"key": "3e37f808-da29-4f42-b9fd-ed0c5a9f55af",
@@ -159,7 +159,7 @@
"customValue": "",
"defaultValue": "",
"description": "",
"dynamicVariablesAttribute": "cloud_account_id",
"dynamicVariablesAttribute": "cloud.account.id",
"dynamicVariablesSource": "Metrics",
"id": "ae760815-3966-421c-97ac-f7793e524779",
"key": "ae760815-3966-421c-97ac-f7793e524779",
@@ -232,7 +232,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
},
"functions": [],
"groupBy": [],
@@ -364,7 +364,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service"
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service"
},
"functions": [],
"groupBy": [],
@@ -496,7 +496,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
},
"functions": [],
"groupBy": [],
@@ -628,7 +628,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service"
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service"
},
"functions": [],
"groupBy": [],
@@ -760,7 +760,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
},
"functions": [],
"groupBy": [
@@ -901,7 +901,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
},
"functions": [],
"groupBy": [
@@ -1042,7 +1042,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
},
"functions": [],
"groupBy": [
@@ -1183,7 +1183,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
},
"functions": [],
"groupBy": [
@@ -1324,7 +1324,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
},
"functions": [],
"groupBy": [
@@ -1465,7 +1465,7 @@
"disabled": false,
"expression": "A",
"filter": {
"expression": "cloud_account_id = $Account AND cloud_region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
"expression": "cloud.account.id = $Account AND cloud.region = $Region AND ClusterName = $Cluster AND ServiceName = $Service AND TaskId in $TaskId AND TaskId != \"\""
},
"functions": [],
"groupBy": [
@@ -1572,5 +1572,5 @@
"yAxisUnit": "Bps"
}
],
"uuid": "019ada51-9b8a-75b8-aa67-8fd35114855c"
"uuid": "019add91-55bd-778b-8459-60e19b691b6e"
}

View File

@@ -54,7 +54,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' GROUP BY cloud_account_id",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -70,7 +70,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -86,7 +86,7 @@
"multiSelect": true,
"name": "Cluster",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS cluster\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} AND JSONExtractString(labels, 'cloud_region') IN {{.Region}}\nGROUP BY cluster",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS cluster\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}}\nGROUP BY cluster",
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
@@ -130,10 +130,10 @@
"id": "26ac617d",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -143,10 +143,10 @@
"id": "57172ed9",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -318,10 +318,10 @@
"id": "cd4b8848",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -331,10 +331,10 @@
"id": "aa5115c6",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -506,10 +506,10 @@
"id": "2c13c8ee",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -519,10 +519,10 @@
"id": "f489f6a8",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -694,10 +694,10 @@
"id": "758ba906",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -707,10 +707,10 @@
"id": "4ffe6bf7",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -848,4 +848,4 @@
"yAxisUnit": "none"
}
]
}
}

View File

@@ -1,851 +0,0 @@
{
"description": "View key AWS ECS metrics with an out of the box dashboard.\n",
"image":"data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%3Csvg%20width%3D%2280px%22%20height%3D%2280px%22%20viewBox%3D%220%200%2080%2080%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%3C!--%20Generator%3A%20Sketch%2064%20(93537)%20-%20https%3A%2F%2Fsketch.com%20--%3E%3Ctitle%3EIcon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%3C%2Ftitle%3E%3Cdesc%3ECreated%20with%20Sketch.%3C%2Fdesc%3E%3Cdefs%3E%3ClinearGradient%20x1%3D%220%25%22%20y1%3D%22100%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%20id%3D%22linearGradient-1%22%3E%3Cstop%20stop-color%3D%22%23C8511B%22%20offset%3D%220%25%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23FF9900%22%20offset%3D%22100%25%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20id%3D%22Icon-Architecture%2F64%2FArch_Amazon-Elastic-Container-Service_64%22%20stroke%3D%22none%22%20stroke-width%3D%221%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Cg%20id%3D%22Icon-Architecture-BG%2F64%2FContainers%22%20fill%3D%22url(%23linearGradient-1)%22%3E%3Crect%20id%3D%22Rectangle%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2280%22%20height%3D%2280%22%3E%3C%2Frect%3E%3C%2Fg%3E%3Cpath%20d%3D%22M64%2C48.2340095%20L56%2C43.4330117%20L56%2C32.0000169%20C56%2C31.6440171%2055.812%2C31.3150172%2055.504%2C31.1360173%20L44%2C24.4260204%20L44%2C14.7520248%20L64%2C26.5710194%20L64%2C48.2340095%20Z%20M65.509%2C25.13902%20L43.509%2C12.139026%20C43.199%2C11.9560261%2042.818%2C11.9540261%2042.504%2C12.131026%20C42.193%2C12.3090259%2042%2C12.6410257%2042%2C13.0000256%20L42%2C25.0000201%20C42%2C25.3550199%2042.189%2C25.6840198%2042.496%2C25.8640197%20L54%2C32.5740166%20L54%2C44.0000114%20C54%2C44.3510113%2054.185%2C44.6770111%2054.486%2C44.857011%20L64.486%2C50.8570083%20C64.644%2C50.9520082%2064.822%2C51%2065%2C51%20C65.17%2C51%2065.34%2C50.9570082%2065.493%2C50.8700083%20C65.807%2C50.6930084%2066%2C50.3600085%2066%2C50%20L66%2C26.0000196%20C66%2C25.6460198%2065.814%2C25.31902%2065.509%2C25.13902%20L65.509%2C25.13902%20Z%20M40.445%2C66.863001%20L17%2C54.3990067%20L17%2C26.5710194%20L37%2C14.7520248%20L37%2C24.4510204%20L26.463%2C31.1560173%20C26.175%2C31.3400172%2026%2C31.6580171%2026%2C32.0000169%20L26%2C49.0000091%20C26%2C49.373009%2026.208%2C49.7150088%2026.538%2C49.8870087%20L39.991%2C56.8870055%20C40.28%2C57.0370055%2040.624%2C57.0380055%2040.912%2C56.8880055%20L53.964%2C50.1440086%20L61.996%2C54.9640064%20L40.445%2C66.863001%20Z%20M64.515%2C54.1420068%20L54.515%2C48.1420095%20C54.217%2C47.9640096%2053.849%2C47.9520096%2053.541%2C48.1120095%20L40.455%2C54.8730065%20L28%2C48.3930094%20L28%2C32.5490167%20L38.537%2C25.8440197%20C38.825%2C25.6600198%2039%2C25.3420199%2039%2C25.0000201%20L39%2C13.0000256%20C39%2C12.6410257%2038.808%2C12.3090259%2038.496%2C12.131026%20C38.184%2C11.9540261%2037.802%2C11.9560261%2037.491%2C12.139026%20L15.491%2C25.13902%20C15.187%2C25.31902%2015%2C25.6460198%2015%2C26.0000196%20L15%2C55%20C15%2C55.3690062%2015.204%2C55.7090061%2015.53%2C55.883006%20L39.984%2C68.8830001%20C40.131%2C68.961%2040.292%2C69%2040.453%2C69%20C40.62%2C69%2040.786%2C68.958%2040.937%2C68.8750001%20L64.484%2C55.875006%20C64.797%2C55.7020061%2064.993%2C55.3750062%2065.0001416%2C55.0180064%20C65.006%2C54.6600066%2064.821%2C54.3260067%2064.515%2C54.1420068%20L64.515%2C54.1420068%20Z%22%20id%3D%22Amazon-Elastic-Container-Service_Icon_64_Squid%22%20fill%3D%22%23FFFFFF%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E",
"layout": [
{
"h": 6,
"i": "f78becf8-0328-48b4-84b6-ff4dac325940",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 0
},
{
"h": 6,
"i": "2b4eac06-b426-4f78-b874-2e1734c4104b",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 0
},
{
"h": 6,
"i": "5bea2bc0-13a2-4937-bccb-60ffe8a43ad5",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 6
},
{
"h": 6,
"i": "6fac67b0-50ec-4b43-ac4b-320a303d0369",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 6
}
],
"panelMap": {},
"tags": [],
"title": "AWS ECS Overview",
"uploadedGrafana": false,
"variables": {
"51f4fa2b-89c7-47c2-9795-f32cffaab985": {
"allSelected": false,
"customValue": "",
"description": "AWS Account ID",
"id": "51f4fa2b-89c7-47c2-9795-f32cffaab985",
"key": "51f4fa2b-89c7-47c2-9795-f32cffaab985",
"modificationUUID": "7b814d17-8fff-4ed6-a4ea-90e3b1a97584",
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
"type": "QUERY"
},
"9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0": {
"allSelected": false,
"customValue": "",
"description": "Account Region",
"id": "9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0",
"key": "9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0",
"modificationUUID": "3b5f499b-22a3-4c8a-847c-8d3811c9e6b2",
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
},
"bfbdbcbe-a168-4d81-b108-36339e249116": {
"allSelected": true,
"customValue": "",
"description": "ECS Cluster Name",
"id": "bfbdbcbe-a168-4d81-b108-36339e249116",
"key": "bfbdbcbe-a168-4d81-b108-36339e249116",
"modificationUUID": "9fb0d63c-ac6c-497d-82b3-17d95944e245",
"multiSelect": true,
"name": "Cluster",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS cluster\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_ECS_MemoryUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}}\nGROUP BY cluster",
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
}
},
"version": "v4",
"widgets": [
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "f78becf8-0328-48b4-84b6-ff4dac325940",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_MemoryUtilization_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_MemoryUtilization_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filters": {
"items": [
{
"id": "26ac617d",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "57172ed9",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "49b9f85e",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
{
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
}
],
"having": [],
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "56068fdd-d523-4117-92fa-87c6518ad07c",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Maximum Memory Utilization",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "2b4eac06-b426-4f78-b874-2e1734c4104b",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_MemoryUtilization_min--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_MemoryUtilization_min",
"type": "Gauge"
},
"aggregateOperator": "min",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filters": {
"items": [
{
"id": "cd4b8848",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "aa5115c6",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "f60677b6",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
{
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
}
],
"having": [],
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "avg",
"spaceAggregation": "min",
"stepInterval": 60,
"timeAggregation": "min"
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "fb19342e-cbde-40d8-b12f-ad108698356b",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Minimum Memory Utilization",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "5bea2bc0-13a2-4937-bccb-60ffe8a43ad5",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_CPUUtilization_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_CPUUtilization_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filters": {
"items": [
{
"id": "2c13c8ee",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "f489f6a8",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "94012320",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
{
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
}
],
"having": [],
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "273e0a76-c780-4b9a-9b03-2649d4227173",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Maximum CPU Utilization",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "6fac67b0-50ec-4b43-ac4b-320a303d0369",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_ECS_CPUUtilization_min--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_ECS_CPUUtilization_min",
"type": "Gauge"
},
"aggregateOperator": "min",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filters": {
"items": [
{
"id": "758ba906",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "4ffe6bf7",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
},
{
"id": "53d98059",
"key": {
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
},
"op": "in",
"value": [
"$Cluster"
]
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "ServiceName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ServiceName",
"type": "tag"
},
{
"dataType": "string",
"id": "ClusterName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "ClusterName",
"type": "tag"
}
],
"having": [],
"legend": "{{ServiceName}} ({{ClusterName}})",
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "avg",
"spaceAggregation": "min",
"stepInterval": 60,
"timeAggregation": "min"
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "c89482b3-5a98-4e2c-be0d-ef036d7dac05",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Minimum CPU Utilization",
"yAxisUnit": "none"
}
]
}

View File

@@ -99,7 +99,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_ContainerInsights%' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_ContainerInsights%' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -115,7 +115,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_ContainerInsights%' GROUP BY cloud_account_id",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_ContainerInsights%' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -130,7 +130,7 @@
"multiSelect": true,
"name": "Namespace",
"order": 3,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'Namespace') AS namespace FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name like '%aws_ContainerInsights%' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} AND JSONExtractString(labels, 'cloud_region') IN {{.Region}} AND JSONExtractString(labels, 'ClusterName') IN {{.Cluster}} and namespace != '' GROUP BY namespace\n",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'Namespace') AS namespace FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name like '%aws_ContainerInsights%' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}} AND JSONExtractString(labels, 'ClusterName') IN {{.Cluster}} and namespace != '' GROUP BY namespace\n",
"showALLOption": true,
"sort": "DISABLED",
"textboxValue": "",
@@ -146,7 +146,7 @@
"multiSelect": false,
"name": "Cluster",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS table FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name like '%aws_ContainerInsights%' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} AND JSONExtractString(labels, 'cloud_region') IN {{.Region}} and table != '' GROUP BY table\n",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS table FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name like '%aws_ContainerInsights%' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}} and table != '' GROUP BY table\n",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -190,10 +190,10 @@
"id": "3c9d3220",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -203,10 +203,10 @@
"id": "c7ec3ea4",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -406,10 +406,10 @@
"id": "84a456ab",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -419,10 +419,10 @@
"id": "4317ebfb",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -622,10 +622,10 @@
"id": "a93d165c",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -635,10 +635,10 @@
"id": "99c79a76",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -815,10 +815,10 @@
"id": "afed4306",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -828,10 +828,10 @@
"id": "92ab51e8",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -880,7 +880,7 @@
}
],
"having": [],
"legend": " {{NodeName}} ",
"legend": "{{NodeName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
@@ -1008,10 +1008,10 @@
"id": "1020db2d",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1021,10 +1021,10 @@
"id": "c74e1d9c",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1101,10 +1101,10 @@
"id": "6e9e1a4a",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1114,10 +1114,10 @@
"id": "4f6ba883",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1317,10 +1317,10 @@
"id": "09854d1f",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1330,10 +1330,10 @@
"id": "2d14e3fa",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1410,10 +1410,10 @@
"id": "02e9e011",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1423,10 +1423,10 @@
"id": "690694fd",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1626,10 +1626,10 @@
"id": "a8e7b55b",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1639,10 +1639,10 @@
"id": "6e34744c",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1817,10 +1817,10 @@
"id": "76fe4793",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1830,10 +1830,10 @@
"id": "b39cec30",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2033,10 +2033,10 @@
"id": "b00a5918",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2046,10 +2046,10 @@
"id": "e2ad047a",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2179,4 +2179,4 @@
"yAxisUnit": "none"
}
]
}
}

View File

@@ -64,7 +64,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_EKS%' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_EKS%' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -80,7 +80,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_EKS%' GROUP BY cloud_account_id",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name like '%aws_EKS%' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -94,7 +94,7 @@
"multiSelect": false,
"name": "Cluster",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS table FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name like '%aws_EKS%' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} AND JSONExtractString(labels, 'cloud_region') IN {{.Region}} and table != '' GROUP BY table\n",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'ClusterName') AS cluster_name FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name like '%aws_EKS%' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}} and cluster_name != '' GROUP BY cluster_name\n",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -139,10 +139,10 @@
"id": "cd48d097",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -152,10 +152,10 @@
"id": "e15d2193",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -319,10 +319,10 @@
"id": "ceb37a7e",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -332,10 +332,10 @@
"id": "43d6f274",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -399,10 +399,10 @@
"id": "ba6a48c6",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -412,10 +412,10 @@
"id": "fe1a0cd2",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -579,10 +579,10 @@
"id": "fd1d1922",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -592,10 +592,10 @@
"id": "d7eb2ac6",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -659,10 +659,10 @@
"id": "f1d20f31",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -672,10 +672,10 @@
"id": "ce660d67",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -739,10 +739,10 @@
"id": "cd6566ff",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -752,10 +752,10 @@
"id": "e582ca67",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -919,10 +919,10 @@
"id": "cdd3d571",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -932,10 +932,10 @@
"id": "badba5d2",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -999,10 +999,10 @@
"id": "07af73bd",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1012,10 +1012,10 @@
"id": "a5792c41",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1179,10 +1179,10 @@
"id": "9272ad56",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1192,10 +1192,10 @@
"id": "1b6292ad",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1259,10 +1259,10 @@
"id": "37b6b2c2",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1272,10 +1272,10 @@
"id": "904415fa",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1339,10 +1339,10 @@
"id": "3c7ff964",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1352,10 +1352,10 @@
"id": "945a29cd",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1519,10 +1519,10 @@
"id": "506f5d0b",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1532,10 +1532,10 @@
"id": "1ea4e5ea",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1599,10 +1599,10 @@
"id": "42761bd5",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1612,10 +1612,10 @@
"id": "80d9d3ff",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1745,4 +1745,4 @@
"yAxisUnit": "none"
}
]
}
}

View File

@@ -143,7 +143,7 @@
"multiSelect": true,
"name": "Cluster",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'CacheClusterId') AS cluster FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name = 'aws_ElastiCache_CPUUtilization_max' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} AND JSONExtractString(labels, 'cloud_region') IN {{.Region}} AND cluster != '' GROUP BY cluster",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'CacheClusterId') AS cluster FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name = 'aws_ElastiCache_CPUUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}} AND cluster != '' GROUP BY cluster",
"showALLOption": true,
"sort": "DISABLED",
"textboxValue": "",
@@ -159,7 +159,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name = 'aws_ElastiCache_CPUUtilization_max' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name = 'aws_ElastiCache_CPUUtilization_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -175,7 +175,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name = 'aws_ElastiCache_CPUUtilization_max' GROUP BY cloud_account_id",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id` FROM signoz_metrics.distributed_time_series_v4_1day WHERE metric_name = 'aws_ElastiCache_CPUUtilization_max' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -234,10 +234,10 @@
"id": "a2e662bc",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -247,10 +247,10 @@
"id": "b7391c4e",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -414,10 +414,10 @@
"id": "0c3a5e7a",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -427,10 +427,10 @@
"id": "de00d7b3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -594,10 +594,10 @@
"id": "7087d8df",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -607,10 +607,10 @@
"id": "26bd4c51",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -774,10 +774,10 @@
"id": "63918715",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -787,10 +787,10 @@
"id": "647e4dbe",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -954,10 +954,10 @@
"id": "72e562a1",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -967,10 +967,10 @@
"id": "26891e8d",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1134,10 +1134,10 @@
"id": "c6612aef",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1147,10 +1147,10 @@
"id": "b863daa8",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1314,10 +1314,10 @@
"id": "05806d0e",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1327,10 +1327,10 @@
"id": "edfe2e2c",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1494,10 +1494,10 @@
"id": "088c9b4a",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1507,10 +1507,10 @@
"id": "1a86c392",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1672,10 +1672,10 @@
"id": "10a254a8",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1685,10 +1685,10 @@
"id": "310ce219",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1852,10 +1852,10 @@
"id": "a3ab9c6c",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1865,10 +1865,10 @@
"id": "cfd6d4ee",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2032,10 +2032,10 @@
"id": "0e7a0149",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2045,10 +2045,10 @@
"id": "1440550c",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2197,10 +2197,10 @@
"id": "43ef42eb",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2225,10 +2225,10 @@
"id": "4cc11182",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2377,10 +2377,10 @@
"id": "87b3e146",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2405,10 +2405,10 @@
"id": "07a5a0d1",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2557,10 +2557,10 @@
"id": "6764e117",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -2585,10 +2585,10 @@
"id": "a1c90d55",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -2703,4 +2703,4 @@
"yAxisUnit": "none"
}
]
}
}

View File

@@ -81,7 +81,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_account_id') as cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_Lambda_Invocations_sum'\nGROUP BY cloud_account_id\n\n",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.account.id') as `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_Lambda_Invocations_sum'\nGROUP BY `cloud.account.id`\n\n",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -96,7 +96,7 @@
"multiSelect": false,
"name": "Region",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_region') as cloud_region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_Lambda_Invocations_sum'\n and JSONExtractString(labels, 'cloud_account_id') IN {{.Account}}\nGROUP BY cloud_region\n",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.region') as `cloud.region`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_Lambda_Invocations_sum'\n and JSONExtractString(labels, 'cloud.account.id') IN {{.Account}}\nGROUP BY `cloud.region`\n",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -139,10 +139,10 @@
"id": "49d33567",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -152,10 +152,10 @@
"id": "b9dfa1c9",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -190,18 +190,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -240,7 +240,7 @@
"disabled": false,
"legend": "",
"name": "A",
"query": "aws_Lambda_Invocations_sum{cloud_region=\"us-east-2\"}"
"query": "{\"aws_Lambda_Invocations_sum\",\"cloud.region\"=\"us-east-2\"}"
}
],
"queryType": "builder"
@@ -341,10 +341,10 @@
"id": "af05252d",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -354,10 +354,10 @@
"id": "983efea5",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -396,18 +396,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -446,7 +446,7 @@
"disabled": false,
"legend": "",
"name": "A",
"query": "aws_Lambda_Invocations_sum{cloud_region=\"us-east-2\"}"
"query": "{\"aws_Lambda_Invocations_sum\", \"cloud.region\"=\"us-east-2\"}"
}
],
"queryType": "builder"
@@ -547,10 +547,10 @@
"id": "c67262c9",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -560,10 +560,10 @@
"id": "c5ccbbf4",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -602,18 +602,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -652,7 +652,7 @@
"disabled": false,
"legend": "",
"name": "A",
"query": "aws_Lambda_Invocations_sum{cloud_region=\"us-east-2\"}"
"query": "{\"aws_Lambda_Invocations_sum\", \"cloud.region\"=\"us-east-2\"}"
}
],
"queryType": "builder"
@@ -753,10 +753,10 @@
"id": "6c956b7d",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -766,10 +766,10 @@
"id": "5fef840b",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -808,18 +808,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -858,7 +858,7 @@
"disabled": false,
"legend": "",
"name": "A",
"query": "aws_Lambda_Invocations_sum{cloud_region=\"us-east-2\"}"
"query": "{\"aws_Lambda_Invocations_sum\",\"cloud.region\"=\"us-east-2\"}"
}
],
"queryType": "builder"
@@ -959,10 +959,10 @@
"id": "f4c6246b",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -972,10 +972,10 @@
"id": "5b7a75a1",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1014,18 +1014,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1064,7 +1064,7 @@
"disabled": false,
"legend": "",
"name": "A",
"query": "aws_Lambda_Invocations_sum{cloud_region=\"us-east-2\"}"
"query": "{\"aws_Lambda_Invocations_sum\",\"cloud.region=\"us-east-2\"}"
}
],
"queryType": "builder"
@@ -1165,10 +1165,10 @@
"id": "1aee3626",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1178,10 +1178,10 @@
"id": "11631fda",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1220,18 +1220,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1270,7 +1270,7 @@
"disabled": false,
"legend": "",
"name": "A",
"query": "aws_Lambda_Invocations_sum{cloud_region=\"us-east-2\"}"
"query": "{\"aws_Lambda_Invocations_sum\",\"cloud.region=\"us-east-2\"}"
}
],
"queryType": "builder"
@@ -1371,10 +1371,10 @@
"id": "a8c65389",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1384,10 +1384,10 @@
"id": "2ab205c8",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1426,18 +1426,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1476,7 +1476,7 @@
"disabled": false,
"legend": "",
"name": "A",
"query": "aws_Lambda_Invocations_sum{cloud_region=\"us-east-2\"}"
"query": "{\"aws_Lambda_Invocations_sum\",\"cloud.region\"=\"us-east-2\"}"
}
],
"queryType": "builder"

View File

@@ -72,7 +72,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_Kafka_KafkaDataLogsDiskUsed_max' GROUP BY cloud_account_id\n",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_Kafka_KafkaDataLogsDiskUsed_max' GROUP BY `cloud.account.id`\n",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -87,7 +87,7 @@
"multiSelect": false,
"name": "Region",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_Kafka_KafkaDataLogsDiskUsed_max' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region\n",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_Kafka_KafkaDataLogsDiskUsed_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region\n",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -143,10 +143,10 @@
"id": "8b658843",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -156,10 +156,10 @@
"id": "9cbc21ee",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -328,10 +328,10 @@
"id": "754c3c99",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -341,10 +341,10 @@
"id": "09ad3a79",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -513,10 +513,10 @@
"id": "3e5db1d7",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -526,10 +526,10 @@
"id": "9e9bf94c",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -698,10 +698,10 @@
"id": "2233f9a5",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -711,10 +711,10 @@
"id": "52bd69d4",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -870,10 +870,10 @@
"id": "a00425be",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -896,10 +896,10 @@
"id": "02adea69",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1055,10 +1055,10 @@
"id": "0626eebd",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1068,10 +1068,10 @@
"id": "b633d867",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1186,4 +1186,4 @@
"yAxisUnit": "none"
}
]
}
}

View File

@@ -90,7 +90,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_account_id') as cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_RDS_CPUUtilization_sum'\nGROUP BY cloud_account_id",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.account.id') as `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_RDS_CPUUtilization_sum'\nGROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -106,7 +106,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT JSONExtractString(labels, 'cloud_region') as cloud_region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_RDS_CPUUtilization_sum'\n and JSONExtractString(labels, 'cloud_account_id') IN {{.Account}}\nGROUP BY cloud_region",
"queryValue": "SELECT JSONExtractString(labels, 'cloud.region') as `cloud.region`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE \n metric_name like 'aws_RDS_CPUUtilization_sum'\n and JSONExtractString(labels, 'cloud.account.id') IN {{.Account}}\nGROUP BY `cloud.region`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -149,10 +149,10 @@
"id": "f8e72efc",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -162,10 +162,10 @@
"id": "4e68256a",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -191,18 +191,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -342,10 +342,10 @@
"id": "723ba84a",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -355,10 +355,10 @@
"id": "f8227b55",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -384,18 +384,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -535,10 +535,10 @@
"id": "31191f74",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -548,10 +548,10 @@
"id": "aa644bbf",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -577,18 +577,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -728,10 +728,10 @@
"id": "83f232af",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -741,10 +741,10 @@
"id": "2677873f",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -770,18 +770,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -822,10 +822,10 @@
"id": "e2df7981",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -835,10 +835,10 @@
"id": "6daad748",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -864,18 +864,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1015,10 +1015,10 @@
"id": "17142c3d",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1028,10 +1028,10 @@
"id": "27fcc87d",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1057,18 +1057,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1109,10 +1109,10 @@
"id": "a050e23a",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1122,10 +1122,10 @@
"id": "6df80990",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1151,18 +1151,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1302,10 +1302,10 @@
"id": "a298d4bd",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1315,10 +1315,10 @@
"id": "810c0586",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1344,18 +1344,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1396,10 +1396,10 @@
"id": "d46f3f53",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1409,10 +1409,10 @@
"id": "4ec47a19",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1438,18 +1438,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1589,10 +1589,10 @@
"id": "f64f0096",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1602,10 +1602,10 @@
"id": "18ad7c1e",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1631,18 +1631,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1782,10 +1782,10 @@
"id": "7786e529",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1795,10 +1795,10 @@
"id": "f27b4616",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1824,18 +1824,18 @@
"groupBy": [
{
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
{
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
{
@@ -1942,4 +1942,4 @@
"yAxisUnit": "bytes"
}
]
}
}

View File

@@ -54,7 +54,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' GROUP BY cloud_account_id",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -70,7 +70,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -85,7 +85,7 @@
"multiSelect": true,
"name": "Topic",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'TopicName') AS topic\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} AND JSONExtractString(labels, 'cloud_region') IN {{.Region}}\nGROUP BY topic",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'TopicName') AS topic\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}}\nGROUP BY topic",
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
@@ -144,10 +144,10 @@
"id": "b18187c3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -157,10 +157,10 @@
"id": "eebe4578",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -324,10 +324,10 @@
"id": "62255cff",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -337,10 +337,10 @@
"id": "17c7153e",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -504,10 +504,10 @@
"id": "8ca86829",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -517,10 +517,10 @@
"id": "8a444f66",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -684,10 +684,10 @@
"id": "e2084931",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -697,10 +697,10 @@
"id": "0b05209a",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -815,4 +815,4 @@
"yAxisUnit": "none"
}
]
}
}

View File

@@ -1,818 +0,0 @@
{
"description": "View key AWS SNS metrics with an out of the box dashboard.",
"image": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODBweCIgaGVpZ2h0PSI4MHB4IiB2aWV3Qm94PSIwIDAgODAgODAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDY0ICg5MzUzNykgLSBodHRwczovL3NrZXRjaC5jb20gLS0+CiAgICA8dGl0bGU+SWNvbi1BcmNoaXRlY3R1cmUvNjQvQXJjaF9BV1MtU2ltcGxlLU5vdGlmaWNhdGlvbi1TZXJ2aWNlXzY0PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+CiAgICAgICAgPGxpbmVhckdyYWRpZW50IHgxPSIwJSIgeTE9IjEwMCUiIHgyPSIxMDAlIiB5Mj0iMCUiIGlkPSJsaW5lYXJHcmFkaWVudC0xIj4KICAgICAgICAgICAgPHN0b3Agc3RvcC1jb2xvcj0iI0IwMDg0RCIgb2Zmc2V0PSIwJSI+PC9zdG9wPgogICAgICAgICAgICA8c3RvcCBzdG9wLWNvbG9yPSIjRkY0RjhCIiBvZmZzZXQ9IjEwMCUiPjwvc3RvcD4KICAgICAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPC9kZWZzPgogICAgPGcgaWQ9Ikljb24tQXJjaGl0ZWN0dXJlLzY0L0FyY2hfQVdTLVNpbXBsZS1Ob3RpZmljYXRpb24tU2VydmljZV82NCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ikljb24tQXJjaGl0ZWN0dXJlLUJHLzY0L0FwcGxpY2F0aW9uLUludGVncmF0aW9uIiBmaWxsPSJ1cmwoI2xpbmVhckdyYWRpZW50LTEpIj4KICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZSIgeD0iMCIgeT0iMCIgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIj48L3JlY3Q+CiAgICAgICAgPC9nPgogICAgICAgIDxwYXRoIGQ9Ik0xNywzOCBDMTguMTAzLDM4IDE5LDM4Ljg5NyAxOSw0MCBDMTksNDEuMTAzIDE4LjEwMyw0MiAxNyw0MiBDMTUuODk3LDQyIDE1LDQxLjEwMyAxNSw0MCBDMTUsMzguODk3IDE1Ljg5NywzOCAxNywzOCBMMTcsMzggWiBNNDEsNjQgQzI5LjMxNCw2NCAxOS4yODksNTUuNDY2IDE3LjE5NCw0My45OCBDMTguOTY1LDQzLjg5NCAyMC40MjcsNDIuNjU5IDIwLjg1Nyw0MSBMMjcsNDEgTDI3LDM5IEwyMC44NTcsMzkgQzIwLjQyNywzNy4zNDIgMTguOTY2LDM2LjEwNyAxNy4xOTUsMzYuMDIgQzE5LjI4NSwyNC43MSAyOS41MTEsMTYgNDEsMTYgQzQ1LjMxMywxNiA0OS44MzIsMTcuNjIyIDU0LjQyOSwyMC44MjEgTDU1LjU3MSwxOS4xNzkgQzUwLjYzMywxNS43NDMgNDUuNzMsMTQgNDEsMTQgQzI4LjI3LDE0IDE2Ljk0OSwyMy44NjUgMTUuMDYzLDM2LjUyMSBDMTMuODM5LDM3LjIwNyAxMywzOC41IDEzLDQwIEMxMyw0MS41IDEzLjgzOSw0Mi43OTMgMTUuMDYzLDQzLjQ3OCBDMTYuOTcsNTYuMzQxIDI4LjA1Niw2NiA0MSw2NiBDNDYuNDA3LDY2IDUxLjk0Miw2NC4xNTcgNTYuNTg1LDYwLjgxMSBMNTUuNDE1LDU5LjE4OSBDNTEuMTEsNjIuMjkyIDQ1Ljk5MSw2NCA0MSw2NCBMNDEsNjQgWiBNMzAuMTAxLDM2LjQ0MiBDMzEuOTU1LDM2Ljg5NSAzNC4yNzUsMzcgMzYsMzcgQzM3LjY0MiwzNyAzOS44MjMsMzYuOTA1IDQxLjYyOSwzNi41MDYgTDM3LjEwNSw0NS41NTMgQzM3LjAzNiw0NS42OTEgMzcsNDUuODQ1IDM3LDQ2IEwzNyw1MC40NTMgQzM2LjE5OSw1MC45NjQgMzQuODMzLDUxLjgxMiAzNCw1MS45ODYgTDM0LDQ2IEMzNCw0NS44NjggMzMuOTc0LDQ1LjczNyAzMy45MjMsNDUuNjE1IEwzMC4xMDEsMzYuNDQyIFogTTM2LDMzIEM0MC4wMjUsMzMgNDIuMTc0LDMzLjYwNCA0Mi44NDEsMzQgQzQyLjE3NCwzNC4zOTYgNDAuMDI1LDM1IDM2LDM1IEMzMS45NzUsMzUgMjkuODI2LDM0LjM5NiAyOS4xNTksMzQgQzI5LjgyNiwzMy42MDQgMzEuOTc1LDMzIDM2LDMzIEwzNiwzMyBaIE0zMyw1NCBMMzQsNTQgQzM0LjA0Myw1NCAzNC4wODYsNTMuOTk3IDM0LjEyOCw1My45OTIgQzM1LjM1Miw1My44MzMgMzYuOTA5LDUyLjg4NyAzOC4yNzIsNTIuMDEzIEwzOC41MzUsNTEuODQ1IEMzOC44MjQsNTEuNjYxIDM5LDUxLjM0MiAzOSw1MSBMMzksNDYuMjM2IEw0NC41NTksMzUuMTIgQzQ0LjgzMywzNC44MDEgNDUsMzQuNDM0IDQ1LDM0IEM0NSwzMS4zOSAzOS4zNjEsMzEgMzYsMzEgQzMyLjYzOSwzMSAyNywzMS4zOSAyNywzNCBDMjcsMzQuMzY2IDI3LjEyLDM0LjY4NCAyNy4zMiwzNC45NjcgTDMyLDQ2LjIgTDMyLDUzIEMzMiw1My41NTIgMzIuNDQ3LDU0IDMzLDU0IEwzMyw1NCBaIE02Miw1MyBDNjMuMTAzLDUzIDY0LDUzLjg5NyA2NCw1NSBDNjQsNTYuMTAzIDYzLjEwMyw1NyA2Miw1NyBDNjAuODk3LDU3IDYwLDU2LjEwMyA2MCw1NSBDNjAsNTMuODk3IDYwLjg5Nyw1MyA2Miw1MyBMNjIsNTMgWiBNNjIsMjMgQzYzLjEwMywyMyA2NCwyMy44OTcgNjQsMjUgQzY0LDI2LjEwMyA2My4xMDMsMjcgNjIsMjcgQzYwLjg5NywyNyA2MCwyNi4xMDMgNjAsMjUgQzYwLDIzLjg5NyA2MC44OTcsMjMgNjIsMjMgTDYyLDIzIFogTTY0LDM4IEM2NS4xMDMsMzggNjYsMzguODk3IDY2LDQwIEM2Niw0MS4xMDMgNjUuMTAzLDQyIDY0LDQyIEM2Mi44OTcsNDIgNjIsNDEuMTAzIDYyLDQwIEM2MiwzOC44OTcgNjIuODk3LDM4IDY0LDM4IEw2NCwzOCBaIE01NCw0MSBMNjAuMTQzLDQxIEM2MC41ODksNDIuNzIgNjIuMTQyLDQ0IDY0LDQ0IEM2Ni4yMDYsNDQgNjgsNDIuMjA2IDY4LDQwIEM2OCwzNy43OTQgNjYuMjA2LDM2IDY0LDM2IEM2Mi4xNDIsMzYgNjAuNTg5LDM3LjI4IDYwLjE0MywzOSBMNTQsMzkgTDU0LDI2IEw1OC4xNDMsMjYgQzU4LjU4OSwyNy43MiA2MC4xNDIsMjkgNjIsMjkgQzY0LjIwNiwyOSA2NiwyNy4yMDYgNjYsMjUgQzY2LDIyLjc5NCA2NC4yMDYsMjEgNjIsMjEgQzYwLjE0MiwyMSA1OC41ODksMjIuMjggNTguMTQzLDI0IEw1MywyNCBDNTIuNDQ3LDI0IDUyLDI0LjQ0OCA1MiwyNSBMNTIsMzkgTDQ1LDM5IEw0NSw0MSBMNTIsNDEgTDUyLDU1IEM1Miw1NS41NTIgNTIuNDQ3LDU2IDUzLDU2IEw1OC4xNDMsNTYgQzU4LjU4OSw1Ny43MiA2MC4xNDIsNTkgNjIsNTkgQzY0LjIwNiw1OSA2Niw1Ny4yMDYgNjYsNTUgQzY2LDUyLjc5NCA2NC4yMDYsNTEgNjIsNTEgQzYwLjE0Miw1MSA1OC41ODksNTIuMjggNTguMTQzLDU0IEw1NCw1NCBMNTQsNDEgWiIgaWQ9IkFXUy1TaW1wbGUtTm90aWZpY2F0aW9uLVNlcnZpY2VfSWNvbl82NF9TcXVpZCIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgPC9nPgo8L3N2Zz4=",
"layout": [
{
"h": 6,
"i": "4eb87f89-0213-4773-9b06-6aecc6701898",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 0
},
{
"h": 6,
"i": "7a010b4e-ea7c-4a45-a9eb-93af650c45b4",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 0
},
{
"h": 6,
"i": "2299d4e3-6c40-4bf2-a550-c7bb8a7acd38",
"moved": false,
"static": false,
"w": 6,
"x": 0,
"y": 6
},
{
"h": 6,
"i": "16eec8b7-de1a-4039-b180-24c7a6704b6e",
"moved": false,
"static": false,
"w": 6,
"x": 6,
"y": 6
}
],
"panelMap": {},
"tags": [],
"title": "SNS Overview",
"uploadedGrafana": false,
"variables": {
"51f4fa2b-89c7-47c2-9795-f32cffaab985": {
"allSelected": false,
"customValue": "",
"description": "AWS Account ID",
"id": "51f4fa2b-89c7-47c2-9795-f32cffaab985",
"key": "51f4fa2b-89c7-47c2-9795-f32cffaab985",
"modificationUUID": "b7a6b06b-fa1f-4fb8-b70e-6bd9b350f29e",
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
"type": "QUERY"
},
"9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0": {
"allSelected": false,
"customValue": "",
"description": "Account Region",
"id": "9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0",
"key": "9faf0f4b-b245-4b3c-83a3-60cfa76dfeb0",
"modificationUUID": "8428a5de-bfd1-4a69-9601-63e3041cd556",
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
},
"bfbdbcbe-a168-4d81-b108-36339e249116": {
"allSelected": true,
"customValue": "",
"description": "SNS Topic Name",
"id": "bfbdbcbe-a168-4d81-b108-36339e249116",
"modificationUUID": "dfed7272-16dc-4eb6-99bf-7c82fc8e04f0",
"multiSelect": true,
"name": "Topic",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'TopicName') AS topic\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SNS_PublishSize_count' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} AND JSONExtractString(labels, 'cloud.region') IN {{.Region}}\nGROUP BY topic",
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
"type": "QUERY"
}
},
"version": "v4",
"widgets": [
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "4eb87f89-0213-4773-9b06-6aecc6701898",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_SNS_NumberOfMessagesPublished_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_SNS_NumberOfMessagesPublished_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filters": {
"items": [
{
"id": "8fd51b53",
"key": {
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
},
"op": "in",
"value": [
"$Topic"
]
},
{
"id": "b18187c3",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "eebe4578",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
}
],
"having": [],
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "9c67615a-55f7-42da-835c-86922f2ff8bb",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Number of Messages Published",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "7a010b4e-ea7c-4a45-a9eb-93af650c45b4",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_SNS_PublishSize_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_SNS_PublishSize_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filters": {
"items": [
{
"id": "1aa0d1a9",
"key": {
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
},
"op": "in",
"value": [
"$Topic"
]
},
{
"id": "62255cff",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "17c7153e",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
}
],
"having": [],
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "a635a15b-dfe6-4617-a82e-29d93e27deaf",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Published Message Size",
"yAxisUnit": "decbytes"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "2299d4e3-6c40-4bf2-a550-c7bb8a7acd38",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_SNS_NumberOfNotificationsDelivered_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_SNS_NumberOfNotificationsDelivered_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filters": {
"items": [
{
"id": "c96a4ac0",
"key": {
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
},
"op": "in",
"value": [
"$Topic"
]
},
{
"id": "8ca86829",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "8a444f66",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
}
],
"having": [],
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "0d2fc26c-9b21-4dfc-b631-64b7c8d3bd71",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Number of Notifications Delivered",
"yAxisUnit": "none"
},
{
"bucketCount": 30,
"bucketWidth": 0,
"columnUnits": {},
"description": "",
"fillSpans": false,
"id": "16eec8b7-de1a-4039-b180-24c7a6704b6e",
"isLogScale": false,
"isStacked": false,
"mergeAllActiveQueries": false,
"nullZeroValues": "zero",
"opacity": "1",
"panelTypes": "graph",
"query": {
"builder": {
"queryData": [
{
"aggregateAttribute": {
"dataType": "float64",
"id": "aws_SNS_NumberOfNotificationsFailed_max--float64--Gauge--true",
"isColumn": true,
"isJSON": false,
"key": "aws_SNS_NumberOfNotificationsFailed_max",
"type": "Gauge"
},
"aggregateOperator": "max",
"dataSource": "metrics",
"disabled": false,
"expression": "A",
"filters": {
"items": [
{
"id": "6175f3d5",
"key": {
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
},
"op": "in",
"value": [
"$Topic"
]
},
{
"id": "e2084931",
"key": {
"dataType": "string",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.region",
"type": "tag"
},
"op": "=",
"value": "$Region"
},
{
"id": "0b05209a",
"key": {
"dataType": "string",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
"value": "$Account"
}
],
"op": "AND"
},
"functions": [],
"groupBy": [
{
"dataType": "string",
"id": "TopicName--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "TopicName",
"type": "tag"
}
],
"having": [],
"legend": "{{TopicName}}",
"limit": null,
"orderBy": [],
"queryName": "A",
"reduceTo": "avg",
"spaceAggregation": "max",
"stepInterval": 60,
"timeAggregation": "max"
}
],
"queryFormulas": []
},
"clickhouse_sql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"id": "526247af-6ac9-42ff-83e9-cce0e32a9e63",
"promql": [
{
"disabled": false,
"legend": "",
"name": "A",
"query": ""
}
],
"queryType": "builder"
},
"selectedLogFields": [
{
"dataType": "string",
"name": "body",
"type": ""
},
{
"dataType": "string",
"name": "timestamp",
"type": ""
}
],
"selectedTracesFields": [
{
"dataType": "string",
"id": "serviceName--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "serviceName",
"type": "tag"
},
{
"dataType": "string",
"id": "name--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "name",
"type": "tag"
},
{
"dataType": "float64",
"id": "durationNano--float64--tag--true",
"isColumn": true,
"isJSON": false,
"key": "durationNano",
"type": "tag"
},
{
"dataType": "string",
"id": "httpMethod--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "httpMethod",
"type": "tag"
},
{
"dataType": "string",
"id": "responseStatusCode--string--tag--true",
"isColumn": true,
"isJSON": false,
"key": "responseStatusCode",
"type": "tag"
}
],
"softMax": 0,
"softMin": 0,
"stackedBarChart": false,
"thresholds": [],
"timePreferance": "GLOBAL_TIME",
"title": "Number of Notifications Failed",
"yAxisUnit": "none"
}
]
}

View File

@@ -96,7 +96,7 @@
"multiSelect": true,
"name": "Queue",
"order": 2,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'QueueName') AS queue\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SQS_ApproximateAgeOfOldestMessage_max' \nAND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} \nAND JSONExtractString(labels, 'cloud_region') IN {{.Region}} \nGROUP BY queue",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'QueueName') AS queue\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SQS_ApproximateAgeOfOldestMessage_max' \nAND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} \nAND JSONExtractString(labels, 'cloud.region') IN {{.Region}} \nGROUP BY queue",
"showALLOption": true,
"sort": "ASC",
"textboxValue": "",
@@ -112,7 +112,7 @@
"multiSelect": false,
"name": "Region",
"order": 1,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SQS_ApproximateAgeOfOldestMessage_max' AND JSONExtractString(labels, 'cloud_account_id') IN {{.Account}} GROUP BY region",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.region') AS region\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SQS_ApproximateAgeOfOldestMessage_max' AND JSONExtractString(labels, 'cloud.account.id') IN {{.Account}} GROUP BY region",
"showALLOption": false,
"sort": "DISABLED",
"textboxValue": "",
@@ -128,7 +128,7 @@
"multiSelect": false,
"name": "Account",
"order": 0,
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud_account_id') AS cloud_account_id\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SQS_ApproximateAgeOfOldestMessage_max' GROUP BY cloud_account_id",
"queryValue": "SELECT DISTINCT JSONExtractString(labels, 'cloud.account.id') AS `cloud.account.id`\nFROM signoz_metrics.distributed_time_series_v4_1day\nWHERE metric_name = 'aws_SQS_ApproximateAgeOfOldestMessage_max' GROUP BY `cloud.account.id`",
"showALLOption": false,
"sort": "ASC",
"textboxValue": "",
@@ -172,10 +172,10 @@
"id": "f3faf3d7",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -185,10 +185,10 @@
"id": "e9f94e6c",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -352,10 +352,10 @@
"id": "bcad72b1",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -365,10 +365,10 @@
"id": "7e9fbca3",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -532,10 +532,10 @@
"id": "d20d64d4",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -545,10 +545,10 @@
"id": "072f1e3f",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -712,10 +712,10 @@
"id": "20a35c55",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -725,10 +725,10 @@
"id": "4d702aca",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -892,10 +892,10 @@
"id": "d6acfbea",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -905,10 +905,10 @@
"id": "c8f19331",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1072,10 +1072,10 @@
"id": "0fe5e8bd",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1085,10 +1085,10 @@
"id": "6702e7e6",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1252,10 +1252,10 @@
"id": "52cf9dd8",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1265,10 +1265,10 @@
"id": "35ebf39a",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1432,10 +1432,10 @@
"id": "b8f487f1",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1445,10 +1445,10 @@
"id": "e89032c8",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1612,10 +1612,10 @@
"id": "0711b803",
"key": {
"dataType": "string",
"id": "cloud_account_id--string--tag--false",
"id": "cloud.account.id--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_account_id",
"key": "cloud.account.id",
"type": "tag"
},
"op": "=",
@@ -1625,10 +1625,10 @@
"id": "15f30a54",
"key": {
"dataType": "string",
"id": "cloud_region--string--tag--false",
"id": "cloud.region--string--tag--false",
"isColumn": false,
"isJSON": false,
"key": "cloud_region",
"key": "cloud.region",
"type": "tag"
},
"op": "=",
@@ -1758,4 +1758,4 @@
"yAxisUnit": "decbytes"
}
]
}
}

View File

@@ -889,7 +889,12 @@ func (t *telemetryMetaStore) getMetricsKeys(ctx context.Context, fieldKeySelecto
// }
if fieldKeySelector.MetricContext != nil {
fieldConds = append(fieldConds, sb.E("metric_name", fieldKeySelector.MetricContext.MetricName))
if fieldKeySelector.MetricContext.MetricName != "" {
fieldConds = append(fieldConds, sb.E("metric_name", fieldKeySelector.MetricContext.MetricName))
}
if fieldKeySelector.MetricContext.MetricNamespace != "" {
fieldConds = append(fieldConds, sb.Like("metric_name", escapeForLike(fieldKeySelector.MetricContext.MetricNamespace)+"%"))
}
}
conds = append(conds, sb.And(fieldConds...))
@@ -977,7 +982,12 @@ func (t *telemetryMetaStore) getMeterSourceMetricKeys(ctx context.Context, field
fieldConds = append(fieldConds, sb.NotLike("attr_name", "\\_\\_%"))
if fieldKeySelector.MetricContext != nil {
fieldConds = append(fieldConds, sb.E("metric_name", fieldKeySelector.MetricContext.MetricName))
if fieldKeySelector.MetricContext.MetricName != "" {
fieldConds = append(fieldConds, sb.E("metric_name", fieldKeySelector.MetricContext.MetricName))
}
if fieldKeySelector.MetricContext.MetricNamespace != "" {
fieldConds = append(fieldConds, sb.Like("metric_name", escapeForLike(fieldKeySelector.MetricContext.MetricNamespace)+"%"))
}
}
conds = append(conds, sb.And(fieldConds...))
@@ -1071,8 +1081,8 @@ func enrichWithIntrinsicMetricKeys(keys map[string][]*telemetrytypes.TelemetryFi
if selector.Signal != telemetrytypes.SignalMetrics && selector.Signal != telemetrytypes.SignalUnspecified {
continue
}
// If a metricName is provided, dont surface intrinsic metric keys
if selector.MetricContext != nil && selector.MetricContext.MetricName != "" {
// If metric filters are provided, do not surface intrinsic metric keys.
if selector.MetricContext != nil && (selector.MetricContext.MetricName != "" || selector.MetricContext.MetricNamespace != "") {
continue
}
@@ -1728,9 +1738,12 @@ func (t *telemetryMetaStore) getMetricFieldValues(ctx context.Context, fieldValu
sb.Where(sb.E("attr_datatype", fieldValueSelector.FieldDataType.TagDataType()))
}
if fieldValueSelector.MetricContext != nil {
if fieldValueSelector.MetricContext != nil && fieldValueSelector.MetricContext.MetricName != "" {
sb.Where(sb.E("metric_name", fieldValueSelector.MetricContext.MetricName))
}
if fieldValueSelector.MetricContext != nil && fieldValueSelector.MetricContext.MetricNamespace != "" {
sb.Where(sb.Like("metric_name", escapeForLike(fieldValueSelector.MetricContext.MetricNamespace)+"%"))
}
if fieldValueSelector.StartUnixMilli > 0 {
sb.Where(sb.GE("last_reported_unix_milli", fieldValueSelector.StartUnixMilli))
@@ -1812,6 +1825,9 @@ func (t *telemetryMetaStore) getIntrinsicMetricFieldValues(ctx context.Context,
if fieldValueSelector.MetricContext != nil && fieldValueSelector.MetricContext.MetricName != "" {
sb.Where(sb.E("metric_name", fieldValueSelector.MetricContext.MetricName))
}
if fieldValueSelector.MetricContext != nil && fieldValueSelector.MetricContext.MetricNamespace != "" {
sb.Where(sb.Like("metric_name", escapeForLike(fieldValueSelector.MetricContext.MetricNamespace)+"%"))
}
if fieldValueSelector.StartUnixMilli > 0 {
sb.Where(sb.GE("unix_milli", fieldValueSelector.StartUnixMilli))
@@ -1869,6 +1885,13 @@ func (t *telemetryMetaStore) getMeterSourceMetricFieldValues(ctx context.Context
}
sb.Where(sb.NotLike("attr.1", "\\_\\_%"))
if fieldValueSelector.MetricContext != nil && fieldValueSelector.MetricContext.MetricName != "" {
sb.Where(sb.E("metric_name", fieldValueSelector.MetricContext.MetricName))
}
if fieldValueSelector.MetricContext != nil && fieldValueSelector.MetricContext.MetricNamespace != "" {
sb.Where(sb.Like("metric_name", escapeForLike(fieldValueSelector.MetricContext.MetricNamespace)+"%"))
}
if fieldValueSelector.Value != "" {
if fieldValueSelector.SelectorMatchType == telemetrytypes.FieldSelectorMatchTypeExact {
sb.Where(sb.E("attr.2", fieldValueSelector.Value))

View File

@@ -320,6 +320,20 @@ func TestEnrichWithIntrinsicMetricKeys(t *testing.T) {
},
)
assert.NotContains(t, result, "metric_name")
result = enrichWithIntrinsicMetricKeys(
map[string][]*telemetrytypes.TelemetryFieldKey{},
[]*telemetrytypes.FieldKeySelector{
{
Signal: telemetrytypes.SignalMetrics,
MetricContext: &telemetrytypes.MetricContext{
MetricNamespace: "system.cpu",
},
SelectorMatchType: telemetrytypes.FieldSelectorMatchTypeFuzzy,
},
},
)
assert.NotContains(t, result, "metric_name")
}
func TestGetMetricFieldValuesIntrinsicMetricName(t *testing.T) {
@@ -392,3 +406,174 @@ func TestGetMetricFieldValuesIntrinsicBoolReturnsEmpty(t *testing.T) {
assert.Empty(t, values.BoolValues)
require.NoError(t, mock.ExpectationsWereMet())
}
func TestGetMetricFieldValuesAppliesMetricNamespace(t *testing.T) {
mockTelemetryStore := telemetrystoretest.New(telemetrystore.Config{}, &regexMatcher{})
mock := mockTelemetryStore.Mock()
metadata := newTestTelemetryMetaStoreTestHelper(mockTelemetryStore)
valueRows := cmock.NewRows([]cmock.ColumnType{
{Name: "attr_string_value", Type: "String"},
}, [][]any{{"value.a"}})
mock.ExpectQuery(regexp.QuoteMeta("SELECT DISTINCT attr_string_value FROM signoz_metrics.distributed_metadata WHERE attr_name = ? AND metric_name LIKE ? LIMIT ?")).
WithArgs("custom_key", "system.cpu%", 11).
WillReturnRows(valueRows)
values, complete, err := metadata.(*telemetryMetaStore).getMetricFieldValues(context.Background(), &telemetrytypes.FieldValueSelector{
FieldKeySelector: &telemetrytypes.FieldKeySelector{
Signal: telemetrytypes.SignalMetrics,
Name: "custom_key",
Limit: 10,
SelectorMatchType: telemetrytypes.FieldSelectorMatchTypeFuzzy,
MetricContext: &telemetrytypes.MetricContext{
MetricNamespace: "system.cpu",
},
},
Limit: 10,
})
require.NoError(t, err)
assert.True(t, complete)
assert.ElementsMatch(t, []string{"value.a"}, values.StringValues)
require.NoError(t, mock.ExpectationsWereMet())
}
func TestGetMetricFieldValuesIntrinsicMetricNameAppliesMetricNamespace(t *testing.T) {
mockTelemetryStore := telemetrystoretest.New(telemetrystore.Config{}, &regexMatcher{})
mock := mockTelemetryStore.Mock()
metadata := newTestTelemetryMetaStoreTestHelper(mockTelemetryStore)
valueRows := cmock.NewRows([]cmock.ColumnType{
{Name: "metric_name", Type: "String"},
}, [][]any{{"system.cpu.utilization"}})
mock.ExpectQuery(regexp.QuoteMeta("SELECT metric_name FROM signoz_metrics.distributed_time_series_v4_1week WHERE metric_name LIKE ? GROUP BY metric_name LIMIT ?")).
WithArgs("system.cpu%", 51).
WillReturnRows(valueRows)
metadataRows := cmock.NewRows([]cmock.ColumnType{
{Name: "attr_string_value", Type: "String"},
}, [][]any{})
mock.ExpectQuery(regexp.QuoteMeta("SELECT DISTINCT attr_string_value FROM signoz_metrics.distributed_metadata WHERE attr_name = ? AND metric_name LIKE ? LIMIT ?")).
WithArgs("metric_name", "system.cpu%", 50).
WillReturnRows(metadataRows)
values, complete, err := metadata.(*telemetryMetaStore).getMetricFieldValues(context.Background(), &telemetrytypes.FieldValueSelector{
FieldKeySelector: &telemetrytypes.FieldKeySelector{
Signal: telemetrytypes.SignalMetrics,
Name: "metric_name",
Limit: 50,
SelectorMatchType: telemetrytypes.FieldSelectorMatchTypeFuzzy,
MetricContext: &telemetrytypes.MetricContext{
MetricNamespace: "system.cpu",
},
},
Limit: 50,
})
require.NoError(t, err)
assert.True(t, complete)
assert.ElementsMatch(t, []string{"system.cpu.utilization"}, values.StringValues)
require.NoError(t, mock.ExpectationsWereMet())
}
func TestGetMeterSourceMetricFieldValuesAppliesMetricNamespace(t *testing.T) {
mockTelemetryStore := telemetrystoretest.New(telemetrystore.Config{}, &regexMatcher{})
mock := mockTelemetryStore.Mock()
metadata := newTestTelemetryMetaStoreTestHelper(mockTelemetryStore)
rows := cmock.NewRows([]cmock.ColumnType{
{Name: "attr", Type: "Array(String)"},
}, [][]any{{[]string{"service.name", "frontend"}}})
mock.ExpectQuery(`SELECT .*distributed_samples_agg_1d.*metric_name LIKE .*`).
WithArgs("service.name", "\\_\\_%", "system.cpu%", "", 11).
WillReturnRows(rows)
values, complete, err := metadata.(*telemetryMetaStore).getMeterSourceMetricFieldValues(context.Background(), &telemetrytypes.FieldValueSelector{
FieldKeySelector: &telemetrytypes.FieldKeySelector{
Signal: telemetrytypes.SignalMetrics,
Source: telemetrytypes.SourceMeter,
Name: "service.name",
MetricContext: &telemetrytypes.MetricContext{
MetricNamespace: "system.cpu",
},
},
Limit: 10,
})
require.NoError(t, err)
assert.True(t, complete)
assert.ElementsMatch(t, []string{"frontend"}, values.StringValues)
require.NoError(t, mock.ExpectationsWereMet())
}
func TestGetMetricsKeysAppliesMetricNamespace(t *testing.T) {
mockTelemetryStore := telemetrystoretest.New(telemetrystore.Config{}, &regexMatcher{})
mock := mockTelemetryStore.Mock()
metadata := newTestTelemetryMetaStoreTestHelper(mockTelemetryStore)
rows := cmock.NewRows([]cmock.ColumnType{
{Name: "name", Type: "String"},
{Name: "field_context", Type: "String"},
{Name: "field_data_type", Type: "String"},
{Name: "priority", Type: "UInt8"},
}, [][]any{{"service.name", "resource", "String", 1}})
mock.ExpectQuery(`(?s)SELECT.*distributed_metadata.*metric_name LIKE.*`).
WithArgs("%service%", "\\_\\_%", "system.cpu%", 11).
WillReturnRows(rows)
keys, complete, err := metadata.(*telemetryMetaStore).getMetricsKeys(context.Background(), []*telemetrytypes.FieldKeySelector{
{
Signal: telemetrytypes.SignalMetrics,
Name: "service",
Limit: 10,
SelectorMatchType: telemetrytypes.FieldSelectorMatchTypeFuzzy,
MetricContext: &telemetrytypes.MetricContext{
MetricNamespace: "system.cpu",
},
},
})
require.NoError(t, err)
assert.True(t, complete)
assert.Len(t, keys, 1)
assert.Equal(t, "service.name", keys[0].Name)
require.NoError(t, mock.ExpectationsWereMet())
}
func TestGetMeterSourceMetricKeysAppliesMetricNamespace(t *testing.T) {
mockTelemetryStore := telemetrystoretest.New(telemetrystore.Config{}, &regexMatcher{})
mock := mockTelemetryStore.Mock()
metadata := newTestTelemetryMetaStoreTestHelper(mockTelemetryStore)
rows := cmock.NewRows([]cmock.ColumnType{
{Name: "attr_name", Type: "String"},
}, [][]any{{"service.name"}})
mock.ExpectQuery(`SELECT.*distributed_samples_agg_1d.*metric_name LIKE.*`).
WithArgs("%service%", "\\_\\_%", "system.cpu%", 10).
WillReturnRows(rows)
keys, complete, err := metadata.(*telemetryMetaStore).getMeterSourceMetricKeys(context.Background(), []*telemetrytypes.FieldKeySelector{
{
Signal: telemetrytypes.SignalMetrics,
Source: telemetrytypes.SourceMeter,
Name: "service",
Limit: 10,
SelectorMatchType: telemetrytypes.FieldSelectorMatchTypeFuzzy,
MetricContext: &telemetrytypes.MetricContext{
MetricNamespace: "system.cpu",
},
},
})
require.NoError(t, err)
assert.True(t, complete)
assert.Len(t, keys, 1)
assert.Equal(t, "service.name", keys[0].Name)
require.NoError(t, mock.ExpectationsWereMet())
}

View File

@@ -268,7 +268,8 @@ func (t *TelemetryFieldValues) NumValues() int {
}
type MetricContext struct {
MetricName string `json:"metricName"`
MetricName string `json:"metricName"`
MetricNamespace string `json:"metricNamespace,omitempty"`
}
type FieldKeySelector struct {
@@ -297,15 +298,16 @@ type GettableFieldKeys struct {
}
type PostableFieldKeysParams struct {
Signal Signal `query:"signal"`
Source Source `query:"source"`
Limit int `query:"limit"`
StartUnixMilli int64 `query:"startUnixMilli"`
EndUnixMilli int64 `query:"endUnixMilli"`
FieldContext FieldContext `query:"fieldContext"`
FieldDataType FieldDataType `query:"fieldDataType"`
MetricName string `query:"metricName"`
SearchText string `query:"searchText"`
Signal Signal `query:"signal"`
Source Source `query:"source"`
Limit int `query:"limit"`
StartUnixMilli int64 `query:"startUnixMilli"`
EndUnixMilli int64 `query:"endUnixMilli"`
FieldContext FieldContext `query:"fieldContext"`
FieldDataType FieldDataType `query:"fieldDataType"`
MetricName string `query:"metricName"`
MetricNamespace string `query:"metricNamespace"`
SearchText string `query:"searchText"`
}
type GettableFieldValues struct {
@@ -344,9 +346,10 @@ func NewFieldKeySelectorFromPostableFieldKeysParams(params PostableFieldKeysPara
req.Limit = 1000
}
if params.MetricName != "" {
if params.MetricName != "" || params.MetricNamespace != "" {
req.MetricContext = &MetricContext{
MetricName: params.MetricName,
MetricName: params.MetricName,
MetricNamespace: params.MetricNamespace,
}
}

View File

@@ -394,3 +394,20 @@ func TestNormalize(t *testing.T) {
})
}
}
func TestNewFieldKeySelectorFromPostableFieldKeysParamsMetricNamespace(t *testing.T) {
selector := NewFieldKeySelectorFromPostableFieldKeysParams(PostableFieldKeysParams{
Signal: SignalMetrics,
MetricNamespace: "system.cpu",
})
if selector.MetricContext == nil {
t.Fatalf("expected metric context to be set")
}
if selector.MetricContext.MetricNamespace != "system.cpu" {
t.Fatalf("expected metric namespace to be propagated, got %q", selector.MetricContext.MetricNamespace)
}
if selector.MetricContext.MetricName != "" {
t.Fatalf("expected metric name to remain empty, got %q", selector.MetricContext.MetricName)
}
}

View File

@@ -658,3 +658,211 @@ def test_non_existent_metrics_returns_404(
get_error_message(response.json())
== "could not find the metric whatevergoennnsgoeshere"
)
# Verify /api/v1/fields/values filters label values by metricNamespace prefix.
# Inserts metrics under ns.a and ns.b, then asserts a specific prefix returns
# only matching values while a common prefix returns both.
def test_metric_namespace_values_filtering(
signoz: types.SigNoz,
create_user_admin: None, # pylint: disable=unused-argument
get_token: Callable[[str, str], str],
insert_metrics: Callable[[List[Metrics]], None],
) -> None:
now = datetime.now(tz=timezone.utc).replace(second=0, microsecond=0)
metrics: List[Metrics] = [
Metrics(
metric_name="ns.a.requests_total",
labels={"service": "svc-a"},
timestamp=now - timedelta(minutes=2),
value=10.0,
),
Metrics(
metric_name="ns.b.requests_total",
labels={"service": "svc-b"},
timestamp=now - timedelta(minutes=2),
value=20.0,
),
]
insert_metrics(metrics)
token = get_token(USER_ADMIN_EMAIL, USER_ADMIN_PASSWORD)
# Specific prefix: metricNamespace=ns.a should return only svc-a
response = requests.get(
signoz.self.host_configs["8080"].get("/api/v1/fields/values"),
timeout=5,
headers={"authorization": f"Bearer {token}"},
params={
"signal": "metrics",
"name": "service",
"searchText": "",
"metricNamespace": "ns.a",
},
)
assert response.status_code == HTTPStatus.OK
assert response.json()["status"] == "success"
values = response.json()["data"]["values"]["stringValues"]
assert "svc-a" in values
assert "svc-b" not in values
# Common prefix: metricNamespace=ns should return both
response = requests.get(
signoz.self.host_configs["8080"].get("/api/v1/fields/values"),
timeout=5,
headers={"authorization": f"Bearer {token}"},
params={
"signal": "metrics",
"name": "service",
"searchText": "",
"metricNamespace": "ns",
},
)
assert response.status_code == HTTPStatus.OK
assert response.json()["status"] == "success"
values = response.json()["data"]["values"]["stringValues"]
assert "svc-a" in values
assert "svc-b" in values
# Verify /api/v1/fields/values with name=metric_name filters metric names by
# metricNamespace prefix. A specific prefix returns only its metric names;
# a common prefix returns metric names from all matching namespaces.
def test_metric_namespace_metric_name_values_filtering(
signoz: types.SigNoz,
create_user_admin: None, # pylint: disable=unused-argument
get_token: Callable[[str, str], str],
insert_metrics: Callable[[List[Metrics]], None],
) -> None:
now = datetime.now(tz=timezone.utc).replace(second=0, microsecond=0)
metrics: List[Metrics] = [
Metrics(
metric_name="ns.a.cpu.utilization",
labels={"host": "host-a"},
timestamp=now - timedelta(minutes=2),
value=50.0,
),
Metrics(
metric_name="ns.b.cpu.utilization",
labels={"host": "host-b"},
timestamp=now - timedelta(minutes=2),
value=60.0,
),
]
insert_metrics(metrics)
token = get_token(USER_ADMIN_EMAIL, USER_ADMIN_PASSWORD)
# Specific prefix: metricNamespace=ns.a should return only ns.a.* metric names
response = requests.get(
signoz.self.host_configs["8080"].get("/api/v1/fields/values"),
timeout=5,
headers={"authorization": f"Bearer {token}"},
params={
"signal": "metrics",
"name": "metric_name",
"searchText": "",
"metricNamespace": "ns.a",
},
)
assert response.status_code == HTTPStatus.OK
assert response.json()["status"] == "success"
values = response.json()["data"]["values"]["stringValues"]
assert "ns.a.cpu.utilization" in values
assert "ns.b.cpu.utilization" not in values
# Common prefix: metricNamespace=ns should return both
response = requests.get(
signoz.self.host_configs["8080"].get("/api/v1/fields/values"),
timeout=5,
headers={"authorization": f"Bearer {token}"},
params={
"signal": "metrics",
"name": "metric_name",
"searchText": "",
"metricNamespace": "ns",
},
)
assert response.status_code == HTTPStatus.OK
assert response.json()["status"] == "success"
values = response.json()["data"]["values"]["stringValues"]
assert "ns.a.cpu.utilization" in values
assert "ns.b.cpu.utilization" in values
# Verify /api/v1/fields/keys filters attribute keys by metricNamespace prefix.
# Metrics under ns.a and ns.b carry distinct labels; a specific prefix returns
# only its keys while a common prefix returns keys from both namespaces.
def test_metric_namespace_keys_filtering(
signoz: types.SigNoz,
create_user_admin: None, # pylint: disable=unused-argument
get_token: Callable[[str, str], str],
insert_metrics: Callable[[List[Metrics]], None],
) -> None:
now = datetime.now(tz=timezone.utc).replace(second=0, microsecond=0)
metrics: List[Metrics] = [
Metrics(
metric_name="ns.a.cpu.utilization",
labels={"a_only_label": "val-a"},
timestamp=now - timedelta(minutes=2),
value=10.0,
),
Metrics(
metric_name="ns.b.cpu.utilization",
labels={"b_only_label": "val-b"},
timestamp=now - timedelta(minutes=2),
value=20.0,
),
]
insert_metrics(metrics)
token = get_token(USER_ADMIN_EMAIL, USER_ADMIN_PASSWORD)
# Specific prefix: metricNamespace=ns.a should return only a_only_label
response = requests.get(
signoz.self.host_configs["8080"].get("/api/v1/fields/keys"),
timeout=5,
headers={"authorization": f"Bearer {token}"},
params={
"signal": "metrics",
"searchText": "label",
"metricNamespace": "ns.a",
},
)
assert response.status_code == HTTPStatus.OK
assert response.json()["status"] == "success"
keys = response.json()["data"]["keys"]
assert "a_only_label" in keys
assert "b_only_label" not in keys
# Common prefix: metricNamespace=ns should return both keys
response = requests.get(
signoz.self.host_configs["8080"].get("/api/v1/fields/keys"),
timeout=5,
headers={"authorization": f"Bearer {token}"},
params={
"signal": "metrics",
"searchText": "label",
"metricNamespace": "ns",
},
)
assert response.status_code == HTTPStatus.OK
assert response.json()["status"] == "success"
keys = response.json()["data"]["keys"]
assert "a_only_label" in keys
assert "b_only_label" in keys

View File

@@ -108,3 +108,81 @@ def test_list_meter_metric_names(
assert (
metric_name in metric_names
), f"Expected {metric_name} in metric names, got: {metric_names}"
# Verify /api/v1/fields/values with source=meter filters label values by metricNamespace
# prefix. Inserts meter-source metrics under ns.a and ns.b, then asserts a specific
# prefix returns only matching values while a common prefix returns both.
def test_metric_namespace_meter_values_filtering(
signoz: types.SigNoz,
create_user_admin: None, # pylint: disable=unused-argument
get_token: Callable[[str, str], str],
insert_meter_samples: Callable[[List[MeterSample]], None],
) -> None:
now = datetime.now(tz=timezone.utc).replace(second=0, microsecond=0)
samples_a = make_meter_samples(
"meter.ns.a.cost",
{"service": "billing-a"},
now,
count=5,
base_value=10.0,
temporality="Delta",
type_="Sum",
is_monotonic=True,
)
samples_b = make_meter_samples(
"meter.ns.b.cost",
{"service": "billing-b"},
now,
count=5,
base_value=20.0,
temporality="Delta",
type_="Sum",
is_monotonic=True,
)
insert_meter_samples(samples_a + samples_b)
token = get_token(USER_ADMIN_EMAIL, USER_ADMIN_PASSWORD)
# Specific prefix: metricNamespace=meter.ns.a should return only billing-a
response = requests.get(
signoz.self.host_configs["8080"].get("/api/v1/fields/values"),
timeout=5,
headers={"authorization": f"Bearer {token}"},
params={
"signal": "metrics",
"source": "meter",
"name": "service",
"searchText": "",
"metricNamespace": "meter.ns.a",
},
)
assert response.status_code == HTTPStatus.OK
assert response.json()["status"] == "success"
values = response.json()["data"]["values"]["stringValues"]
assert "billing-a" in values
assert "billing-b" not in values
# Common prefix: metricNamespace=meter.ns should return both
response = requests.get(
signoz.self.host_configs["8080"].get("/api/v1/fields/values"),
timeout=5,
headers={"authorization": f"Bearer {token}"},
params={
"signal": "metrics",
"source": "meter",
"name": "service",
"searchText": "",
"metricNamespace": "meter.ns",
},
)
assert response.status_code == HTTPStatus.OK
assert response.json()["status"] == "success"
values = response.json()["data"]["values"]["stringValues"]
assert "billing-a" in values
assert "billing-b" in values

View File

@@ -390,12 +390,12 @@ def test_logs_list_query_timestamp_expectations(
token = get_token(USER_ADMIN_EMAIL, USER_ADMIN_PASSWORD)
# Query Logs for the last 1 minute and check if the logs are returned in the correct order
# Query Logs for the last 10 minute and check if the logs are returned in the correct order
response = make_query_request(
signoz,
token,
start_ms=int(
(datetime.now(tz=timezone.utc) - timedelta(minutes=1)).timestamp() * 1000
(datetime.now(tz=timezone.utc) - timedelta(minutes=10)).timestamp() * 1000
),
end_ms=int(datetime.now(tz=timezone.utc).timestamp() * 1000),
request_type="raw",
@@ -721,7 +721,7 @@ def test_logs_list_query_trace_id_expectations(
token = get_token(USER_ADMIN_EMAIL, USER_ADMIN_PASSWORD)
# Query Logs for the last 1 minute and check if the logs are returned in the correct order
# Query Logs for the last 10 minute and check if the logs are returned in the correct order
response = make_query_request(
signoz,
token,