mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-24 10:24:28 +08:00
commit
78d1e19e60
@ -133,7 +133,7 @@ services:
|
|||||||
# - ./data/clickhouse-3/:/var/lib/clickhouse/
|
# - ./data/clickhouse-3/:/var/lib/clickhouse/
|
||||||
|
|
||||||
alertmanager:
|
alertmanager:
|
||||||
image: signoz/alertmanager:0.23.5
|
image: signoz/alertmanager:0.23.7
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/alertmanager:/data
|
- ./data/alertmanager:/data
|
||||||
command:
|
command:
|
||||||
@ -146,7 +146,7 @@ services:
|
|||||||
condition: on-failure
|
condition: on-failure
|
||||||
|
|
||||||
query-service:
|
query-service:
|
||||||
image: signoz/query-service:0.55.0
|
image: signoz/query-service:0.56.0
|
||||||
command:
|
command:
|
||||||
[
|
[
|
||||||
"-config=/root/config/prometheus.yml",
|
"-config=/root/config/prometheus.yml",
|
||||||
@ -186,7 +186,7 @@ services:
|
|||||||
<<: *db-depend
|
<<: *db-depend
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
image: signoz/frontend:0.55.0
|
image: signoz/frontend:0.56.0
|
||||||
deploy:
|
deploy:
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: on-failure
|
||||||
@ -199,7 +199,7 @@ services:
|
|||||||
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
|
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
otel-collector:
|
otel-collector:
|
||||||
image: signoz/signoz-otel-collector:0.102.10
|
image: signoz/signoz-otel-collector:0.102.12
|
||||||
command:
|
command:
|
||||||
[
|
[
|
||||||
"--config=/etc/otel-collector-config.yaml",
|
"--config=/etc/otel-collector-config.yaml",
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
version: "2.4"
|
version: "2.4"
|
||||||
|
|
||||||
|
include:
|
||||||
|
- test-app-docker-compose.yaml
|
||||||
|
|
||||||
services:
|
services:
|
||||||
zookeeper-1:
|
zookeeper-1:
|
||||||
image: bitnami/zookeeper:3.7.1
|
image: bitnami/zookeeper:3.7.1
|
||||||
@ -54,7 +57,7 @@ services:
|
|||||||
|
|
||||||
alertmanager:
|
alertmanager:
|
||||||
container_name: signoz-alertmanager
|
container_name: signoz-alertmanager
|
||||||
image: signoz/alertmanager:0.23.5
|
image: signoz/alertmanager:0.23.7
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/alertmanager:/data
|
- ./data/alertmanager:/data
|
||||||
depends_on:
|
depends_on:
|
||||||
@ -81,7 +84,7 @@ services:
|
|||||||
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
||||||
otel-collector:
|
otel-collector:
|
||||||
container_name: signoz-otel-collector
|
container_name: signoz-otel-collector
|
||||||
image: signoz/signoz-otel-collector:0.102.10
|
image: signoz/signoz-otel-collector:0.102.12
|
||||||
command:
|
command:
|
||||||
[
|
[
|
||||||
"--config=/etc/otel-collector-config.yaml",
|
"--config=/etc/otel-collector-config.yaml",
|
||||||
@ -128,29 +131,3 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- otel-collector
|
- otel-collector
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
|
|
||||||
hotrod:
|
|
||||||
image: jaegertracing/example-hotrod:1.30
|
|
||||||
container_name: hotrod
|
|
||||||
logging:
|
|
||||||
options:
|
|
||||||
max-size: 50m
|
|
||||||
max-file: "3"
|
|
||||||
command: [ "all" ]
|
|
||||||
environment:
|
|
||||||
- JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
|
|
||||||
|
|
||||||
load-hotrod:
|
|
||||||
image: "signoz/locust:1.2.3"
|
|
||||||
container_name: load-hotrod
|
|
||||||
hostname: load-hotrod
|
|
||||||
environment:
|
|
||||||
ATTACKED_HOST: http://hotrod:8080
|
|
||||||
LOCUST_MODE: standalone
|
|
||||||
NO_PROXY: standalone
|
|
||||||
TASK_DELAY_FROM: 5
|
|
||||||
TASK_DELAY_TO: 30
|
|
||||||
QUIET_MODE: "${QUIET_MODE:-false}"
|
|
||||||
LOCUST_OPTS: "--headless -u 10 -r 1"
|
|
||||||
volumes:
|
|
||||||
- ../common/locust-scripts:/locust
|
|
||||||
|
279
deploy/docker/clickhouse-setup/docker-compose-minimal.yaml
Normal file
279
deploy/docker/clickhouse-setup/docker-compose-minimal.yaml
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
x-clickhouse-defaults: &clickhouse-defaults
|
||||||
|
restart: on-failure
|
||||||
|
# addding non LTS version due to this fix https://github.com/ClickHouse/ClickHouse/commit/32caf8716352f45c1b617274c7508c86b7d1afab
|
||||||
|
image: clickhouse/clickhouse-server:24.1.2-alpine
|
||||||
|
tty: true
|
||||||
|
depends_on:
|
||||||
|
- zookeeper-1
|
||||||
|
# - zookeeper-2
|
||||||
|
# - zookeeper-3
|
||||||
|
logging:
|
||||||
|
options:
|
||||||
|
max-size: 50m
|
||||||
|
max-file: "3"
|
||||||
|
healthcheck:
|
||||||
|
# "clickhouse", "client", "-u ${CLICKHOUSE_USER}", "--password ${CLICKHOUSE_PASSWORD}", "-q 'SELECT 1'"
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"wget",
|
||||||
|
"--spider",
|
||||||
|
"-q",
|
||||||
|
"0.0.0.0:8123/ping"
|
||||||
|
]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
ulimits:
|
||||||
|
nproc: 65535
|
||||||
|
nofile:
|
||||||
|
soft: 262144
|
||||||
|
hard: 262144
|
||||||
|
|
||||||
|
x-db-depend: &db-depend
|
||||||
|
depends_on:
|
||||||
|
clickhouse:
|
||||||
|
condition: service_healthy
|
||||||
|
otel-collector-migrator:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
# clickhouse-2:
|
||||||
|
# condition: service_healthy
|
||||||
|
# clickhouse-3:
|
||||||
|
# condition: service_healthy
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
zookeeper-1:
|
||||||
|
image: bitnami/zookeeper:3.7.1
|
||||||
|
container_name: signoz-zookeeper-1
|
||||||
|
hostname: zookeeper-1
|
||||||
|
user: root
|
||||||
|
ports:
|
||||||
|
- "2181:2181"
|
||||||
|
- "2888:2888"
|
||||||
|
- "3888:3888"
|
||||||
|
volumes:
|
||||||
|
- ./data/zookeeper-1:/bitnami/zookeeper
|
||||||
|
environment:
|
||||||
|
- ZOO_SERVER_ID=1
|
||||||
|
# - ZOO_SERVERS=0.0.0.0:2888:3888,zookeeper-2:2888:3888,zookeeper-3:2888:3888
|
||||||
|
- ALLOW_ANONYMOUS_LOGIN=yes
|
||||||
|
- ZOO_AUTOPURGE_INTERVAL=1
|
||||||
|
|
||||||
|
# zookeeper-2:
|
||||||
|
# image: bitnami/zookeeper:3.7.0
|
||||||
|
# container_name: signoz-zookeeper-2
|
||||||
|
# hostname: zookeeper-2
|
||||||
|
# user: root
|
||||||
|
# ports:
|
||||||
|
# - "2182:2181"
|
||||||
|
# - "2889:2888"
|
||||||
|
# - "3889:3888"
|
||||||
|
# volumes:
|
||||||
|
# - ./data/zookeeper-2:/bitnami/zookeeper
|
||||||
|
# environment:
|
||||||
|
# - ZOO_SERVER_ID=2
|
||||||
|
# - ZOO_SERVERS=zookeeper-1:2888:3888,0.0.0.0:2888:3888,zookeeper-3:2888:3888
|
||||||
|
# - ALLOW_ANONYMOUS_LOGIN=yes
|
||||||
|
# - ZOO_AUTOPURGE_INTERVAL=1
|
||||||
|
|
||||||
|
# zookeeper-3:
|
||||||
|
# image: bitnami/zookeeper:3.7.0
|
||||||
|
# container_name: signoz-zookeeper-3
|
||||||
|
# hostname: zookeeper-3
|
||||||
|
# user: root
|
||||||
|
# ports:
|
||||||
|
# - "2183:2181"
|
||||||
|
# - "2890:2888"
|
||||||
|
# - "3890:3888"
|
||||||
|
# volumes:
|
||||||
|
# - ./data/zookeeper-3:/bitnami/zookeeper
|
||||||
|
# environment:
|
||||||
|
# - ZOO_SERVER_ID=3
|
||||||
|
# - ZOO_SERVERS=zookeeper-1:2888:3888,zookeeper-2:2888:3888,0.0.0.0:2888:3888
|
||||||
|
# - ALLOW_ANONYMOUS_LOGIN=yes
|
||||||
|
# - ZOO_AUTOPURGE_INTERVAL=1
|
||||||
|
|
||||||
|
clickhouse:
|
||||||
|
<<: *clickhouse-defaults
|
||||||
|
container_name: signoz-clickhouse
|
||||||
|
hostname: clickhouse
|
||||||
|
ports:
|
||||||
|
- "9000:9000"
|
||||||
|
- "8123:8123"
|
||||||
|
- "9181:9181"
|
||||||
|
volumes:
|
||||||
|
- ./clickhouse-config.xml:/etc/clickhouse-server/config.xml
|
||||||
|
- ./clickhouse-users.xml:/etc/clickhouse-server/users.xml
|
||||||
|
- ./custom-function.xml:/etc/clickhouse-server/custom-function.xml
|
||||||
|
- ./clickhouse-cluster.xml:/etc/clickhouse-server/config.d/cluster.xml
|
||||||
|
# - ./clickhouse-storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||||
|
- ./data/clickhouse/:/var/lib/clickhouse/
|
||||||
|
- ./user_scripts:/var/lib/clickhouse/user_scripts/
|
||||||
|
|
||||||
|
# clickhouse-2:
|
||||||
|
# <<: *clickhouse-defaults
|
||||||
|
# container_name: signoz-clickhouse-2
|
||||||
|
# hostname: clickhouse-2
|
||||||
|
# ports:
|
||||||
|
# - "9001:9000"
|
||||||
|
# - "8124:8123"
|
||||||
|
# - "9182:9181"
|
||||||
|
# volumes:
|
||||||
|
# - ./clickhouse-config.xml:/etc/clickhouse-server/config.xml
|
||||||
|
# - ./clickhouse-users.xml:/etc/clickhouse-server/users.xml
|
||||||
|
# - ./custom-function.xml:/etc/clickhouse-server/custom-function.xml
|
||||||
|
# - ./clickhouse-cluster.xml:/etc/clickhouse-server/config.d/cluster.xml
|
||||||
|
# # - ./clickhouse-storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||||
|
# - ./data/clickhouse-2/:/var/lib/clickhouse/
|
||||||
|
# - ./user_scripts:/var/lib/clickhouse/user_scripts/
|
||||||
|
|
||||||
|
|
||||||
|
# clickhouse-3:
|
||||||
|
# <<: *clickhouse-defaults
|
||||||
|
# container_name: signoz-clickhouse-3
|
||||||
|
# hostname: clickhouse-3
|
||||||
|
# ports:
|
||||||
|
# - "9002:9000"
|
||||||
|
# - "8125:8123"
|
||||||
|
# - "9183:9181"
|
||||||
|
# volumes:
|
||||||
|
# - ./clickhouse-config.xml:/etc/clickhouse-server/config.xml
|
||||||
|
# - ./clickhouse-users.xml:/etc/clickhouse-server/users.xml
|
||||||
|
# - ./custom-function.xml:/etc/clickhouse-server/custom-function.xml
|
||||||
|
# - ./clickhouse-cluster.xml:/etc/clickhouse-server/config.d/cluster.xml
|
||||||
|
# # - ./clickhouse-storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
||||||
|
# - ./data/clickhouse-3/:/var/lib/clickhouse/
|
||||||
|
# - ./user_scripts:/var/lib/clickhouse/user_scripts/
|
||||||
|
|
||||||
|
alertmanager:
|
||||||
|
image: signoz/alertmanager:${ALERTMANAGER_TAG:-0.23.7}
|
||||||
|
container_name: signoz-alertmanager
|
||||||
|
volumes:
|
||||||
|
- ./data/alertmanager:/data
|
||||||
|
depends_on:
|
||||||
|
query-service:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: on-failure
|
||||||
|
command:
|
||||||
|
- --queryService.url=http://query-service:8085
|
||||||
|
- --storage.path=/data
|
||||||
|
|
||||||
|
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
||||||
|
|
||||||
|
query-service:
|
||||||
|
image: signoz/query-service:${DOCKER_TAG:-0.56.0}
|
||||||
|
container_name: signoz-query-service
|
||||||
|
command:
|
||||||
|
[
|
||||||
|
"-config=/root/config/prometheus.yml",
|
||||||
|
"--use-logs-new-schema=true"
|
||||||
|
]
|
||||||
|
# ports:
|
||||||
|
# - "6060:6060" # pprof port
|
||||||
|
# - "8080:8080" # query-service port
|
||||||
|
volumes:
|
||||||
|
- ./prometheus.yml:/root/config/prometheus.yml
|
||||||
|
- ../dashboards:/root/config/dashboards
|
||||||
|
- ./data/signoz/:/var/lib/signoz/
|
||||||
|
environment:
|
||||||
|
- ClickHouseUrl=tcp://clickhouse:9000
|
||||||
|
- ALERTMANAGER_API_PREFIX=http://alertmanager:9093/api/
|
||||||
|
- SIGNOZ_LOCAL_DB_PATH=/var/lib/signoz/signoz.db
|
||||||
|
- DASHBOARDS_PATH=/root/config/dashboards
|
||||||
|
- STORAGE=clickhouse
|
||||||
|
- GODEBUG=netdns=go
|
||||||
|
- TELEMETRY_ENABLED=true
|
||||||
|
- DEPLOYMENT_TYPE=docker-standalone-amd
|
||||||
|
restart: on-failure
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"wget",
|
||||||
|
"--spider",
|
||||||
|
"-q",
|
||||||
|
"localhost:8080/api/v1/health"
|
||||||
|
]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
<<: *db-depend
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: signoz/frontend:${DOCKER_TAG:-0.56.0}
|
||||||
|
container_name: signoz-frontend
|
||||||
|
restart: on-failure
|
||||||
|
depends_on:
|
||||||
|
- alertmanager
|
||||||
|
- query-service
|
||||||
|
ports:
|
||||||
|
- "3301:3301"
|
||||||
|
volumes:
|
||||||
|
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
otel-collector-migrator:
|
||||||
|
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.102.10}
|
||||||
|
container_name: otel-migrator
|
||||||
|
command:
|
||||||
|
- "--dsn=tcp://clickhouse:9000"
|
||||||
|
depends_on:
|
||||||
|
clickhouse:
|
||||||
|
condition: service_healthy
|
||||||
|
# clickhouse-2:
|
||||||
|
# condition: service_healthy
|
||||||
|
# clickhouse-3:
|
||||||
|
# condition: service_healthy
|
||||||
|
|
||||||
|
|
||||||
|
otel-collector:
|
||||||
|
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.102.12}
|
||||||
|
container_name: signoz-otel-collector
|
||||||
|
command:
|
||||||
|
[
|
||||||
|
"--config=/etc/otel-collector-config.yaml",
|
||||||
|
"--manager-config=/etc/manager-config.yaml",
|
||||||
|
"--copy-path=/var/tmp/collector-config.yaml",
|
||||||
|
"--feature-gates=-pkg.translator.prometheus.NormalizeName"
|
||||||
|
]
|
||||||
|
user: root # required for reading docker container logs
|
||||||
|
volumes:
|
||||||
|
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
|
||||||
|
- ./otel-collector-opamp-config.yaml:/etc/manager-config.yaml
|
||||||
|
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
||||||
|
- /:/hostfs:ro
|
||||||
|
environment:
|
||||||
|
- OTEL_RESOURCE_ATTRIBUTES=host.name=signoz-host,os.type=linux
|
||||||
|
- DOCKER_MULTI_NODE_CLUSTER=false
|
||||||
|
- LOW_CARDINAL_EXCEPTION_GROUPING=false
|
||||||
|
ports:
|
||||||
|
# - "1777:1777" # pprof extension
|
||||||
|
- "4317:4317" # OTLP gRPC receiver
|
||||||
|
- "4318:4318" # OTLP HTTP receiver
|
||||||
|
# - "8888:8888" # OtelCollector internal metrics
|
||||||
|
# - "8889:8889" # signoz spanmetrics exposed by the agent
|
||||||
|
# - "9411:9411" # Zipkin port
|
||||||
|
# - "13133:13133" # health check extension
|
||||||
|
# - "14250:14250" # Jaeger gRPC
|
||||||
|
# - "14268:14268" # Jaeger thrift HTTP
|
||||||
|
# - "55678:55678" # OpenCensus receiver
|
||||||
|
# - "55679:55679" # zPages extension
|
||||||
|
restart: on-failure
|
||||||
|
depends_on:
|
||||||
|
clickhouse:
|
||||||
|
condition: service_healthy
|
||||||
|
otel-collector-migrator:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
query-service:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
logspout:
|
||||||
|
image: "gliderlabs/logspout:v3.2.14"
|
||||||
|
container_name: signoz-logspout
|
||||||
|
volumes:
|
||||||
|
- /etc/hostname:/etc/host_hostname:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
command: syslog+tcp://otel-collector:2255
|
||||||
|
depends_on:
|
||||||
|
- otel-collector
|
||||||
|
restart: on-failure
|
@ -1,5 +1,8 @@
|
|||||||
version: "2.4"
|
version: "2.4"
|
||||||
|
|
||||||
|
include:
|
||||||
|
- test-app-docker-compose.yaml
|
||||||
|
|
||||||
x-clickhouse-defaults: &clickhouse-defaults
|
x-clickhouse-defaults: &clickhouse-defaults
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
# addding non LTS version due to this fix https://github.com/ClickHouse/ClickHouse/commit/32caf8716352f45c1b617274c7508c86b7d1afab
|
# addding non LTS version due to this fix https://github.com/ClickHouse/ClickHouse/commit/32caf8716352f45c1b617274c7508c86b7d1afab
|
||||||
@ -149,7 +152,7 @@ services:
|
|||||||
# - ./user_scripts:/var/lib/clickhouse/user_scripts/
|
# - ./user_scripts:/var/lib/clickhouse/user_scripts/
|
||||||
|
|
||||||
alertmanager:
|
alertmanager:
|
||||||
image: signoz/alertmanager:${ALERTMANAGER_TAG:-0.23.5}
|
image: signoz/alertmanager:${ALERTMANAGER_TAG:-0.23.7}
|
||||||
container_name: signoz-alertmanager
|
container_name: signoz-alertmanager
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/alertmanager:/data
|
- ./data/alertmanager:/data
|
||||||
@ -164,7 +167,7 @@ services:
|
|||||||
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
||||||
|
|
||||||
query-service:
|
query-service:
|
||||||
image: signoz/query-service:${DOCKER_TAG:-0.55.0}
|
image: signoz/query-service:${DOCKER_TAG:-0.56.0}
|
||||||
container_name: signoz-query-service
|
container_name: signoz-query-service
|
||||||
command:
|
command:
|
||||||
[
|
[
|
||||||
@ -204,7 +207,7 @@ services:
|
|||||||
<<: *db-depend
|
<<: *db-depend
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
image: signoz/frontend:${DOCKER_TAG:-0.55.0}
|
image: signoz/frontend:${DOCKER_TAG:-0.56.0}
|
||||||
container_name: signoz-frontend
|
container_name: signoz-frontend
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
depends_on:
|
depends_on:
|
||||||
@ -230,7 +233,7 @@ services:
|
|||||||
|
|
||||||
|
|
||||||
otel-collector:
|
otel-collector:
|
||||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.102.10}
|
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.102.12}
|
||||||
container_name: signoz-otel-collector
|
container_name: signoz-otel-collector
|
||||||
command:
|
command:
|
||||||
[
|
[
|
||||||
@ -280,29 +283,3 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- otel-collector
|
- otel-collector
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
|
|
||||||
hotrod:
|
|
||||||
image: jaegertracing/example-hotrod:1.30
|
|
||||||
container_name: hotrod
|
|
||||||
logging:
|
|
||||||
options:
|
|
||||||
max-size: 50m
|
|
||||||
max-file: "3"
|
|
||||||
command: [ "all" ]
|
|
||||||
environment:
|
|
||||||
- JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
|
|
||||||
|
|
||||||
load-hotrod:
|
|
||||||
image: "signoz/locust:1.2.3"
|
|
||||||
container_name: load-hotrod
|
|
||||||
hostname: load-hotrod
|
|
||||||
environment:
|
|
||||||
ATTACKED_HOST: http://hotrod:8080
|
|
||||||
LOCUST_MODE: standalone
|
|
||||||
NO_PROXY: standalone
|
|
||||||
TASK_DELAY_FROM: 5
|
|
||||||
TASK_DELAY_TO: 30
|
|
||||||
QUIET_MODE: "${QUIET_MODE:-false}"
|
|
||||||
LOCUST_OPTS: "--headless -u 10 -r 1"
|
|
||||||
volumes:
|
|
||||||
- ../common/locust-scripts:/locust
|
|
||||||
|
@ -1,307 +1,3 @@
|
|||||||
version: "2.4"
|
include:
|
||||||
|
- test-app-docker-compose.yaml
|
||||||
x-clickhouse-defaults: &clickhouse-defaults
|
- docker-compose-minimal.yaml
|
||||||
restart: on-failure
|
|
||||||
# addding non LTS version due to this fix https://github.com/ClickHouse/ClickHouse/commit/32caf8716352f45c1b617274c7508c86b7d1afab
|
|
||||||
image: clickhouse/clickhouse-server:24.1.2-alpine
|
|
||||||
tty: true
|
|
||||||
depends_on:
|
|
||||||
- zookeeper-1
|
|
||||||
# - zookeeper-2
|
|
||||||
# - zookeeper-3
|
|
||||||
logging:
|
|
||||||
options:
|
|
||||||
max-size: 50m
|
|
||||||
max-file: "3"
|
|
||||||
healthcheck:
|
|
||||||
# "clickhouse", "client", "-u ${CLICKHOUSE_USER}", "--password ${CLICKHOUSE_PASSWORD}", "-q 'SELECT 1'"
|
|
||||||
test:
|
|
||||||
[
|
|
||||||
"CMD",
|
|
||||||
"wget",
|
|
||||||
"--spider",
|
|
||||||
"-q",
|
|
||||||
"0.0.0.0:8123/ping"
|
|
||||||
]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
ulimits:
|
|
||||||
nproc: 65535
|
|
||||||
nofile:
|
|
||||||
soft: 262144
|
|
||||||
hard: 262144
|
|
||||||
|
|
||||||
x-db-depend: &db-depend
|
|
||||||
depends_on:
|
|
||||||
clickhouse:
|
|
||||||
condition: service_healthy
|
|
||||||
otel-collector-migrator:
|
|
||||||
condition: service_completed_successfully
|
|
||||||
# clickhouse-2:
|
|
||||||
# condition: service_healthy
|
|
||||||
# clickhouse-3:
|
|
||||||
# condition: service_healthy
|
|
||||||
|
|
||||||
services:
|
|
||||||
|
|
||||||
zookeeper-1:
|
|
||||||
image: bitnami/zookeeper:3.7.1
|
|
||||||
container_name: signoz-zookeeper-1
|
|
||||||
hostname: zookeeper-1
|
|
||||||
user: root
|
|
||||||
ports:
|
|
||||||
- "2181:2181"
|
|
||||||
- "2888:2888"
|
|
||||||
- "3888:3888"
|
|
||||||
volumes:
|
|
||||||
- ./data/zookeeper-1:/bitnami/zookeeper
|
|
||||||
environment:
|
|
||||||
- ZOO_SERVER_ID=1
|
|
||||||
# - ZOO_SERVERS=0.0.0.0:2888:3888,zookeeper-2:2888:3888,zookeeper-3:2888:3888
|
|
||||||
- ALLOW_ANONYMOUS_LOGIN=yes
|
|
||||||
- ZOO_AUTOPURGE_INTERVAL=1
|
|
||||||
|
|
||||||
# zookeeper-2:
|
|
||||||
# image: bitnami/zookeeper:3.7.0
|
|
||||||
# container_name: signoz-zookeeper-2
|
|
||||||
# hostname: zookeeper-2
|
|
||||||
# user: root
|
|
||||||
# ports:
|
|
||||||
# - "2182:2181"
|
|
||||||
# - "2889:2888"
|
|
||||||
# - "3889:3888"
|
|
||||||
# volumes:
|
|
||||||
# - ./data/zookeeper-2:/bitnami/zookeeper
|
|
||||||
# environment:
|
|
||||||
# - ZOO_SERVER_ID=2
|
|
||||||
# - ZOO_SERVERS=zookeeper-1:2888:3888,0.0.0.0:2888:3888,zookeeper-3:2888:3888
|
|
||||||
# - ALLOW_ANONYMOUS_LOGIN=yes
|
|
||||||
# - ZOO_AUTOPURGE_INTERVAL=1
|
|
||||||
|
|
||||||
# zookeeper-3:
|
|
||||||
# image: bitnami/zookeeper:3.7.0
|
|
||||||
# container_name: signoz-zookeeper-3
|
|
||||||
# hostname: zookeeper-3
|
|
||||||
# user: root
|
|
||||||
# ports:
|
|
||||||
# - "2183:2181"
|
|
||||||
# - "2890:2888"
|
|
||||||
# - "3890:3888"
|
|
||||||
# volumes:
|
|
||||||
# - ./data/zookeeper-3:/bitnami/zookeeper
|
|
||||||
# environment:
|
|
||||||
# - ZOO_SERVER_ID=3
|
|
||||||
# - ZOO_SERVERS=zookeeper-1:2888:3888,zookeeper-2:2888:3888,0.0.0.0:2888:3888
|
|
||||||
# - ALLOW_ANONYMOUS_LOGIN=yes
|
|
||||||
# - ZOO_AUTOPURGE_INTERVAL=1
|
|
||||||
|
|
||||||
clickhouse:
|
|
||||||
<<: *clickhouse-defaults
|
|
||||||
container_name: signoz-clickhouse
|
|
||||||
hostname: clickhouse
|
|
||||||
ports:
|
|
||||||
- "9000:9000"
|
|
||||||
- "8123:8123"
|
|
||||||
- "9181:9181"
|
|
||||||
volumes:
|
|
||||||
- ./clickhouse-config.xml:/etc/clickhouse-server/config.xml
|
|
||||||
- ./clickhouse-users.xml:/etc/clickhouse-server/users.xml
|
|
||||||
- ./custom-function.xml:/etc/clickhouse-server/custom-function.xml
|
|
||||||
- ./clickhouse-cluster.xml:/etc/clickhouse-server/config.d/cluster.xml
|
|
||||||
# - ./clickhouse-storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
|
||||||
- ./data/clickhouse/:/var/lib/clickhouse/
|
|
||||||
- ./user_scripts:/var/lib/clickhouse/user_scripts/
|
|
||||||
|
|
||||||
# clickhouse-2:
|
|
||||||
# <<: *clickhouse-defaults
|
|
||||||
# container_name: signoz-clickhouse-2
|
|
||||||
# hostname: clickhouse-2
|
|
||||||
# ports:
|
|
||||||
# - "9001:9000"
|
|
||||||
# - "8124:8123"
|
|
||||||
# - "9182:9181"
|
|
||||||
# volumes:
|
|
||||||
# - ./clickhouse-config.xml:/etc/clickhouse-server/config.xml
|
|
||||||
# - ./clickhouse-users.xml:/etc/clickhouse-server/users.xml
|
|
||||||
# - ./custom-function.xml:/etc/clickhouse-server/custom-function.xml
|
|
||||||
# - ./clickhouse-cluster.xml:/etc/clickhouse-server/config.d/cluster.xml
|
|
||||||
# # - ./clickhouse-storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
|
||||||
# - ./data/clickhouse-2/:/var/lib/clickhouse/
|
|
||||||
# - ./user_scripts:/var/lib/clickhouse/user_scripts/
|
|
||||||
|
|
||||||
|
|
||||||
# clickhouse-3:
|
|
||||||
# <<: *clickhouse-defaults
|
|
||||||
# container_name: signoz-clickhouse-3
|
|
||||||
# hostname: clickhouse-3
|
|
||||||
# ports:
|
|
||||||
# - "9002:9000"
|
|
||||||
# - "8125:8123"
|
|
||||||
# - "9183:9181"
|
|
||||||
# volumes:
|
|
||||||
# - ./clickhouse-config.xml:/etc/clickhouse-server/config.xml
|
|
||||||
# - ./clickhouse-users.xml:/etc/clickhouse-server/users.xml
|
|
||||||
# - ./custom-function.xml:/etc/clickhouse-server/custom-function.xml
|
|
||||||
# - ./clickhouse-cluster.xml:/etc/clickhouse-server/config.d/cluster.xml
|
|
||||||
# # - ./clickhouse-storage.xml:/etc/clickhouse-server/config.d/storage.xml
|
|
||||||
# - ./data/clickhouse-3/:/var/lib/clickhouse/
|
|
||||||
# - ./user_scripts:/var/lib/clickhouse/user_scripts/
|
|
||||||
|
|
||||||
alertmanager:
|
|
||||||
image: signoz/alertmanager:${ALERTMANAGER_TAG:-0.23.5}
|
|
||||||
container_name: signoz-alertmanager
|
|
||||||
volumes:
|
|
||||||
- ./data/alertmanager:/data
|
|
||||||
depends_on:
|
|
||||||
query-service:
|
|
||||||
condition: service_healthy
|
|
||||||
restart: on-failure
|
|
||||||
command:
|
|
||||||
- --queryService.url=http://query-service:8085
|
|
||||||
- --storage.path=/data
|
|
||||||
|
|
||||||
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
|
|
||||||
|
|
||||||
query-service:
|
|
||||||
image: signoz/query-service:${DOCKER_TAG:-0.55.0}
|
|
||||||
container_name: signoz-query-service
|
|
||||||
command:
|
|
||||||
[
|
|
||||||
"-config=/root/config/prometheus.yml",
|
|
||||||
"--use-logs-new-schema=true"
|
|
||||||
]
|
|
||||||
# ports:
|
|
||||||
# - "6060:6060" # pprof port
|
|
||||||
# - "8080:8080" # query-service port
|
|
||||||
volumes:
|
|
||||||
- ./prometheus.yml:/root/config/prometheus.yml
|
|
||||||
- ../dashboards:/root/config/dashboards
|
|
||||||
- ./data/signoz/:/var/lib/signoz/
|
|
||||||
environment:
|
|
||||||
- ClickHouseUrl=tcp://clickhouse:9000
|
|
||||||
- ALERTMANAGER_API_PREFIX=http://alertmanager:9093/api/
|
|
||||||
- SIGNOZ_LOCAL_DB_PATH=/var/lib/signoz/signoz.db
|
|
||||||
- DASHBOARDS_PATH=/root/config/dashboards
|
|
||||||
- STORAGE=clickhouse
|
|
||||||
- GODEBUG=netdns=go
|
|
||||||
- TELEMETRY_ENABLED=true
|
|
||||||
- DEPLOYMENT_TYPE=docker-standalone-amd
|
|
||||||
restart: on-failure
|
|
||||||
healthcheck:
|
|
||||||
test:
|
|
||||||
[
|
|
||||||
"CMD",
|
|
||||||
"wget",
|
|
||||||
"--spider",
|
|
||||||
"-q",
|
|
||||||
"localhost:8080/api/v1/health"
|
|
||||||
]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
<<: *db-depend
|
|
||||||
|
|
||||||
frontend:
|
|
||||||
image: signoz/frontend:${DOCKER_TAG:-0.55.0}
|
|
||||||
container_name: signoz-frontend
|
|
||||||
restart: on-failure
|
|
||||||
depends_on:
|
|
||||||
- alertmanager
|
|
||||||
- query-service
|
|
||||||
ports:
|
|
||||||
- "3301:3301"
|
|
||||||
volumes:
|
|
||||||
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
|
|
||||||
|
|
||||||
otel-collector-migrator:
|
|
||||||
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.102.10}
|
|
||||||
container_name: otel-migrator
|
|
||||||
command:
|
|
||||||
- "--dsn=tcp://clickhouse:9000"
|
|
||||||
depends_on:
|
|
||||||
clickhouse:
|
|
||||||
condition: service_healthy
|
|
||||||
# clickhouse-2:
|
|
||||||
# condition: service_healthy
|
|
||||||
# clickhouse-3:
|
|
||||||
# condition: service_healthy
|
|
||||||
|
|
||||||
|
|
||||||
otel-collector:
|
|
||||||
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.102.10}
|
|
||||||
container_name: signoz-otel-collector
|
|
||||||
command:
|
|
||||||
[
|
|
||||||
"--config=/etc/otel-collector-config.yaml",
|
|
||||||
"--manager-config=/etc/manager-config.yaml",
|
|
||||||
"--copy-path=/var/tmp/collector-config.yaml",
|
|
||||||
"--feature-gates=-pkg.translator.prometheus.NormalizeName"
|
|
||||||
]
|
|
||||||
user: root # required for reading docker container logs
|
|
||||||
volumes:
|
|
||||||
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
|
|
||||||
- ./otel-collector-opamp-config.yaml:/etc/manager-config.yaml
|
|
||||||
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
|
||||||
- /:/hostfs:ro
|
|
||||||
environment:
|
|
||||||
- OTEL_RESOURCE_ATTRIBUTES=host.name=signoz-host,os.type=linux
|
|
||||||
- DOCKER_MULTI_NODE_CLUSTER=false
|
|
||||||
- LOW_CARDINAL_EXCEPTION_GROUPING=false
|
|
||||||
ports:
|
|
||||||
# - "1777:1777" # pprof extension
|
|
||||||
- "4317:4317" # OTLP gRPC receiver
|
|
||||||
- "4318:4318" # OTLP HTTP receiver
|
|
||||||
# - "8888:8888" # OtelCollector internal metrics
|
|
||||||
# - "8889:8889" # signoz spanmetrics exposed by the agent
|
|
||||||
# - "9411:9411" # Zipkin port
|
|
||||||
# - "13133:13133" # health check extension
|
|
||||||
# - "14250:14250" # Jaeger gRPC
|
|
||||||
# - "14268:14268" # Jaeger thrift HTTP
|
|
||||||
# - "55678:55678" # OpenCensus receiver
|
|
||||||
# - "55679:55679" # zPages extension
|
|
||||||
restart: on-failure
|
|
||||||
depends_on:
|
|
||||||
clickhouse:
|
|
||||||
condition: service_healthy
|
|
||||||
otel-collector-migrator:
|
|
||||||
condition: service_completed_successfully
|
|
||||||
query-service:
|
|
||||||
condition: service_healthy
|
|
||||||
|
|
||||||
logspout:
|
|
||||||
image: "gliderlabs/logspout:v3.2.14"
|
|
||||||
container_name: signoz-logspout
|
|
||||||
volumes:
|
|
||||||
- /etc/hostname:/etc/host_hostname:ro
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
command: syslog+tcp://otel-collector:2255
|
|
||||||
depends_on:
|
|
||||||
- otel-collector
|
|
||||||
restart: on-failure
|
|
||||||
|
|
||||||
hotrod:
|
|
||||||
image: jaegertracing/example-hotrod:1.30
|
|
||||||
container_name: hotrod
|
|
||||||
logging:
|
|
||||||
options:
|
|
||||||
max-size: 50m
|
|
||||||
max-file: "3"
|
|
||||||
command: [ "all" ]
|
|
||||||
environment:
|
|
||||||
- JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
|
|
||||||
|
|
||||||
load-hotrod:
|
|
||||||
image: "signoz/locust:1.2.3"
|
|
||||||
container_name: load-hotrod
|
|
||||||
hostname: load-hotrod
|
|
||||||
environment:
|
|
||||||
ATTACKED_HOST: http://hotrod:8080
|
|
||||||
LOCUST_MODE: standalone
|
|
||||||
NO_PROXY: standalone
|
|
||||||
TASK_DELAY_FROM: 5
|
|
||||||
TASK_DELAY_TO: 30
|
|
||||||
QUIET_MODE: "${QUIET_MODE:-false}"
|
|
||||||
LOCUST_OPTS: "--headless -u 10 -r 1"
|
|
||||||
volumes:
|
|
||||||
- ../common/locust-scripts:/locust
|
|
||||||
|
26
deploy/docker/clickhouse-setup/test-app-docker-compose.yaml
Normal file
26
deploy/docker/clickhouse-setup/test-app-docker-compose.yaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
services:
|
||||||
|
hotrod:
|
||||||
|
image: jaegertracing/example-hotrod:1.30
|
||||||
|
container_name: hotrod
|
||||||
|
logging:
|
||||||
|
options:
|
||||||
|
max-size: 50m
|
||||||
|
max-file: "3"
|
||||||
|
command: [ "all" ]
|
||||||
|
environment:
|
||||||
|
- JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
|
||||||
|
|
||||||
|
load-hotrod:
|
||||||
|
image: "signoz/locust:1.2.3"
|
||||||
|
container_name: load-hotrod
|
||||||
|
hostname: load-hotrod
|
||||||
|
environment:
|
||||||
|
ATTACKED_HOST: http://hotrod:8080
|
||||||
|
LOCUST_MODE: standalone
|
||||||
|
NO_PROXY: standalone
|
||||||
|
TASK_DELAY_FROM: 5
|
||||||
|
TASK_DELAY_TO: 30
|
||||||
|
QUIET_MODE: "${QUIET_MODE:-false}"
|
||||||
|
LOCUST_OPTS: "--headless -u 10 -r 1"
|
||||||
|
volumes:
|
||||||
|
- ../common/locust-scripts:/locust
|
@ -106,12 +106,11 @@ func (aH *APIHandler) queryRangeV4(w http.ResponseWriter, r *http.Request) {
|
|||||||
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uniqueResults := make(map[string]*v3.Result)
|
resp := v3.QueryRangeResponse{
|
||||||
for _, anomaly := range anomalies.Results {
|
Result: anomalies.Results,
|
||||||
uniqueResults[anomaly.QueryName] = anomaly
|
ResultType: "anomaly",
|
||||||
uniqueResults[anomaly.QueryName].IsAnomaly = true
|
|
||||||
}
|
}
|
||||||
aH.Respond(w, uniqueResults)
|
aH.Respond(w, resp)
|
||||||
} else {
|
} else {
|
||||||
r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||||
aH.QueryRangeV4(w, r)
|
aH.QueryRangeV4(w, r)
|
||||||
|
@ -757,7 +757,7 @@ func makeRulesManager(
|
|||||||
RepoURL: ruleRepoURL,
|
RepoURL: ruleRepoURL,
|
||||||
DBConn: db,
|
DBConn: db,
|
||||||
Context: context.Background(),
|
Context: context.Background(),
|
||||||
Logger: nil,
|
Logger: zap.L(),
|
||||||
DisableRules: disableRules,
|
DisableRules: disableRules,
|
||||||
FeatureFlags: fm,
|
FeatureFlags: fm,
|
||||||
Reader: ch,
|
Reader: ch,
|
||||||
|
@ -20,6 +20,8 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
|
||||||
|
prommodel "github.com/prometheus/common/model"
|
||||||
|
|
||||||
zapotlpencoder "github.com/SigNoz/zap_otlp/zap_otlp_encoder"
|
zapotlpencoder "github.com/SigNoz/zap_otlp/zap_otlp_encoder"
|
||||||
zapotlpsync "github.com/SigNoz/zap_otlp/zap_otlp_sync"
|
zapotlpsync "github.com/SigNoz/zap_otlp/zap_otlp_sync"
|
||||||
|
|
||||||
@ -77,6 +79,10 @@ func initZapLog(enableQueryServiceLogOTLPExport bool) *zap.Logger {
|
|||||||
return logger
|
return logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
prommodel.NameValidationScheme = prommodel.UTF8Validation
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var promConfigPath, skipTopLvlOpsPath string
|
var promConfigPath, skipTopLvlOpsPath string
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ func (r *AnomalyRule) Eval(ctx context.Context, ts time.Time) (interface{}, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
lb := labels.NewBuilder(smpl.Metric).Del(labels.MetricNameLabel).Del(labels.TemporalityLabel)
|
lb := labels.NewBuilder(smpl.Metric).Del(labels.MetricNameLabel).Del(labels.TemporalityLabel)
|
||||||
resultLabels := labels.NewBuilder(smpl.MetricOrig).Del(labels.MetricNameLabel).Del(labels.TemporalityLabel).Labels()
|
resultLabels := labels.NewBuilder(smpl.Metric).Del(labels.MetricNameLabel).Del(labels.TemporalityLabel).Labels()
|
||||||
|
|
||||||
for name, value := range r.Labels().Map() {
|
for name, value := range r.Labels().Map() {
|
||||||
lb.Set(name, expand(value))
|
lb.Set(name, expand(value))
|
||||||
@ -262,7 +262,7 @@ func (r *AnomalyRule) Eval(ctx context.Context, ts time.Time) (interface{}, erro
|
|||||||
|
|
||||||
annotations := make(labels.Labels, 0, len(r.Annotations().Map()))
|
annotations := make(labels.Labels, 0, len(r.Annotations().Map()))
|
||||||
for name, value := range r.Annotations().Map() {
|
for name, value := range r.Annotations().Map() {
|
||||||
annotations = append(annotations, labels.Label{Name: common.NormalizeLabelName(name), Value: expand(value)})
|
annotations = append(annotations, labels.Label{Name: name, Value: expand(value)})
|
||||||
}
|
}
|
||||||
if smpl.IsMissing {
|
if smpl.IsMissing {
|
||||||
lb.Set(labels.AlertNameLabel, "[No data] "+r.Name())
|
lb.Set(labels.AlertNameLabel, "[No data] "+r.Name())
|
||||||
|
@ -73,7 +73,7 @@ func PrepareTaskFunc(opts baserules.PrepareTaskOptions) (baserules.Task, error)
|
|||||||
task = newTask(baserules.TaskTypeCh, opts.TaskName, time.Duration(opts.Rule.Frequency), rules, opts.ManagerOpts, opts.NotifyFunc, opts.RuleDB)
|
task = newTask(baserules.TaskTypeCh, opts.TaskName, time.Duration(opts.Rule.Frequency), rules, opts.ManagerOpts, opts.NotifyFunc, opts.RuleDB)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unsupported rule type. Supported types: %s, %s", baserules.RuleTypeProm, baserules.RuleTypeThreshold)
|
return nil, fmt.Errorf("unsupported rule type %s. Supported types: %s, %s", opts.Rule.RuleType, baserules.RuleTypeProm, baserules.RuleTypeThreshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
return task, nil
|
return task, nil
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" fill="none"><rect width="100" height="100" fill="url(#a)" rx="20"/><g fill="#fff" fill-rule="evenodd" clip-rule="evenodd" filter="url(#b)"><path d="M11 49.941v-.003l.002-.005.003-.014.007-.035a8.37 8.37 0 0 1 .105-.42c.073-.263.184-.624.348-1.072.328-.896.866-2.135 1.73-3.617 1.732-2.97 4.753-6.883 9.95-10.955 5.223-4.092 10.295-6.293 14.08-7.471a35.328 35.328 0 0 1 4.585-1.114 23.628 23.628 0 0 1 1.687-.223 9.17 9.17 0 0 1 .108-.009l.034-.002h.011l.007-.001s.002 0 .133 2.217c.13 2.218.132 2.218.132 2.218h-.002l-.053.004a19.098 19.098 0 0 0-1.326.178c-.809.136-1.937.37-3.302.763l-.127.043c-2.745.94-6.666 2.775-11.249 6.362-4.572 3.577-7.142 6.95-8.563 9.393-.711 1.222-1.137 2.215-1.383 2.889a9.995 9.995 0 0 0-.29.933c.008.037.022.095.044.173.046.166.123.423.246.76.246.674.672 1.667 1.383 2.89 1.421 2.441 3.991 5.815 8.563 9.392 4.584 3.587 8.504 5.423 11.25 6.362l.126.043c1.365.393 2.493.627 3.302.763a19.098 19.098 0 0 0 1.326.178l.053.004h.002s-.002 0-.133 2.218C43.66 75 43.657 75 43.657 75h-.007l-.011-.001-.034-.002a9.17 9.17 0 0 1-.478-.046 23.628 23.628 0 0 1-1.317-.186 35.328 35.328 0 0 1-4.584-1.114c-3.786-1.178-8.858-3.38-14.081-7.471-5.197-4.072-8.218-7.985-9.95-10.955-.864-1.482-1.402-2.72-1.73-3.617-.164-.448-.275-.81-.348-1.072a8.37 8.37 0 0 1-.105-.42l-.007-.035-.003-.014-.002-.005v-.121Zm78 0v-.003l-.002-.005-.002-.014-.008-.035a8.532 8.532 0 0 0-.105-.42 14.049 14.049 0 0 0-.348-1.072c-.328-.896-.866-2.135-1.73-3.617-1.732-2.97-4.753-6.883-9.95-10.955-5.223-4.092-10.295-6.293-14.08-7.471a35.328 35.328 0 0 0-4.585-1.114 23.628 23.628 0 0 0-1.687-.223 9.17 9.17 0 0 0-.108-.009l-.034-.002h-.011L56.343 25s-.002 0-.133 2.217c-.13 2.218-.132 2.218-.132 2.218h.002l.053.004a19.098 19.098 0 0 1 1.326.178c.809.136 1.937.37 3.302.763l.127.043c2.745.94 6.666 2.775 11.249 6.362 4.572 3.577 7.141 6.95 8.563 9.393.711 1.222 1.137 2.215 1.383 2.889a9.995 9.995 0 0 1 .29.933 9.995 9.995 0 0 1-.29.934c-.246.673-.672 1.666-1.383 2.888-1.422 2.442-3.991 5.816-8.563 9.393-4.584 3.587-8.504 5.423-11.25 6.362l-.126.043a30.108 30.108 0 0 1-3.302.763 19.098 19.098 0 0 1-1.326.178l-.053.004h-.002s.002 0 .133 2.218C56.34 75 56.343 75 56.343 75h.007l.011-.001.034-.002a9.17 9.17 0 0 0 .478-.046c.314-.034.758-.092 1.317-.186a35.328 35.328 0 0 0 4.584-1.114c3.786-1.178 8.858-3.38 14.081-7.471 5.197-4.072 8.218-7.985 9.95-10.955.864-1.482 1.402-2.72 1.73-3.617.164-.448.275-.81.348-1.072a8.532 8.532 0 0 0 .105-.42l.008-.035.002-.014.001-.005.001-.003v-.118Z"/><path d="M68.342 49.998c0 9.846-7.924 17.827-17.7 17.827-9.775 0-17.7-7.981-17.7-17.827 0-9.846 7.925-17.827 17.7-17.827 9.776 0 17.7 7.981 17.7 17.827ZM46.218 39.97s-2.127 2.508-2.766 4.457c-.412 1.257-.553 3.343-.553 3.343h-5.531s0-1.672 1.106-4.457c1.106-2.786 2.212-3.343 2.212-3.343h5.532Zm-2.766 15.6c.639 1.949 2.766 4.457 2.766 4.457h-5.532s-1.106-.557-2.212-3.343c-1.106-2.785-1.106-4.457-1.106-4.457h5.53s.142 2.086.554 3.343Z"/></g><defs><radialGradient id="a" cx="0" cy="0" r="1" gradientTransform="matrix(40.99997 42 -42 40.99997 50 50)" gradientUnits="userSpaceOnUse"><stop offset=".33" stop-color="#F76526"/><stop offset="1" stop-color="#F43030"/></radialGradient><filter id="b" width="90" height="62" x="5" y="23" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/><feOffset dy="4"/><feGaussianBlur stdDeviation="3"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0.368384 0 0 0 0 0.0623777 0 0 0 0 0.0623777 0 0 0 0.25 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_3909_18731"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_3909_18731" result="shape"/><feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/><feOffset dy="4"/><feGaussianBlur stdDeviation="3"/><feComposite in2="hardAlpha" k2="-1" k3="1" operator="arithmetic"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend in2="shape" result="effect2_innerShadow_3909_18731"/></filter></defs></svg>
|
||||||
<g clip-path="url(#clip0_2048_2251)">
|
|
||||||
<path opacity="0.9" d="M8.02226 15.9866C3.56539 15.9866 -6.10352e-05 12.4896 -6.10352e-05 8.11832C-6.10352e-05 3.79075 3.56539 0.25 8.02226 0.25H13.0584C14.7075 0.25 15.9999 1.56139 15.9999 3.13506V8.11832C15.9999 12.4896 12.4345 15.9866 8.02226 15.9866Z" fill="#F25733"/>
|
|
||||||
<path d="M7.95919 4.71207C4.63025 4.71207 2.75514 7.46868 2.67693 7.58603C2.48413 7.87508 2.48413 8.24888 2.67707 8.53816C2.75514 8.65528 4.63025 11.4119 7.95919 11.4119C11.2881 11.4119 13.1633 8.65528 13.2414 8.53792C13.4342 8.24888 13.4342 7.87508 13.2413 7.58582C13.1632 7.46868 11.2881 4.71207 7.95919 4.71207ZM3.13771 8.23088C3.06925 8.12832 3.06925 7.99571 3.13771 7.89307C3.20059 7.79867 4.53564 5.83764 6.92256 5.36723C5.84092 5.78476 5.07127 6.83485 5.07127 8.062C5.07127 9.28912 5.84092 10.3392 6.92256 10.7567C4.53564 10.2863 3.20059 8.32528 3.13771 8.23088ZM6.62838 8.062C6.62838 8.21488 6.50443 8.3388 6.35151 8.3388C6.19859 8.3388 6.07465 8.21488 6.07465 8.062C6.07465 7.02287 6.92003 6.17748 7.95916 6.17748C8.11207 6.17748 8.23599 6.30141 8.23599 6.45434C8.23599 6.60727 8.11207 6.73119 7.95916 6.73119C7.22535 6.73119 6.62838 7.32815 6.62838 8.062ZM7.95919 8.73504C7.58803 8.73504 7.2861 8.43312 7.2861 8.062C7.2861 7.69085 7.58803 7.3889 7.95919 7.3889C8.33039 7.3889 8.63231 7.69083 8.63231 8.062C8.63231 8.43312 8.33039 8.73504 7.95919 8.73504ZM12.7806 8.23088C12.7178 8.32528 11.3827 10.2863 8.99583 10.7567C10.0775 10.3392 10.8471 9.28912 10.8471 8.062C10.8471 6.83487 10.0775 5.78477 8.99583 5.36724C11.3827 5.83768 12.7178 7.7987 12.7806 7.89307C12.8491 7.99571 12.8491 8.12832 12.7806 8.23088Z" fill="#F9F2F9"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_2048_2251">
|
|
||||||
<rect width="16" height="16" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 13 KiB |
@ -118,6 +118,8 @@
|
|||||||
"exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.",
|
"exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.",
|
||||||
"field_unit": "Threshold unit",
|
"field_unit": "Threshold unit",
|
||||||
"text_alert_on_absent": "Send a notification if data is missing for",
|
"text_alert_on_absent": "Send a notification if data is missing for",
|
||||||
|
"text_require_min_points": "Run alert evaluation only when there are minimum of",
|
||||||
|
"text_num_points": "data points in each result group",
|
||||||
"text_alert_frequency": "Run alert every",
|
"text_alert_frequency": "Run alert every",
|
||||||
"text_for": "minutes",
|
"text_for": "minutes",
|
||||||
"selected_query_placeholder": "Select query"
|
"selected_query_placeholder": "Select query"
|
||||||
|
@ -118,6 +118,8 @@
|
|||||||
"exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.",
|
"exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.",
|
||||||
"field_unit": "Threshold unit",
|
"field_unit": "Threshold unit",
|
||||||
"text_alert_on_absent": "Send a notification if data is missing for",
|
"text_alert_on_absent": "Send a notification if data is missing for",
|
||||||
|
"text_require_min_points": "Run alert evaluation only when there are minimum of",
|
||||||
|
"text_num_points": "data points in each result group",
|
||||||
"text_alert_frequency": "Run alert every",
|
"text_alert_frequency": "Run alert every",
|
||||||
"text_for": "minutes",
|
"text_for": "minutes",
|
||||||
"selected_query_placeholder": "Select query"
|
"selected_query_placeholder": "Select query"
|
||||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 10 KiB |
@ -12,6 +12,7 @@ import useAnalytics from 'hooks/analytics/useAnalytics';
|
|||||||
import { KeyboardHotkeysProvider } from 'hooks/hotkeys/useKeyboardHotkeys';
|
import { KeyboardHotkeysProvider } from 'hooks/hotkeys/useKeyboardHotkeys';
|
||||||
import { useIsDarkMode, useThemeConfig } from 'hooks/useDarkMode';
|
import { useIsDarkMode, useThemeConfig } from 'hooks/useDarkMode';
|
||||||
import { THEME_MODE } from 'hooks/useDarkMode/constant';
|
import { THEME_MODE } from 'hooks/useDarkMode/constant';
|
||||||
|
import useFeatureFlags from 'hooks/useFeatureFlag';
|
||||||
import useGetFeatureFlag from 'hooks/useGetFeatureFlag';
|
import useGetFeatureFlag from 'hooks/useGetFeatureFlag';
|
||||||
import useLicense, { LICENSE_PLAN_KEY } from 'hooks/useLicense';
|
import useLicense, { LICENSE_PLAN_KEY } from 'hooks/useLicense';
|
||||||
import { NotificationProvider } from 'hooks/useNotifications';
|
import { NotificationProvider } from 'hooks/useNotifications';
|
||||||
@ -58,23 +59,13 @@ function App(): JSX.Element {
|
|||||||
|
|
||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
|
|
||||||
|
const isChatSupportEnabled =
|
||||||
|
useFeatureFlags(FeatureKeys.CHAT_SUPPORT)?.active || false;
|
||||||
|
|
||||||
|
const isPremiumSupportEnabled =
|
||||||
|
useFeatureFlags(FeatureKeys.PREMIUM_SUPPORT)?.active || false;
|
||||||
|
|
||||||
const featureResponse = useGetFeatureFlag((allFlags) => {
|
const featureResponse = useGetFeatureFlag((allFlags) => {
|
||||||
const isOnboardingEnabled =
|
|
||||||
allFlags.find((flag) => flag.name === FeatureKeys.ONBOARDING)?.active ||
|
|
||||||
false;
|
|
||||||
|
|
||||||
const isChatSupportEnabled =
|
|
||||||
allFlags.find((flag) => flag.name === FeatureKeys.CHAT_SUPPORT)?.active ||
|
|
||||||
false;
|
|
||||||
|
|
||||||
const isPremiumSupportEnabled =
|
|
||||||
allFlags.find((flag) => flag.name === FeatureKeys.PREMIUM_SUPPORT)?.active ||
|
|
||||||
false;
|
|
||||||
|
|
||||||
const showAddCreditCardModal =
|
|
||||||
!isPremiumSupportEnabled &&
|
|
||||||
!licenseData?.payload?.trialConvertedToSubscription;
|
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: UPDATE_FEATURE_FLAG_RESPONSE,
|
type: UPDATE_FEATURE_FLAG_RESPONSE,
|
||||||
payload: {
|
payload: {
|
||||||
@ -83,6 +74,10 @@ function App(): JSX.Element {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isOnboardingEnabled =
|
||||||
|
allFlags.find((flag) => flag.name === FeatureKeys.ONBOARDING)?.active ||
|
||||||
|
false;
|
||||||
|
|
||||||
if (!isOnboardingEnabled || !isCloudUserVal) {
|
if (!isOnboardingEnabled || !isCloudUserVal) {
|
||||||
const newRoutes = routes.filter(
|
const newRoutes = routes.filter(
|
||||||
(route) => route?.path !== ROUTES.GET_STARTED,
|
(route) => route?.path !== ROUTES.GET_STARTED,
|
||||||
@ -90,16 +85,6 @@ function App(): JSX.Element {
|
|||||||
|
|
||||||
setRoutes(newRoutes);
|
setRoutes(newRoutes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoggedInState && isChatSupportEnabled && !showAddCreditCardModal) {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
window.Intercom('boot', {
|
|
||||||
app_id: process.env.INTERCOM_APP_ID,
|
|
||||||
email: user?.email || '',
|
|
||||||
name: user?.name || '',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const isOnBasicPlan =
|
const isOnBasicPlan =
|
||||||
@ -201,6 +186,26 @@ function App(): JSX.Element {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [pathname]);
|
}, [pathname]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const showAddCreditCardModal =
|
||||||
|
!isPremiumSupportEnabled &&
|
||||||
|
!licenseData?.payload?.trialConvertedToSubscription;
|
||||||
|
|
||||||
|
if (isLoggedInState && isChatSupportEnabled && !showAddCreditCardModal) {
|
||||||
|
window.Intercom('boot', {
|
||||||
|
app_id: process.env.INTERCOM_APP_ID,
|
||||||
|
email: user?.email || '',
|
||||||
|
name: user?.name || '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
isLoggedInState,
|
||||||
|
isChatSupportEnabled,
|
||||||
|
user,
|
||||||
|
licenseData,
|
||||||
|
isPremiumSupportEnabled,
|
||||||
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user && user?.email && user?.userId && user?.name) {
|
if (user && user?.email && user?.userId && user?.name) {
|
||||||
try {
|
try {
|
||||||
@ -227,6 +232,10 @@ function App(): JSX.Element {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [user]);
|
}, [user]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.info('We are hiring! https://jobs.gem.com/signoz');
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigProvider theme={themeConfig}>
|
<ConfigProvider theme={themeConfig}>
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
.client-side-qb-search {
|
||||||
|
.ant-select-selection-search {
|
||||||
|
width: max-content !important;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,654 @@
|
|||||||
|
/* eslint-disable sonarjs/cognitive-complexity */
|
||||||
|
|
||||||
|
import './ClientSideQBSearch.styles.scss';
|
||||||
|
|
||||||
|
import { Color } from '@signozhq/design-tokens';
|
||||||
|
import { Select, Tag, Tooltip } from 'antd';
|
||||||
|
import {
|
||||||
|
OPERATORS,
|
||||||
|
QUERY_BUILDER_OPERATORS_BY_TYPES,
|
||||||
|
QUERY_BUILDER_SEARCH_VALUES,
|
||||||
|
} from 'constants/queryBuilder';
|
||||||
|
import { CustomTagProps } from 'container/QueryBuilder/filters/QueryBuilderSearch';
|
||||||
|
import { selectStyle } from 'container/QueryBuilder/filters/QueryBuilderSearch/config';
|
||||||
|
import { PLACEHOLDER } from 'container/QueryBuilder/filters/QueryBuilderSearch/constant';
|
||||||
|
import { TypographyText } from 'container/QueryBuilder/filters/QueryBuilderSearch/style';
|
||||||
|
import {
|
||||||
|
checkCommaInValue,
|
||||||
|
getOperatorFromValue,
|
||||||
|
getOperatorValue,
|
||||||
|
getTagToken,
|
||||||
|
isInNInOperator,
|
||||||
|
} from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
|
||||||
|
import {
|
||||||
|
DropdownState,
|
||||||
|
ITag,
|
||||||
|
Option,
|
||||||
|
} from 'container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2';
|
||||||
|
import Suggestions from 'container/QueryBuilder/filters/QueryBuilderSearchV2/Suggestions';
|
||||||
|
import { WhereClauseConfig } from 'hooks/queryBuilder/useAutoComplete';
|
||||||
|
import { validationMapper } from 'hooks/queryBuilder/useIsValidTag';
|
||||||
|
import { operatorTypeMapper } from 'hooks/queryBuilder/useOperatorType';
|
||||||
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
|
import { isArray, isEmpty, isEqual, isObject } from 'lodash-es';
|
||||||
|
import { ChevronDown, ChevronUp } from 'lucide-react';
|
||||||
|
import type { BaseSelectRef } from 'rc-select';
|
||||||
|
import {
|
||||||
|
KeyboardEvent,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
|
import {
|
||||||
|
BaseAutocompleteData,
|
||||||
|
DataTypes,
|
||||||
|
} from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
|
import {
|
||||||
|
IBuilderQuery,
|
||||||
|
TagFilter,
|
||||||
|
} from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
import { popupContainer } from 'utils/selectPopupContainer';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
|
export interface AttributeKey {
|
||||||
|
key: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AttributeValuesMap {
|
||||||
|
[key: string]: AttributeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ClientSideQBSearchProps {
|
||||||
|
filters: TagFilter;
|
||||||
|
onChange: (value: TagFilter) => void;
|
||||||
|
whereClauseConfig?: WhereClauseConfig;
|
||||||
|
placeholder?: string;
|
||||||
|
className?: string;
|
||||||
|
suffixIcon?: React.ReactNode;
|
||||||
|
attributeValuesMap?: AttributeValuesMap;
|
||||||
|
attributeKeys: AttributeKey[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AttributeValue {
|
||||||
|
stringAttributeValues: string[] | [];
|
||||||
|
numberAttributeValues: number[] | [];
|
||||||
|
boolAttributeValues: boolean[] | [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function ClientSideQBSearch(
|
||||||
|
props: ClientSideQBSearchProps,
|
||||||
|
): React.ReactElement {
|
||||||
|
const {
|
||||||
|
onChange,
|
||||||
|
placeholder,
|
||||||
|
className,
|
||||||
|
suffixIcon,
|
||||||
|
whereClauseConfig,
|
||||||
|
attributeValuesMap,
|
||||||
|
attributeKeys,
|
||||||
|
filters,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const isDarkMode = useIsDarkMode();
|
||||||
|
|
||||||
|
const selectRef = useRef<BaseSelectRef>(null);
|
||||||
|
|
||||||
|
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
|
// create the tags from the initial query here, this should only be computed on the first load as post that tags and query will be always in sync.
|
||||||
|
const [tags, setTags] = useState<ITag[]>(filters.items as ITag[]);
|
||||||
|
|
||||||
|
// this will maintain the current state of in process filter item
|
||||||
|
const [currentFilterItem, setCurrentFilterItem] = useState<ITag | undefined>();
|
||||||
|
|
||||||
|
const [currentState, setCurrentState] = useState<DropdownState>(
|
||||||
|
DropdownState.ATTRIBUTE_KEY,
|
||||||
|
);
|
||||||
|
|
||||||
|
// to maintain the current running state until the tokenization happens for the tag
|
||||||
|
const [searchValue, setSearchValue] = useState<string>('');
|
||||||
|
|
||||||
|
const [dropdownOptions, setDropdownOptions] = useState<Option[]>([]);
|
||||||
|
|
||||||
|
const attributeValues = useMemo(() => {
|
||||||
|
if (currentFilterItem?.key?.key) {
|
||||||
|
return attributeValuesMap?.[currentFilterItem.key.key];
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
stringAttributeValues: [],
|
||||||
|
numberAttributeValues: [],
|
||||||
|
boolAttributeValues: [],
|
||||||
|
};
|
||||||
|
}, [attributeValuesMap, currentFilterItem?.key?.key]);
|
||||||
|
|
||||||
|
const handleDropdownSelect = useCallback(
|
||||||
|
(value: string) => {
|
||||||
|
let parsedValue: BaseAutocompleteData | string;
|
||||||
|
|
||||||
|
try {
|
||||||
|
parsedValue = JSON.parse(value);
|
||||||
|
} catch {
|
||||||
|
parsedValue = value;
|
||||||
|
}
|
||||||
|
if (currentState === DropdownState.ATTRIBUTE_KEY) {
|
||||||
|
setCurrentFilterItem((prev) => ({
|
||||||
|
...prev,
|
||||||
|
key: parsedValue as BaseAutocompleteData,
|
||||||
|
op: '',
|
||||||
|
value: '',
|
||||||
|
}));
|
||||||
|
setCurrentState(DropdownState.OPERATOR);
|
||||||
|
setSearchValue((parsedValue as BaseAutocompleteData)?.key);
|
||||||
|
} else if (currentState === DropdownState.OPERATOR) {
|
||||||
|
if (value === OPERATORS.EXISTS || value === OPERATORS.NOT_EXISTS) {
|
||||||
|
setTags((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
key: currentFilterItem?.key,
|
||||||
|
op: value,
|
||||||
|
value: '',
|
||||||
|
} as ITag,
|
||||||
|
]);
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setSearchValue('');
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
} else {
|
||||||
|
setCurrentFilterItem((prev) => ({
|
||||||
|
key: prev?.key as BaseAutocompleteData,
|
||||||
|
op: value as string,
|
||||||
|
value: '',
|
||||||
|
}));
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_VALUE);
|
||||||
|
setSearchValue(`${currentFilterItem?.key?.key} ${value}`);
|
||||||
|
}
|
||||||
|
} else if (currentState === DropdownState.ATTRIBUTE_VALUE) {
|
||||||
|
const operatorType =
|
||||||
|
operatorTypeMapper[currentFilterItem?.op || ''] || 'NOT_VALID';
|
||||||
|
const isMulti = operatorType === QUERY_BUILDER_SEARCH_VALUES.MULTIPLY;
|
||||||
|
|
||||||
|
if (isMulti) {
|
||||||
|
const { tagKey, tagOperator, tagValue } = getTagToken(searchValue);
|
||||||
|
// this condition takes care of adding the IN/NIN multi values when pressed enter on an already existing value.
|
||||||
|
// not the best interaction but in sync with what we have today!
|
||||||
|
if (tagValue.includes(String(value))) {
|
||||||
|
setSearchValue('');
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setTags((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
key: currentFilterItem?.key,
|
||||||
|
op: currentFilterItem?.op,
|
||||||
|
value: tagValue,
|
||||||
|
} as ITag,
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// this is for adding subsequent comma seperated values
|
||||||
|
const newSearch = [...tagValue];
|
||||||
|
newSearch[newSearch.length === 0 ? 0 : newSearch.length - 1] = value;
|
||||||
|
const newSearchValue = newSearch.join(',');
|
||||||
|
setSearchValue(`${tagKey} ${tagOperator} ${newSearchValue},`);
|
||||||
|
} else {
|
||||||
|
setSearchValue('');
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setTags((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
key: currentFilterItem?.key,
|
||||||
|
op: currentFilterItem?.op,
|
||||||
|
value,
|
||||||
|
} as ITag,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[currentFilterItem?.key, currentFilterItem?.op, currentState, searchValue],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSearch = useCallback((value: string) => {
|
||||||
|
setSearchValue(value);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onInputKeyDownHandler = useCallback(
|
||||||
|
(event: KeyboardEvent<Element>): void => {
|
||||||
|
if (event.key === 'Backspace' && !searchValue) {
|
||||||
|
event.stopPropagation();
|
||||||
|
setTags((prev) => prev.slice(0, -1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[searchValue],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOnBlur = useCallback((): void => {
|
||||||
|
if (searchValue) {
|
||||||
|
const operatorType =
|
||||||
|
operatorTypeMapper[currentFilterItem?.op || ''] || 'NOT_VALID';
|
||||||
|
// if key is added and operator is not present then convert to body CONTAINS key
|
||||||
|
if (
|
||||||
|
currentFilterItem?.key &&
|
||||||
|
isEmpty(currentFilterItem?.op) &&
|
||||||
|
whereClauseConfig?.customKey === 'body' &&
|
||||||
|
whereClauseConfig?.customOp === OPERATORS.CONTAINS
|
||||||
|
) {
|
||||||
|
setTags((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
key: {
|
||||||
|
key: 'body',
|
||||||
|
dataType: DataTypes.String,
|
||||||
|
type: '',
|
||||||
|
isColumn: true,
|
||||||
|
isJSON: false,
|
||||||
|
id: 'body--string----true',
|
||||||
|
},
|
||||||
|
op: OPERATORS.CONTAINS,
|
||||||
|
value: currentFilterItem?.key?.key,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setSearchValue('');
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
} else if (
|
||||||
|
currentFilterItem?.op === OPERATORS.EXISTS ||
|
||||||
|
currentFilterItem?.op === OPERATORS.NOT_EXISTS
|
||||||
|
) {
|
||||||
|
// is exists and not exists operator is present then convert directly to tag! no need of value here
|
||||||
|
setTags((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
key: currentFilterItem?.key,
|
||||||
|
op: currentFilterItem?.op,
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setSearchValue('');
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
} else if (
|
||||||
|
// if the current state is in sync with the kind of operator used then convert into a tag
|
||||||
|
validationMapper[operatorType]?.(
|
||||||
|
isArray(currentFilterItem?.value)
|
||||||
|
? currentFilterItem?.value.length || 0
|
||||||
|
: 1,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
setTags((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
key: currentFilterItem?.key as BaseAutocompleteData,
|
||||||
|
op: currentFilterItem?.op as string,
|
||||||
|
value: currentFilterItem?.value || '',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setSearchValue('');
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
currentFilterItem?.key,
|
||||||
|
currentFilterItem?.op,
|
||||||
|
currentFilterItem?.value,
|
||||||
|
searchValue,
|
||||||
|
whereClauseConfig?.customKey,
|
||||||
|
whereClauseConfig?.customOp,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// this useEffect takes care of tokenisation based on the search state
|
||||||
|
useEffect(() => {
|
||||||
|
// if there is no search value reset to the default state
|
||||||
|
if (!searchValue) {
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// split the current search value based on delimiters
|
||||||
|
const { tagKey, tagOperator, tagValue } = getTagToken(searchValue);
|
||||||
|
|
||||||
|
if (
|
||||||
|
// Case 1 - if key is defined but the search text doesn't match with the set key,
|
||||||
|
// can happen when user selects from dropdown and then deletes a few characters
|
||||||
|
currentFilterItem?.key &&
|
||||||
|
currentFilterItem?.key?.key !== tagKey.split(' ')[0]
|
||||||
|
) {
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
} else if (tagOperator && isEmpty(currentFilterItem?.op)) {
|
||||||
|
// Case 2 -> key is set and now typing for the operator
|
||||||
|
if (
|
||||||
|
tagOperator === OPERATORS.EXISTS ||
|
||||||
|
tagOperator === OPERATORS.NOT_EXISTS
|
||||||
|
) {
|
||||||
|
setTags((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
key: currentFilterItem?.key,
|
||||||
|
op: tagOperator,
|
||||||
|
value: '',
|
||||||
|
} as ITag,
|
||||||
|
]);
|
||||||
|
setCurrentFilterItem(undefined);
|
||||||
|
setSearchValue('');
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_KEY);
|
||||||
|
} else {
|
||||||
|
setCurrentFilterItem((prev) => ({
|
||||||
|
key: prev?.key as BaseAutocompleteData,
|
||||||
|
op: tagOperator,
|
||||||
|
value: '',
|
||||||
|
}));
|
||||||
|
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_VALUE);
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
// Case 3 -> selected operator from dropdown and then erased a part of it
|
||||||
|
!isEmpty(currentFilterItem?.op) &&
|
||||||
|
tagOperator !== currentFilterItem?.op
|
||||||
|
) {
|
||||||
|
setCurrentFilterItem((prev) => ({
|
||||||
|
key: prev?.key as BaseAutocompleteData,
|
||||||
|
op: '',
|
||||||
|
value: '',
|
||||||
|
}));
|
||||||
|
setCurrentState(DropdownState.OPERATOR);
|
||||||
|
} else if (currentState === DropdownState.ATTRIBUTE_VALUE) {
|
||||||
|
// Case 4 -> the final value state where we set the current filter values and the tokenisation happens on either
|
||||||
|
// dropdown click or blur event
|
||||||
|
const currentValue = {
|
||||||
|
key: currentFilterItem?.key as BaseAutocompleteData,
|
||||||
|
op: currentFilterItem?.op as string,
|
||||||
|
value: tagValue,
|
||||||
|
};
|
||||||
|
if (!isEqual(currentValue, currentFilterItem)) {
|
||||||
|
setCurrentFilterItem((prev) => ({
|
||||||
|
key: prev?.key as BaseAutocompleteData,
|
||||||
|
op: prev?.op as string,
|
||||||
|
value: tagValue,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
currentFilterItem,
|
||||||
|
currentFilterItem?.key,
|
||||||
|
currentFilterItem?.op,
|
||||||
|
searchValue,
|
||||||
|
currentState,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// the useEffect takes care of setting the dropdown values correctly on change of the current state
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentState === DropdownState.ATTRIBUTE_KEY) {
|
||||||
|
const filteredAttributeKeys = attributeKeys.filter((key) =>
|
||||||
|
key.key.startsWith(searchValue),
|
||||||
|
);
|
||||||
|
setDropdownOptions(
|
||||||
|
filteredAttributeKeys?.map(
|
||||||
|
(key) =>
|
||||||
|
({
|
||||||
|
label: key.key,
|
||||||
|
value: key,
|
||||||
|
} as Option),
|
||||||
|
) || [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (currentState === DropdownState.OPERATOR) {
|
||||||
|
const keyOperator = searchValue.split(' ');
|
||||||
|
const partialOperator = keyOperator?.[1];
|
||||||
|
const strippedKey = keyOperator?.[0];
|
||||||
|
|
||||||
|
let operatorOptions;
|
||||||
|
if (currentFilterItem?.key?.dataType) {
|
||||||
|
operatorOptions = QUERY_BUILDER_OPERATORS_BY_TYPES[
|
||||||
|
currentFilterItem.key
|
||||||
|
.dataType as keyof typeof QUERY_BUILDER_OPERATORS_BY_TYPES
|
||||||
|
].map((operator) => ({
|
||||||
|
label: operator,
|
||||||
|
value: operator,
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (partialOperator) {
|
||||||
|
operatorOptions = operatorOptions.filter((op) =>
|
||||||
|
op.label.startsWith(partialOperator.toLocaleUpperCase()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setDropdownOptions(operatorOptions);
|
||||||
|
} else if (strippedKey.endsWith('[*]') && strippedKey.startsWith('body.')) {
|
||||||
|
operatorOptions = [OPERATORS.HAS, OPERATORS.NHAS].map((operator) => ({
|
||||||
|
label: operator,
|
||||||
|
value: operator,
|
||||||
|
}));
|
||||||
|
setDropdownOptions(operatorOptions);
|
||||||
|
} else {
|
||||||
|
operatorOptions = QUERY_BUILDER_OPERATORS_BY_TYPES.universal.map(
|
||||||
|
(operator) => ({
|
||||||
|
label: operator,
|
||||||
|
value: operator,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (partialOperator) {
|
||||||
|
operatorOptions = operatorOptions.filter((op) =>
|
||||||
|
op.label.startsWith(partialOperator.toLocaleUpperCase()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setDropdownOptions(operatorOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentState === DropdownState.ATTRIBUTE_VALUE) {
|
||||||
|
const values: Array<string | number | boolean> = [];
|
||||||
|
const { tagValue } = getTagToken(searchValue);
|
||||||
|
if (isArray(tagValue)) {
|
||||||
|
if (!isEmpty(tagValue[tagValue.length - 1]))
|
||||||
|
values.push(tagValue[tagValue.length - 1]);
|
||||||
|
} else if (!isEmpty(tagValue)) values.push(tagValue);
|
||||||
|
|
||||||
|
const currentAttributeValues =
|
||||||
|
attributeValues?.stringAttributeValues ||
|
||||||
|
attributeValues?.numberAttributeValues ||
|
||||||
|
attributeValues?.boolAttributeValues ||
|
||||||
|
[];
|
||||||
|
|
||||||
|
values.push(...currentAttributeValues);
|
||||||
|
|
||||||
|
if (attributeValuesMap) {
|
||||||
|
setDropdownOptions(
|
||||||
|
values.map(
|
||||||
|
(val) =>
|
||||||
|
({
|
||||||
|
label: checkCommaInValue(String(val)),
|
||||||
|
value: val,
|
||||||
|
} as Option),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// If attributeValuesMap is not provided, don't set dropdown options
|
||||||
|
setDropdownOptions([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
attributeValues,
|
||||||
|
currentFilterItem?.key?.dataType,
|
||||||
|
currentState,
|
||||||
|
attributeKeys,
|
||||||
|
searchValue,
|
||||||
|
attributeValuesMap,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const filterTags: IBuilderQuery['filters'] = {
|
||||||
|
op: 'AND',
|
||||||
|
items: [],
|
||||||
|
};
|
||||||
|
tags.forEach((tag) => {
|
||||||
|
const computedTagValue =
|
||||||
|
tag.value &&
|
||||||
|
Array.isArray(tag.value) &&
|
||||||
|
tag.value[tag.value.length - 1] === ''
|
||||||
|
? tag.value?.slice(0, -1)
|
||||||
|
: tag.value ?? '';
|
||||||
|
filterTags.items.push({
|
||||||
|
id: tag.id || uuid().slice(0, 8),
|
||||||
|
key: tag.key,
|
||||||
|
op: getOperatorValue(tag.op),
|
||||||
|
value: computedTagValue,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isEqual(filters, filterTags)) {
|
||||||
|
onChange(filterTags);
|
||||||
|
setTags(
|
||||||
|
filterTags.items.map((tag) => ({
|
||||||
|
...tag,
|
||||||
|
op: getOperatorFromValue(tag.op),
|
||||||
|
})) as ITag[],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [tags]);
|
||||||
|
|
||||||
|
const queryTags = useMemo(
|
||||||
|
() => tags.map((tag) => `${tag.key.key} ${tag.op} ${tag.value}`),
|
||||||
|
[tags],
|
||||||
|
);
|
||||||
|
|
||||||
|
const onTagRender = ({
|
||||||
|
value,
|
||||||
|
closable,
|
||||||
|
onClose,
|
||||||
|
}: CustomTagProps): React.ReactElement => {
|
||||||
|
const { tagOperator } = getTagToken(value);
|
||||||
|
const isInNin = isInNInOperator(tagOperator);
|
||||||
|
const chipValue = isInNin
|
||||||
|
? value?.trim()?.replace(/,\s*$/, '')
|
||||||
|
: value?.trim();
|
||||||
|
|
||||||
|
const indexInQueryTags = queryTags.findIndex((qTag) => isEqual(qTag, value));
|
||||||
|
const tagDetails = tags[indexInQueryTags];
|
||||||
|
|
||||||
|
const onCloseHandler = (): void => {
|
||||||
|
onClose();
|
||||||
|
setSearchValue('');
|
||||||
|
setTags((prev) => prev.filter((t) => !isEqual(t, tagDetails)));
|
||||||
|
};
|
||||||
|
|
||||||
|
const tagEditHandler = (value: string): void => {
|
||||||
|
setCurrentFilterItem(tagDetails);
|
||||||
|
setSearchValue(value);
|
||||||
|
setCurrentState(DropdownState.ATTRIBUTE_VALUE);
|
||||||
|
setTags((prev) => prev.filter((t) => !isEqual(t, tagDetails)));
|
||||||
|
};
|
||||||
|
|
||||||
|
const isDisabled = !!searchValue;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className="qb-search-bar-tokenised-tags">
|
||||||
|
<Tag
|
||||||
|
closable={!searchValue && closable}
|
||||||
|
onClose={onCloseHandler}
|
||||||
|
className={tagDetails?.key?.type || ''}
|
||||||
|
>
|
||||||
|
<Tooltip title={chipValue}>
|
||||||
|
<TypographyText
|
||||||
|
ellipsis
|
||||||
|
$isInNin={isInNin}
|
||||||
|
disabled={isDisabled}
|
||||||
|
$isEnabled={!!searchValue}
|
||||||
|
onClick={(): void => {
|
||||||
|
if (!isDisabled) tagEditHandler(value);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{chipValue}
|
||||||
|
</TypographyText>
|
||||||
|
</Tooltip>
|
||||||
|
</Tag>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const suffixIconContent = useMemo(() => {
|
||||||
|
if (suffixIcon) {
|
||||||
|
return suffixIcon;
|
||||||
|
}
|
||||||
|
return isOpen ? (
|
||||||
|
<ChevronUp
|
||||||
|
size={14}
|
||||||
|
color={isDarkMode ? Color.TEXT_VANILLA_100 : Color.TEXT_INK_100}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ChevronDown
|
||||||
|
size={14}
|
||||||
|
color={isDarkMode ? Color.TEXT_VANILLA_100 : Color.TEXT_INK_100}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}, [isDarkMode, isOpen, suffixIcon]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="query-builder-search-v2 ">
|
||||||
|
<Select
|
||||||
|
ref={selectRef}
|
||||||
|
getPopupContainer={popupContainer}
|
||||||
|
virtual={false}
|
||||||
|
showSearch
|
||||||
|
tagRender={onTagRender}
|
||||||
|
transitionName=""
|
||||||
|
choiceTransitionName=""
|
||||||
|
filterOption={false}
|
||||||
|
open={isOpen}
|
||||||
|
suffixIcon={suffixIconContent}
|
||||||
|
onDropdownVisibleChange={setIsOpen}
|
||||||
|
autoClearSearchValue={false}
|
||||||
|
mode="multiple"
|
||||||
|
placeholder={placeholder}
|
||||||
|
value={queryTags}
|
||||||
|
searchValue={searchValue}
|
||||||
|
className={className}
|
||||||
|
rootClassName="query-builder-search client-side-qb-search"
|
||||||
|
disabled={!attributeKeys.length}
|
||||||
|
style={selectStyle}
|
||||||
|
onSearch={handleSearch}
|
||||||
|
onSelect={handleDropdownSelect}
|
||||||
|
onInputKeyDown={onInputKeyDownHandler}
|
||||||
|
notFoundContent={null}
|
||||||
|
showAction={['focus']}
|
||||||
|
onBlur={handleOnBlur}
|
||||||
|
>
|
||||||
|
{dropdownOptions.map((option) => {
|
||||||
|
let val = option.value;
|
||||||
|
try {
|
||||||
|
if (isObject(option.value)) {
|
||||||
|
val = JSON.stringify(option.value);
|
||||||
|
} else {
|
||||||
|
val = option.value;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
val = option.value;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Select.Option key={isObject(val) ? `select-option` : val} value={val}>
|
||||||
|
<Suggestions
|
||||||
|
label={option.label}
|
||||||
|
value={option.value}
|
||||||
|
option={currentState}
|
||||||
|
searchValue={searchValue}
|
||||||
|
/>
|
||||||
|
</Select.Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSideQBSearch.defaultProps = {
|
||||||
|
placeholder: PLACEHOLDER,
|
||||||
|
className: '',
|
||||||
|
suffixIcon: null,
|
||||||
|
whereClauseConfig: {},
|
||||||
|
attributeValuesMap: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ClientSideQBSearch;
|
@ -22,7 +22,13 @@ export type GetViewDetailsUsingViewKey = (
|
|||||||
viewKey: string,
|
viewKey: string,
|
||||||
data: ViewProps[] | undefined,
|
data: ViewProps[] | undefined,
|
||||||
) =>
|
) =>
|
||||||
| { query: Query; name: string; uuid: string; panelType: PANEL_TYPES }
|
| {
|
||||||
|
query: Query;
|
||||||
|
name: string;
|
||||||
|
uuid: string;
|
||||||
|
panelType: PANEL_TYPES;
|
||||||
|
extraData?: string;
|
||||||
|
}
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
export interface IsQueryUpdatedInViewProps {
|
export interface IsQueryUpdatedInViewProps {
|
||||||
|
@ -29,9 +29,9 @@ export const getViewDetailsUsingViewKey: GetViewDetailsUsingViewKey = (
|
|||||||
) => {
|
) => {
|
||||||
const selectedView = data?.find((view) => view.uuid === viewKey);
|
const selectedView = data?.find((view) => view.uuid === viewKey);
|
||||||
if (selectedView) {
|
if (selectedView) {
|
||||||
const { compositeQuery, name, uuid } = selectedView;
|
const { compositeQuery, name, uuid, extraData } = selectedView;
|
||||||
const query = mapQueryDataFromApi(compositeQuery);
|
const query = mapQueryDataFromApi(compositeQuery);
|
||||||
return { query, name, uuid, panelType: compositeQuery.panelType };
|
return { query, name, uuid, panelType: compositeQuery.panelType, extraData };
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,7 @@ function WelcomeLeftContainer({
|
|||||||
<Container>
|
<Container>
|
||||||
<LeftContainer direction="vertical">
|
<LeftContainer direction="vertical">
|
||||||
<Space align="center">
|
<Space align="center">
|
||||||
<Logo src="signoz-signup.svg" alt="logo" />
|
<Logo src="/Logos/signoz-brand-logo.svg" alt="logo" />
|
||||||
<Title style={{ fontSize: '46px', margin: 0 }}>SigNoz</Title>
|
<Title style={{ fontSize: '46px', margin: 0 }}>SigNoz</Title>
|
||||||
</Space>
|
</Space>
|
||||||
<Typography>{t('monitor_signup')}</Typography>
|
<Typography>{t('monitor_signup')}</Typography>
|
||||||
|
@ -6,7 +6,6 @@ export const AUTH0_REDIRECT_PATH = '/redirect';
|
|||||||
|
|
||||||
export const DEFAULT_AUTH0_APP_REDIRECTION_PATH = ROUTES.APPLICATION;
|
export const DEFAULT_AUTH0_APP_REDIRECTION_PATH = ROUTES.APPLICATION;
|
||||||
|
|
||||||
export const IS_SIDEBAR_COLLAPSED = 'isSideBarCollapsed';
|
|
||||||
export const INVITE_MEMBERS_HASH = '#invite-team-members';
|
export const INVITE_MEMBERS_HASH = '#invite-team-members';
|
||||||
|
|
||||||
export const SIGNOZ_UPGRADE_PLAN_URL =
|
export const SIGNOZ_UPGRADE_PLAN_URL =
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import { getUserOperatingSystem, UserOperatingSystem } from 'utils/getUserOS';
|
|
||||||
|
|
||||||
const userOS = getUserOperatingSystem();
|
|
||||||
export const GlobalShortcuts = {
|
export const GlobalShortcuts = {
|
||||||
SidebarCollapse: '\\+meta',
|
|
||||||
NavigateToServices: 's+shift',
|
NavigateToServices: 's+shift',
|
||||||
NavigateToTraces: 't+shift',
|
NavigateToTraces: 't+shift',
|
||||||
NavigateToLogs: 'l+shift',
|
NavigateToLogs: 'l+shift',
|
||||||
@ -13,7 +9,6 @@ export const GlobalShortcuts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const GlobalShortcutsName = {
|
export const GlobalShortcutsName = {
|
||||||
SidebarCollapse: `${userOS === UserOperatingSystem.MACOS ? 'cmd' : 'ctrl'}+\\`,
|
|
||||||
NavigateToServices: 'shift+s',
|
NavigateToServices: 'shift+s',
|
||||||
NavigateToTraces: 'shift+t',
|
NavigateToTraces: 'shift+t',
|
||||||
NavigateToLogs: 'shift+l',
|
NavigateToLogs: 'shift+l',
|
||||||
@ -24,7 +19,6 @@ export const GlobalShortcutsName = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const GlobalShortcutsDescription = {
|
export const GlobalShortcutsDescription = {
|
||||||
SidebarCollapse: 'Collpase the sidebar',
|
|
||||||
NavigateToServices: 'Navigate to Services page',
|
NavigateToServices: 'Navigate to Services page',
|
||||||
NavigateToTraces: 'Navigate to Traces page',
|
NavigateToTraces: 'Navigate to Traces page',
|
||||||
NavigateToLogs: 'Navigate to logs page',
|
NavigateToLogs: 'Navigate to logs page',
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import Uplot from 'components/Uplot';
|
import Uplot from 'components/Uplot';
|
||||||
|
import { QueryParams } from 'constants/query';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { useResizeObserver } from 'hooks/useDimensions';
|
import { useResizeObserver } from 'hooks/useDimensions';
|
||||||
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import history from 'lib/history';
|
||||||
import heatmapPlugin from 'lib/uPlotLib/plugins/heatmapPlugin';
|
import heatmapPlugin from 'lib/uPlotLib/plugins/heatmapPlugin';
|
||||||
import timelinePlugin from 'lib/uPlotLib/plugins/timelinePlugin';
|
import timelinePlugin from 'lib/uPlotLib/plugins/timelinePlugin';
|
||||||
import { useMemo, useRef } from 'react';
|
import { useMemo, useRef } from 'react';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { AlertRuleTimelineGraphResponse } from 'types/api/alerts/def';
|
import { AlertRuleTimelineGraphResponse } from 'types/api/alerts/def';
|
||||||
import uPlot, { AlignedData } from 'uplot';
|
import uPlot, { AlignedData } from 'uplot';
|
||||||
|
|
||||||
@ -41,11 +46,13 @@ function HorizontalTimelineGraph({
|
|||||||
return [timestamps, states];
|
return [timestamps, states];
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const urlQuery = useUrlQuery();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const options: uPlot.Options = useMemo(
|
const options: uPlot.Options = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
width,
|
width,
|
||||||
height: 85,
|
height: 85,
|
||||||
cursor: { show: false },
|
|
||||||
|
|
||||||
axes: [
|
axes: [
|
||||||
{
|
{
|
||||||
@ -66,6 +73,40 @@ function HorizontalTimelineGraph({
|
|||||||
label: 'States',
|
label: 'States',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
hooks: {
|
||||||
|
setSelect: [
|
||||||
|
(self): void => {
|
||||||
|
const selection = self.select;
|
||||||
|
if (selection) {
|
||||||
|
const startTime = self.posToVal(selection.left, 'x');
|
||||||
|
const endTime = self.posToVal(selection.left + selection.width, 'x');
|
||||||
|
|
||||||
|
const diff = endTime - startTime;
|
||||||
|
|
||||||
|
if (diff > 0) {
|
||||||
|
if (urlQuery.has(QueryParams.relativeTime)) {
|
||||||
|
urlQuery.delete(QueryParams.relativeTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
const startTimestamp = Math.floor(startTime * 1000);
|
||||||
|
const endTimestamp = Math.floor(endTime * 1000);
|
||||||
|
|
||||||
|
if (startTimestamp !== endTimestamp) {
|
||||||
|
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
|
||||||
|
}
|
||||||
|
|
||||||
|
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
|
||||||
|
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
|
||||||
|
|
||||||
|
history.push({
|
||||||
|
search: urlQuery.toString(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
transformedData?.length > 1
|
transformedData?.length > 1
|
||||||
? [
|
? [
|
||||||
@ -76,7 +117,7 @@ function HorizontalTimelineGraph({
|
|||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
}),
|
}),
|
||||||
[width, isDarkMode, transformedData],
|
[width, isDarkMode, transformedData.length, urlQuery, dispatch],
|
||||||
);
|
);
|
||||||
return <Uplot data={transformedData} options={options} />;
|
return <Uplot data={transformedData} options={options} />;
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.alert-rule {
|
.alert-rule {
|
||||||
&-value,
|
&__value,
|
||||||
&-created-at {
|
&__created-at {
|
||||||
color: var(--text-ink-400);
|
color: var(--text-ink-400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
import './Table.styles.scss';
|
import './Table.styles.scss';
|
||||||
|
|
||||||
import { Table } from 'antd';
|
import { Table } from 'antd';
|
||||||
|
import { initialFilters } from 'constants/queryBuilder';
|
||||||
import {
|
import {
|
||||||
useGetAlertRuleDetailsTimelineTable,
|
useGetAlertRuleDetailsTimelineTable,
|
||||||
useTimelineTable,
|
useTimelineTable,
|
||||||
} from 'pages/AlertDetails/hooks';
|
} from 'pages/AlertDetails/hooks';
|
||||||
import { useMemo } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
import { timelineTableColumns } from './useTimelineTable';
|
import { timelineTableColumns } from './useTimelineTable';
|
||||||
|
|
||||||
function TimelineTable(): JSX.Element {
|
function TimelineTable(): JSX.Element {
|
||||||
|
const [filters, setFilters] = useState<TagFilter>(initialFilters);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isLoading,
|
isLoading,
|
||||||
isRefetching,
|
isRefetching,
|
||||||
@ -18,13 +22,14 @@ function TimelineTable(): JSX.Element {
|
|||||||
data,
|
data,
|
||||||
isValidRuleId,
|
isValidRuleId,
|
||||||
ruleId,
|
ruleId,
|
||||||
} = useGetAlertRuleDetailsTimelineTable();
|
} = useGetAlertRuleDetailsTimelineTable({ filters });
|
||||||
|
|
||||||
const { timelineData, totalItems } = useMemo(() => {
|
const { timelineData, totalItems, labels } = useMemo(() => {
|
||||||
const response = data?.payload?.data;
|
const response = data?.payload?.data;
|
||||||
return {
|
return {
|
||||||
timelineData: response?.items,
|
timelineData: response?.items,
|
||||||
totalItems: response?.total,
|
totalItems: response?.total,
|
||||||
|
labels: response?.labels,
|
||||||
};
|
};
|
||||||
}, [data?.payload?.data]);
|
}, [data?.payload?.data]);
|
||||||
|
|
||||||
@ -42,7 +47,11 @@ function TimelineTable(): JSX.Element {
|
|||||||
<div className="timeline-table">
|
<div className="timeline-table">
|
||||||
<Table
|
<Table
|
||||||
rowKey={(row): string => `${row.fingerprint}-${row.value}-${row.unixMilli}`}
|
rowKey={(row): string => `${row.fingerprint}-${row.value}-${row.unixMilli}`}
|
||||||
columns={timelineTableColumns()}
|
columns={timelineTableColumns({
|
||||||
|
filters,
|
||||||
|
labels: labels ?? {},
|
||||||
|
setFilters,
|
||||||
|
})}
|
||||||
dataSource={timelineData}
|
dataSource={timelineData}
|
||||||
pagination={paginationConfig}
|
pagination={paginationConfig}
|
||||||
size="middle"
|
size="middle"
|
||||||
|
@ -1,13 +1,84 @@
|
|||||||
import { EllipsisOutlined } from '@ant-design/icons';
|
import { EllipsisOutlined } from '@ant-design/icons';
|
||||||
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import { ColumnsType } from 'antd/es/table';
|
import { ColumnsType } from 'antd/es/table';
|
||||||
|
import ClientSideQBSearch, {
|
||||||
|
AttributeKey,
|
||||||
|
} from 'components/ClientSideQBSearch/ClientSideQBSearch';
|
||||||
import { ConditionalAlertPopover } from 'container/AlertHistory/AlertPopover/AlertPopover';
|
import { ConditionalAlertPopover } from 'container/AlertHistory/AlertPopover/AlertPopover';
|
||||||
import AlertLabels from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels';
|
import { transformKeyValuesToAttributeValuesMap } from 'container/QueryBuilder/filters/utils';
|
||||||
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
|
import { Search } from 'lucide-react';
|
||||||
|
import AlertLabels, {
|
||||||
|
AlertLabelsProps,
|
||||||
|
} from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels';
|
||||||
import AlertState from 'pages/AlertDetails/AlertHeader/AlertState/AlertState';
|
import AlertState from 'pages/AlertDetails/AlertHeader/AlertState/AlertState';
|
||||||
|
import { useMemo } from 'react';
|
||||||
import { AlertRuleTimelineTableResponse } from 'types/api/alerts/def';
|
import { AlertRuleTimelineTableResponse } from 'types/api/alerts/def';
|
||||||
|
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { formatEpochTimestamp } from 'utils/timeUtils';
|
import { formatEpochTimestamp } from 'utils/timeUtils';
|
||||||
|
|
||||||
export const timelineTableColumns = (): ColumnsType<AlertRuleTimelineTableResponse> => [
|
const transformLabelsToQbKeys = (
|
||||||
|
labels: AlertRuleTimelineTableResponse['labels'],
|
||||||
|
): AttributeKey[] => Object.keys(labels).flatMap((key) => [{ key }]);
|
||||||
|
|
||||||
|
function LabelFilter({
|
||||||
|
filters,
|
||||||
|
setFilters,
|
||||||
|
labels,
|
||||||
|
}: {
|
||||||
|
setFilters: (filters: TagFilter) => void;
|
||||||
|
filters: TagFilter;
|
||||||
|
labels: AlertLabelsProps['labels'];
|
||||||
|
}): JSX.Element | null {
|
||||||
|
const isDarkMode = useIsDarkMode();
|
||||||
|
|
||||||
|
const { transformedKeys, attributesMap } = useMemo(
|
||||||
|
() => ({
|
||||||
|
transformedKeys: transformLabelsToQbKeys(labels || {}),
|
||||||
|
attributesMap: transformKeyValuesToAttributeValuesMap(labels),
|
||||||
|
}),
|
||||||
|
[labels],
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSearch = (tagFilters: TagFilter): void => {
|
||||||
|
const tagFiltersLength = tagFilters.items.length;
|
||||||
|
|
||||||
|
if (
|
||||||
|
(!tagFiltersLength && (!filters || !filters.items.length)) ||
|
||||||
|
tagFiltersLength === filters?.items.length
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setFilters(tagFilters);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ClientSideQBSearch
|
||||||
|
onChange={handleSearch}
|
||||||
|
filters={filters}
|
||||||
|
className="alert-history-label-search"
|
||||||
|
attributeKeys={transformedKeys}
|
||||||
|
attributeValuesMap={attributesMap}
|
||||||
|
suffixIcon={
|
||||||
|
<Search
|
||||||
|
size={14}
|
||||||
|
color={isDarkMode ? Color.TEXT_VANILLA_100 : Color.TEXT_INK_100}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const timelineTableColumns = ({
|
||||||
|
filters,
|
||||||
|
labels,
|
||||||
|
setFilters,
|
||||||
|
}: {
|
||||||
|
filters: TagFilter;
|
||||||
|
labels: AlertLabelsProps['labels'];
|
||||||
|
setFilters: (filters: TagFilter) => void;
|
||||||
|
}): ColumnsType<AlertRuleTimelineTableResponse> => [
|
||||||
{
|
{
|
||||||
title: 'STATE',
|
title: 'STATE',
|
||||||
dataIndex: 'state',
|
dataIndex: 'state',
|
||||||
@ -20,7 +91,9 @@ export const timelineTableColumns = (): ColumnsType<AlertRuleTimelineTableRespon
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'LABELS',
|
title: (
|
||||||
|
<LabelFilter setFilters={setFilters} filters={filters} labels={labels} />
|
||||||
|
),
|
||||||
dataIndex: 'labels',
|
dataIndex: 'labels',
|
||||||
render: (labels): JSX.Element => (
|
render: (labels): JSX.Element => (
|
||||||
<div className="alert-rule-labels">
|
<div className="alert-rule-labels">
|
||||||
|
@ -16,12 +16,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.docked {
|
|
||||||
.app-content {
|
|
||||||
width: calc(100% - 240px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-support-gateway {
|
.chat-support-gateway {
|
||||||
|
@ -5,13 +5,11 @@ import './AppLayout.styles.scss';
|
|||||||
|
|
||||||
import * as Sentry from '@sentry/react';
|
import * as Sentry from '@sentry/react';
|
||||||
import { Flex } from 'antd';
|
import { Flex } from 'antd';
|
||||||
import getLocalStorageKey from 'api/browser/localstorage/get';
|
|
||||||
import getUserLatestVersion from 'api/user/getLatestVersion';
|
import getUserLatestVersion from 'api/user/getLatestVersion';
|
||||||
import getUserVersion from 'api/user/getVersion';
|
import getUserVersion from 'api/user/getVersion';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import ChatSupportGateway from 'components/ChatSupportGateway/ChatSupportGateway';
|
import ChatSupportGateway from 'components/ChatSupportGateway/ChatSupportGateway';
|
||||||
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
|
||||||
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
|
||||||
import { FeatureKeys } from 'constants/features';
|
import { FeatureKeys } from 'constants/features';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import SideNav from 'container/SideNav';
|
import SideNav from 'container/SideNav';
|
||||||
@ -22,22 +20,13 @@ import useLicense from 'hooks/useLicense';
|
|||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||||
import {
|
import { ReactNode, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
ReactNode,
|
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useLayoutEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import { Helmet } from 'react-helmet-async';
|
import { Helmet } from 'react-helmet-async';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useQueries } from 'react-query';
|
import { useQueries } from 'react-query';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { Dispatch } from 'redux';
|
import { Dispatch } from 'redux';
|
||||||
import { sideBarCollapse } from 'store/actions';
|
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import AppActions from 'types/actions';
|
import AppActions from 'types/actions';
|
||||||
import {
|
import {
|
||||||
@ -59,10 +48,6 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
(state) => state.app,
|
(state) => state.app,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [collapsed, setCollapsed] = useState<boolean>(
|
|
||||||
getLocalStorageKey(IS_SIDEBAR_COLLAPSED) === 'true',
|
|
||||||
);
|
|
||||||
|
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
|
|
||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
@ -117,14 +102,6 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
const latestCurrentCounter = useRef(0);
|
const latestCurrentCounter = useRef(0);
|
||||||
const latestVersionCounter = useRef(0);
|
const latestVersionCounter = useRef(0);
|
||||||
|
|
||||||
const onCollapse = useCallback(() => {
|
|
||||||
setCollapsed((collapsed) => !collapsed);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
dispatch(sideBarCollapse(collapsed));
|
|
||||||
}, [collapsed, dispatch]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
getUserLatestVersionResponse.isFetched &&
|
getUserLatestVersionResponse.isFetched &&
|
||||||
@ -255,19 +232,16 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
const isDashboardListView = (): boolean => routeKey === 'ALL_DASHBOARD';
|
const isDashboardListView = (): boolean => routeKey === 'ALL_DASHBOARD';
|
||||||
const isAlertHistory = (): boolean => routeKey === 'ALERT_HISTORY';
|
const isAlertHistory = (): boolean => routeKey === 'ALERT_HISTORY';
|
||||||
const isAlertOverview = (): boolean => routeKey === 'ALERT_OVERVIEW';
|
const isAlertOverview = (): boolean => routeKey === 'ALERT_OVERVIEW';
|
||||||
const isDashboardView = (): boolean => {
|
const isPathMatch = (regex: RegExp): boolean => regex.test(pathname);
|
||||||
/**
|
|
||||||
* need to match using regex here as the getRoute function will not work for
|
|
||||||
* routes with id
|
|
||||||
*/
|
|
||||||
const regex = /^\/dashboard\/[a-zA-Z0-9_-]+$/;
|
|
||||||
return regex.test(pathname);
|
|
||||||
};
|
|
||||||
|
|
||||||
const isDashboardWidgetView = (): boolean => {
|
const isDashboardView = (): boolean =>
|
||||||
const regex = /^\/dashboard\/[a-zA-Z0-9_-]+\/new$/;
|
isPathMatch(/^\/dashboard\/[a-zA-Z0-9_-]+$/);
|
||||||
return regex.test(pathname);
|
|
||||||
};
|
const isDashboardWidgetView = (): boolean =>
|
||||||
|
isPathMatch(/^\/dashboard\/[a-zA-Z0-9_-]+\/new$/);
|
||||||
|
|
||||||
|
const isTraceDetailsView = (): boolean =>
|
||||||
|
isPathMatch(/^\/trace\/[a-zA-Z0-9]+(\?.*)?$/);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isDarkMode) {
|
if (isDarkMode) {
|
||||||
@ -279,23 +253,8 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
}
|
}
|
||||||
}, [isDarkMode]);
|
}, [isDarkMode]);
|
||||||
|
|
||||||
const isSideNavCollapsed = getLocalStorageKey(IS_SIDEBAR_COLLAPSED);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Note: Right now we don't have a page-level method to pass the sidebar collapse state.
|
|
||||||
* Since the use case for overriding is not widely needed, we are setting it here
|
|
||||||
* so that the workspace locked page will have an expanded sidebar regardless of how users
|
|
||||||
* have set it or what is stored in localStorage. This will not affect the localStorage config.
|
|
||||||
*/
|
|
||||||
const isWorkspaceLocked = pathname === ROUTES.WORKSPACE_LOCKED;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout
|
<Layout className={cx(isDarkMode ? 'darkMode' : 'lightMode')}>
|
||||||
className={cx(
|
|
||||||
isDarkMode ? 'darkMode' : 'lightMode',
|
|
||||||
isSideNavCollapsed ? 'sidebarCollapsed' : '',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{pageTitle}</title>
|
<title>{pageTitle}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
@ -321,25 +280,11 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Flex
|
<Flex className={cx('app-layout', isDarkMode ? 'darkMode' : 'lightMode')}>
|
||||||
className={cx(
|
|
||||||
'app-layout',
|
|
||||||
isDarkMode ? 'darkMode' : 'lightMode',
|
|
||||||
!collapsed && !renderFullScreen ? 'docked' : '',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{isToDisplayLayout && !renderFullScreen && (
|
{isToDisplayLayout && !renderFullScreen && (
|
||||||
<SideNav
|
<SideNav licenseData={licenseData} isFetching={isFetching} />
|
||||||
licenseData={licenseData}
|
|
||||||
isFetching={isFetching}
|
|
||||||
onCollapse={onCollapse}
|
|
||||||
collapsed={isWorkspaceLocked ? false : collapsed}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<div
|
<div className="app-content" data-overlayscrollbars-initialize>
|
||||||
className={cx('app-content', collapsed ? 'collapsed' : '')}
|
|
||||||
data-overlayscrollbars-initialize
|
|
||||||
>
|
|
||||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||||
<LayoutContent data-overlayscrollbars-initialize>
|
<LayoutContent data-overlayscrollbars-initialize>
|
||||||
<OverlayScrollbar>
|
<OverlayScrollbar>
|
||||||
@ -356,6 +301,8 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
|
|||||||
isMessagingQueues()
|
isMessagingQueues()
|
||||||
? 0
|
? 0
|
||||||
: '0 1rem',
|
: '0 1rem',
|
||||||
|
|
||||||
|
...(isTraceDetailsView() ? { marginRight: 0 } : {}),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isToDisplayLayout && !renderFullScreen && <TopNav />}
|
{isToDisplayLayout && !renderFullScreen && <TopNav />}
|
||||||
|
@ -58,6 +58,21 @@ const calculateStartEndTime = (
|
|||||||
|
|
||||||
export function BillingUsageGraph(props: BillingUsageGraphProps): JSX.Element {
|
export function BillingUsageGraph(props: BillingUsageGraphProps): JSX.Element {
|
||||||
const { data, billAmount } = props;
|
const { data, billAmount } = props;
|
||||||
|
// Added this to fix the issue where breakdown with one day data are causing the bars to spread across multiple days
|
||||||
|
data?.details?.breakdown?.forEach((breakdown: any) => {
|
||||||
|
if (breakdown?.dayWiseBreakdown?.breakdown?.length === 1) {
|
||||||
|
const currentDay = breakdown.dayWiseBreakdown.breakdown[0];
|
||||||
|
const nextDay = {
|
||||||
|
...currentDay,
|
||||||
|
timestamp: currentDay.timestamp + 86400,
|
||||||
|
count: 0,
|
||||||
|
size: 0,
|
||||||
|
quantity: 0,
|
||||||
|
total: 0,
|
||||||
|
};
|
||||||
|
breakdown.dayWiseBreakdown.breakdown.push(nextDay);
|
||||||
|
}
|
||||||
|
});
|
||||||
const graphCompatibleData = useMemo(
|
const graphCompatibleData = useMemo(
|
||||||
() => convertDataToMetricRangePayload(data),
|
() => convertDataToMetricRangePayload(data),
|
||||||
[data],
|
[data],
|
||||||
|
@ -55,6 +55,7 @@ function SelectAlertType({ onSelect }: SelectAlertTypeProps): JSX.Element {
|
|||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
onSelect(option.selection);
|
onSelect(option.selection);
|
||||||
}}
|
}}
|
||||||
|
data-testid={`alert-type-card-${option.selection}`}
|
||||||
>
|
>
|
||||||
{option.description}{' '}
|
{option.description}{' '}
|
||||||
<Typography.Link
|
<Typography.Link
|
||||||
|
@ -24,6 +24,9 @@ import { QueryParams } from 'constants/query';
|
|||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import ROUTES from 'constants/routes';
|
import ROUTES from 'constants/routes';
|
||||||
import ExportPanelContainer from 'container/ExportPanel/ExportPanelContainer';
|
import ExportPanelContainer from 'container/ExportPanel/ExportPanelContainer';
|
||||||
|
import { useOptionsMenu } from 'container/OptionsMenu';
|
||||||
|
import { defaultTraceSelectedColumns } from 'container/OptionsMenu/constants';
|
||||||
|
import { OptionsQuery } from 'container/OptionsMenu/types';
|
||||||
import { useGetSearchQueryParam } from 'hooks/queryBuilder/useGetSearchQueryParam';
|
import { useGetSearchQueryParam } from 'hooks/queryBuilder/useGetSearchQueryParam';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
import { useGetAllViews } from 'hooks/saveViews/useGetAllViews';
|
import { useGetAllViews } from 'hooks/saveViews/useGetAllViews';
|
||||||
@ -34,7 +37,7 @@ import useErrorNotification from 'hooks/useErrorNotification';
|
|||||||
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
|
import { useHandleExplorerTabChange } from 'hooks/useHandleExplorerTabChange';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
|
import { mapCompositeQueryFromQuery } from 'lib/newQueryBuilder/queryBuilderMappers/mapCompositeQueryFromQuery';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep, isEqual } from 'lodash-es';
|
||||||
import {
|
import {
|
||||||
Check,
|
Check,
|
||||||
ConciergeBell,
|
ConciergeBell,
|
||||||
@ -58,7 +61,9 @@ import { useSelector } from 'react-redux';
|
|||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { Dashboard } from 'types/api/dashboard/getAll';
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||||
|
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
import { ViewProps } from 'types/api/saveViews/types';
|
||||||
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
import { DataSource, StringOperators } from 'types/common/queryBuilder';
|
||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
import { USER_ROLES } from 'types/roles';
|
import { USER_ROLES } from 'types/roles';
|
||||||
@ -252,6 +257,46 @@ function ExplorerOptions({
|
|||||||
|
|
||||||
const { handleExplorerTabChange } = useHandleExplorerTabChange();
|
const { handleExplorerTabChange } = useHandleExplorerTabChange();
|
||||||
|
|
||||||
|
const { options, handleOptionsChange } = useOptionsMenu({
|
||||||
|
storageKey: LOCALSTORAGE.TRACES_LIST_OPTIONS,
|
||||||
|
dataSource: DataSource.TRACES,
|
||||||
|
aggregateOperator: StringOperators.NOOP,
|
||||||
|
});
|
||||||
|
|
||||||
|
type ExtraData = {
|
||||||
|
selectColumns?: BaseAutocompleteData[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateOrRestoreSelectColumns = (
|
||||||
|
key: string,
|
||||||
|
allViewsData: ViewProps[] | undefined,
|
||||||
|
options: OptionsQuery,
|
||||||
|
handleOptionsChange: (newQueryData: OptionsQuery) => void,
|
||||||
|
): void => {
|
||||||
|
const currentViewDetails = getViewDetailsUsingViewKey(key, allViewsData);
|
||||||
|
if (!currentViewDetails) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let extraData: ExtraData = {};
|
||||||
|
try {
|
||||||
|
extraData = JSON.parse(currentViewDetails?.extraData ?? '{}') as ExtraData;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing extraData:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extraData.selectColumns?.length) {
|
||||||
|
handleOptionsChange({
|
||||||
|
...options,
|
||||||
|
selectColumns: extraData.selectColumns,
|
||||||
|
});
|
||||||
|
} else if (!isEqual(defaultTraceSelectedColumns, options.selectColumns)) {
|
||||||
|
handleOptionsChange({
|
||||||
|
...options,
|
||||||
|
selectColumns: defaultTraceSelectedColumns,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
const onMenuItemSelectHandler = useCallback(
|
const onMenuItemSelectHandler = useCallback(
|
||||||
({ key }: { key: string }): void => {
|
({ key }: { key: string }): void => {
|
||||||
const currentViewDetails = getViewDetailsUsingViewKey(
|
const currentViewDetails = getViewDetailsUsingViewKey(
|
||||||
@ -321,6 +366,13 @@ function ExplorerOptions({
|
|||||||
|
|
||||||
updatePreservedViewInLocalStorage(option);
|
updatePreservedViewInLocalStorage(option);
|
||||||
|
|
||||||
|
updateOrRestoreSelectColumns(
|
||||||
|
option.key,
|
||||||
|
viewsData?.data?.data,
|
||||||
|
options,
|
||||||
|
handleOptionsChange,
|
||||||
|
);
|
||||||
|
|
||||||
if (ref.current) {
|
if (ref.current) {
|
||||||
ref.current.blur();
|
ref.current.blur();
|
||||||
}
|
}
|
||||||
@ -360,14 +412,20 @@ function ExplorerOptions({
|
|||||||
viewName: newViewName || '',
|
viewName: newViewName || '',
|
||||||
compositeQuery,
|
compositeQuery,
|
||||||
sourcePage: sourcepage,
|
sourcePage: sourcepage,
|
||||||
extraData: JSON.stringify({ color }),
|
extraData: JSON.stringify({
|
||||||
|
color,
|
||||||
|
selectColumns: options.selectColumns,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSaveHandler = (): void => {
|
const onSaveHandler = (): void => {
|
||||||
saveNewViewHandler({
|
saveNewViewHandler({
|
||||||
compositeQuery,
|
compositeQuery,
|
||||||
handlePopOverClose: hideSaveViewModal,
|
handlePopOverClose: hideSaveViewModal,
|
||||||
extraData: JSON.stringify({ color }),
|
extraData: JSON.stringify({
|
||||||
|
color,
|
||||||
|
selectColumns: options.selectColumns,
|
||||||
|
}),
|
||||||
notifications,
|
notifications,
|
||||||
panelType: panelType || PANEL_TYPES.LIST,
|
panelType: panelType || PANEL_TYPES.LIST,
|
||||||
redirectWithQueryBuilderData,
|
redirectWithQueryBuilderData,
|
||||||
|
@ -189,6 +189,7 @@ function BasicInfo({
|
|||||||
checked={shouldBroadCastToAllChannels}
|
checked={shouldBroadCastToAllChannels}
|
||||||
onChange={handleBroadcastToAllChannels}
|
onChange={handleBroadcastToAllChannels}
|
||||||
disabled={noChannels || !!channels.loading}
|
disabled={noChannels || !!channels.loading}
|
||||||
|
data-testid="alert-broadcast-to-all-channels"
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</FormItemMedium>
|
</FormItemMedium>
|
||||||
|
@ -63,6 +63,7 @@ function ChannelSelect({
|
|||||||
mode="multiple"
|
mode="multiple"
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
placeholder={t('placeholder_channel_select')}
|
placeholder={t('placeholder_channel_select')}
|
||||||
|
data-testid="alert-channel-select"
|
||||||
value={currentValue}
|
value={currentValue}
|
||||||
onChange={(value): void => {
|
onChange={(value): void => {
|
||||||
handleChange(value as string[]);
|
handleChange(value as string[]);
|
||||||
|
@ -99,7 +99,7 @@ function QuerySection({
|
|||||||
{
|
{
|
||||||
label: (
|
label: (
|
||||||
<Tooltip title="Query Builder">
|
<Tooltip title="Query Builder">
|
||||||
<Button className="nav-btns">
|
<Button className="nav-btns" data-testid="query-builder-tab">
|
||||||
<Atom size={14} />
|
<Atom size={14} />
|
||||||
</Button>
|
</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -323,6 +323,45 @@ function RuleOptions({
|
|||||||
<Typography.Text>{t('text_for')}</Typography.Text>
|
<Typography.Text>{t('text_for')}</Typography.Text>
|
||||||
</Space>
|
</Space>
|
||||||
</VerticalLine>
|
</VerticalLine>
|
||||||
|
|
||||||
|
<VerticalLine>
|
||||||
|
<Space direction="horizontal" align="center">
|
||||||
|
<Form.Item noStyle name={['condition', 'requireMinPoints']}>
|
||||||
|
<Checkbox
|
||||||
|
checked={alertDef?.condition?.requireMinPoints}
|
||||||
|
onChange={(e): void => {
|
||||||
|
setAlertDef({
|
||||||
|
...alertDef,
|
||||||
|
condition: {
|
||||||
|
...alertDef.condition,
|
||||||
|
requireMinPoints: e.target.checked,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Typography.Text>{t('text_require_min_points')}</Typography.Text>
|
||||||
|
|
||||||
|
<Form.Item noStyle name={['condition', 'requiredNumPoints']}>
|
||||||
|
<InputNumber
|
||||||
|
min={1}
|
||||||
|
value={alertDef?.condition?.requiredNumPoints}
|
||||||
|
onChange={(value): void => {
|
||||||
|
setAlertDef({
|
||||||
|
...alertDef,
|
||||||
|
condition: {
|
||||||
|
...alertDef.condition,
|
||||||
|
requiredNumPoints: Number(value) || 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
type="number"
|
||||||
|
onWheel={(e): void => e.currentTarget.blur()}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Typography.Text>{t('text_num_points')}</Typography.Text>
|
||||||
|
</Space>
|
||||||
|
</VerticalLine>
|
||||||
</Space>
|
</Space>
|
||||||
</Collapse.Panel>
|
</Collapse.Panel>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
@ -20,6 +20,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.widget-header-title-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
.widget-header-title {
|
.widget-header-title {
|
||||||
max-width: 80%;
|
max-width: 80%;
|
||||||
}
|
}
|
||||||
@ -58,3 +66,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.long-tooltip {
|
||||||
|
.ant-tooltip-content {
|
||||||
|
max-height: 500px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
&.ant-tooltip {
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-tooltip {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@ -6,8 +6,8 @@ import {
|
|||||||
CopyOutlined,
|
CopyOutlined,
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
EditFilled,
|
EditFilled,
|
||||||
ExclamationCircleOutlined,
|
|
||||||
FullscreenOutlined,
|
FullscreenOutlined,
|
||||||
|
InfoCircleOutlined,
|
||||||
MoreOutlined,
|
MoreOutlined,
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
WarningOutlined,
|
WarningOutlined,
|
||||||
@ -21,7 +21,7 @@ import useComponentPermission from 'hooks/useComponentPermission';
|
|||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||||
import { isEmpty } from 'lodash-es';
|
import { isEmpty } from 'lodash-es';
|
||||||
import { X } from 'lucide-react';
|
import { CircleX, X } from 'lucide-react';
|
||||||
import { unparse } from 'papaparse';
|
import { unparse } from 'papaparse';
|
||||||
import { ReactNode, useCallback, useMemo, useState } from 'react';
|
import { ReactNode, useCallback, useMemo, useState } from 'react';
|
||||||
import { UseQueryResult } from 'react-query';
|
import { UseQueryResult } from 'react-query';
|
||||||
@ -234,13 +234,25 @@ function WidgetHeader({
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Typography.Text
|
<div className="widget-header-title-container">
|
||||||
ellipsis
|
<Typography.Text
|
||||||
data-testid={title}
|
ellipsis
|
||||||
className="widget-header-title"
|
data-testid={title}
|
||||||
>
|
className="widget-header-title"
|
||||||
{title}
|
>
|
||||||
</Typography.Text>
|
{title}
|
||||||
|
</Typography.Text>
|
||||||
|
{widget.description && (
|
||||||
|
<Tooltip
|
||||||
|
title={widget.description}
|
||||||
|
overlayClassName="long-tooltip"
|
||||||
|
className="info-tooltip"
|
||||||
|
placement="right"
|
||||||
|
>
|
||||||
|
<InfoCircleOutlined />
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className="widget-header-actions">
|
<div className="widget-header-actions">
|
||||||
<div className="widget-api-actions">{threshold}</div>
|
<div className="widget-api-actions">{threshold}</div>
|
||||||
{isFetchingResponse && !queryResponse.isError && (
|
{isFetchingResponse && !queryResponse.isError && (
|
||||||
@ -252,7 +264,7 @@ function WidgetHeader({
|
|||||||
placement={errorTooltipPosition}
|
placement={errorTooltipPosition}
|
||||||
className="widget-api-actions"
|
className="widget-api-actions"
|
||||||
>
|
>
|
||||||
<ExclamationCircleOutlined />
|
<CircleX size={20} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
.long-text-tooltip {
|
||||||
|
max-width: 500px;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import './GridTableComponent.styles.scss';
|
||||||
|
|
||||||
import { ExclamationCircleFilled } from '@ant-design/icons';
|
import { ExclamationCircleFilled } from '@ant-design/icons';
|
||||||
import { Space, Tooltip } from 'antd';
|
import { Space, Tooltip } from 'antd';
|
||||||
import { getYAxisFormattedValue } from 'components/Graph/yAxisConfig';
|
import { getYAxisFormattedValue } from 'components/Graph/yAxisConfig';
|
||||||
@ -5,6 +7,7 @@ import { Events } from 'constants/events';
|
|||||||
import { QueryTable } from 'container/QueryTable';
|
import { QueryTable } from 'container/QueryTable';
|
||||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||||
import { cloneDeep, get, isEmpty } from 'lodash-es';
|
import { cloneDeep, get, isEmpty } from 'lodash-es';
|
||||||
|
import LineClampedText from 'periscope/components/LineClampedText/LineClampedText';
|
||||||
import { memo, ReactNode, useCallback, useEffect, useMemo } from 'react';
|
import { memo, ReactNode, useCallback, useEffect, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { eventEmitter } from 'utils/getEventEmitter';
|
import { eventEmitter } from 'utils/getEventEmitter';
|
||||||
@ -116,7 +119,16 @@ function GridTableComponent({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Space>
|
<Space>
|
||||||
{text}
|
<LineClampedText
|
||||||
|
text={text}
|
||||||
|
lines={3}
|
||||||
|
tooltipProps={{
|
||||||
|
placement: 'right',
|
||||||
|
autoAdjustOverflow: true,
|
||||||
|
overlayClassName: 'long-text-tooltip',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
{hasMultipleMatches && (
|
{hasMultipleMatches && (
|
||||||
<Tooltip title={t('this_value_satisfies_multiple_thresholds')}>
|
<Tooltip title={t('this_value_satisfies_multiple_thresholds')}>
|
||||||
<ExclamationCircleFilled className="value-graph-icon" />
|
<ExclamationCircleFilled className="value-graph-icon" />
|
||||||
@ -127,7 +139,19 @@ function GridTableComponent({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <div>{text}</div>;
|
return (
|
||||||
|
<div>
|
||||||
|
<LineClampedText
|
||||||
|
text={text}
|
||||||
|
lines={3}
|
||||||
|
tooltipProps={{
|
||||||
|
placement: 'right',
|
||||||
|
autoAdjustOverflow: true,
|
||||||
|
overlayClassName: 'long-text-tooltip',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -63,8 +63,7 @@
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
margin-top: 12px;
|
margin: 12px 0 2px;
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,12 @@ import {
|
|||||||
resourceAttributesToTagFilterItems,
|
resourceAttributesToTagFilterItems,
|
||||||
} from 'hooks/useResourceAttribute/utils';
|
} from 'hooks/useResourceAttribute/utils';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
|
import store from 'store';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
@ -123,6 +125,16 @@ function DBCall(): JSX.Element {
|
|||||||
[servicename, tagFilterItems],
|
[servicename, tagFilterItems],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const stepInterval = useMemo(
|
||||||
|
() =>
|
||||||
|
getStep({
|
||||||
|
end: store.getState().globalTime.maxTime,
|
||||||
|
inputFormat: 'ns',
|
||||||
|
start: store.getState().globalTime.minTime,
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
const logEventCalledRef = useRef(false);
|
const logEventCalledRef = useRef(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -158,6 +170,7 @@ function DBCall(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -192,6 +205,7 @@ function DBCall(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
|
@ -16,10 +16,12 @@ import {
|
|||||||
resourceAttributesToTagFilterItems,
|
resourceAttributesToTagFilterItems,
|
||||||
} from 'hooks/useResourceAttribute/utils';
|
} from 'hooks/useResourceAttribute/utils';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
|
import store from 'store';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
@ -141,6 +143,15 @@ function External(): JSX.Element {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const stepInterval = useMemo(
|
||||||
|
() =>
|
||||||
|
getStep({
|
||||||
|
end: store.getState().globalTime.maxTime,
|
||||||
|
inputFormat: 'ns',
|
||||||
|
start: store.getState().globalTime.minTime,
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
const logEventCalledRef = useRef(false);
|
const logEventCalledRef = useRef(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!logEventCalledRef.current) {
|
if (!logEventCalledRef.current) {
|
||||||
@ -222,6 +233,7 @@ function External(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery: errorApmToTraceQuery,
|
apmToTraceQuery: errorApmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -257,6 +269,7 @@ function External(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -295,6 +308,7 @@ function External(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -330,6 +344,7 @@ function External(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
resourceAttributesToTagFilterItems,
|
resourceAttributesToTagFilterItems,
|
||||||
} from 'hooks/useResourceAttribute/utils';
|
} from 'hooks/useResourceAttribute/utils';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
||||||
import { defaultTo } from 'lodash-es';
|
import { defaultTo } from 'lodash-es';
|
||||||
@ -38,6 +39,7 @@ import {
|
|||||||
} from '../MetricsPageQueries/OverviewQueries';
|
} from '../MetricsPageQueries/OverviewQueries';
|
||||||
import { Col, ColApDexContainer, ColErrorContainer, Row } from '../styles';
|
import { Col, ColApDexContainer, ColErrorContainer, Row } from '../styles';
|
||||||
import ApDex from './Overview/ApDex';
|
import ApDex from './Overview/ApDex';
|
||||||
|
import GraphControlsPanel from './Overview/GraphControlsPanel/GraphControlsPanel';
|
||||||
import ServiceOverview from './Overview/ServiceOverview';
|
import ServiceOverview from './Overview/ServiceOverview';
|
||||||
import TopLevelOperation from './Overview/TopLevelOperations';
|
import TopLevelOperation from './Overview/TopLevelOperations';
|
||||||
import TopOperation from './Overview/TopOperation';
|
import TopOperation from './Overview/TopOperation';
|
||||||
@ -45,9 +47,11 @@ import TopOperationMetrics from './Overview/TopOperationMetrics';
|
|||||||
import { Button, Card } from './styles';
|
import { Button, Card } from './styles';
|
||||||
import { IServiceName } from './types';
|
import { IServiceName } from './types';
|
||||||
import {
|
import {
|
||||||
|
generateExplorerPath,
|
||||||
handleNonInQueryRange,
|
handleNonInQueryRange,
|
||||||
onGraphClickHandler,
|
onGraphClickHandler,
|
||||||
onViewTracePopupClick,
|
onViewTracePopupClick,
|
||||||
|
useGetAPMToLogsQueries,
|
||||||
useGetAPMToTracesQueries,
|
useGetAPMToTracesQueries,
|
||||||
} from './util';
|
} from './util';
|
||||||
|
|
||||||
@ -177,6 +181,16 @@ function Application(): JSX.Element {
|
|||||||
id: SERVICE_CHART_ID.errorPercentage,
|
id: SERVICE_CHART_ID.errorPercentage,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const stepInterval = useMemo(
|
||||||
|
() =>
|
||||||
|
getStep({
|
||||||
|
end: maxTime,
|
||||||
|
inputFormat: 'ns',
|
||||||
|
start: minTime,
|
||||||
|
}),
|
||||||
|
[maxTime, minTime],
|
||||||
|
);
|
||||||
|
|
||||||
const onDragSelect = useCallback(
|
const onDragSelect = useCallback(
|
||||||
(start: number, end: number) => {
|
(start: number, end: number) => {
|
||||||
const startTimestamp = Math.trunc(start);
|
const startTimestamp = Math.trunc(start);
|
||||||
@ -194,33 +208,60 @@ function Application(): JSX.Element {
|
|||||||
[dispatch, pathname, urlQuery],
|
[dispatch, pathname, urlQuery],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onErrorTrackHandler = (
|
const onErrorTrackHandler = useCallback(
|
||||||
timestamp: number,
|
(
|
||||||
apmToTraceQuery: Query,
|
timestamp: number,
|
||||||
): (() => void) => (): void => {
|
apmToTraceQuery: Query,
|
||||||
const currentTime = timestamp;
|
isViewLogsClicked?: boolean,
|
||||||
const tPlusOne = timestamp + 60 * 1000;
|
): (() => void) => (): void => {
|
||||||
|
const currentTime = timestamp;
|
||||||
|
const endTime = timestamp + stepInterval;
|
||||||
|
console.log(endTime, stepInterval);
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(search);
|
const urlParams = new URLSearchParams(search);
|
||||||
urlParams.set(QueryParams.startTime, currentTime.toString());
|
urlParams.set(QueryParams.startTime, currentTime.toString());
|
||||||
urlParams.set(QueryParams.endTime, tPlusOne.toString());
|
urlParams.set(QueryParams.endTime, endTime.toString());
|
||||||
|
urlParams.delete(QueryParams.relativeTime);
|
||||||
|
const avialableParams = routeConfig[ROUTES.TRACE];
|
||||||
|
const queryString = getQueryString(avialableParams, urlParams);
|
||||||
|
|
||||||
const avialableParams = routeConfig[ROUTES.TRACE];
|
const JSONCompositeQuery = encodeURIComponent(
|
||||||
const queryString = getQueryString(avialableParams, urlParams);
|
JSON.stringify(apmToTraceQuery),
|
||||||
|
);
|
||||||
|
|
||||||
const JSONCompositeQuery = encodeURIComponent(
|
const newPath = generateExplorerPath(
|
||||||
JSON.stringify(apmToTraceQuery),
|
isViewLogsClicked,
|
||||||
);
|
urlParams,
|
||||||
|
servicename,
|
||||||
|
selectedTraceTags,
|
||||||
|
JSONCompositeQuery,
|
||||||
|
queryString,
|
||||||
|
);
|
||||||
|
|
||||||
const newTraceExplorerPath = `${
|
history.push(newPath);
|
||||||
ROUTES.TRACES_EXPLORER
|
},
|
||||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
QueryParams.compositeQuery
|
[stepInterval],
|
||||||
}=${JSONCompositeQuery}&${queryString.join('&')}`;
|
);
|
||||||
|
|
||||||
history.push(newTraceExplorerPath);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const logErrorQuery = useGetAPMToLogsQueries({
|
||||||
|
servicename,
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
id: uuid().slice(0, 8),
|
||||||
|
key: {
|
||||||
|
key: 'severity_text',
|
||||||
|
dataType: DataTypes.String,
|
||||||
|
type: '',
|
||||||
|
isColumn: true,
|
||||||
|
isJSON: false,
|
||||||
|
id: 'severity_text--string----true',
|
||||||
|
},
|
||||||
|
op: 'in',
|
||||||
|
value: ['ERROR', 'FATAL', 'error', 'fatal'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
const errorTrackQuery = useGetAPMToTracesQueries({
|
const errorTrackQuery = useGetAPMToTracesQueries({
|
||||||
servicename,
|
servicename,
|
||||||
filters: [
|
filters: [
|
||||||
@ -251,6 +292,7 @@ function Application(): JSX.Element {
|
|||||||
selectedTraceTags={selectedTraceTags}
|
selectedTraceTags={selectedTraceTags}
|
||||||
topLevelOperationsRoute={topLevelOperationsRoute}
|
topLevelOperationsRoute={topLevelOperationsRoute}
|
||||||
topLevelOperationsIsLoading={topLevelOperationsIsLoading}
|
topLevelOperationsIsLoading={topLevelOperationsIsLoading}
|
||||||
|
stepInterval={stepInterval}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
@ -264,6 +306,7 @@ function Application(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -292,6 +335,7 @@ function Application(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -304,14 +348,18 @@ function Application(): JSX.Element {
|
|||||||
/>
|
/>
|
||||||
</ColApDexContainer>
|
</ColApDexContainer>
|
||||||
<ColErrorContainer>
|
<ColErrorContainer>
|
||||||
<Button
|
<GraphControlsPanel
|
||||||
type="default"
|
|
||||||
size="small"
|
|
||||||
id="Error_button"
|
id="Error_button"
|
||||||
onClick={onErrorTrackHandler(selectedTimeStamp, errorTrackQuery)}
|
onViewLogsClick={onErrorTrackHandler(
|
||||||
>
|
selectedTimeStamp,
|
||||||
View Traces
|
logErrorQuery,
|
||||||
</Button>
|
true,
|
||||||
|
)}
|
||||||
|
onViewTracesClick={onErrorTrackHandler(
|
||||||
|
selectedTimeStamp,
|
||||||
|
errorTrackQuery,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<TopLevelOperation
|
<TopLevelOperation
|
||||||
handleGraphClick={handleGraphClick}
|
handleGraphClick={handleGraphClick}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
.graph-controls-panel {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 999;
|
||||||
|
display: none;
|
||||||
|
width: 110px;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: var(--bg-slate-400);
|
||||||
|
|
||||||
|
.ant-btn-link {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--bg-vanilla-100);
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-link:hover {
|
||||||
|
color: var(--bg-vanilla-100);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
import './GraphControlsPanel.styles.scss';
|
||||||
|
|
||||||
|
import { Color } from '@signozhq/design-tokens';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
import { DraftingCompass, ScrollText } from 'lucide-react';
|
||||||
|
|
||||||
|
interface GraphControlsPanelProps {
|
||||||
|
id: string;
|
||||||
|
onViewLogsClick: () => void;
|
||||||
|
onViewTracesClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GraphControlsPanel({
|
||||||
|
id,
|
||||||
|
onViewLogsClick,
|
||||||
|
onViewTracesClick,
|
||||||
|
}: GraphControlsPanelProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<div id={id} className="graph-controls-panel">
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={<DraftingCompass size={14} />}
|
||||||
|
size="small"
|
||||||
|
onClick={onViewTracesClick}
|
||||||
|
style={{ color: Color.BG_VANILLA_100 }}
|
||||||
|
>
|
||||||
|
View traces
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={<ScrollText size={14} />}
|
||||||
|
size="small"
|
||||||
|
onClick={onViewLogsClick}
|
||||||
|
style={{ color: Color.BG_VANILLA_100 }}
|
||||||
|
>
|
||||||
|
View logs
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GraphControlsPanel;
|
@ -19,13 +19,14 @@ import { useParams } from 'react-router-dom';
|
|||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
import { Button } from '../styles';
|
|
||||||
import { IServiceName } from '../types';
|
import { IServiceName } from '../types';
|
||||||
import {
|
import {
|
||||||
handleNonInQueryRange,
|
handleNonInQueryRange,
|
||||||
onViewTracePopupClick,
|
onViewTracePopupClick,
|
||||||
|
useGetAPMToLogsQueries,
|
||||||
useGetAPMToTracesQueries,
|
useGetAPMToTracesQueries,
|
||||||
} from '../util';
|
} from '../util';
|
||||||
|
import GraphControlsPanel from './GraphControlsPanel/GraphControlsPanel';
|
||||||
|
|
||||||
function ServiceOverview({
|
function ServiceOverview({
|
||||||
onDragSelect,
|
onDragSelect,
|
||||||
@ -34,6 +35,7 @@ function ServiceOverview({
|
|||||||
selectedTimeStamp,
|
selectedTimeStamp,
|
||||||
topLevelOperationsRoute,
|
topLevelOperationsRoute,
|
||||||
topLevelOperationsIsLoading,
|
topLevelOperationsIsLoading,
|
||||||
|
stepInterval,
|
||||||
}: ServiceOverviewProps): JSX.Element {
|
}: ServiceOverviewProps): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
@ -75,21 +77,28 @@ function ServiceOverview({
|
|||||||
|
|
||||||
const apmToTraceQuery = useGetAPMToTracesQueries({ servicename });
|
const apmToTraceQuery = useGetAPMToTracesQueries({ servicename });
|
||||||
|
|
||||||
|
const apmToLogQuery = useGetAPMToLogsQueries({ servicename });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<GraphControlsPanel
|
||||||
type="default"
|
|
||||||
size="small"
|
|
||||||
id="Service_button"
|
id="Service_button"
|
||||||
onClick={onViewTracePopupClick({
|
onViewLogsClick={onViewTracePopupClick({
|
||||||
|
servicename,
|
||||||
|
selectedTraceTags,
|
||||||
|
timestamp: selectedTimeStamp,
|
||||||
|
apmToTraceQuery: apmToLogQuery,
|
||||||
|
isViewLogsClicked: true,
|
||||||
|
stepInterval,
|
||||||
|
})}
|
||||||
|
onViewTracesClick={onViewTracePopupClick({
|
||||||
servicename,
|
servicename,
|
||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
/>
|
||||||
View Traces
|
|
||||||
</Button>
|
|
||||||
<Card data-testid="service_latency">
|
<Card data-testid="service_latency">
|
||||||
<GraphContainer>
|
<GraphContainer>
|
||||||
{topLevelOperationsIsLoading && (
|
{topLevelOperationsIsLoading && (
|
||||||
@ -114,8 +123,8 @@ function ServiceOverview({
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ServiceOverviewProps {
|
interface ServiceOverviewProps {
|
||||||
|
stepInterval: number;
|
||||||
selectedTimeStamp: number;
|
selectedTimeStamp: number;
|
||||||
selectedTraceTags: string;
|
selectedTraceTags: string;
|
||||||
onDragSelect: (start: number, end: number) => void;
|
onDragSelect: (start: number, end: number) => void;
|
||||||
|
@ -7,6 +7,7 @@ import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
|||||||
import useResourceAttribute from 'hooks/useResourceAttribute';
|
import useResourceAttribute from 'hooks/useResourceAttribute';
|
||||||
import { resourceAttributesToTracesFilterItems } from 'hooks/useResourceAttribute/utils';
|
import { resourceAttributesToTracesFilterItems } from 'hooks/useResourceAttribute/utils';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
|
import { prepareQueryWithDefaultTimestamp } from 'pages/LogsExplorer/utils';
|
||||||
import { traceFilterKeys } from 'pages/TracesExplorer/Filter/filterUtils';
|
import { traceFilterKeys } from 'pages/TracesExplorer/Filter/filterUtils';
|
||||||
import { Dispatch, SetStateAction, useMemo } from 'react';
|
import { Dispatch, SetStateAction, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
@ -33,21 +34,44 @@ interface OnViewTracePopupClickProps {
|
|||||||
selectedTraceTags: string;
|
selectedTraceTags: string;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
apmToTraceQuery: Query;
|
apmToTraceQuery: Query;
|
||||||
|
isViewLogsClicked?: boolean;
|
||||||
|
stepInterval?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function generateExplorerPath(
|
||||||
|
isViewLogsClicked: boolean | undefined,
|
||||||
|
urlParams: URLSearchParams,
|
||||||
|
servicename: string | undefined,
|
||||||
|
selectedTraceTags: string,
|
||||||
|
JSONCompositeQuery: string,
|
||||||
|
queryString: string[],
|
||||||
|
): string {
|
||||||
|
const basePath = isViewLogsClicked
|
||||||
|
? ROUTES.LOGS_EXPLORER
|
||||||
|
: ROUTES.TRACES_EXPLORER;
|
||||||
|
|
||||||
|
return `${basePath}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${
|
||||||
|
QueryParams.compositeQuery
|
||||||
|
}=${JSONCompositeQuery}&${queryString.join('&')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(@rahul-signoz): update the name of this function once we have view logs button in every panel
|
||||||
export function onViewTracePopupClick({
|
export function onViewTracePopupClick({
|
||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
servicename,
|
servicename,
|
||||||
timestamp,
|
timestamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
isViewLogsClicked,
|
||||||
|
stepInterval,
|
||||||
}: OnViewTracePopupClickProps): VoidFunction {
|
}: OnViewTracePopupClickProps): VoidFunction {
|
||||||
return (): void => {
|
return (): void => {
|
||||||
const currentTime = timestamp;
|
const currentTime = timestamp;
|
||||||
|
const endTime = timestamp + (stepInterval || 60);
|
||||||
const tPlusOne = timestamp + 60;
|
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
urlParams.set(QueryParams.startTime, currentTime.toString());
|
urlParams.set(QueryParams.startTime, currentTime.toString());
|
||||||
urlParams.set(QueryParams.endTime, tPlusOne.toString());
|
urlParams.set(QueryParams.endTime, endTime.toString());
|
||||||
|
urlParams.delete(QueryParams.relativeTime);
|
||||||
const avialableParams = routeConfig[ROUTES.TRACE];
|
const avialableParams = routeConfig[ROUTES.TRACE];
|
||||||
const queryString = getQueryString(avialableParams, urlParams);
|
const queryString = getQueryString(avialableParams, urlParams);
|
||||||
|
|
||||||
@ -55,13 +79,16 @@ export function onViewTracePopupClick({
|
|||||||
JSON.stringify(apmToTraceQuery),
|
JSON.stringify(apmToTraceQuery),
|
||||||
);
|
);
|
||||||
|
|
||||||
const newTraceExplorerPath = `${
|
const newPath = generateExplorerPath(
|
||||||
ROUTES.TRACES_EXPLORER
|
isViewLogsClicked,
|
||||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${
|
urlParams,
|
||||||
QueryParams.compositeQuery
|
servicename,
|
||||||
}=${JSONCompositeQuery}&${queryString.join('&')}`;
|
selectedTraceTags,
|
||||||
|
JSONCompositeQuery,
|
||||||
|
queryString,
|
||||||
|
);
|
||||||
|
|
||||||
history.push(newTraceExplorerPath);
|
history.push(newPath);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,12 +135,13 @@ export function handleQueryChange(
|
|||||||
attributeKeys: BaseAutocompleteData,
|
attributeKeys: BaseAutocompleteData,
|
||||||
serviceAttribute: string,
|
serviceAttribute: string,
|
||||||
filters?: TagFilterItem[],
|
filters?: TagFilterItem[],
|
||||||
|
logs?: boolean,
|
||||||
): Query {
|
): Query {
|
||||||
const filterItem: TagFilterItem[] = [
|
const filterItem: TagFilterItem[] = [
|
||||||
{
|
{
|
||||||
id: uuid().slice(0, 8),
|
id: uuid().slice(0, 8),
|
||||||
key: attributeKeys,
|
key: attributeKeys,
|
||||||
op: 'in',
|
op: logs ? '=' : 'in',
|
||||||
value: serviceAttribute,
|
value: serviceAttribute,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -132,6 +160,42 @@ export function handleQueryChange(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useGetAPMToLogsQueries({
|
||||||
|
servicename,
|
||||||
|
filters,
|
||||||
|
}: {
|
||||||
|
servicename: string;
|
||||||
|
filters?: TagFilterItem[];
|
||||||
|
}): Query {
|
||||||
|
const finalFilters: TagFilterItem[] = [];
|
||||||
|
const { updateAllQueriesOperators } = useQueryBuilder();
|
||||||
|
let updatedQuery = updateAllQueriesOperators(
|
||||||
|
initialQueriesMap.logs,
|
||||||
|
PANEL_TYPES.LIST,
|
||||||
|
DataSource.LOGS,
|
||||||
|
);
|
||||||
|
const serviceName = {
|
||||||
|
id: 'service.name--string--resource--true',
|
||||||
|
dataType: DataTypes.String,
|
||||||
|
isColumn: false,
|
||||||
|
key: 'service.name',
|
||||||
|
type: 'resource',
|
||||||
|
isJSON: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (filters?.length) {
|
||||||
|
finalFilters.push(...filters);
|
||||||
|
}
|
||||||
|
updatedQuery = prepareQueryWithDefaultTimestamp(updatedQuery);
|
||||||
|
return handleQueryChange(
|
||||||
|
updatedQuery,
|
||||||
|
serviceName,
|
||||||
|
servicename,
|
||||||
|
finalFilters,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function useGetAPMToTracesQueries({
|
export function useGetAPMToTracesQueries({
|
||||||
servicename,
|
servicename,
|
||||||
isExternalCall,
|
isExternalCall,
|
||||||
|
@ -182,6 +182,15 @@ function DashboardDescription(props: DashboardDescriptionProps): JSX.Element {
|
|||||||
|
|
||||||
const { t } = useTranslation(['dashboard', 'common']);
|
const { t } = useTranslation(['dashboard', 'common']);
|
||||||
|
|
||||||
|
// used to set the initial value for the updatedTitle
|
||||||
|
// the context value is sometimes not available during the initial render
|
||||||
|
// due to which the updatedTitle is set to some previous value
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedDashboard) {
|
||||||
|
setUpdatedTitle(selectedDashboard.data.title);
|
||||||
|
}
|
||||||
|
}, [selectedDashboard]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state.error) {
|
if (state.error) {
|
||||||
notifications.error({
|
notifications.error({
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
import './QuerySection.styles.scss';
|
import './QuerySection.styles.scss';
|
||||||
|
|
||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Button, Tabs, Tooltip, Typography } from 'antd';
|
import { Button, Tabs, Typography } from 'antd';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import PromQLIcon from 'assets/Dashboard/PromQl';
|
import PromQLIcon from 'assets/Dashboard/PromQl';
|
||||||
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
|
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
|
||||||
import TextToolTip from 'components/TextToolTip';
|
import TextToolTip from 'components/TextToolTip';
|
||||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||||
import { QBShortcuts } from 'constants/shortcuts/QBShortcuts';
|
import { QBShortcuts } from 'constants/shortcuts/QBShortcuts';
|
||||||
import { getDefaultWidgetData } from 'container/NewWidget/utils';
|
import {
|
||||||
|
getDefaultWidgetData,
|
||||||
|
PANEL_TYPE_TO_QUERY_TYPES,
|
||||||
|
} from 'container/NewWidget/utils';
|
||||||
import { QueryBuilder } from 'container/QueryBuilder';
|
import { QueryBuilder } from 'container/QueryBuilder';
|
||||||
import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces';
|
import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interfaces';
|
||||||
import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys';
|
import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys';
|
||||||
@ -112,16 +115,18 @@ function QuerySection({
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleQueryCategoryChange = (qCategory: string): void => {
|
const handleQueryCategoryChange = useCallback(
|
||||||
const currentQueryType = qCategory;
|
(qCategory: string): void => {
|
||||||
|
const currentQueryType = qCategory;
|
||||||
featureResponse.refetch().then(() => {
|
featureResponse.refetch().then(() => {
|
||||||
handleStageQuery({
|
handleStageQuery({
|
||||||
...currentQuery,
|
...currentQuery,
|
||||||
queryType: currentQueryType as EQueryType,
|
queryType: currentQueryType as EQueryType,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
};
|
[currentQuery, featureResponse, handleStageQuery],
|
||||||
|
);
|
||||||
|
|
||||||
const handleRunQuery = (): void => {
|
const handleRunQuery = (): void => {
|
||||||
const widgetId = urlQuery.get('widgetId');
|
const widgetId = urlQuery.get('widgetId');
|
||||||
@ -147,72 +152,55 @@ function QuerySection({
|
|||||||
return config;
|
return config;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const listItems = [
|
const items = useMemo(() => {
|
||||||
{
|
const supportedQueryTypes = PANEL_TYPE_TO_QUERY_TYPES[selectedGraph] || [];
|
||||||
key: EQueryType.QUERY_BUILDER,
|
|
||||||
label: (
|
|
||||||
<Button className="nav-btns">
|
|
||||||
<Atom size={14} />
|
|
||||||
<Typography>Query Builder</Typography>
|
|
||||||
</Button>
|
|
||||||
),
|
|
||||||
tab: <Typography>Query Builder</Typography>,
|
|
||||||
children: (
|
|
||||||
<QueryBuilder
|
|
||||||
panelType={PANEL_TYPES.LIST}
|
|
||||||
filterConfigs={filterConfigs}
|
|
||||||
version={selectedDashboard?.data?.version || 'v3'}
|
|
||||||
isListViewPanel
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const items = [
|
const queryTypeComponents = {
|
||||||
{
|
[EQueryType.QUERY_BUILDER]: {
|
||||||
key: EQueryType.QUERY_BUILDER,
|
icon: <Atom size={14} />,
|
||||||
|
label: 'Query Builder',
|
||||||
|
component: (
|
||||||
|
<QueryBuilder
|
||||||
|
panelType={selectedGraph}
|
||||||
|
filterConfigs={filterConfigs}
|
||||||
|
version={selectedDashboard?.data?.version || 'v3'}
|
||||||
|
isListViewPanel={selectedGraph === PANEL_TYPES.LIST}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
[EQueryType.CLICKHOUSE]: {
|
||||||
|
icon: <Terminal size={14} />,
|
||||||
|
label: 'ClickHouse Query',
|
||||||
|
component: <ClickHouseQueryContainer />,
|
||||||
|
},
|
||||||
|
[EQueryType.PROM]: {
|
||||||
|
icon: (
|
||||||
|
<PromQLIcon
|
||||||
|
fillColor={isDarkMode ? Color.BG_VANILLA_200 : Color.BG_INK_300}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
label: 'PromQL',
|
||||||
|
component: <PromQLQueryContainer />,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return supportedQueryTypes.map((queryType) => ({
|
||||||
|
key: queryType,
|
||||||
label: (
|
label: (
|
||||||
<Button className="nav-btns">
|
<Button className="nav-btns">
|
||||||
<Atom size={14} />
|
{queryTypeComponents[queryType].icon}
|
||||||
<Typography>Query Builder</Typography>
|
<Typography>{queryTypeComponents[queryType].label}</Typography>
|
||||||
</Button>
|
</Button>
|
||||||
),
|
),
|
||||||
tab: <Typography>Query Builder</Typography>,
|
tab: <Typography>{queryTypeComponents[queryType].label}</Typography>,
|
||||||
children: (
|
children: queryTypeComponents[queryType].component,
|
||||||
<QueryBuilder
|
}));
|
||||||
panelType={selectedGraph}
|
}, [
|
||||||
filterConfigs={filterConfigs}
|
selectedGraph,
|
||||||
version={selectedDashboard?.data?.version || 'v3'}
|
filterConfigs,
|
||||||
/>
|
selectedDashboard?.data?.version,
|
||||||
),
|
isDarkMode,
|
||||||
},
|
]);
|
||||||
{
|
|
||||||
key: EQueryType.CLICKHOUSE,
|
|
||||||
label: (
|
|
||||||
<Button className="nav-btns">
|
|
||||||
<Terminal size={14} />
|
|
||||||
<Typography>ClickHouse Query</Typography>
|
|
||||||
</Button>
|
|
||||||
),
|
|
||||||
tab: <Typography>ClickHouse Query</Typography>,
|
|
||||||
children: <ClickHouseQueryContainer />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: EQueryType.PROM,
|
|
||||||
label: (
|
|
||||||
<Tooltip title="PromQL">
|
|
||||||
<Button className="nav-btns">
|
|
||||||
<PromQLIcon
|
|
||||||
fillColor={isDarkMode ? Color.BG_VANILLA_200 : Color.BG_INK_300}
|
|
||||||
/>
|
|
||||||
<Typography>PromQL</Typography>
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
),
|
|
||||||
tab: <Typography>PromQL</Typography>,
|
|
||||||
children: <PromQLQueryContainer />,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
registerShortcut(QBShortcuts.StageAndRunQuery, handleRunQuery);
|
registerShortcut(QBShortcuts.StageAndRunQuery, handleRunQuery);
|
||||||
@ -223,6 +211,16 @@ function QuerySection({
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [handleRunQuery]);
|
}, [handleRunQuery]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// switch to query builder if query type is not supported
|
||||||
|
if (
|
||||||
|
(selectedGraph === PANEL_TYPES.TABLE || selectedGraph === PANEL_TYPES.PIE) &&
|
||||||
|
currentQuery.queryType === EQueryType.PROM
|
||||||
|
) {
|
||||||
|
handleQueryCategoryChange(EQueryType.QUERY_BUILDER);
|
||||||
|
}
|
||||||
|
}, [currentQuery, handleQueryCategoryChange, selectedGraph]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dashboard-navigation">
|
<div className="dashboard-navigation">
|
||||||
<Tabs
|
<Tabs
|
||||||
@ -267,7 +265,7 @@ function QuerySection({
|
|||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
items={selectedGraph === PANEL_TYPES.LIST ? listItems : items}
|
items={items}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
import { cloneDeep, isEqual, set, unset } from 'lodash-es';
|
import { cloneDeep, isEqual, set, unset } from 'lodash-es';
|
||||||
import { Widgets } from 'types/api/dashboard/getAll';
|
import { Widgets } from 'types/api/dashboard/getAll';
|
||||||
import { IBuilderQuery, Query } from 'types/api/queryBuilder/queryBuilderData';
|
import { IBuilderQuery, Query } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
|
|
||||||
export const getIsQueryModified = (
|
export const getIsQueryModified = (
|
||||||
@ -492,3 +493,39 @@ export const getDefaultWidgetData = (
|
|||||||
...listViewInitialTraceQuery.builder.queryData[0].selectColumns,
|
...listViewInitialTraceQuery.builder.queryData[0].selectColumns,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const PANEL_TYPE_TO_QUERY_TYPES: Record<PANEL_TYPES, EQueryType[]> = {
|
||||||
|
[PANEL_TYPES.TIME_SERIES]: [
|
||||||
|
EQueryType.QUERY_BUILDER,
|
||||||
|
EQueryType.CLICKHOUSE,
|
||||||
|
EQueryType.PROM,
|
||||||
|
],
|
||||||
|
[PANEL_TYPES.TABLE]: [EQueryType.QUERY_BUILDER, EQueryType.CLICKHOUSE],
|
||||||
|
[PANEL_TYPES.VALUE]: [
|
||||||
|
EQueryType.QUERY_BUILDER,
|
||||||
|
EQueryType.CLICKHOUSE,
|
||||||
|
EQueryType.PROM,
|
||||||
|
],
|
||||||
|
[PANEL_TYPES.LIST]: [EQueryType.QUERY_BUILDER],
|
||||||
|
[PANEL_TYPES.TRACE]: [
|
||||||
|
EQueryType.QUERY_BUILDER,
|
||||||
|
EQueryType.CLICKHOUSE,
|
||||||
|
EQueryType.PROM,
|
||||||
|
],
|
||||||
|
[PANEL_TYPES.BAR]: [
|
||||||
|
EQueryType.QUERY_BUILDER,
|
||||||
|
EQueryType.CLICKHOUSE,
|
||||||
|
EQueryType.PROM,
|
||||||
|
],
|
||||||
|
[PANEL_TYPES.PIE]: [EQueryType.QUERY_BUILDER, EQueryType.CLICKHOUSE],
|
||||||
|
[PANEL_TYPES.HISTOGRAM]: [
|
||||||
|
EQueryType.QUERY_BUILDER,
|
||||||
|
EQueryType.CLICKHOUSE,
|
||||||
|
EQueryType.PROM,
|
||||||
|
],
|
||||||
|
[PANEL_TYPES.EMPTY_WIDGET]: [
|
||||||
|
EQueryType.QUERY_BUILDER,
|
||||||
|
EQueryType.CLICKHOUSE,
|
||||||
|
EQueryType.PROM,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
@ -266,14 +266,22 @@ exports[`Table panel wrappper tests table should render fine with the query resp
|
|||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
demo-app
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
demo-app
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
4.35 s
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
4.35 s
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -284,14 +292,22 @@ exports[`Table panel wrappper tests table should render fine with the query resp
|
|||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
customer
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
customer
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
431 ms
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
431 ms
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -302,14 +318,22 @@ exports[`Table panel wrappper tests table should render fine with the query resp
|
|||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
mysql
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
mysql
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
431 ms
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
431 ms
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -320,14 +344,22 @@ exports[`Table panel wrappper tests table should render fine with the query resp
|
|||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
frontend
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
frontend
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
287 ms
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
287 ms
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -338,14 +370,22 @@ exports[`Table panel wrappper tests table should render fine with the query resp
|
|||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
driver
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
driver
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
230 ms
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
230 ms
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -356,14 +396,22 @@ exports[`Table panel wrappper tests table should render fine with the query resp
|
|||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
route
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
route
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
66.4 ms
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
66.4 ms
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -374,14 +422,22 @@ exports[`Table panel wrappper tests table should render fine with the query resp
|
|||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
redis
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
redis
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="ant-table-cell"
|
class="ant-table-cell"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
31.3 ms
|
<div
|
||||||
|
class="line-clamped-text"
|
||||||
|
>
|
||||||
|
31.3 ms
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -333,7 +333,7 @@ export const Query = memo(function Query({
|
|||||||
const isVersionV4 = version && version === ENTITY_VERSION_V4;
|
const isVersionV4 = version && version === ENTITY_VERSION_V4;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row gutter={[0, 12]}>
|
<Row gutter={[0, 12]} className={`query-builder-${version}`}>
|
||||||
<QBEntityOptions
|
<QBEntityOptions
|
||||||
isMetricsDataSource={isMetricsDataSource}
|
isMetricsDataSource={isMetricsDataSource}
|
||||||
showFunctions={
|
showFunctions={
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Select } from 'antd';
|
import { Select } from 'antd';
|
||||||
import { ENTITY_VERSION_V4 } from 'constants/app';
|
import { ENTITY_VERSION_V4 } from 'constants/app';
|
||||||
// ** Constants
|
// ** Constants
|
||||||
@ -34,6 +35,7 @@ export function HavingFilter({
|
|||||||
const [currentFormValue, setCurrentFormValue] = useState<HavingForm>(
|
const [currentFormValue, setCurrentFormValue] = useState<HavingForm>(
|
||||||
initialHavingValues,
|
initialHavingValues,
|
||||||
);
|
);
|
||||||
|
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||||
|
|
||||||
const { isMulti } = useTagValidation(
|
const { isMulti } = useTagValidation(
|
||||||
currentFormValue.op,
|
currentFormValue.op,
|
||||||
@ -198,6 +200,29 @@ export function HavingFilter({
|
|||||||
resetChanges();
|
resetChanges();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleFocus = useCallback(() => {
|
||||||
|
setErrorMessage(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleBlur = useCallback((): void => {
|
||||||
|
if (searchText) {
|
||||||
|
const { columnName, op, value } = getHavingObject(searchText);
|
||||||
|
const isCompleteHavingClause =
|
||||||
|
columnName && op && value.every((v) => v !== '');
|
||||||
|
|
||||||
|
if (isCompleteHavingClause && isValidHavingValue(searchText)) {
|
||||||
|
setLocalValues((prev) => {
|
||||||
|
const updatedValues = [...prev, searchText];
|
||||||
|
onChange(updatedValues.map(transformFromStringToHaving));
|
||||||
|
return updatedValues;
|
||||||
|
});
|
||||||
|
setSearchText('');
|
||||||
|
} else {
|
||||||
|
setErrorMessage('Invalid HAVING clause');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [searchText, onChange]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
parseSearchText(searchText);
|
parseSearchText(searchText);
|
||||||
}, [searchText, parseSearchText]);
|
}, [searchText, parseSearchText]);
|
||||||
@ -209,28 +234,36 @@ export function HavingFilter({
|
|||||||
const isMetricsDataSource = query.dataSource === DataSource.METRICS;
|
const isMetricsDataSource = query.dataSource === DataSource.METRICS;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<>
|
||||||
getPopupContainer={popupContainer}
|
<Select
|
||||||
autoClearSearchValue={false}
|
getPopupContainer={popupContainer}
|
||||||
mode="multiple"
|
autoClearSearchValue={false}
|
||||||
onSearch={handleSearch}
|
mode="multiple"
|
||||||
searchValue={searchText}
|
onSearch={handleSearch}
|
||||||
tagRender={tagRender}
|
searchValue={searchText}
|
||||||
value={localValues}
|
tagRender={tagRender}
|
||||||
data-testid="havingSelect"
|
value={localValues}
|
||||||
disabled={isMetricsDataSource && !query.aggregateAttribute.key}
|
data-testid="havingSelect"
|
||||||
style={{ width: '100%' }}
|
disabled={isMetricsDataSource && !query.aggregateAttribute.key}
|
||||||
notFoundContent={currentFormValue.value.length === 0 ? undefined : null}
|
style={{ width: '100%' }}
|
||||||
placeholder="GroupBy(operation) > 5"
|
notFoundContent={currentFormValue.value.length === 0 ? undefined : null}
|
||||||
onDeselect={handleDeselect}
|
placeholder="GroupBy(operation) > 5"
|
||||||
onChange={handleChange}
|
onDeselect={handleDeselect}
|
||||||
onSelect={handleSelect}
|
onChange={handleChange}
|
||||||
>
|
onSelect={handleSelect}
|
||||||
{options.map((opt) => (
|
onFocus={handleFocus}
|
||||||
<Select.Option key={opt.value} value={opt.value} title="havingOption">
|
onBlur={handleBlur}
|
||||||
{opt.label}
|
status={errorMessage ? 'error' : undefined}
|
||||||
</Select.Option>
|
>
|
||||||
))}
|
{options.map((opt) => (
|
||||||
</Select>
|
<Select.Option key={opt.value} value={opt.value} title="havingOption">
|
||||||
|
{opt.label}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
{errorMessage && (
|
||||||
|
<div style={{ color: Color.BG_CHERRY_500 }}>{errorMessage}</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -334,8 +334,8 @@
|
|||||||
|
|
||||||
.qb-search-bar-tokenised-tags {
|
.qb-search-bar-tokenised-tags {
|
||||||
.ant-tag {
|
.ant-tag {
|
||||||
border: 1px solid var(--bg-slate-100);
|
|
||||||
background: var(--bg-vanilla-300);
|
background: var(--bg-vanilla-300);
|
||||||
|
border: 1px solid var(--bg-slate-100);
|
||||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
|
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
.ant-typography {
|
.ant-typography {
|
||||||
|
@ -244,7 +244,7 @@ function QueryBuilderSearchV2(
|
|||||||
isFetching: isFetchingSuggestions,
|
isFetching: isFetchingSuggestions,
|
||||||
} = useGetAttributeSuggestions(
|
} = useGetAttributeSuggestions(
|
||||||
{
|
{
|
||||||
searchText: searchValue.split(' ')[0],
|
searchText: searchValue?.split(' ')[0],
|
||||||
dataSource: query.dataSource,
|
dataSource: query.dataSource,
|
||||||
filters: query.filters,
|
filters: query.filters,
|
||||||
},
|
},
|
||||||
@ -691,7 +691,7 @@ function QueryBuilderSearchV2(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentState === DropdownState.OPERATOR) {
|
if (currentState === DropdownState.OPERATOR) {
|
||||||
const keyOperator = searchValue.split(' ');
|
const keyOperator = searchValue?.split(' ');
|
||||||
const partialOperator = keyOperator?.[1];
|
const partialOperator = keyOperator?.[1];
|
||||||
const strippedKey = keyOperator?.[0];
|
const strippedKey = keyOperator?.[0];
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
width: 5px;
|
width: 5px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: var(--bg-slate-300);
|
background-color: var(--bg-slate-300);
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.option {
|
.option {
|
||||||
@ -207,6 +208,10 @@
|
|||||||
background: var(--bg-vanilla-300);
|
background: var(--bg-vanilla-300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: var(--bg-ink-100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.option:hover {
|
.option:hover {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { AttributeValuesMap } from 'components/ClientSideQBSearch/ClientSideQBSearch';
|
||||||
import { HAVING_FILTER_REGEXP } from 'constants/regExp';
|
import { HAVING_FILTER_REGEXP } from 'constants/regExp';
|
||||||
import { IOption } from 'hooks/useResourceAttribute/types';
|
import { IOption } from 'hooks/useResourceAttribute/types';
|
||||||
import uniqWith from 'lodash-es/unionWith';
|
import uniqWith from 'lodash-es/unionWith';
|
||||||
@ -92,3 +93,20 @@ export const getValidOrderByResult = (result: IOption[]): IOption[] =>
|
|||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
export const transformKeyValuesToAttributeValuesMap = (
|
||||||
|
attributeValuesMap: Record<string, string[] | number[] | boolean[]>,
|
||||||
|
): AttributeValuesMap =>
|
||||||
|
Object.fromEntries(
|
||||||
|
Object.entries(attributeValuesMap || {}).map(([key, values]) => [
|
||||||
|
key,
|
||||||
|
{
|
||||||
|
stringAttributeValues:
|
||||||
|
typeof values[0] === 'string' ? (values as string[]) : [],
|
||||||
|
numberAttributeValues:
|
||||||
|
typeof values[0] === 'number' ? (values as number[]) : [],
|
||||||
|
boolAttributeValues:
|
||||||
|
typeof values[0] === 'boolean' ? (values as boolean[]) : [],
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
@ -3,10 +3,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
&.docked {
|
|
||||||
width: 240px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sideNav {
|
.sideNav {
|
||||||
@ -229,39 +225,6 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.docked {
|
|
||||||
flex: 0 0 240px;
|
|
||||||
max-width: 240px;
|
|
||||||
min-width: 240px;
|
|
||||||
width: 240px;
|
|
||||||
|
|
||||||
.secondary-nav-items {
|
|
||||||
width: 240px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brand {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.get-started-nav-items {
|
|
||||||
.get-started-btn {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapse-expand-handlers {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item-label {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item-beta {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.lightMode {
|
.lightMode {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import './SideNav.styles.scss';
|
import './SideNav.styles.scss';
|
||||||
|
|
||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Button, Tooltip } from 'antd';
|
import { Button } from 'antd';
|
||||||
import logEvent from 'api/common/logEvent';
|
import logEvent from 'api/common/logEvent';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import { FeatureKeys } from 'constants/features';
|
import { FeatureKeys } from 'constants/features';
|
||||||
@ -16,9 +16,6 @@ import history from 'lib/history';
|
|||||||
import {
|
import {
|
||||||
AlertTriangle,
|
AlertTriangle,
|
||||||
CheckSquare,
|
CheckSquare,
|
||||||
ChevronLeftCircle,
|
|
||||||
ChevronRightCircle,
|
|
||||||
PanelRight,
|
|
||||||
RocketIcon,
|
RocketIcon,
|
||||||
UserCircle,
|
UserCircle,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
@ -55,13 +52,9 @@ interface UserManagementMenuItems {
|
|||||||
function SideNav({
|
function SideNav({
|
||||||
licenseData,
|
licenseData,
|
||||||
isFetching,
|
isFetching,
|
||||||
onCollapse,
|
|
||||||
collapsed,
|
|
||||||
}: {
|
}: {
|
||||||
licenseData: any;
|
licenseData: any;
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
onCollapse: () => void;
|
|
||||||
collapsed: boolean;
|
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [menuItems, setMenuItems] = useState(defaultMenuItems);
|
const [menuItems, setMenuItems] = useState(defaultMenuItems);
|
||||||
|
|
||||||
@ -330,8 +323,6 @@ function SideNav({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
registerShortcut(GlobalShortcuts.SidebarCollapse, onCollapse);
|
|
||||||
|
|
||||||
registerShortcut(GlobalShortcuts.NavigateToServices, () =>
|
registerShortcut(GlobalShortcuts.NavigateToServices, () =>
|
||||||
onClickHandler(ROUTES.APPLICATION, null),
|
onClickHandler(ROUTES.APPLICATION, null),
|
||||||
);
|
);
|
||||||
@ -359,7 +350,6 @@ function SideNav({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (): void => {
|
return (): void => {
|
||||||
deregisterShortcut(GlobalShortcuts.SidebarCollapse);
|
|
||||||
deregisterShortcut(GlobalShortcuts.NavigateToServices);
|
deregisterShortcut(GlobalShortcuts.NavigateToServices);
|
||||||
deregisterShortcut(GlobalShortcuts.NavigateToTraces);
|
deregisterShortcut(GlobalShortcuts.NavigateToTraces);
|
||||||
deregisterShortcut(GlobalShortcuts.NavigateToLogs);
|
deregisterShortcut(GlobalShortcuts.NavigateToLogs);
|
||||||
@ -368,11 +358,11 @@ function SideNav({
|
|||||||
deregisterShortcut(GlobalShortcuts.NavigateToExceptions);
|
deregisterShortcut(GlobalShortcuts.NavigateToExceptions);
|
||||||
deregisterShortcut(GlobalShortcuts.NavigateToMessagingQueues);
|
deregisterShortcut(GlobalShortcuts.NavigateToMessagingQueues);
|
||||||
};
|
};
|
||||||
}, [deregisterShortcut, onClickHandler, onCollapse, registerShortcut]);
|
}, [deregisterShortcut, onClickHandler, registerShortcut]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('sidenav-container', !collapsed ? 'docked' : '')}>
|
<div className={cx('sidenav-container')}>
|
||||||
<div className={cx('sideNav', !collapsed ? 'docked' : '')}>
|
<div className={cx('sideNav')}>
|
||||||
<div className="brand">
|
<div className="brand">
|
||||||
<div className="brand-company-meta">
|
<div className="brand-company-meta">
|
||||||
<div
|
<div
|
||||||
@ -392,17 +382,6 @@ function SideNav({
|
|||||||
<div className="license tag nav-item-label">{licenseTag}</div>
|
<div className="license tag nav-item-label">{licenseTag}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Tooltip
|
|
||||||
title={collapsed ? 'Dock Sidebar' : 'Undock Sidebar'}
|
|
||||||
placement="right"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
className="periscope-btn nav-item-label dockBtn"
|
|
||||||
icon={<PanelRight size={16} />}
|
|
||||||
onClick={onCollapse}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isCloudUserVal && (
|
{isCloudUserVal && (
|
||||||
@ -504,14 +483,6 @@ function SideNav({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="collapse-expand-handlers" onClick={onCollapse}>
|
|
||||||
{collapsed ? (
|
|
||||||
<ChevronRightCircle size={18} />
|
|
||||||
) : (
|
|
||||||
<ChevronLeftCircle size={18} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { initialAutocompleteData, OPERATORS } from 'constants/queryBuilder';
|
import { initialAutocompleteData, OPERATORS } from 'constants/queryBuilder';
|
||||||
|
import { getOperatorValue } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils';
|
||||||
import getStep from 'lib/getStep';
|
import getStep from 'lib/getStep';
|
||||||
import {
|
import {
|
||||||
BaseAutocompleteData,
|
BaseAutocompleteData,
|
||||||
@ -27,7 +28,8 @@ export const getTraceToLogsQuery = (
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
op: OPERATORS.IN,
|
// for generating query we use in instead of IN
|
||||||
|
op: getOperatorValue(OPERATORS.IN),
|
||||||
value: traceId,
|
value: traceId,
|
||||||
key,
|
key,
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Button, Modal, Tabs, Tooltip, Typography } from 'antd';
|
import { Button, Modal, Row, Tabs, Tooltip, Typography } from 'antd';
|
||||||
import Editor from 'components/Editor';
|
import Editor from 'components/Editor';
|
||||||
import { StyledSpace } from 'components/Styled';
|
import { StyledSpace } from 'components/Styled';
|
||||||
import { QueryParams } from 'constants/query';
|
import { QueryParams } from 'constants/query';
|
||||||
@ -6,7 +6,8 @@ import ROUTES from 'constants/routes';
|
|||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import createQueryParams from 'lib/createQueryParams';
|
import createQueryParams from 'lib/createQueryParams';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { useState } from 'react';
|
import { PanelRight } from 'lucide-react';
|
||||||
|
import { Dispatch, SetStateAction, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
@ -28,6 +29,7 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
|
|||||||
firstSpanStartTime,
|
firstSpanStartTime,
|
||||||
traceStartTime = minTime,
|
traceStartTime = minTime,
|
||||||
traceEndTime = maxTime,
|
traceEndTime = maxTime,
|
||||||
|
setCollapsed,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const { id: traceId } = useParams<Params>();
|
const { id: traceId } = useParams<Params>();
|
||||||
@ -96,14 +98,14 @@ function SelectedSpanDetails(props: SelectedSpanDetailsProps): JSX.Element {
|
|||||||
styledclass={[styles.selectedSpanDetailsContainer, styles.overflow]}
|
styledclass={[styles.selectedSpanDetailsContainer, styles.overflow]}
|
||||||
direction="vertical"
|
direction="vertical"
|
||||||
>
|
>
|
||||||
<Typography.Text
|
<Row align="middle" justify="space-between">
|
||||||
strong
|
<Typography.Text strong>Details for selected Span</Typography.Text>
|
||||||
style={{
|
<Button
|
||||||
marginTop: '16px',
|
className="periscope-btn nav-item-label expand-collapse-btn"
|
||||||
}}
|
icon={<PanelRight size={16} />}
|
||||||
>
|
onClick={(): void => setCollapsed((prev) => !prev)}
|
||||||
Details for selected Span
|
/>
|
||||||
</Typography.Text>
|
</Row>
|
||||||
|
|
||||||
<Typography.Text style={{ fontWeight: 700 }}>Service</Typography.Text>
|
<Typography.Text style={{ fontWeight: 700 }}>Service</Typography.Text>
|
||||||
|
|
||||||
@ -170,6 +172,7 @@ interface SelectedSpanDetailsProps {
|
|||||||
firstSpanStartTime: number;
|
firstSpanStartTime: number;
|
||||||
traceStartTime?: number;
|
traceStartTime?: number;
|
||||||
traceEndTime?: number;
|
traceEndTime?: number;
|
||||||
|
setCollapsed: Dispatch<SetStateAction<boolean>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectedSpanDetails.defaultProps = {
|
SelectedSpanDetails.defaultProps = {
|
||||||
|
@ -20,4 +20,10 @@
|
|||||||
background-color: white !important;
|
background-color: white !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expand-collapse-btn {
|
||||||
|
padding: 4px;
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import useUrlQuery from 'hooks/useUrlQuery';
|
|||||||
import { spanServiceNameToColorMapping } from 'lib/getRandomColor';
|
import { spanServiceNameToColorMapping } from 'lib/getRandomColor';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { map } from 'lodash-es';
|
import { map } from 'lodash-es';
|
||||||
|
import { PanelRight } from 'lucide-react';
|
||||||
import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants';
|
import { SPAN_DETAILS_LEFT_COL_WIDTH } from 'pages/TraceDetail/constants';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { ITraceForest, PayloadProps } from 'types/api/trace/getTraceItem';
|
import { ITraceForest, PayloadProps } from 'types/api/trace/getTraceItem';
|
||||||
@ -267,14 +268,21 @@ function TraceDetail({ response }: TraceDetailProps): JSX.Element {
|
|||||||
collapsed={collapsed}
|
collapsed={collapsed}
|
||||||
reverseArrow
|
reverseArrow
|
||||||
width={300}
|
width={300}
|
||||||
collapsedWidth={40}
|
collapsedWidth={48}
|
||||||
defaultCollapsed
|
defaultCollapsed
|
||||||
onCollapse={(value): void => setCollapsed(value)}
|
trigger={null}
|
||||||
data-testid="span-details-sider"
|
data-testid="span-details-sider"
|
||||||
>
|
>
|
||||||
{!collapsed && (
|
<StyledCol styledclass={[styles.selectedSpanDetailContainer]}>
|
||||||
<StyledCol styledclass={[styles.selectedSpanDetailContainer]}>
|
{collapsed ? (
|
||||||
|
<Button
|
||||||
|
className="periscope-btn nav-item-label expand-collapse-btn"
|
||||||
|
icon={<PanelRight size={16} />}
|
||||||
|
onClick={(): void => setCollapsed((prev) => !prev)}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<SelectedSpanDetails
|
<SelectedSpanDetails
|
||||||
|
setCollapsed={setCollapsed}
|
||||||
firstSpanStartTime={firstSpanStartTime}
|
firstSpanStartTime={firstSpanStartTime}
|
||||||
traceStartTime={traceStartTime}
|
traceStartTime={traceStartTime}
|
||||||
traceEndTime={traceEndTime}
|
traceEndTime={traceEndTime}
|
||||||
@ -287,8 +295,8 @@ function TraceDetail({ response }: TraceDetailProps): JSX.Element {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.find((tree) => tree)}
|
.find((tree) => tree)}
|
||||||
/>
|
/>
|
||||||
</StyledCol>
|
)}
|
||||||
)}
|
</StyledCol>
|
||||||
</Sider>
|
</Sider>
|
||||||
</StyledRow>
|
</StyledRow>
|
||||||
);
|
);
|
||||||
|
@ -59,6 +59,8 @@ export const selectedSpanDetailContainer = css`
|
|||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 12px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,9 +14,8 @@ import { Pagination } from 'hooks/queryPagination';
|
|||||||
import useDragColumns from 'hooks/useDragColumns';
|
import useDragColumns from 'hooks/useDragColumns';
|
||||||
import { getDraggedColumns } from 'hooks/useDragColumns/utils';
|
import { getDraggedColumns } from 'hooks/useDragColumns/utils';
|
||||||
import useUrlQueryData from 'hooks/useUrlQueryData';
|
import useUrlQueryData from 'hooks/useUrlQueryData';
|
||||||
import history from 'lib/history';
|
|
||||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||||
import { HTMLAttributes, memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
@ -25,7 +24,7 @@ import { GlobalReducer } from 'types/reducer/globalTime';
|
|||||||
import { TracesLoading } from '../TraceLoading/TraceLoading';
|
import { TracesLoading } from '../TraceLoading/TraceLoading';
|
||||||
import { defaultSelectedColumns, PER_PAGE_OPTIONS } from './configs';
|
import { defaultSelectedColumns, PER_PAGE_OPTIONS } from './configs';
|
||||||
import { Container, ErrorText, tableStyles } from './styles';
|
import { Container, ErrorText, tableStyles } from './styles';
|
||||||
import { getListColumns, getTraceLink, transformDataWithDate } from './utils';
|
import { getListColumns, transformDataWithDate } from './utils';
|
||||||
|
|
||||||
interface ListViewProps {
|
interface ListViewProps {
|
||||||
isFilterApplied: boolean;
|
isFilterApplied: boolean;
|
||||||
@ -108,21 +107,6 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
|
|||||||
[queryTableData],
|
[queryTableData],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleRow = useCallback(
|
|
||||||
(record: RowData): HTMLAttributes<RowData> => ({
|
|
||||||
onClick: (event): void => {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
if (event.metaKey || event.ctrlKey) {
|
|
||||||
window.open(getTraceLink(record), '_blank');
|
|
||||||
} else {
|
|
||||||
history.push(getTraceLink(record));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleDragColumn = useCallback(
|
const handleDragColumn = useCallback(
|
||||||
(fromIndex: number, toIndex: number) =>
|
(fromIndex: number, toIndex: number) =>
|
||||||
onDragColumns(columns, fromIndex, toIndex),
|
onDragColumns(columns, fromIndex, toIndex),
|
||||||
@ -169,7 +153,6 @@ function ListView({ isFilterApplied }: ListViewProps): JSX.Element {
|
|||||||
style={tableStyles}
|
style={tableStyles}
|
||||||
dataSource={transformedQueryTableData}
|
dataSource={transformedQueryTableData}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
onRow={handleRow}
|
|
||||||
onDragColumn={handleDragColumn}
|
onDragColumn={handleDragColumn}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -47,11 +47,11 @@ export const getListColumns = (
|
|||||||
key: 'date',
|
key: 'date',
|
||||||
title: 'Timestamp',
|
title: 'Timestamp',
|
||||||
width: 145,
|
width: 145,
|
||||||
render: (item): JSX.Element => {
|
render: (value, item): JSX.Element => {
|
||||||
const date =
|
const date =
|
||||||
typeof item === 'string'
|
typeof value === 'string'
|
||||||
? dayjs(item).format('YYYY-MM-DD HH:mm:ss.SSS')
|
? dayjs(value).format('YYYY-MM-DD HH:mm:ss.SSS')
|
||||||
: dayjs(item / 1e6).format('YYYY-MM-DD HH:mm:ss.SSS');
|
: dayjs(value / 1e6).format('YYYY-MM-DD HH:mm:ss.SSS');
|
||||||
return (
|
return (
|
||||||
<BlockLink to={getTraceLink(item)}>
|
<BlockLink to={getTraceLink(item)}>
|
||||||
<Typography.Text>{date}</Typography.Text>
|
<Typography.Text>{date}</Typography.Text>
|
||||||
@ -67,10 +67,10 @@ export const getListColumns = (
|
|||||||
dataIndex: key,
|
dataIndex: key,
|
||||||
key: `${key}-${dataType}-${type}`,
|
key: `${key}-${dataType}-${type}`,
|
||||||
width: 145,
|
width: 145,
|
||||||
render: (value): JSX.Element => {
|
render: (value, item): JSX.Element => {
|
||||||
if (value === '') {
|
if (value === '') {
|
||||||
return (
|
return (
|
||||||
<BlockLink to={getTraceLink(value)}>
|
<BlockLink to={getTraceLink(item)}>
|
||||||
<Typography data-testid={key}>N/A</Typography>
|
<Typography data-testid={key}>N/A</Typography>
|
||||||
</BlockLink>
|
</BlockLink>
|
||||||
);
|
);
|
||||||
@ -78,7 +78,7 @@ export const getListColumns = (
|
|||||||
|
|
||||||
if (key === 'httpMethod' || key === 'responseStatusCode') {
|
if (key === 'httpMethod' || key === 'responseStatusCode') {
|
||||||
return (
|
return (
|
||||||
<BlockLink to={getTraceLink(value)}>
|
<BlockLink to={getTraceLink(item)}>
|
||||||
<Tag data-testid={key} color="magenta">
|
<Tag data-testid={key} color="magenta">
|
||||||
{value}
|
{value}
|
||||||
</Tag>
|
</Tag>
|
||||||
@ -88,14 +88,14 @@ export const getListColumns = (
|
|||||||
|
|
||||||
if (key === 'durationNano') {
|
if (key === 'durationNano') {
|
||||||
return (
|
return (
|
||||||
<BlockLink to={getTraceLink(value)}>
|
<BlockLink to={getTraceLink(item)}>
|
||||||
<Typography data-testid={key}>{getMs(value)}ms</Typography>
|
<Typography data-testid={key}>{getMs(value)}ms</Typography>
|
||||||
</BlockLink>
|
</BlockLink>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BlockLink to={getTraceLink(value)}>
|
<BlockLink to={getTraceLink(item)}>
|
||||||
<Typography data-testid={key}>{value}</Typography>
|
<Typography data-testid={key}>{value}</Typography>
|
||||||
</BlockLink>
|
</BlockLink>
|
||||||
);
|
);
|
||||||
|
@ -52,8 +52,7 @@
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
margin-top: 12px;
|
margin: 12px 0 2px;
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import type { SelectProps } from 'antd';
|
import type { SelectProps } from 'antd';
|
||||||
import { Tag, Tooltip } from 'antd';
|
import { Tag, Tooltip } from 'antd';
|
||||||
import { BaseOptionType } from 'antd/es/select';
|
import { BaseOptionType } from 'antd/es/select';
|
||||||
import { Dispatch, SetStateAction, useCallback, useMemo, useRef } from 'react';
|
import { useCallback, useMemo, useRef } from 'react';
|
||||||
import { Alerts } from 'types/api/alerts/getTriggered';
|
import { Alerts } from 'types/api/alerts/getTriggered';
|
||||||
|
|
||||||
import { Container, Select } from './styles';
|
import { Container, Select } from './styles';
|
||||||
@ -31,8 +31,8 @@ function TextOverflowTooltip({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Filter({
|
function Filter({
|
||||||
setSelectedFilter,
|
onSelectedFilterChange,
|
||||||
setSelectedGroup,
|
onSelectedGroupChange,
|
||||||
allAlerts,
|
allAlerts,
|
||||||
selectedGroup,
|
selectedGroup,
|
||||||
selectedFilter,
|
selectedFilter,
|
||||||
@ -40,27 +40,27 @@ function Filter({
|
|||||||
const onChangeSelectGroupHandler = useCallback(
|
const onChangeSelectGroupHandler = useCallback(
|
||||||
(value: unknown) => {
|
(value: unknown) => {
|
||||||
if (typeof value === 'object' && Array.isArray(value)) {
|
if (typeof value === 'object' && Array.isArray(value)) {
|
||||||
setSelectedGroup(
|
onSelectedGroupChange(
|
||||||
value.map((e) => ({
|
value.map((e) => ({
|
||||||
value: e,
|
value: e,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setSelectedGroup],
|
[onSelectedGroupChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onChangeSelectedFilterHandler = useCallback(
|
const onChangeSelectedFilterHandler = useCallback(
|
||||||
(value: unknown) => {
|
(value: unknown) => {
|
||||||
if (typeof value === 'object' && Array.isArray(value)) {
|
if (typeof value === 'object' && Array.isArray(value)) {
|
||||||
setSelectedFilter(
|
onSelectedFilterChange(
|
||||||
value.map((e) => ({
|
value.map((e) => ({
|
||||||
value: e,
|
value: e,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setSelectedFilter],
|
[onSelectedFilterChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
const uniqueLabels: Array<string> = useMemo(() => {
|
const uniqueLabels: Array<string> = useMemo(() => {
|
||||||
@ -122,8 +122,8 @@ function Filter({
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface FilterProps {
|
interface FilterProps {
|
||||||
setSelectedFilter: Dispatch<SetStateAction<Array<Value>>>;
|
onSelectedFilterChange: (value: Array<Value>) => void;
|
||||||
setSelectedGroup: Dispatch<SetStateAction<Array<Value>>>;
|
onSelectedGroupChange: (value: Array<Value>) => void;
|
||||||
allAlerts: Alerts[];
|
allAlerts: Alerts[];
|
||||||
selectedGroup: Array<Value>;
|
selectedGroup: Array<Value>;
|
||||||
selectedFilter: Array<Value>;
|
selectedFilter: Array<Value>;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
import { Alerts } from 'types/api/alerts/getTriggered';
|
import { Alerts } from 'types/api/alerts/getTriggered';
|
||||||
|
|
||||||
import Filter, { Value } from './Filter';
|
import Filter, { Value } from './Filter';
|
||||||
@ -6,18 +5,21 @@ import FilteredTable from './FilteredTable';
|
|||||||
import NoFilterTable from './NoFilterTable';
|
import NoFilterTable from './NoFilterTable';
|
||||||
import { NoTableContainer } from './styles';
|
import { NoTableContainer } from './styles';
|
||||||
|
|
||||||
function TriggeredAlerts({ allAlerts }: TriggeredAlertsProps): JSX.Element {
|
function TriggeredAlerts({
|
||||||
const [selectedGroup, setSelectedGroup] = useState<Value[]>([]);
|
allAlerts,
|
||||||
const [selectedFilter, setSelectedFilter] = useState<Value[]>([]);
|
selectedFilter,
|
||||||
|
selectedGroup,
|
||||||
|
onSelectedFilterChange,
|
||||||
|
onSelectedGroupChange,
|
||||||
|
}: TriggeredAlertsProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Filter
|
<Filter
|
||||||
allAlerts={allAlerts}
|
allAlerts={allAlerts}
|
||||||
selectedFilter={selectedFilter}
|
selectedFilter={selectedFilter}
|
||||||
selectedGroup={selectedGroup}
|
selectedGroup={selectedGroup}
|
||||||
setSelectedFilter={setSelectedFilter}
|
onSelectedFilterChange={onSelectedFilterChange}
|
||||||
setSelectedGroup={setSelectedGroup}
|
onSelectedGroupChange={onSelectedGroupChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{selectedFilter.length === 0 && selectedGroup.length === 0 ? (
|
{selectedFilter.length === 0 && selectedGroup.length === 0 ? (
|
||||||
@ -45,6 +47,10 @@ function TriggeredAlerts({ allAlerts }: TriggeredAlertsProps): JSX.Element {
|
|||||||
|
|
||||||
interface TriggeredAlertsProps {
|
interface TriggeredAlertsProps {
|
||||||
allAlerts: Alerts[];
|
allAlerts: Alerts[];
|
||||||
|
selectedFilter: Array<Value>;
|
||||||
|
selectedGroup: Array<Value>;
|
||||||
|
onSelectedFilterChange: (value: Array<Value>) => void;
|
||||||
|
onSelectedGroupChange: (value: Array<Value>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TriggeredAlerts;
|
export default TriggeredAlerts;
|
||||||
|
@ -4,14 +4,17 @@ import Spinner from 'components/Spinner';
|
|||||||
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
||||||
import useAxiosError from 'hooks/useAxiosError';
|
import useAxiosError from 'hooks/useAxiosError';
|
||||||
import { isUndefined } from 'lodash-es';
|
import { isUndefined } from 'lodash-es';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
|
|
||||||
|
import { Value } from './Filter';
|
||||||
import TriggerComponent from './TriggeredAlert';
|
import TriggerComponent from './TriggeredAlert';
|
||||||
|
|
||||||
function TriggeredAlerts(): JSX.Element {
|
function TriggeredAlerts(): JSX.Element {
|
||||||
|
const [selectedGroup, setSelectedGroup] = useState<Value[]>([]);
|
||||||
|
const [selectedFilter, setSelectedFilter] = useState<Value[]>([]);
|
||||||
const userId = useSelector<AppState, string | undefined>(
|
const userId = useSelector<AppState, string | undefined>(
|
||||||
(state) => state.app.user?.userId,
|
(state) => state.app.user?.userId,
|
||||||
);
|
);
|
||||||
@ -34,6 +37,14 @@ function TriggeredAlerts(): JSX.Element {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleSelectedFilterChange = useCallback((newFilter: Value[]) => {
|
||||||
|
setSelectedFilter(newFilter);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleSelectedGroupChange = useCallback((newGroup: Value[]) => {
|
||||||
|
setSelectedGroup(newGroup);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hasLoggedEvent.current && !isUndefined(alertsResponse.data?.payload)) {
|
if (!hasLoggedEvent.current && !isUndefined(alertsResponse.data?.payload)) {
|
||||||
logEvent('Alert: Triggered alert list page visited', {
|
logEvent('Alert: Triggered alert list page visited', {
|
||||||
@ -44,14 +55,30 @@ function TriggeredAlerts(): JSX.Element {
|
|||||||
}, [alertsResponse.data?.payload]);
|
}, [alertsResponse.data?.payload]);
|
||||||
|
|
||||||
if (alertsResponse.error) {
|
if (alertsResponse.error) {
|
||||||
return <TriggerComponent allAlerts={[]} />;
|
return (
|
||||||
|
<TriggerComponent
|
||||||
|
allAlerts={[]}
|
||||||
|
selectedFilter={selectedFilter}
|
||||||
|
selectedGroup={selectedGroup}
|
||||||
|
onSelectedFilterChange={handleSelectedFilterChange}
|
||||||
|
onSelectedGroupChange={handleSelectedGroupChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alertsResponse.isFetching || alertsResponse?.data?.payload === undefined) {
|
if (alertsResponse.isFetching || alertsResponse?.data?.payload === undefined) {
|
||||||
return <Spinner height="75vh" tip="Loading Alerts..." />;
|
return <Spinner height="75vh" tip="Loading Alerts..." />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <TriggerComponent allAlerts={alertsResponse?.data?.payload || []} />;
|
return (
|
||||||
|
<TriggerComponent
|
||||||
|
allAlerts={alertsResponse?.data?.payload || []}
|
||||||
|
selectedFilter={selectedFilter}
|
||||||
|
selectedGroup={selectedGroup}
|
||||||
|
onSelectedFilterChange={handleSelectedFilterChange}
|
||||||
|
onSelectedGroupChange={handleSelectedGroupChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TriggeredAlerts;
|
export default TriggeredAlerts;
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
/>
|
/>
|
||||||
<meta data-react-helmet="true" name="docusaurus_locale" content="en" />
|
<meta data-react-helmet="true" name="docusaurus_locale" content="en" />
|
||||||
<meta data-react-helmet="true" name="docusaurus_tag" content="default" />
|
<meta data-react-helmet="true" name="docusaurus_tag" content="default" />
|
||||||
|
<meta name="robots" content="noindex">
|
||||||
<link data-react-helmet="true" rel="shortcut icon" href="/favicon.ico" />
|
<link data-react-helmet="true" rel="shortcut icon" href="/favicon.ico" />
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
@ -15,7 +15,7 @@ import {
|
|||||||
} from 'pages/AlertDetails/hooks';
|
} from 'pages/AlertDetails/hooks';
|
||||||
import CopyToClipboard from 'periscope/components/CopyToClipboard';
|
import CopyToClipboard from 'periscope/components/CopyToClipboard';
|
||||||
import { useAlertRule } from 'providers/Alert';
|
import { useAlertRule } from 'providers/Alert';
|
||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { CSSProperties } from 'styled-components';
|
import { CSSProperties } from 'styled-components';
|
||||||
import { AlertDef } from 'types/api/alerts/def';
|
import { AlertDef } from 'types/api/alerts/def';
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ function AlertActionButtons({
|
|||||||
ruleId: string;
|
ruleId: string;
|
||||||
alertDetails: AlertHeaderProps['alertDetails'];
|
alertDetails: AlertHeaderProps['alertDetails'];
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const { isAlertRuleDisabled } = useAlertRule();
|
const { alertRuleState, setAlertRuleState } = useAlertRule();
|
||||||
const { handleAlertStateToggle } = useAlertRuleStatusToggle({ ruleId });
|
const { handleAlertStateToggle } = useAlertRuleStatusToggle({ ruleId });
|
||||||
|
|
||||||
const { handleAlertDuplicate } = useAlertRuleDuplicate({
|
const { handleAlertDuplicate } = useAlertRuleDuplicate({
|
||||||
@ -79,13 +79,32 @@ function AlertActionButtons({
|
|||||||
);
|
);
|
||||||
const isDarkMode = useIsDarkMode();
|
const isDarkMode = useIsDarkMode();
|
||||||
|
|
||||||
|
// state for immediate UI feedback rather than waiting for onSuccess of handleAlertStateTiggle to updating the alertRuleState
|
||||||
|
const [isAlertRuleDisabled, setIsAlertRuleDisabled] = useState<
|
||||||
|
undefined | boolean
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (alertRuleState === undefined) {
|
||||||
|
setAlertRuleState(alertDetails.state);
|
||||||
|
setIsAlertRuleDisabled(alertDetails.state === 'disabled');
|
||||||
|
}
|
||||||
|
}, [setAlertRuleState, alertRuleState, alertDetails.state]);
|
||||||
|
|
||||||
|
// on unmount remove the alert state
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
useEffect(() => (): void => setAlertRuleState(undefined), []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="alert-action-buttons">
|
<div className="alert-action-buttons">
|
||||||
<Tooltip title={isAlertRuleDisabled ? 'Enable alert' : 'Disable alert'}>
|
<Tooltip title={alertRuleState ? 'Enable alert' : 'Disable alert'}>
|
||||||
{isAlertRuleDisabled !== undefined && (
|
{isAlertRuleDisabled !== undefined && (
|
||||||
<Switch
|
<Switch
|
||||||
size="small"
|
size="small"
|
||||||
onChange={handleAlertStateToggle}
|
onChange={(): void => {
|
||||||
|
setIsAlertRuleDisabled((prev) => !prev);
|
||||||
|
handleAlertStateToggle();
|
||||||
|
}}
|
||||||
checked={!isAlertRuleDisabled}
|
checked={!isAlertRuleDisabled}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -2,7 +2,7 @@ import './AlertHeader.styles.scss';
|
|||||||
|
|
||||||
import LineClampedText from 'periscope/components/LineClampedText/LineClampedText';
|
import LineClampedText from 'periscope/components/LineClampedText/LineClampedText';
|
||||||
import { useAlertRule } from 'providers/Alert';
|
import { useAlertRule } from 'providers/Alert';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import AlertActionButtons from './ActionButtons/ActionButtons';
|
import AlertActionButtons from './ActionButtons/ActionButtons';
|
||||||
import AlertLabels from './AlertLabels/AlertLabels';
|
import AlertLabels from './AlertLabels/AlertLabels';
|
||||||
@ -19,7 +19,7 @@ export type AlertHeaderProps = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element {
|
function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element {
|
||||||
const { state, alert, labels, disabled } = alertDetails;
|
const { state, alert, labels } = alertDetails;
|
||||||
|
|
||||||
const labelsWithoutSeverity = useMemo(
|
const labelsWithoutSeverity = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -29,20 +29,14 @@ function AlertHeader({ alertDetails }: AlertHeaderProps): JSX.Element {
|
|||||||
[labels],
|
[labels],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { isAlertRuleDisabled, setIsAlertRuleDisabled } = useAlertRule();
|
const { alertRuleState } = useAlertRule();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isAlertRuleDisabled === undefined) {
|
|
||||||
setIsAlertRuleDisabled(disabled);
|
|
||||||
}
|
|
||||||
}, [disabled, setIsAlertRuleDisabled, isAlertRuleDisabled]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="alert-info">
|
<div className="alert-info">
|
||||||
<div className="alert-info__info-wrapper">
|
<div className="alert-info__info-wrapper">
|
||||||
<div className="top-section">
|
<div className="top-section">
|
||||||
<div className="alert-title-wrapper">
|
<div className="alert-title-wrapper">
|
||||||
<AlertState state={isAlertRuleDisabled ? 'disabled' : state} />
|
<AlertState state={alertRuleState ?? state} />
|
||||||
<div className="alert-title">
|
<div className="alert-title">
|
||||||
<LineClampedText text={alert} />
|
<LineClampedText text={alert} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@ import KeyValueLabel from 'periscope/components/KeyValueLabel';
|
|||||||
import SeeMore from 'periscope/components/SeeMore';
|
import SeeMore from 'periscope/components/SeeMore';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
type AlertLabelsProps = {
|
export type AlertLabelsProps = {
|
||||||
labels: Record<string, any>;
|
labels: Record<string, any>;
|
||||||
initialCount?: number;
|
initialCount?: number;
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@ import AlertHistory from 'container/AlertHistory';
|
|||||||
import { TIMELINE_TABLE_PAGE_SIZE } from 'container/AlertHistory/constants';
|
import { TIMELINE_TABLE_PAGE_SIZE } from 'container/AlertHistory/constants';
|
||||||
import { AlertDetailsTab, TimelineFilter } from 'container/AlertHistory/types';
|
import { AlertDetailsTab, TimelineFilter } from 'container/AlertHistory/types';
|
||||||
import { urlKey } from 'container/AllError/utils';
|
import { urlKey } from 'container/AllError/utils';
|
||||||
|
import { RelativeTimeMap } from 'container/TopNav/DateTimeSelection/config';
|
||||||
import useAxiosError from 'hooks/useAxiosError';
|
import useAxiosError from 'hooks/useAxiosError';
|
||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
@ -31,9 +32,7 @@ import PaginationInfoText from 'periscope/components/PaginationInfoText/Paginati
|
|||||||
import { useAlertRule } from 'providers/Alert';
|
import { useAlertRule } from 'providers/Alert';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import { generatePath, useLocation } from 'react-router-dom';
|
import { generatePath, useLocation } from 'react-router-dom';
|
||||||
import { AppState } from 'store/reducers';
|
|
||||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
import {
|
import {
|
||||||
AlertDef,
|
AlertDef,
|
||||||
@ -44,7 +43,7 @@ import {
|
|||||||
AlertRuleTopContributorsPayload,
|
AlertRuleTopContributorsPayload,
|
||||||
} from 'types/api/alerts/def';
|
} from 'types/api/alerts/def';
|
||||||
import { PayloadProps } from 'types/api/alerts/get';
|
import { PayloadProps } from 'types/api/alerts/get';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { nanoToMilli } from 'utils/timeUtils';
|
import { nanoToMilli } from 'utils/timeUtils';
|
||||||
|
|
||||||
export const useAlertHistoryQueryParams = (): {
|
export const useAlertHistoryQueryParams = (): {
|
||||||
@ -56,11 +55,10 @@ export const useAlertHistoryQueryParams = (): {
|
|||||||
} => {
|
} => {
|
||||||
const params = useUrlQuery();
|
const params = useUrlQuery();
|
||||||
|
|
||||||
const globalTime = useSelector<AppState, GlobalReducer>(
|
|
||||||
(state) => state.globalTime,
|
|
||||||
);
|
|
||||||
const startTime = params.get(QueryParams.startTime);
|
const startTime = params.get(QueryParams.startTime);
|
||||||
const endTime = params.get(QueryParams.endTime);
|
const endTime = params.get(QueryParams.endTime);
|
||||||
|
const relativeTime =
|
||||||
|
params.get(QueryParams.relativeTime) ?? RelativeTimeMap['6hr'];
|
||||||
|
|
||||||
const intStartTime = parseInt(startTime || '0', 10);
|
const intStartTime = parseInt(startTime || '0', 10);
|
||||||
const intEndTime = parseInt(endTime || '0', 10);
|
const intEndTime = parseInt(endTime || '0', 10);
|
||||||
@ -69,8 +67,8 @@ export const useAlertHistoryQueryParams = (): {
|
|||||||
const { maxTime, minTime } = useMemo(() => {
|
const { maxTime, minTime } = useMemo(() => {
|
||||||
if (hasStartAndEndParams)
|
if (hasStartAndEndParams)
|
||||||
return GetMinMax('custom', [intStartTime, intEndTime]);
|
return GetMinMax('custom', [intStartTime, intEndTime]);
|
||||||
return GetMinMax(globalTime.selectedTime);
|
return GetMinMax(relativeTime);
|
||||||
}, [hasStartAndEndParams, intStartTime, intEndTime, globalTime.selectedTime]);
|
}, [hasStartAndEndParams, intStartTime, intEndTime, relativeTime]);
|
||||||
|
|
||||||
const ruleId = params.get(QueryParams.ruleId);
|
const ruleId = params.get(QueryParams.ruleId);
|
||||||
|
|
||||||
@ -164,7 +162,6 @@ export const useGetAlertRuleDetails = (): Props => {
|
|||||||
id: parseInt(ruleId || '', 10),
|
id: parseInt(ruleId || '', 10),
|
||||||
}),
|
}),
|
||||||
enabled: isValidRuleId,
|
enabled: isValidRuleId,
|
||||||
refetchOnMount: false,
|
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -253,7 +250,11 @@ type GetAlertRuleDetailsTimelineTableProps = GetAlertRuleDetailsApiProps & {
|
|||||||
| undefined;
|
| undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetAlertRuleDetailsTimelineTable = (): GetAlertRuleDetailsTimelineTableProps => {
|
export const useGetAlertRuleDetailsTimelineTable = ({
|
||||||
|
filters,
|
||||||
|
}: {
|
||||||
|
filters: TagFilter;
|
||||||
|
}): GetAlertRuleDetailsTimelineTableProps => {
|
||||||
const { ruleId, startTime, endTime, params } = useAlertHistoryQueryParams();
|
const { ruleId, startTime, endTime, params } = useAlertHistoryQueryParams();
|
||||||
const { updatedOrder, offset } = useMemo(
|
const { updatedOrder, offset } = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@ -277,6 +278,7 @@ export const useGetAlertRuleDetailsTimelineTable = (): GetAlertRuleDetailsTimeli
|
|||||||
timelineFilter,
|
timelineFilter,
|
||||||
updatedOrder,
|
updatedOrder,
|
||||||
offset,
|
offset,
|
||||||
|
JSON.stringify(filters.items),
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
@ -287,7 +289,7 @@ export const useGetAlertRuleDetailsTimelineTable = (): GetAlertRuleDetailsTimeli
|
|||||||
limit: TIMELINE_TABLE_PAGE_SIZE,
|
limit: TIMELINE_TABLE_PAGE_SIZE,
|
||||||
order: updatedOrder,
|
order: updatedOrder,
|
||||||
offset,
|
offset,
|
||||||
|
filters,
|
||||||
...(timelineFilter && timelineFilter !== TimelineFilter.ALL
|
...(timelineFilter && timelineFilter !== TimelineFilter.ALL
|
||||||
? {
|
? {
|
||||||
state: timelineFilter === TimelineFilter.FIRED ? 'firing' : 'normal',
|
state: timelineFilter === TimelineFilter.FIRED ? 'firing' : 'normal',
|
||||||
@ -372,9 +374,9 @@ export const useAlertRuleStatusToggle = ({
|
|||||||
}: {
|
}: {
|
||||||
ruleId: string;
|
ruleId: string;
|
||||||
}): {
|
}): {
|
||||||
handleAlertStateToggle: (state: boolean) => void;
|
handleAlertStateToggle: () => void;
|
||||||
} => {
|
} => {
|
||||||
const { isAlertRuleDisabled, setIsAlertRuleDisabled } = useAlertRule();
|
const { alertRuleState, setAlertRuleState } = useAlertRule();
|
||||||
const { notifications } = useNotifications();
|
const { notifications } = useNotifications();
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
@ -384,16 +386,17 @@ export const useAlertRuleStatusToggle = ({
|
|||||||
[REACT_QUERY_KEY.TOGGLE_ALERT_STATE, ruleId],
|
[REACT_QUERY_KEY.TOGGLE_ALERT_STATE, ruleId],
|
||||||
patchAlert,
|
patchAlert,
|
||||||
{
|
{
|
||||||
onMutate: () => {
|
onSuccess: (data) => {
|
||||||
setIsAlertRuleDisabled((prev) => !prev);
|
setAlertRuleState(data?.payload?.state);
|
||||||
},
|
|
||||||
onSuccess: () => {
|
|
||||||
notifications.success({
|
notifications.success({
|
||||||
message: `Alert has been ${isAlertRuleDisabled ? 'enabled' : 'disabled'}.`,
|
message: `Alert has been ${
|
||||||
|
data?.payload?.state === 'disabled' ? 'disabled' : 'enabled'
|
||||||
|
}.`,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
queryClient.refetchQueries([REACT_QUERY_KEY.ALERT_RULE_DETAILS]);
|
queryClient.refetchQueries([REACT_QUERY_KEY.ALERT_RULE_DETAILS, ruleId]);
|
||||||
handleError(error);
|
handleError(error);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -402,7 +405,7 @@ export const useAlertRuleStatusToggle = ({
|
|||||||
const handleAlertStateToggle = (): void => {
|
const handleAlertStateToggle = (): void => {
|
||||||
const args = {
|
const args = {
|
||||||
id: parseInt(ruleId, 10),
|
id: parseInt(ruleId, 10),
|
||||||
data: { disabled: !isAlertRuleDisabled },
|
data: { disabled: alertRuleState !== 'disabled' },
|
||||||
};
|
};
|
||||||
toggleAlertState(args);
|
toggleAlertState(args);
|
||||||
};
|
};
|
||||||
|
@ -10,8 +10,6 @@ import useLicense from 'hooks/useLicense';
|
|||||||
import { useNotifications } from 'hooks/useNotifications';
|
import { useNotifications } from 'hooks/useNotifications';
|
||||||
import {
|
import {
|
||||||
Book,
|
Book,
|
||||||
Cable,
|
|
||||||
Calendar,
|
|
||||||
CreditCard,
|
CreditCard,
|
||||||
Github,
|
Github,
|
||||||
MessageSquare,
|
MessageSquare,
|
||||||
@ -78,22 +76,6 @@ const supportChannels = [
|
|||||||
url: '',
|
url: '',
|
||||||
btnText: 'Launch chat',
|
btnText: 'Launch chat',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'schedule_call',
|
|
||||||
name: 'Schedule a call',
|
|
||||||
icon: <Calendar />,
|
|
||||||
title: 'Schedule a call with the founders.',
|
|
||||||
url: 'https://calendly.com/vishal-signoz/30min',
|
|
||||||
btnText: 'Schedule call',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'slack_connect',
|
|
||||||
name: 'Slack Connect',
|
|
||||||
icon: <Cable />,
|
|
||||||
title: 'Get a dedicated support channel for your team.',
|
|
||||||
url: '',
|
|
||||||
btnText: 'Request Slack connect',
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Support(): JSX.Element {
|
export default function Support(): JSX.Element {
|
||||||
@ -122,20 +104,6 @@ export default function Support(): JSX.Element {
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSlackConnectRequest = (): void => {
|
|
||||||
const recipient = 'support@signoz.io';
|
|
||||||
const subject = 'Slack Connect Request';
|
|
||||||
const body = `I'd like to request a dedicated Slack Connect channel for me and my team. Users (emails) to include besides mine:`;
|
|
||||||
|
|
||||||
// Create the mailto link
|
|
||||||
const mailtoLink = `mailto:${recipient}?subject=${encodeURIComponent(
|
|
||||||
subject,
|
|
||||||
)}&body=${encodeURIComponent(body)}`;
|
|
||||||
|
|
||||||
// Open the default email client
|
|
||||||
window.location.href = mailtoLink;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isPremiumChatSupportEnabled =
|
const isPremiumChatSupportEnabled =
|
||||||
useFeatureFlags(FeatureKeys.PREMIUM_SUPPORT)?.active || false;
|
useFeatureFlags(FeatureKeys.PREMIUM_SUPPORT)?.active || false;
|
||||||
|
|
||||||
@ -214,15 +182,11 @@ export default function Support(): JSX.Element {
|
|||||||
case channelsMap.documentation:
|
case channelsMap.documentation:
|
||||||
case channelsMap.github:
|
case channelsMap.github:
|
||||||
case channelsMap.slack_community:
|
case channelsMap.slack_community:
|
||||||
case channelsMap.schedule_call:
|
|
||||||
handleChannelWithRedirects(channel.url);
|
handleChannelWithRedirects(channel.url);
|
||||||
break;
|
break;
|
||||||
case channelsMap.chat:
|
case channelsMap.chat:
|
||||||
handleChat();
|
handleChat();
|
||||||
break;
|
break;
|
||||||
case channelsMap.slack_connect:
|
|
||||||
handleSlackConnectRequest();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
handleChannelWithRedirects('https://signoz.io/slack');
|
handleChannelWithRedirects('https://signoz.io/slack');
|
||||||
break;
|
break;
|
||||||
|
@ -139,9 +139,7 @@ describe('TraceDetail', () => {
|
|||||||
const slider = await findByTestId('span-details-sider');
|
const slider = await findByTestId('span-details-sider');
|
||||||
expect(slider).toBeInTheDocument();
|
expect(slider).toBeInTheDocument();
|
||||||
|
|
||||||
fireEvent.click(
|
fireEvent.click(slider.querySelector('.expand-collapse-btn') as HTMLElement);
|
||||||
slider.querySelector('.ant-layout-sider-trigger') as HTMLElement,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(queryByText('Details for selected Span')).not.toBeInTheDocument();
|
expect(queryByText('Details for selected Span')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
.trace-explorer-header {
|
.trace-explorer-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.trace-explorer-run-query {
|
.trace-explorer-run-query {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -32,4 +32,5 @@ function CustomerStoryCard({
|
|||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CustomerStoryCard;
|
export default CustomerStoryCard;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
$light-theme: 'lightMode';
|
$light-theme: 'lightMode';
|
||||||
|
$dark-theme: 'darkMode';
|
||||||
|
|
||||||
@keyframes gradientFlow {
|
@keyframes gradientFlow {
|
||||||
0% {
|
0% {
|
||||||
@ -147,6 +148,34 @@ $light-theme: 'lightMode';
|
|||||||
animation: gradientFlow 24s ease infinite;
|
animation: gradientFlow 24s ease infinite;
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__faq-container {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.ant-collapse,
|
||||||
|
.ant-collapse-item,
|
||||||
|
.ant-collapse-content-active {
|
||||||
|
.#{$dark-theme} & {
|
||||||
|
border-color: var(--bg-slate-400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__customer-stories {
|
||||||
|
&__left-container,
|
||||||
|
&__right-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__left-container {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__right-container {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact-us {
|
.contact-us {
|
||||||
|
@ -54,6 +54,25 @@ export default function WorkspaceBlocked(): JSX.Element {
|
|||||||
data: licensesData,
|
data: licensesData,
|
||||||
} = useLicense();
|
} = useLicense();
|
||||||
|
|
||||||
|
useEffect((): void => {
|
||||||
|
logEvent('Workspace Blocked: Screen Viewed', {});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleContactUsClick = (): void => {
|
||||||
|
logEvent('Workspace Blocked: Contact Us Clicked', {});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTabClick = (key: string): void => {
|
||||||
|
logEvent('Workspace Blocked: Screen Tabs Clicked', { tabKey: key });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCollapseChange = (key: string | string[]): void => {
|
||||||
|
const lastKey = Array.isArray(key) ? key.slice(-1)[0] : key;
|
||||||
|
logEvent('Workspace Blocked: Screen Tab FAQ Item Clicked', {
|
||||||
|
panelKey: lastKey,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isFetchingLicenseData) {
|
if (!isFetchingLicenseData) {
|
||||||
const shouldBlockWorkspace = licensesData?.payload?.workSpaceBlock;
|
const shouldBlockWorkspace = licensesData?.payload?.workSpaceBlock;
|
||||||
@ -135,7 +154,7 @@ export default function WorkspaceBlocked(): JSX.Element {
|
|||||||
|
|
||||||
const tabItems: TabsProps['items'] = [
|
const tabItems: TabsProps['items'] = [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: 'whyChooseSignoz',
|
||||||
label: t('whyChooseSignoz'),
|
label: t('whyChooseSignoz'),
|
||||||
children: (
|
children: (
|
||||||
<Row align="middle" justify="center">
|
<Row align="middle" justify="center">
|
||||||
@ -182,13 +201,23 @@ export default function WorkspaceBlocked(): JSX.Element {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '2',
|
key: 'youAreInGoodCompany',
|
||||||
label: t('youAreInGoodCompany'),
|
label: t('youAreInGoodCompany'),
|
||||||
children: (
|
children: (
|
||||||
<Row gutter={[24, 16]} justify="center">
|
<Row gutter={[24, 16]} justify="center">
|
||||||
{/* #FIXME: please suggest if there is any better way to loop in different columns to get the masonry layout */}
|
{/* #FIXME: please suggest if there is any better way to loop in different columns to get the masonry layout */}
|
||||||
<Col span={10}>{renderCustomerStories((index) => index % 2 === 0)}</Col>
|
<Col
|
||||||
<Col span={10}>{renderCustomerStories((index) => index % 2 !== 0)}</Col>
|
span={10}
|
||||||
|
className="workspace-locked__customer-stories__left-container"
|
||||||
|
>
|
||||||
|
{renderCustomerStories((index) => index % 2 === 0)}
|
||||||
|
</Col>
|
||||||
|
<Col
|
||||||
|
span={10}
|
||||||
|
className="workspace-locked__customer-stories__right-container"
|
||||||
|
>
|
||||||
|
{renderCustomerStories((index) => index % 2 !== 0)}
|
||||||
|
</Col>
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<Flex justify="center">
|
<Flex justify="center">
|
||||||
@ -214,13 +243,21 @@ export default function WorkspaceBlocked(): JSX.Element {
|
|||||||
// children: 'Our Pricing',
|
// children: 'Our Pricing',
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
key: '4',
|
key: 'faqs',
|
||||||
label: t('faqs'),
|
label: t('faqs'),
|
||||||
children: (
|
children: (
|
||||||
<Row align="middle" justify="center">
|
<Row align="middle" justify="center">
|
||||||
<Col span={18}>
|
<Col span={12}>
|
||||||
<Space size="large" direction="vertical">
|
<Space
|
||||||
<Collapse items={faqData} defaultActiveKey={['1']} />
|
size="large"
|
||||||
|
direction="vertical"
|
||||||
|
className="workspace-locked__faq-container"
|
||||||
|
>
|
||||||
|
<Collapse
|
||||||
|
items={faqData}
|
||||||
|
defaultActiveKey={['signoz-cloud-vs-community']}
|
||||||
|
onChange={handleCollapseChange}
|
||||||
|
/>
|
||||||
{isAdmin && (
|
{isAdmin && (
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
@ -258,6 +295,7 @@ export default function WorkspaceBlocked(): JSX.Element {
|
|||||||
size="middle"
|
size="middle"
|
||||||
href="mailto:cloud-support@signoz.io"
|
href="mailto:cloud-support@signoz.io"
|
||||||
role="button"
|
role="button"
|
||||||
|
onClick={handleContactUsClick}
|
||||||
>
|
>
|
||||||
Contact Us
|
Contact Us
|
||||||
</Button>
|
</Button>
|
||||||
@ -324,7 +362,7 @@ export default function WorkspaceBlocked(): JSX.Element {
|
|||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
onClick={handleUpdateCreditCard}
|
onClick={handleUpdateCreditCard}
|
||||||
>
|
>
|
||||||
continue my journey
|
Continue my Journey
|
||||||
</Button>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
@ -340,9 +378,13 @@ export default function WorkspaceBlocked(): JSX.Element {
|
|||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Flex justify="center" className="workspace-locked__tabs">
|
<div className="workspace-locked__tabs">
|
||||||
<Tabs items={tabItems} defaultActiveKey="2" />
|
<Tabs
|
||||||
</Flex>
|
items={tabItems}
|
||||||
|
defaultActiveKey="youAreInGoodCompany"
|
||||||
|
onTabClick={handleTabClick}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,7 +42,7 @@ export const enterpriseGradeValuesData = [
|
|||||||
|
|
||||||
export const customerStoriesData = [
|
export const customerStoriesData = [
|
||||||
{
|
{
|
||||||
key: 'c-story-1',
|
key: 'story-subomi-oluwalana',
|
||||||
avatar: 'https://signoz.io/img/users/subomi-oluwalana.webp',
|
avatar: 'https://signoz.io/img/users/subomi-oluwalana.webp',
|
||||||
personName: 'Subomi Oluwalana',
|
personName: 'Subomi Oluwalana',
|
||||||
role: 'Founder & CEO at Convoy',
|
role: 'Founder & CEO at Convoy',
|
||||||
@ -53,7 +53,7 @@ export const customerStoriesData = [
|
|||||||
'https://www.linkedin.com/feed/update/urn:li:activity:7212117589068591105/',
|
'https://www.linkedin.com/feed/update/urn:li:activity:7212117589068591105/',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'c-story-2',
|
key: 'story-dhruv-garg',
|
||||||
avatar: 'https://signoz.io/img/users/dhruv-garg.webp',
|
avatar: 'https://signoz.io/img/users/dhruv-garg.webp',
|
||||||
personName: 'Dhruv Garg',
|
personName: 'Dhruv Garg',
|
||||||
role: 'Tech Lead at Nudge',
|
role: 'Tech Lead at Nudge',
|
||||||
@ -64,7 +64,7 @@ export const customerStoriesData = [
|
|||||||
'https://www.linkedin.com/posts/dhruv-garg79_signoz-docker-kubernetes-activity-7205163679028240384-Otlb/',
|
'https://www.linkedin.com/posts/dhruv-garg79_signoz-docker-kubernetes-activity-7205163679028240384-Otlb/',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'c-story-3',
|
key: 'story-vivek-bhakta',
|
||||||
avatar: 'https://signoz.io/img/users/vivek-bhakta.webp',
|
avatar: 'https://signoz.io/img/users/vivek-bhakta.webp',
|
||||||
personName: 'Vivek Bhakta',
|
personName: 'Vivek Bhakta',
|
||||||
role: 'CTO at Wombo AI',
|
role: 'CTO at Wombo AI',
|
||||||
@ -74,7 +74,7 @@ export const customerStoriesData = [
|
|||||||
link: 'https://x.com/notorious_VB/status/1701773119696904242',
|
link: 'https://x.com/notorious_VB/status/1701773119696904242',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'c-story-4',
|
key: 'story-pranay-narang',
|
||||||
avatar: 'https://signoz.io/img/users/pranay-narang.webp',
|
avatar: 'https://signoz.io/img/users/pranay-narang.webp',
|
||||||
personName: 'Pranay Narang',
|
personName: 'Pranay Narang',
|
||||||
role: 'Engineering at Azodha',
|
role: 'Engineering at Azodha',
|
||||||
@ -84,7 +84,7 @@ export const customerStoriesData = [
|
|||||||
link: 'https://x.com/PranayNarang/status/1676247073396752387',
|
link: 'https://x.com/PranayNarang/status/1676247073396752387',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'c-story-4',
|
key: 'story-Sheheryar-Sewani',
|
||||||
avatar: 'https://signoz.io/img/users/shey.webp',
|
avatar: 'https://signoz.io/img/users/shey.webp',
|
||||||
personName: 'Sheheryar Sewani',
|
personName: 'Sheheryar Sewani',
|
||||||
role: 'Seasoned Rails Dev & Founder',
|
role: 'Seasoned Rails Dev & Founder',
|
||||||
@ -95,7 +95,7 @@ export const customerStoriesData = [
|
|||||||
'https://www.linkedin.com/feed/update/urn:li:activity:7181011853915926528/',
|
'https://www.linkedin.com/feed/update/urn:li:activity:7181011853915926528/',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'c-story-5',
|
key: 'story-daniel-schell',
|
||||||
avatar: 'https://signoz.io/img/users/daniel.webp',
|
avatar: 'https://signoz.io/img/users/daniel.webp',
|
||||||
personName: 'Daniel Schell',
|
personName: 'Daniel Schell',
|
||||||
role: 'Founder & CTO at Airlockdigital',
|
role: 'Founder & CTO at Airlockdigital',
|
||||||
@ -115,7 +115,7 @@ export const customerStoriesData = [
|
|||||||
link: 'https://x.com/gofrendiasgard/status/1680139003658641408',
|
link: 'https://x.com/gofrendiasgard/status/1680139003658641408',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'c-story-7',
|
key: 'story-anselm-eickhoff',
|
||||||
avatar: 'https://signoz.io/img/users/anselm.jpg',
|
avatar: 'https://signoz.io/img/users/anselm.jpg',
|
||||||
personName: 'Anselm Eickhoff',
|
personName: 'Anselm Eickhoff',
|
||||||
role: 'Software Architect',
|
role: 'Software Architect',
|
||||||
@ -129,26 +129,26 @@ export const customerStoriesData = [
|
|||||||
|
|
||||||
export const faqData = [
|
export const faqData = [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: 'signoz-cloud-vs-community',
|
||||||
label:
|
label:
|
||||||
'What is the difference between SigNoz Cloud(Teams) and Community Edition?',
|
'What is the difference between SigNoz Cloud(Teams) and Community Edition?',
|
||||||
children:
|
children:
|
||||||
'You can self-host and manage the community edition yourself. You should choose SigNoz Cloud if you don’t want to worry about managing the SigNoz cluster. There are some exclusive features like SSO & SAML support, which come with SigNoz cloud offering. Our team also offers support on the initial configuration of dashboards & alerts and advises on best practices for setting up your observability stack in the SigNoz cloud offering.',
|
'You can self-host and manage the community edition yourself. You should choose SigNoz Cloud if you don’t want to worry about managing the SigNoz cluster. There are some exclusive features like SSO & SAML support, which come with SigNoz cloud offering. Our team also offers support on the initial configuration of dashboards & alerts and advises on best practices for setting up your observability stack in the SigNoz cloud offering.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '2',
|
key: 'calc-for-metrics',
|
||||||
label: 'How are number of samples calculated for metrics pricing?',
|
label: 'How are number of samples calculated for metrics pricing?',
|
||||||
children:
|
children:
|
||||||
"If a timeseries sends data every 30s, then it will generate 2 samples per min. So, if you have 10,000 time series sending data every 30s then you will be sending 20,000 samples per min to SigNoz. This will be around 864 mn samples per month and would cost 86.4 USD/month. Here's an explainer video on how metrics pricing is calculated - Link: https://vimeo.com/973012522",
|
"If a timeseries sends data every 30s, then it will generate 2 samples per min. So, if you have 10,000 time series sending data every 30s then you will be sending 20,000 samples per min to SigNoz. This will be around 864 mn samples per month and would cost 86.4 USD/month. Here's an explainer video on how metrics pricing is calculated - Link: https://vimeo.com/973012522",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '3',
|
key: 'enterprise-support-plans',
|
||||||
label: 'Do you offer enterprise support plans?',
|
label: 'Do you offer enterprise support plans?',
|
||||||
children:
|
children:
|
||||||
'Yes, feel free to reach out to us on hello@signoz.io if you need a dedicated support plan or paid support for setting up your initial SigNoz setup.',
|
'Yes, feel free to reach out to us on hello@signoz.io if you need a dedicated support plan or paid support for setting up your initial SigNoz setup.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '4',
|
key: 'who-should-use-enterprise-plans',
|
||||||
label: 'Who should use Enterprise plans?',
|
label: 'Who should use Enterprise plans?',
|
||||||
children:
|
children:
|
||||||
'Teams which need enterprise support or features like SSO, Audit logs, etc. may find our enterprise plans valuable.',
|
'Teams which need enterprise support or features like SSO, Audit logs, etc. may find our enterprise plans valuable.',
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import './LineClampedText.styles.scss';
|
import './LineClampedText.styles.scss';
|
||||||
|
|
||||||
import { Tooltip } from 'antd';
|
import { Tooltip, TooltipProps } from 'antd';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
function LineClampedText({
|
function LineClampedText({
|
||||||
text,
|
text,
|
||||||
lines,
|
lines,
|
||||||
|
tooltipProps,
|
||||||
}: {
|
}: {
|
||||||
text: string;
|
text: string;
|
||||||
lines?: number;
|
lines?: number;
|
||||||
|
tooltipProps?: TooltipProps;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [isOverflowing, setIsOverflowing] = useState(false);
|
const [isOverflowing, setIsOverflowing] = useState(false);
|
||||||
const textRef = useRef<HTMLDivElement>(null);
|
const textRef = useRef<HTMLDivElement>(null);
|
||||||
@ -42,11 +44,22 @@ function LineClampedText({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return isOverflowing ? <Tooltip title={text}>{content}</Tooltip> : content;
|
return isOverflowing ? (
|
||||||
|
<Tooltip
|
||||||
|
title={text}
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
{...tooltipProps}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
content
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
LineClampedText.defaultProps = {
|
LineClampedText.defaultProps = {
|
||||||
lines: 1,
|
lines: 1,
|
||||||
|
tooltipProps: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LineClampedText;
|
export default LineClampedText;
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import React, { createContext, useContext, useState } from 'react';
|
import React, { createContext, useContext, useState } from 'react';
|
||||||
|
|
||||||
interface AlertRuleContextType {
|
interface AlertRuleContextType {
|
||||||
isAlertRuleDisabled: boolean | undefined;
|
alertRuleState: string | undefined;
|
||||||
setIsAlertRuleDisabled: React.Dispatch<
|
setAlertRuleState: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||||
React.SetStateAction<boolean | undefined>
|
|
||||||
>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const AlertRuleContext = createContext<AlertRuleContextType | undefined>(
|
const AlertRuleContext = createContext<AlertRuleContextType | undefined>(
|
||||||
@ -16,13 +14,16 @@ function AlertRuleProvider({
|
|||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const [isAlertRuleDisabled, setIsAlertRuleDisabled] = useState<
|
const [alertRuleState, setAlertRuleState] = useState<string | undefined>(
|
||||||
boolean | undefined
|
undefined,
|
||||||
>(undefined);
|
);
|
||||||
|
|
||||||
const value = React.useMemo(
|
const value = React.useMemo(
|
||||||
() => ({ isAlertRuleDisabled, setIsAlertRuleDisabled }),
|
() => ({
|
||||||
[isAlertRuleDisabled],
|
alertRuleState,
|
||||||
|
setAlertRuleState,
|
||||||
|
}),
|
||||||
|
[alertRuleState],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export * from './sideBarCollapse';
|
|
@ -1,16 +0,0 @@
|
|||||||
import setLocalStorageKey from 'api/browser/localstorage/set';
|
|
||||||
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
|
||||||
import { Dispatch } from 'redux';
|
|
||||||
import AppActions from 'types/actions';
|
|
||||||
|
|
||||||
export const sideBarCollapse = (
|
|
||||||
collapseState: boolean,
|
|
||||||
): ((dispatch: Dispatch<AppActions>) => void) => {
|
|
||||||
setLocalStorageKey(IS_SIDEBAR_COLLAPSED, `${collapseState}`);
|
|
||||||
return (dispatch: Dispatch<AppActions>): void => {
|
|
||||||
dispatch({
|
|
||||||
type: 'SIDEBAR_COLLAPSE',
|
|
||||||
payload: collapseState,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,4 +1,3 @@
|
|||||||
export * from './app';
|
|
||||||
export * from './global';
|
export * from './global';
|
||||||
export * from './metrics';
|
export * from './metrics';
|
||||||
export * from './serviceMap';
|
export * from './serviceMap';
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import getLocalStorageKey from 'api/browser/localstorage/get';
|
import getLocalStorageKey from 'api/browser/localstorage/get';
|
||||||
import { IS_SIDEBAR_COLLAPSED } from 'constants/app';
|
|
||||||
import { LOCALSTORAGE } from 'constants/localStorage';
|
import { LOCALSTORAGE } from 'constants/localStorage';
|
||||||
import { getInitialUserTokenRefreshToken } from 'store/utils';
|
import { getInitialUserTokenRefreshToken } from 'store/utils';
|
||||||
import {
|
import {
|
||||||
AppAction,
|
AppAction,
|
||||||
LOGGED_IN,
|
LOGGED_IN,
|
||||||
SIDEBAR_COLLAPSE,
|
|
||||||
UPDATE_CONFIGS,
|
UPDATE_CONFIGS,
|
||||||
UPDATE_CURRENT_ERROR,
|
UPDATE_CURRENT_ERROR,
|
||||||
UPDATE_CURRENT_VERSION,
|
UPDATE_CURRENT_VERSION,
|
||||||
@ -44,7 +42,6 @@ const getInitialUser = (): User | null => {
|
|||||||
|
|
||||||
const InitialValue: InitialValueTypes = {
|
const InitialValue: InitialValueTypes = {
|
||||||
isLoggedIn: getLocalStorageKey(LOCALSTORAGE.IS_LOGGED_IN) === 'true',
|
isLoggedIn: getLocalStorageKey(LOCALSTORAGE.IS_LOGGED_IN) === 'true',
|
||||||
isSideBarCollapsed: getLocalStorageKey(IS_SIDEBAR_COLLAPSED) === 'true',
|
|
||||||
currentVersion: '',
|
currentVersion: '',
|
||||||
latestVersion: '',
|
latestVersion: '',
|
||||||
featureResponse: {
|
featureResponse: {
|
||||||
@ -76,13 +73,6 @@ const appReducer = (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case SIDEBAR_COLLAPSE: {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isSideBarCollapsed: action.payload,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
case UPDATE_FEATURE_FLAG_RESPONSE: {
|
case UPDATE_FEATURE_FLAG_RESPONSE: {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -34,11 +34,6 @@ export interface LoggedInUser {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SideBarCollapse {
|
|
||||||
type: typeof SIDEBAR_COLLAPSE;
|
|
||||||
payload: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UpdateAppVersion {
|
export interface UpdateAppVersion {
|
||||||
type: typeof UPDATE_CURRENT_VERSION;
|
type: typeof UPDATE_CURRENT_VERSION;
|
||||||
payload: {
|
payload: {
|
||||||
@ -137,7 +132,6 @@ export interface UpdateFeatureFlag {
|
|||||||
|
|
||||||
export type AppAction =
|
export type AppAction =
|
||||||
| LoggedInUser
|
| LoggedInUser
|
||||||
| SideBarCollapse
|
|
||||||
| UpdateAppVersion
|
| UpdateAppVersion
|
||||||
| UpdateLatestVersion
|
| UpdateLatestVersion
|
||||||
| UpdateVersionError
|
| UpdateVersionError
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { AlertLabelsProps } from 'pages/AlertDetails/AlertHeader/AlertLabels/AlertLabels';
|
||||||
import { ICompositeMetricQuery } from 'types/api/alerts/compositeQuery';
|
import { ICompositeMetricQuery } from 'types/api/alerts/compositeQuery';
|
||||||
|
|
||||||
// default match type for threshold
|
// default match type for threshold
|
||||||
@ -37,6 +38,8 @@ export interface RuleCondition {
|
|||||||
selectedQueryName?: string;
|
selectedQueryName?: string;
|
||||||
alertOnAbsent?: boolean | undefined;
|
alertOnAbsent?: boolean | undefined;
|
||||||
absentFor?: number | undefined;
|
absentFor?: number | undefined;
|
||||||
|
requireMinPoints?: boolean | undefined;
|
||||||
|
requiredNumPoints?: number | undefined;
|
||||||
}
|
}
|
||||||
export interface Labels {
|
export interface Labels {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
@ -94,7 +97,11 @@ export interface AlertRuleTimelineTableResponse {
|
|||||||
relatedLogsLink: string;
|
relatedLogsLink: string;
|
||||||
}
|
}
|
||||||
export type AlertRuleTimelineTableResponsePayload = {
|
export type AlertRuleTimelineTableResponsePayload = {
|
||||||
data: { items: AlertRuleTimelineTableResponse[]; total: number };
|
data: {
|
||||||
|
items: AlertRuleTimelineTableResponse[];
|
||||||
|
total: number;
|
||||||
|
labels: AlertLabelsProps['labels'];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
type AlertState = 'firing' | 'normal' | 'no-data' | 'muted';
|
type AlertState = 'firing' | 'normal' | 'no-data' | 'muted';
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ export interface User {
|
|||||||
|
|
||||||
export default interface AppReducer {
|
export default interface AppReducer {
|
||||||
isLoggedIn: boolean;
|
isLoggedIn: boolean;
|
||||||
isSideBarCollapsed: boolean;
|
|
||||||
currentVersion: string;
|
currentVersion: string;
|
||||||
latestVersion: string;
|
latestVersion: string;
|
||||||
isCurrentVersionError: boolean;
|
isCurrentVersionError: boolean;
|
||||||
|
@ -1,38 +1,34 @@
|
|||||||
{
|
{
|
||||||
"cookies": [],
|
"cookies": [],
|
||||||
"origins": [
|
"origins": [
|
||||||
{
|
{
|
||||||
"origin": "http://localhost:3301",
|
"origin": "http://localhost:3301",
|
||||||
"localStorage": [
|
"localStorage": [
|
||||||
{
|
{
|
||||||
"name": "isSideBarCollapsed",
|
"name": "metricsTimeDurations",
|
||||||
"value": "false"
|
"value": "{}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "metricsTimeDurations",
|
"name": "i18nextLng",
|
||||||
"value": "{}"
|
"value": "en-US"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "i18nextLng",
|
"name": "reactQueryDevtoolsSortFn",
|
||||||
"value": "en-US"
|
"value": "\"Status > Last Updated\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "reactQueryDevtoolsSortFn",
|
"name": "AUTH_TOKEN",
|
||||||
"value": "\"Status > Last Updated\""
|
"value": "authtoken"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "AUTH_TOKEN",
|
"name": "IS_LOGGED_IN",
|
||||||
"value": "authtoken"
|
"value": "true"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IS_LOGGED_IN",
|
"name": "REFRESH_AUTH_TOKEN",
|
||||||
"value": "true"
|
"value": "refreshJwt"
|
||||||
},
|
}
|
||||||
{
|
]
|
||||||
"name": "REFRESH_AUTH_TOKEN",
|
}
|
||||||
"value": "refreshJwt"
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
80
go.mod
80
go.mod
@ -1,12 +1,14 @@
|
|||||||
module go.signoz.io/signoz
|
module go.signoz.io/signoz
|
||||||
|
|
||||||
go 1.21.3
|
go 1.22.0
|
||||||
|
|
||||||
|
toolchain go1.22.7
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ClickHouse/clickhouse-go/v2 v2.23.2
|
github.com/ClickHouse/clickhouse-go/v2 v2.25.0
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.2
|
github.com/DATA-DOG/go-sqlmock v1.5.2
|
||||||
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd
|
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd
|
||||||
github.com/SigNoz/signoz-otel-collector v0.102.10
|
github.com/SigNoz/signoz-otel-collector v0.102.12
|
||||||
github.com/SigNoz/zap_otlp/zap_otlp_encoder v0.0.0-20230822164844-1b861a431974
|
github.com/SigNoz/zap_otlp/zap_otlp_encoder v0.0.0-20230822164844-1b861a431974
|
||||||
github.com/SigNoz/zap_otlp/zap_otlp_sync v0.0.0-20230822164844-1b861a431974
|
github.com/SigNoz/zap_otlp/zap_otlp_sync v0.0.0-20230822164844-1b861a431974
|
||||||
github.com/antonmedv/expr v1.15.3
|
github.com/antonmedv/expr v1.15.3
|
||||||
@ -37,7 +39,7 @@ require (
|
|||||||
github.com/opentracing/opentracing-go v1.2.0
|
github.com/opentracing/opentracing-go v1.2.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/prometheus/common v0.55.0
|
github.com/prometheus/common v0.59.1
|
||||||
github.com/prometheus/prometheus v2.5.0+incompatible
|
github.com/prometheus/prometheus v2.5.0+incompatible
|
||||||
github.com/rs/cors v1.11.0
|
github.com/rs/cors v1.11.0
|
||||||
github.com/russellhaering/gosaml2 v0.9.0
|
github.com/russellhaering/gosaml2 v0.9.0
|
||||||
@ -57,41 +59,44 @@ require (
|
|||||||
go.opentelemetry.io/collector/exporter v0.103.0
|
go.opentelemetry.io/collector/exporter v0.103.0
|
||||||
go.opentelemetry.io/collector/extension v0.103.0
|
go.opentelemetry.io/collector/extension v0.103.0
|
||||||
go.opentelemetry.io/collector/otelcol v0.103.0
|
go.opentelemetry.io/collector/otelcol v0.103.0
|
||||||
go.opentelemetry.io/collector/pdata v1.10.0
|
go.opentelemetry.io/collector/pdata v1.14.1
|
||||||
go.opentelemetry.io/collector/processor v0.103.0
|
go.opentelemetry.io/collector/processor v0.103.0
|
||||||
go.opentelemetry.io/collector/receiver v0.103.0
|
go.opentelemetry.io/collector/receiver v0.103.0
|
||||||
go.opentelemetry.io/collector/service v0.103.0
|
go.opentelemetry.io/collector/service v0.103.0
|
||||||
go.opentelemetry.io/contrib/bridges/otelzap v0.0.0-20240820072021-3fab5f5f20fb
|
go.opentelemetry.io/contrib/bridges/otelzap v0.0.0-20240820072021-3fab5f5f20fb
|
||||||
go.opentelemetry.io/contrib/config v0.8.0
|
go.opentelemetry.io/contrib/config v0.8.0
|
||||||
go.opentelemetry.io/otel v1.28.0
|
go.opentelemetry.io/otel v1.29.0
|
||||||
go.opentelemetry.io/otel/log v0.4.0
|
go.opentelemetry.io/otel/log v0.4.0
|
||||||
go.opentelemetry.io/otel/metric v1.28.0
|
go.opentelemetry.io/otel/metric v1.29.0
|
||||||
go.opentelemetry.io/otel/sdk v1.28.0
|
go.opentelemetry.io/otel/sdk v1.29.0
|
||||||
go.opentelemetry.io/otel/trace v1.28.0
|
go.opentelemetry.io/otel/trace v1.29.0
|
||||||
go.uber.org/multierr v1.11.0
|
go.uber.org/multierr v1.11.0
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
golang.org/x/crypto v0.24.0
|
golang.org/x/crypto v0.26.0
|
||||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
|
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
|
||||||
golang.org/x/net v0.26.0
|
golang.org/x/net v0.28.0
|
||||||
golang.org/x/oauth2 v0.21.0
|
golang.org/x/oauth2 v0.23.0
|
||||||
golang.org/x/text v0.16.0
|
golang.org/x/text v0.18.0
|
||||||
google.golang.org/grpc v1.65.0
|
google.golang.org/grpc v1.66.0
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
gopkg.in/segmentio/analytics-go.v3 v3.1.0
|
gopkg.in/segmentio/analytics-go.v3 v3.1.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
k8s.io/apimachinery v0.29.3
|
k8s.io/apimachinery v0.31.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 // indirect
|
cloud.google.com/go/auth v0.9.3 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 // indirect
|
cloud.google.com/go/compute/metadata v0.5.0 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect
|
||||||
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
|
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
|
||||||
github.com/ClickHouse/ch-go v0.61.5 // indirect
|
github.com/ClickHouse/ch-go v0.61.5 // indirect
|
||||||
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect
|
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect
|
||||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||||
github.com/aws/aws-sdk-go v1.53.16 // indirect
|
github.com/aws/aws-sdk-go v1.55.5 // indirect
|
||||||
github.com/beevik/etree v1.1.0 // indirect
|
github.com/beevik/etree v1.1.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
|
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
|
||||||
@ -117,10 +122,12 @@ require (
|
|||||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/s2a-go v0.1.8 // indirect
|
||||||
|
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||||
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
||||||
github.com/gosimple/unidecode v1.0.0 // indirect
|
github.com/gosimple/unidecode v1.0.0 // indirect
|
||||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
|
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
|
||||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
@ -128,7 +135,7 @@ require (
|
|||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/jpillora/backoff v1.0.0 // indirect
|
github.com/jpillora/backoff v1.0.0 // indirect
|
||||||
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||||
github.com/klauspost/compress v1.17.8 // indirect
|
github.com/klauspost/compress v1.17.9 // indirect
|
||||||
github.com/klauspost/cpuid v1.2.3 // indirect
|
github.com/klauspost/cpuid v1.2.3 // indirect
|
||||||
github.com/knadh/koanf/v2 v2.1.1 // indirect
|
github.com/knadh/koanf/v2 v2.1.1 // indirect
|
||||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||||
@ -153,7 +160,7 @@ require (
|
|||||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
|
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
|
||||||
github.com/prometheus/client_golang v1.19.1 // indirect
|
github.com/prometheus/client_golang v1.20.4 // indirect
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common/sigv4 v0.1.0 // indirect
|
github.com/prometheus/common/sigv4 v0.1.0 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
@ -181,16 +188,16 @@ require (
|
|||||||
go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.103.0 // indirect
|
go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.103.0 // indirect
|
||||||
go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.103.0 // indirect
|
go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.103.0 // indirect
|
||||||
go.opentelemetry.io/collector/featuregate v1.13.0 // indirect
|
go.opentelemetry.io/collector/featuregate v1.13.0 // indirect
|
||||||
go.opentelemetry.io/collector/semconv v0.103.0 // indirect
|
go.opentelemetry.io/collector/semconv v0.108.1 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||||
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 // indirect
|
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 // indirect
|
||||||
go.opentelemetry.io/otel/bridge/opencensus v1.27.0 // indirect
|
go.opentelemetry.io/otel/bridge/opencensus v1.27.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.50.0 // indirect
|
go.opentelemetry.io/otel/exporters/prometheus v0.50.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect
|
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect
|
||||||
@ -198,15 +205,16 @@ require (
|
|||||||
go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect
|
go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||||
go.uber.org/atomic v1.11.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
golang.org/x/sys v0.21.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.6.0 // indirect
|
||||||
gonum.org/v1/gonum v0.15.0 // indirect
|
gonum.org/v1/gonum v0.15.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
|
google.golang.org/api v0.195.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
k8s.io/client-go v0.29.3 // indirect
|
k8s.io/client-go v0.31.0 // indirect
|
||||||
k8s.io/klog/v2 v2.120.1 // indirect
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.11.1
|
replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.12.0
|
||||||
|
238
go.sum
238
go.sum
@ -13,12 +13,18 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
|
|||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||||
|
cloud.google.com/go/auth v0.9.3 h1:VOEUIAADkkLtyfr3BLa3R8Ed/j6w1jTBmARx+wb5w5U=
|
||||||
|
cloud.google.com/go/auth v0.9.3/go.mod h1:7z6VY+7h3KUdRov5F1i8NDP5ZzWKYmEPO842BgCsmTk=
|
||||||
|
cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
|
||||||
|
cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||||
|
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
|
||||||
|
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||||
@ -34,12 +40,12 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
|
|||||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
|
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
|
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo=
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg=
|
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4=
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I=
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA=
|
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA=
|
||||||
@ -50,8 +56,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
|||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4=
|
github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4=
|
||||||
github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
|
github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
|
||||||
github.com/ClickHouse/clickhouse-go/v2 v2.23.2 h1:+DAKPMnxLS7pduQZsrJc8OhdLS2L9MfDEJ2TS+hpYDM=
|
github.com/ClickHouse/clickhouse-go/v2 v2.25.0 h1:rKscwqgQHzWBTZySZDcHKxgs0Ad+xFULfZvo26W5UlY=
|
||||||
github.com/ClickHouse/clickhouse-go/v2 v2.23.2/go.mod h1:aNap51J1OM3yxQJRgM+AlP/MPkGBCL8A74uQThoQhR0=
|
github.com/ClickHouse/clickhouse-go/v2 v2.25.0/go.mod h1:iDTViXk2Fgvf1jn2dbJd1ys+fBkdD1UMRnXlwmhijhQ=
|
||||||
github.com/Code-Hex/go-generics-cache v1.5.1 h1:6vhZGc5M7Y/YD8cIUcY8kcuQLB4cHR7U+0KMqAA0KcU=
|
github.com/Code-Hex/go-generics-cache v1.5.1 h1:6vhZGc5M7Y/YD8cIUcY8kcuQLB4cHR7U+0KMqAA0KcU=
|
||||||
github.com/Code-Hex/go-generics-cache v1.5.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4=
|
github.com/Code-Hex/go-generics-cache v1.5.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||||
@ -62,10 +68,10 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE
|
|||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd h1:Bk43AsDYe0fhkbj57eGXx8H3ZJ4zhmQXBnrW523ktj8=
|
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd h1:Bk43AsDYe0fhkbj57eGXx8H3ZJ4zhmQXBnrW523ktj8=
|
||||||
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd/go.mod h1:nxRcH/OEdM8QxzH37xkGzomr1O0JpYBRS6pwjsWW6Pc=
|
github.com/SigNoz/govaluate v0.0.0-20240203125216-988004ccc7fd/go.mod h1:nxRcH/OEdM8QxzH37xkGzomr1O0JpYBRS6pwjsWW6Pc=
|
||||||
github.com/SigNoz/prometheus v1.11.1 h1:roM8ugYf4UxaeKKujEeBvoX7ybq3IrS+TB26KiRtIJg=
|
github.com/SigNoz/prometheus v1.12.0 h1:+BXeIHyMOOWWa+xjhJ+x80JFva7r1WzWIfIhQ5PUmIE=
|
||||||
github.com/SigNoz/prometheus v1.11.1/go.mod h1:uv4mQwZQtx7y4GQ6EdHOi8Wsk07uHNn2XHd1zM85m6I=
|
github.com/SigNoz/prometheus v1.12.0/go.mod h1:EqNM27OwmPfqMUk+E+XG1L9rfDFcyXnzzDrg0EPOfxA=
|
||||||
github.com/SigNoz/signoz-otel-collector v0.102.10 h1:1zjU31OcRZL6fS0IIag8LA8bdhP4S28dzovDwuOg7Lg=
|
github.com/SigNoz/signoz-otel-collector v0.102.12 h1:5yY0IBtNz6SHMzKzwHmKfIx99Ij8mr72nDI2Xi08pDQ=
|
||||||
github.com/SigNoz/signoz-otel-collector v0.102.10/go.mod h1:APoBVD4aRu9vIny1vdzZSi2wPY3elyjHA/I/rh1hKfs=
|
github.com/SigNoz/signoz-otel-collector v0.102.12/go.mod h1:tcNyU+NSn7ZkzZcLa+k+dJIPOPV+CjHn3+z1SICAfdA=
|
||||||
github.com/SigNoz/zap_otlp v0.1.0 h1:T7rRcFN87GavY8lDGZj0Z3Xv6OhJA6Pj3I9dNPmqvRc=
|
github.com/SigNoz/zap_otlp v0.1.0 h1:T7rRcFN87GavY8lDGZj0Z3Xv6OhJA6Pj3I9dNPmqvRc=
|
||||||
github.com/SigNoz/zap_otlp v0.1.0/go.mod h1:lcHvbDbRgvDnPxo9lDlaL1JK2PyOyouP/C3ynnYIvyo=
|
github.com/SigNoz/zap_otlp v0.1.0/go.mod h1:lcHvbDbRgvDnPxo9lDlaL1JK2PyOyouP/C3ynnYIvyo=
|
||||||
github.com/SigNoz/zap_otlp/zap_otlp_encoder v0.0.0-20230822164844-1b861a431974 h1:PKVgdf83Yw+lZJbFtNGBgqXiXNf3+kOXW2qZ7Ms7OaY=
|
github.com/SigNoz/zap_otlp/zap_otlp_encoder v0.0.0-20230822164844-1b861a431974 h1:PKVgdf83Yw+lZJbFtNGBgqXiXNf3+kOXW2qZ7Ms7OaY=
|
||||||
@ -77,8 +83,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||||
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs=
|
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg=
|
||||||
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
|
||||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
@ -93,8 +99,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI
|
|||||||
github.com/auth0/go-jwt-middleware v1.0.1 h1:/fsQ4vRr4zod1wKReUH+0A3ySRjGiT9G34kypO/EKwI=
|
github.com/auth0/go-jwt-middleware v1.0.1 h1:/fsQ4vRr4zod1wKReUH+0A3ySRjGiT9G34kypO/EKwI=
|
||||||
github.com/auth0/go-jwt-middleware v1.0.1/go.mod h1:YSeUX3z6+TF2H+7padiEqNJ73Zy9vXW72U//IgN0BIM=
|
github.com/auth0/go-jwt-middleware v1.0.1/go.mod h1:YSeUX3z6+TF2H+7padiEqNJ73Zy9vXW72U//IgN0BIM=
|
||||||
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||||
github.com/aws/aws-sdk-go v1.53.16 h1:8oZjKQO/ml1WLUZw5hvF7pvYjPf8o9f57Wldoy/q9Qc=
|
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
|
||||||
github.com/aws/aws-sdk-go v1.53.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
|
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
|
||||||
github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw=
|
github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw=
|
||||||
github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ=
|
github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ=
|
||||||
@ -147,12 +153,12 @@ github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
|
|||||||
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
|
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/digitalocean/godo v1.117.0 h1:WVlTe09melDYTd7VCVyvHcNWbgB+uI1O115+5LOtdSw=
|
github.com/digitalocean/godo v1.122.0 h1:ziytLQi8QKtDp2K1A+YrYl2dWLHLh2uaMzWvcz9HkKg=
|
||||||
github.com/digitalocean/godo v1.117.0/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo=
|
github.com/digitalocean/godo v1.122.0/go.mod h1:WQVH83OHUy6gC4gXpEVQKtxTd4L5oCp+5OialidkPLY=
|
||||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||||
github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo=
|
github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4=
|
||||||
github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
@ -168,11 +174,11 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
|||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI=
|
github.com/envoyproxy/go-control-plane v0.13.0 h1:HzkeUz1Knt+3bK+8LG1bxOO/jzWZmdxpwC51i202les=
|
||||||
github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0=
|
github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
|
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
|
||||||
github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI=
|
github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI=
|
||||||
github.com/expr-lang/expr v1.16.9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
github.com/expr-lang/expr v1.16.9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
|
||||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM=
|
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM=
|
||||||
@ -192,6 +198,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
|||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
|
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||||
|
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-co-op/gocron v1.30.1 h1:tjWUvJl5KrcwpkEkSXFSQFr4F9h5SfV/m4+RX0cV2fs=
|
github.com/go-co-op/gocron v1.30.1 h1:tjWUvJl5KrcwpkEkSXFSQFr4F9h5SfV/m4+RX0cV2fs=
|
||||||
github.com/go-co-op/gocron v1.30.1/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y=
|
github.com/go-co-op/gocron v1.30.1/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y=
|
||||||
@ -242,8 +250,8 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78
|
|||||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc=
|
github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc=
|
||||||
github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
|
github.com/go-zookeeper/zk v1.0.4 h1:DPzxraQx7OrPyXq2phlGlNSIyWEsAox0RJmjTseMV6I=
|
||||||
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
github.com/go-zookeeper/zk v1.0.4/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
@ -322,13 +330,17 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
|
|||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
|
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
|
||||||
|
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
|
||||||
|
github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/gophercloud/gophercloud v1.12.0 h1:Jrz16vPAL93l80q16fp8NplrTCp93y7rZh2P3Q4Yq7g=
|
github.com/gophercloud/gophercloud v1.14.0 h1:Bt9zQDhPrbd4qX7EILGmy+i7GP35cc+AAL2+wIJpUE8=
|
||||||
github.com/gophercloud/gophercloud v1.12.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
|
github.com/gophercloud/gophercloud v1.14.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||||
@ -348,11 +360,11 @@ github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrR
|
|||||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
|
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||||
github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
|
github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
|
||||||
github.com/hashicorp/consul/api v1.29.1 h1:UEwOjYJrd3lG1x5w7HxDRMGiAUPrb3f103EoeKuuEcc=
|
github.com/hashicorp/consul/api v1.29.4 h1:P6slzxDLBOxUSj3fWo2o65VuKtbtOXFi7TSSgtXutuE=
|
||||||
github.com/hashicorp/consul/api v1.29.1/go.mod h1:lumfRkY/coLuqMICkI7Fh3ylMG31mQSRZyef2c5YvJI=
|
github.com/hashicorp/consul/api v1.29.4/go.mod h1:HUlfw+l2Zy68ceJavv2zAyArl2fqhGWnMycyt56sBgg=
|
||||||
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
|
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
|
||||||
github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A=
|
github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A=
|
||||||
github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=
|
github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=
|
||||||
@ -400,8 +412,8 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
|
|||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
|
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
|
||||||
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||||
github.com/hashicorp/nomad/api v0.0.0-20240604134157-e73d8bb1140d h1:KHq+mAzWSkumj4PDoXc5VZbycPGcmYu8tohgVLQ6SIc=
|
github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3 h1:fgVfQ4AC1avVOnu2cfms8VAiD8lUq3vWI8mTocOXN/w=
|
||||||
github.com/hashicorp/nomad/api v0.0.0-20240604134157-e73d8bb1140d/go.mod h1:svtxn6QnrQ69P23VvIWMR34tg3vmwLz4UdUzm1dSCgE=
|
github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3/go.mod h1:svtxn6QnrQ69P23VvIWMR34tg3vmwLz4UdUzm1dSCgE=
|
||||||
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||||
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
|
||||||
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
||||||
@ -409,8 +421,8 @@ github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoI
|
|||||||
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
|
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
|
||||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||||
github.com/hetznercloud/hcloud-go/v2 v2.9.0 h1:s0N6R7Zoi2DPfMtUF5o9VeUBzTtHVY6MIkHOQnfu/AY=
|
github.com/hetznercloud/hcloud-go/v2 v2.13.1 h1:jq0GP4QaYE5d8xR/Zw17s9qoaESRJMXfGmtD1a/qckQ=
|
||||||
github.com/hetznercloud/hcloud-go/v2 v2.9.0/go.mod h1:qtW/TuU7Bs16ibXl/ktJarWqU2LwHr7eGlwoilHxtgg=
|
github.com/hetznercloud/hcloud-go/v2 v2.13.1/go.mod h1:dhix40Br3fDiBhwaSG/zgaYOFFddpfBm/6R1Zz0IiF0=
|
||||||
github.com/hjson/hjson-go/v4 v4.0.0 h1:wlm6IYYqHjOdXH1gHev4VoXCaW20HdQAGCxdOEEg2cs=
|
github.com/hjson/hjson-go/v4 v4.0.0 h1:wlm6IYYqHjOdXH1gHev4VoXCaW20HdQAGCxdOEEg2cs=
|
||||||
github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E=
|
github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
@ -420,8 +432,8 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
|||||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/ionos-cloud/sdk-go/v6 v6.1.11 h1:J/uRN4UWO3wCyGOeDdMKv8LWRzKu6UIkLEaes38Kzh8=
|
github.com/ionos-cloud/sdk-go/v6 v6.2.1 h1:mxxN+frNVmbFrmmFfXnBC3g2USYJrl6mc1LW2iNYbFY=
|
||||||
github.com/ionos-cloud/sdk-go/v6 v6.1.11/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k=
|
github.com/ionos-cloud/sdk-go/v6 v6.2.1/go.mod h1:SXrO9OGyWjd2rZhAhEpdYN6VUAODzzqRdqA9BCviQtI=
|
||||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||||
@ -452,8 +464,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
|||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
||||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
github.com/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs=
|
github.com/klauspost/cpuid v1.2.3 h1:CCtW0xUnWGVINKvE/WWOYKdsPV6mawAtvQuSl8guwQs=
|
||||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs=
|
github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs=
|
||||||
@ -484,8 +496,8 @@ github.com/leodido/ragel-machinery v0.0.0-20190525184631-5f46317e436b/go.mod h1:
|
|||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/linode/linodego v1.35.0 h1:rIhUeCHBLEDlkoRnOTwzSGzljQ3ksXwLxacmXnrV+Do=
|
github.com/linode/linodego v1.40.0 h1:7ESY0PwK94hoggoCtIroT1Xk6b1flrFBNZ6KwqbTqlI=
|
||||||
github.com/linode/linodego v1.35.0/go.mod h1:JxuhOEAMfSxun6RU5/MgTKH2GGTmFrhKRj3wL1NFin0=
|
github.com/linode/linodego v1.40.0/go.mod h1:NsUw4l8QrLdIofRg1NYFBbW5ZERnmbZykVBszPZLORM=
|
||||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
|
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
|
||||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
@ -510,8 +522,8 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW
|
|||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||||
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
|
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||||
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
|
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||||
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
|
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
|
||||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||||
github.com/minio/minio-go/v6 v6.0.57 h1:ixPkbKkyD7IhnluRgQpGSpHdpvNVaW6OD5R9IAO/9Tw=
|
github.com/minio/minio-go/v6 v6.0.57 h1:ixPkbKkyD7IhnluRgQpGSpHdpvNVaW6OD5R9IAO/9Tw=
|
||||||
@ -571,9 +583,8 @@ github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3
|
|||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||||
|
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||||
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
|
|
||||||
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
|
||||||
github.com/open-telemetry/opamp-go v0.5.0 h1:2YFbb6G4qBkq3yTRdVb5Nfz9hKHW/ldUyex352e1J7g=
|
github.com/open-telemetry/opamp-go v0.5.0 h1:2YFbb6G4qBkq3yTRdVb5Nfz9hKHW/ldUyex352e1J7g=
|
||||||
github.com/open-telemetry/opamp-go v0.5.0/go.mod h1:IMdeuHGVc5CjKSu5/oNV0o+UmiXuahoHvoZ4GOmAI9M=
|
github.com/open-telemetry/opamp-go v0.5.0/go.mod h1:IMdeuHGVc5CjKSu5/oNV0o+UmiXuahoHvoZ4GOmAI9M=
|
||||||
github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.102.0 h1:7QHxeMnKzMXMw9oh5lnOHakfPpGSglxiZfbYUn6l6yc=
|
github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.102.0 h1:7QHxeMnKzMXMw9oh5lnOHakfPpGSglxiZfbYUn6l6yc=
|
||||||
@ -596,8 +607,8 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ
|
|||||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||||
github.com/ovh/go-ovh v1.5.1 h1:P8O+7H+NQuFK9P/j4sFW5C0fvSS2DnHYGPwdVCp45wI=
|
github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI=
|
||||||
github.com/ovh/go-ovh v1.5.1/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
github.com/ovh/go-ovh v1.6.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
@ -618,6 +629,8 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||||
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
@ -630,8 +643,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
|
|||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||||
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
|
||||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
@ -642,8 +655,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
|
|||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||||
github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=
|
||||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0=
|
||||||
github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
|
github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4=
|
||||||
github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI=
|
github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
@ -674,8 +687,8 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo
|
|||||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||||
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||||
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.27 h1:yGAraK1uUjlhSXgNMIy8o/J4LFNcy7yeipBqt9N9mVg=
|
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30 h1:yoKAVkEVwAqbGbR8n87rHQ1dulL25rKloGadb3vm770=
|
||||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.27/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
|
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30/go.mod h1:sH0u6fq6x4R5M7WxkoQFY/o7UaiItec0o1LinLCJNq8=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
|
||||||
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
|
||||||
@ -732,6 +745,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
@ -747,6 +761,8 @@ github.com/vjeantet/grok v1.0.1 h1:2rhIR7J4gThTgcZ1m2JY4TrJZNgjn985U28kT2wQrJ4=
|
|||||||
github.com/vjeantet/grok v1.0.1/go.mod h1:ax1aAchzC6/QMXMcyzHQGZWaW1l195+uMYIkCWPCNIo=
|
github.com/vjeantet/grok v1.0.1/go.mod h1:ax1aAchzC6/QMXMcyzHQGZWaW1l195+uMYIkCWPCNIo=
|
||||||
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
|
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
|
||||||
github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
|
github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
|
||||||
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||||
@ -819,30 +835,30 @@ go.opentelemetry.io/collector/featuregate v1.13.0 h1:rc84eCf5hesXQ8/bP6Zc15wqthb
|
|||||||
go.opentelemetry.io/collector/featuregate v1.13.0/go.mod h1:PsOINaGgTiFc+Tzu2K/X2jP+Ngmlp7YKGV1XrnBkH7U=
|
go.opentelemetry.io/collector/featuregate v1.13.0/go.mod h1:PsOINaGgTiFc+Tzu2K/X2jP+Ngmlp7YKGV1XrnBkH7U=
|
||||||
go.opentelemetry.io/collector/otelcol v0.103.0 h1:Skqnc2mxDdk3eiYioUuG7ST6ur5k83SOv7mIBt60fBw=
|
go.opentelemetry.io/collector/otelcol v0.103.0 h1:Skqnc2mxDdk3eiYioUuG7ST6ur5k83SOv7mIBt60fBw=
|
||||||
go.opentelemetry.io/collector/otelcol v0.103.0/go.mod h1:iJF3ghCv+nRZI6+hI7z3kGRZrgH///Fd9tNXY82X90g=
|
go.opentelemetry.io/collector/otelcol v0.103.0/go.mod h1:iJF3ghCv+nRZI6+hI7z3kGRZrgH///Fd9tNXY82X90g=
|
||||||
go.opentelemetry.io/collector/pdata v1.10.0 h1:oLyPLGvPTQrcRT64ZVruwvmH/u3SHTfNo01pteS4WOE=
|
go.opentelemetry.io/collector/pdata v1.14.1 h1:wXZjtQA7Vy5HFqco+yA95ENyMQU5heBB1IxMHQf6mUk=
|
||||||
go.opentelemetry.io/collector/pdata v1.10.0/go.mod h1:IHxHsp+Jq/xfjORQMDJjSH6jvedOSTOyu3nbxqhWSYE=
|
go.opentelemetry.io/collector/pdata v1.14.1/go.mod h1:z1dTjwwtcoXxZx2/nkHysjxMeaxe9pEmYTEr4SMNIx8=
|
||||||
go.opentelemetry.io/collector/pdata/testdata v0.103.0 h1:iI6NOE0L2je/bxlWzAWHQ/yCtnGupgv42Hl9Al1q/g4=
|
go.opentelemetry.io/collector/pdata/testdata v0.103.0 h1:iI6NOE0L2je/bxlWzAWHQ/yCtnGupgv42Hl9Al1q/g4=
|
||||||
go.opentelemetry.io/collector/pdata/testdata v0.103.0/go.mod h1:tLzRhb/h37/9wFRQVr+CxjKi5qmhSRpCAiOlhwRkeEk=
|
go.opentelemetry.io/collector/pdata/testdata v0.103.0/go.mod h1:tLzRhb/h37/9wFRQVr+CxjKi5qmhSRpCAiOlhwRkeEk=
|
||||||
go.opentelemetry.io/collector/processor v0.103.0 h1:YZ+LRuHKtOam7SCeLkJAP6bS1d6XxeYP22OyMN3VP0s=
|
go.opentelemetry.io/collector/processor v0.103.0 h1:YZ+LRuHKtOam7SCeLkJAP6bS1d6XxeYP22OyMN3VP0s=
|
||||||
go.opentelemetry.io/collector/processor v0.103.0/go.mod h1:/mxyh0NpJgpZycm7iHDpM7i5PdtWvKKdCZf0cyADJfU=
|
go.opentelemetry.io/collector/processor v0.103.0/go.mod h1:/mxyh0NpJgpZycm7iHDpM7i5PdtWvKKdCZf0cyADJfU=
|
||||||
go.opentelemetry.io/collector/receiver v0.103.0 h1:V3JBKkX+7e/NYpDDZVyeu2VQB1/lLFuoJFPfupdCcZs=
|
go.opentelemetry.io/collector/receiver v0.103.0 h1:V3JBKkX+7e/NYpDDZVyeu2VQB1/lLFuoJFPfupdCcZs=
|
||||||
go.opentelemetry.io/collector/receiver v0.103.0/go.mod h1:Yybv4ynKFdMOYViWWPMmjkugR89FSQN0P37wP6mX6qM=
|
go.opentelemetry.io/collector/receiver v0.103.0/go.mod h1:Yybv4ynKFdMOYViWWPMmjkugR89FSQN0P37wP6mX6qM=
|
||||||
go.opentelemetry.io/collector/semconv v0.103.0 h1:5tlVoZlo9USHAU2Bz4YrEste0Vm5AMufXkYJhAVve1Q=
|
go.opentelemetry.io/collector/semconv v0.108.1 h1:Txk9tauUnamZaxS5vlf1O0uZ4VD6nioRBR0nX8L/fU4=
|
||||||
go.opentelemetry.io/collector/semconv v0.103.0/go.mod h1:yMVUCNoQPZVq/IPfrHrnntZTWsLf5YGZ7qwKulIl5hw=
|
go.opentelemetry.io/collector/semconv v0.108.1/go.mod h1:zCJ5njhWpejR+A40kiEoeFm1xq1uzyZwMnRNX6/D82A=
|
||||||
go.opentelemetry.io/collector/service v0.103.0 h1:e4Eri4jo+YOuEK0+/JE9SUdT/NZaJ2jz/ROJlmLn96s=
|
go.opentelemetry.io/collector/service v0.103.0 h1:e4Eri4jo+YOuEK0+/JE9SUdT/NZaJ2jz/ROJlmLn96s=
|
||||||
go.opentelemetry.io/collector/service v0.103.0/go.mod h1:p1mlniiC1MuPN5FANYJYgf5V5CGFP0hNqWfI8t7Aw8M=
|
go.opentelemetry.io/collector/service v0.103.0/go.mod h1:p1mlniiC1MuPN5FANYJYgf5V5CGFP0hNqWfI8t7Aw8M=
|
||||||
go.opentelemetry.io/contrib/bridges/otelzap v0.0.0-20240820072021-3fab5f5f20fb h1:ZqncifxU0B1q64FRbhKxsJugRsrEToakmYUsgQ5tGbY=
|
go.opentelemetry.io/contrib/bridges/otelzap v0.0.0-20240820072021-3fab5f5f20fb h1:ZqncifxU0B1q64FRbhKxsJugRsrEToakmYUsgQ5tGbY=
|
||||||
go.opentelemetry.io/contrib/bridges/otelzap v0.0.0-20240820072021-3fab5f5f20fb/go.mod h1:mzv0k5dTnSUE5/ZerXUwGiNKzcPJTakuCh6Wm1emNvU=
|
go.opentelemetry.io/contrib/bridges/otelzap v0.0.0-20240820072021-3fab5f5f20fb/go.mod h1:mzv0k5dTnSUE5/ZerXUwGiNKzcPJTakuCh6Wm1emNvU=
|
||||||
go.opentelemetry.io/contrib/config v0.8.0 h1:OD7aDMhL+2EpzdSHfkDmcdD/uUA+PgKM5faFyF9XFT0=
|
go.opentelemetry.io/contrib/config v0.8.0 h1:OD7aDMhL+2EpzdSHfkDmcdD/uUA+PgKM5faFyF9XFT0=
|
||||||
go.opentelemetry.io/contrib/config v0.8.0/go.mod h1:dGeVZWE//3wrxYHHP0iCBYJU1QmOmPcbV+FNB7pjDYI=
|
go.opentelemetry.io/contrib/config v0.8.0/go.mod h1:dGeVZWE//3wrxYHHP0iCBYJU1QmOmPcbV+FNB7pjDYI=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
|
||||||
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 h1:IjgxbomVrV9za6bRi8fWCNXENs0co37SZedQilP2hm0=
|
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 h1:IjgxbomVrV9za6bRi8fWCNXENs0co37SZedQilP2hm0=
|
||||||
go.opentelemetry.io/contrib/propagators/b3 v1.27.0/go.mod h1:Dv9obQz25lCisDvvs4dy28UPh974CxkahRDUPsY7y9E=
|
go.opentelemetry.io/contrib/propagators/b3 v1.27.0/go.mod h1:Dv9obQz25lCisDvvs4dy28UPh974CxkahRDUPsY7y9E=
|
||||||
go.opentelemetry.io/contrib/zpages v0.52.0 h1:MPgkMy0Cp3O5EdfVXP0ss3ujhEibysTM4eszx7E7d+E=
|
go.opentelemetry.io/contrib/zpages v0.52.0 h1:MPgkMy0Cp3O5EdfVXP0ss3ujhEibysTM4eszx7E7d+E=
|
||||||
go.opentelemetry.io/contrib/zpages v0.52.0/go.mod h1:fqG5AFdoYru3A3DnhibVuaaEfQV2WKxE7fYE1jgDRwk=
|
go.opentelemetry.io/contrib/zpages v0.52.0/go.mod h1:fqG5AFdoYru3A3DnhibVuaaEfQV2WKxE7fYE1jgDRwk=
|
||||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
|
||||||
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
|
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
|
||||||
go.opentelemetry.io/otel/bridge/opencensus v1.27.0 h1:ao9aGGHd+G4YfjBpGs6vbkvt5hoC67STlJA9fCnOAcs=
|
go.opentelemetry.io/otel/bridge/opencensus v1.27.0 h1:ao9aGGHd+G4YfjBpGs6vbkvt5hoC67STlJA9fCnOAcs=
|
||||||
go.opentelemetry.io/otel/bridge/opencensus v1.27.0/go.mod h1:uRvWtAAXzyVOST0WMPX5JHGBaAvBws+2F8PcC5gMnTk=
|
go.opentelemetry.io/otel/bridge/opencensus v1.27.0/go.mod h1:uRvWtAAXzyVOST0WMPX5JHGBaAvBws+2F8PcC5gMnTk=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 h1:zBPZAISA9NOc5cE8zydqDiS0itvg/P/0Hn9m72a5gvM=
|
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 h1:zBPZAISA9NOc5cE8zydqDiS0itvg/P/0Hn9m72a5gvM=
|
||||||
@ -851,12 +867,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2g
|
|||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 h1:aLmmtjRke7LPDQ3lvpFz+kNEH43faFhzW7v8BFIEydg=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 h1:aLmmtjRke7LPDQ3lvpFz+kNEH43faFhzW7v8BFIEydg=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0/go.mod h1:TC1pyCt6G9Sjb4bQpShH+P5R53pO6ZuGnHuuln9xMeE=
|
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0/go.mod h1:TC1pyCt6G9Sjb4bQpShH+P5R53pO6ZuGnHuuln9xMeE=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc=
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng=
|
go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng=
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY=
|
go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE=
|
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE=
|
||||||
@ -865,16 +881,16 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bE
|
|||||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y=
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y=
|
||||||
go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o=
|
go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o=
|
||||||
go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I=
|
go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I=
|
||||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
|
||||||
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
|
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
|
||||||
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
|
go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
|
||||||
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
|
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
|
||||||
go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA=
|
go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA=
|
||||||
go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo=
|
go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
|
go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
|
go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg=
|
||||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
|
||||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
|
||||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
@ -898,8 +914,8 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3
|
|||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@ -934,8 +950,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
|||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -977,16 +993,16 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy
|
|||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -998,8 +1014,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -1063,11 +1079,11 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
||||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -1077,13 +1093,13 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
@ -1130,8 +1146,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@ -1154,6 +1170,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
|
|||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||||
|
google.golang.org/api v0.195.0 h1:Ude4N8FvTKnnQJHU48RFI40jOBgIrL8Zqr3/QeST6yU=
|
||||||
|
google.golang.org/api v0.195.0/go.mod h1:DOGRWuv3P8TU8Lnz7uQc4hyNqrBpMtD9ppW3wBJurgc=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
@ -1192,10 +1210,10 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
|
|||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
@ -1213,8 +1231,8 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
|
|||||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
|
||||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@ -1269,18 +1287,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw=
|
k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo=
|
||||||
k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
|
k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE=
|
||||||
k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU=
|
k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc=
|
||||||
k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU=
|
k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||||
k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg=
|
k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8=
|
||||||
k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0=
|
k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU=
|
||||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
||||||
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak=
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||||
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
@ -13,7 +13,7 @@ https://github.com/SigNoz/signoz/blob/main/CONTRIBUTING.md#to-run-clickhouse-set
|
|||||||
- Change the alertmanager section in `signoz/deploy/docker/clickhouse-setup/docker-compose.yaml` as follows:
|
- Change the alertmanager section in `signoz/deploy/docker/clickhouse-setup/docker-compose.yaml` as follows:
|
||||||
```console
|
```console
|
||||||
alertmanager:
|
alertmanager:
|
||||||
image: signoz/alertmanager:0.23.5
|
image: signoz/alertmanager:0.23.7
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/alertmanager:/data
|
- ./data/alertmanager:/data
|
||||||
expose:
|
expose:
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/SigNoz/signoz-otel-collector/exporter/clickhouselogsexporter/logsv2"
|
||||||
"go.signoz.io/signoz/pkg/query-service/model"
|
"go.signoz.io/signoz/pkg/query-service/model"
|
||||||
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
|
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@ -36,26 +37,7 @@ func (r *ClickHouseReader) GetQBFilterSuggestionsForLogs(
|
|||||||
suggestions.AttributeKeys = attribKeysResp.AttributeKeys
|
suggestions.AttributeKeys = attribKeysResp.AttributeKeys
|
||||||
|
|
||||||
// Rank suggested attributes
|
// Rank suggested attributes
|
||||||
slices.SortFunc(suggestions.AttributeKeys, func(a v3.AttributeKey, b v3.AttributeKey) int {
|
attribRanker.sort(suggestions.AttributeKeys)
|
||||||
|
|
||||||
// Higher score => higher rank
|
|
||||||
attribKeyScore := func(a v3.AttributeKey) int {
|
|
||||||
|
|
||||||
// Scoring criteria is expected to get more sophisticated in follow up changes
|
|
||||||
if a.Type == v3.AttributeKeyTypeResource {
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.Type == v3.AttributeKeyTypeTag {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// To sort in descending order of score the return value must be negative when a > b
|
|
||||||
return attribKeyScore(b) - attribKeyScore(a)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Put together suggested example queries.
|
// Put together suggested example queries.
|
||||||
|
|
||||||
@ -268,3 +250,59 @@ func (r *ClickHouseReader) getValuesForLogAttributes(
|
|||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var attribRanker = newRankingStrategy()
|
||||||
|
|
||||||
|
func newRankingStrategy() attribRankingStrategy {
|
||||||
|
// Some special resource attributes should get ranked above all others.
|
||||||
|
interestingResourceAttrsInDescRank := []string{
|
||||||
|
"service", "service.name", "env", "k8s.namespace.name",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Synonyms of interesting attributes should come next
|
||||||
|
resourceHierarchy := logsv2.ResourceHierarchy()
|
||||||
|
for _, attr := range []string{
|
||||||
|
"service.name",
|
||||||
|
"deployment.environment",
|
||||||
|
"k8s.namespace.name",
|
||||||
|
"k8s.pod.name",
|
||||||
|
"k8s.container.name",
|
||||||
|
"k8s.node.name",
|
||||||
|
} {
|
||||||
|
interestingResourceAttrsInDescRank = append(
|
||||||
|
interestingResourceAttrsInDescRank, resourceHierarchy.Synonyms(attr)...,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
interestingResourceAttrsInAscRank := interestingResourceAttrsInDescRank[:]
|
||||||
|
slices.Reverse(interestingResourceAttrsInAscRank)
|
||||||
|
|
||||||
|
return attribRankingStrategy{
|
||||||
|
interestingResourceAttrsInAscRank: interestingResourceAttrsInAscRank,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type attribRankingStrategy struct {
|
||||||
|
interestingResourceAttrsInAscRank []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// The higher the score, the higher the rank
|
||||||
|
func (s *attribRankingStrategy) score(attrib v3.AttributeKey) int {
|
||||||
|
if attrib.Type == v3.AttributeKeyTypeResource {
|
||||||
|
// 3 + (-1) if attrib.Key is not an interesting resource attribute
|
||||||
|
return 3 + slices.Index(s.interestingResourceAttrsInAscRank, attrib.Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
if attrib.Type == v3.AttributeKeyTypeTag {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *attribRankingStrategy) sort(attribKeys []v3.AttributeKey) {
|
||||||
|
slices.SortFunc(attribKeys, func(a v3.AttributeKey, b v3.AttributeKey) int {
|
||||||
|
// To sort in descending order of score the return value must be negative when a > b
|
||||||
|
return s.score(b) - s.score(a)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -53,21 +53,31 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
primaryNamespace = "clickhouse"
|
primaryNamespace = "clickhouse"
|
||||||
archiveNamespace = "clickhouse-archive"
|
archiveNamespace = "clickhouse-archive"
|
||||||
signozTraceDBName = "signoz_traces"
|
signozTraceDBName = "signoz_traces"
|
||||||
signozHistoryDBName = "signoz_analytics"
|
signozHistoryDBName = "signoz_analytics"
|
||||||
ruleStateHistoryTableName = "distributed_rule_state_history_v0"
|
ruleStateHistoryTableName = "distributed_rule_state_history_v0"
|
||||||
signozDurationMVTable = "distributed_durationSort"
|
signozDurationMVTable = "distributed_durationSort"
|
||||||
signozUsageExplorerTable = "distributed_usage_explorer"
|
signozUsageExplorerTable = "distributed_usage_explorer"
|
||||||
signozSpansTable = "distributed_signoz_spans"
|
signozSpansTable = "distributed_signoz_spans"
|
||||||
signozErrorIndexTable = "distributed_signoz_error_index_v2"
|
signozErrorIndexTable = "distributed_signoz_error_index_v2"
|
||||||
signozTraceTableName = "distributed_signoz_index_v2"
|
signozTraceTableName = "distributed_signoz_index_v2"
|
||||||
signozTraceLocalTableName = "signoz_index_v2"
|
signozTraceLocalTableName = "signoz_index_v2"
|
||||||
signozMetricDBName = "signoz_metrics"
|
signozMetricDBName = "signoz_metrics"
|
||||||
|
|
||||||
signozSampleLocalTableName = "samples_v4"
|
signozSampleLocalTableName = "samples_v4"
|
||||||
signozSampleTableName = "distributed_samples_v4"
|
signozSampleTableName = "distributed_samples_v4"
|
||||||
|
|
||||||
|
signozSamplesAgg5mLocalTableName = "samples_v4_agg_5m"
|
||||||
|
signozSamplesAgg5mTableName = "distributed_samples_v4_agg_5m"
|
||||||
|
|
||||||
|
signozSamplesAgg30mLocalTableName = "samples_v4_agg_30m"
|
||||||
|
signozSamplesAgg30mTableName = "distributed_samples_v4_agg_30m"
|
||||||
|
|
||||||
|
signozExpHistLocalTableName = "exp_hist"
|
||||||
|
signozExpHistTableName = "distributed_exp_hist"
|
||||||
|
|
||||||
signozTSLocalTableNameV4 = "time_series_v4"
|
signozTSLocalTableNameV4 = "time_series_v4"
|
||||||
signozTSTableNameV4 = "distributed_time_series_v4"
|
signozTSTableNameV4 = "distributed_time_series_v4"
|
||||||
|
|
||||||
@ -77,6 +87,9 @@ const (
|
|||||||
signozTSLocalTableNameV41Day = "time_series_v4_1day"
|
signozTSLocalTableNameV41Day = "time_series_v4_1day"
|
||||||
signozTSTableNameV41Day = "distributed_time_series_v4_1day"
|
signozTSTableNameV41Day = "distributed_time_series_v4_1day"
|
||||||
|
|
||||||
|
signozTSLocalTableNameV41Week = "time_series_v4_1week"
|
||||||
|
signozTSTableNameV41Week = "distributed_time_series_v4_1week"
|
||||||
|
|
||||||
minTimespanForProgressiveSearch = time.Hour
|
minTimespanForProgressiveSearch = time.Hour
|
||||||
minTimespanForProgressiveSearchMargin = time.Minute
|
minTimespanForProgressiveSearchMargin = time.Minute
|
||||||
maxProgressiveSteps = 4
|
maxProgressiveSteps = 4
|
||||||
@ -267,6 +280,7 @@ func (r *ClickHouseReader) Start(readerReady chan bool) {
|
|||||||
"",
|
"",
|
||||||
time.Duration(1*time.Minute),
|
time.Duration(1*time.Minute),
|
||||||
nil,
|
nil,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
cfg := struct {
|
cfg := struct {
|
||||||
@ -2115,8 +2129,15 @@ func (r *ClickHouseReader) SetTTL(ctx context.Context,
|
|||||||
|
|
||||||
switch params.Type {
|
switch params.Type {
|
||||||
case constants.TraceTTL:
|
case constants.TraceTTL:
|
||||||
tableNameArray := []string{signozTraceDBName + "." + signozTraceTableName, signozTraceDBName + "." + signozDurationMVTable, signozTraceDBName + "." + signozSpansTable, signozTraceDBName + "." + signozErrorIndexTable, signozTraceDBName + "." + signozUsageExplorerTable, signozTraceDBName + "." + defaultDependencyGraphTable}
|
tableNames := []string{
|
||||||
for _, tableName := range tableNameArray {
|
signozTraceDBName + "." + signozTraceTableName,
|
||||||
|
signozTraceDBName + "." + signozDurationMVTable,
|
||||||
|
signozTraceDBName + "." + signozSpansTable,
|
||||||
|
signozTraceDBName + "." + signozErrorIndexTable,
|
||||||
|
signozTraceDBName + "." + signozUsageExplorerTable,
|
||||||
|
signozTraceDBName + "." + defaultDependencyGraphTable,
|
||||||
|
}
|
||||||
|
for _, tableName := range tableNames {
|
||||||
tableName := getLocalTableName(tableName)
|
tableName := getLocalTableName(tableName)
|
||||||
statusItem, err := r.checkTTLStatusItem(ctx, tableName)
|
statusItem, err := r.checkTTLStatusItem(ctx, tableName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2126,7 +2147,7 @@ func (r *ClickHouseReader) SetTTL(ctx context.Context,
|
|||||||
return nil, &model.ApiError{Typ: model.ErrorConflict, Err: fmt.Errorf("TTL is already running")}
|
return nil, &model.ApiError{Typ: model.ErrorConflict, Err: fmt.Errorf("TTL is already running")}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, tableName := range tableNameArray {
|
for _, tableName := range tableNames {
|
||||||
tableName := getLocalTableName(tableName)
|
tableName := getLocalTableName(tableName)
|
||||||
// TODO: DB queries should be implemented with transactional statements but currently clickhouse doesn't support them. Issue: https://github.com/ClickHouse/ClickHouse/issues/22086
|
// TODO: DB queries should be implemented with transactional statements but currently clickhouse doesn't support them. Issue: https://github.com/ClickHouse/ClickHouse/issues/22086
|
||||||
go func(tableName string) {
|
go func(tableName string) {
|
||||||
@ -2155,7 +2176,7 @@ func (r *ClickHouseReader) SetTTL(ctx context.Context,
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req += " SETTINGS distributed_ddl_task_timeout = -1;"
|
req += " SETTINGS materialize_ttl_after_modify=0;"
|
||||||
zap.L().Error("Executing TTL request: ", zap.String("request", req))
|
zap.L().Error("Executing TTL request: ", zap.String("request", req))
|
||||||
statusItem, _ := r.checkTTLStatusItem(ctx, tableName)
|
statusItem, _ := r.checkTTLStatusItem(ctx, tableName)
|
||||||
if err := r.db.Exec(context.Background(), req); err != nil {
|
if err := r.db.Exec(context.Background(), req); err != nil {
|
||||||
@ -2176,7 +2197,16 @@ func (r *ClickHouseReader) SetTTL(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case constants.MetricsTTL:
|
case constants.MetricsTTL:
|
||||||
tableNames := []string{signozMetricDBName + "." + signozSampleLocalTableName, signozMetricDBName + "." + signozTSLocalTableNameV4, signozMetricDBName + "." + signozTSLocalTableNameV46Hrs, signozMetricDBName + "." + signozTSLocalTableNameV41Day}
|
tableNames := []string{
|
||||||
|
signozMetricDBName + "." + signozSampleLocalTableName,
|
||||||
|
signozMetricDBName + "." + signozSamplesAgg5mLocalTableName,
|
||||||
|
signozMetricDBName + "." + signozSamplesAgg30mLocalTableName,
|
||||||
|
signozMetricDBName + "." + signozExpHistLocalTableName,
|
||||||
|
signozMetricDBName + "." + signozTSLocalTableNameV4,
|
||||||
|
signozMetricDBName + "." + signozTSLocalTableNameV46Hrs,
|
||||||
|
signozMetricDBName + "." + signozTSLocalTableNameV41Day,
|
||||||
|
signozMetricDBName + "." + signozTSLocalTableNameV41Week,
|
||||||
|
}
|
||||||
for _, tableName := range tableNames {
|
for _, tableName := range tableNames {
|
||||||
statusItem, err := r.checkTTLStatusItem(ctx, tableName)
|
statusItem, err := r.checkTTLStatusItem(ctx, tableName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2193,7 +2223,7 @@ func (r *ClickHouseReader) SetTTL(ctx context.Context,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
timeColumn := "timestamp_ms"
|
timeColumn := "timestamp_ms"
|
||||||
if strings.Contains(tableName, "v4") {
|
if strings.Contains(tableName, "v4") || strings.Contains(tableName, "exp_hist") {
|
||||||
timeColumn = "unix_milli"
|
timeColumn = "unix_milli"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2218,7 +2248,7 @@ func (r *ClickHouseReader) SetTTL(ctx context.Context,
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req += " SETTINGS distributed_ddl_task_timeout = -1"
|
req += " SETTINGS materialize_ttl_after_modify=0"
|
||||||
zap.L().Info("Executing TTL request: ", zap.String("request", req))
|
zap.L().Info("Executing TTL request: ", zap.String("request", req))
|
||||||
statusItem, _ := r.checkTTLStatusItem(ctx, tableName)
|
statusItem, _ := r.checkTTLStatusItem(ctx, tableName)
|
||||||
if err := r.db.Exec(ctx, req); err != nil {
|
if err := r.db.Exec(ctx, req); err != nil {
|
||||||
@ -2279,7 +2309,7 @@ func (r *ClickHouseReader) SetTTL(ctx context.Context,
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req += " SETTINGS distributed_ddl_task_timeout = -1"
|
req += " SETTINGS materialize_ttl_after_modify=0"
|
||||||
zap.L().Info("Executing TTL request: ", zap.String("request", req))
|
zap.L().Info("Executing TTL request: ", zap.String("request", req))
|
||||||
statusItem, _ := r.checkTTLStatusItem(ctx, tableName)
|
statusItem, _ := r.checkTTLStatusItem(ctx, tableName)
|
||||||
if err := r.db.Exec(ctx, req); err != nil {
|
if err := r.db.Exec(ctx, req); err != nil {
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"slices"
|
"slices"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -2463,12 +2464,19 @@ func (aH *APIHandler) WriteJSON(w http.ResponseWriter, r *http.Request, response
|
|||||||
|
|
||||||
// RegisterMessagingQueuesRoutes adds messaging-queues routes
|
// RegisterMessagingQueuesRoutes adds messaging-queues routes
|
||||||
func (aH *APIHandler) RegisterMessagingQueuesRoutes(router *mux.Router, am *AuthMiddleware) {
|
func (aH *APIHandler) RegisterMessagingQueuesRoutes(router *mux.Router, am *AuthMiddleware) {
|
||||||
// SubRouter for kafka
|
|
||||||
kafkaSubRouter := router.PathPrefix("/api/v1/messaging-queues/kafka/consumer-lag").Subrouter()
|
|
||||||
|
|
||||||
kafkaSubRouter.HandleFunc("/producer-details", am.ViewAccess(aH.getProducerData)).Methods(http.MethodPost)
|
// SubRouter for kafka
|
||||||
kafkaSubRouter.HandleFunc("/consumer-details", am.ViewAccess(aH.getConsumerData)).Methods(http.MethodPost)
|
kafkaRouter := router.PathPrefix("/api/v1/messaging-queues/kafka").Subrouter()
|
||||||
kafkaSubRouter.HandleFunc("/network-latency", am.ViewAccess(aH.getNetworkData)).Methods(http.MethodPost)
|
|
||||||
|
consumerLagRouter := kafkaRouter.PathPrefix("/consumer-lag").Subrouter()
|
||||||
|
consumerLagRouter.HandleFunc("/producer-details", am.ViewAccess(aH.getProducerData)).Methods(http.MethodPost)
|
||||||
|
consumerLagRouter.HandleFunc("/consumer-details", am.ViewAccess(aH.getConsumerData)).Methods(http.MethodPost)
|
||||||
|
consumerLagRouter.HandleFunc("/network-latency", am.ViewAccess(aH.getNetworkData)).Methods(http.MethodPost)
|
||||||
|
|
||||||
|
onboardingRouter := kafkaRouter.PathPrefix("/onboarding").Subrouter()
|
||||||
|
onboardingRouter.HandleFunc("/producers", am.ViewAccess(aH.onboardProducers)).Methods(http.MethodPost)
|
||||||
|
onboardingRouter.HandleFunc("/consumers", am.ViewAccess(aH.onboardConsumers)).Methods(http.MethodPost)
|
||||||
|
onboardingRouter.HandleFunc("/kafka", am.ViewAccess(aH.onboardKafka)).Methods(http.MethodPost)
|
||||||
|
|
||||||
// for other messaging queues, add SubRouters here
|
// for other messaging queues, add SubRouters here
|
||||||
}
|
}
|
||||||
@ -2478,6 +2486,332 @@ func uniqueIdentifier(clientID, serviceInstanceID, serviceName, separator string
|
|||||||
return clientID + separator + serviceInstanceID + separator + serviceName
|
return clientID + separator + serviceInstanceID + separator + serviceName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) onboardProducers(
|
||||||
|
|
||||||
|
w http.ResponseWriter, r *http.Request,
|
||||||
|
|
||||||
|
) {
|
||||||
|
messagingQueue, apiErr := ParseMessagingQueueBody(r)
|
||||||
|
if apiErr != nil {
|
||||||
|
zap.L().Error(apiErr.Err.Error())
|
||||||
|
RespondError(w, apiErr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := mq.BuildClickHouseQuery(messagingQueue, mq.KafkaQueue, "onboard_producers")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
zap.L().Error(err.Error())
|
||||||
|
RespondError(w, apiErr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
apiErrObj := &model.ApiError{Typ: model.ErrorBadData, Err: err}
|
||||||
|
RespondError(w, apiErrObj, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var entries []mq.OnboardingResponse
|
||||||
|
|
||||||
|
for _, result := range results {
|
||||||
|
|
||||||
|
for key, value := range result.Data {
|
||||||
|
var message, attribute, status string
|
||||||
|
|
||||||
|
intValue := int(*value.(*uint8))
|
||||||
|
|
||||||
|
if key == "entries" {
|
||||||
|
attribute = "telemetry ingestion"
|
||||||
|
if intValue != 0 {
|
||||||
|
entries = nil
|
||||||
|
entry := mq.OnboardingResponse{
|
||||||
|
Attribute: attribute,
|
||||||
|
Message: "No data available in the given time range",
|
||||||
|
Status: "0",
|
||||||
|
}
|
||||||
|
entries = append(entries, entry)
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "queue" {
|
||||||
|
attribute = "messaging.system"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.system attribute is not present or not equal to kafka in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "kind" {
|
||||||
|
attribute = "kind"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "check if your producer spans has kind=4 as attribute"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "destination" {
|
||||||
|
attribute = "messaging.destination.name"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.destination.name attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "partition" {
|
||||||
|
attribute = "messaging.destination.partition.id"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.destination.partition.id attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := mq.OnboardingResponse{
|
||||||
|
Attribute: attribute,
|
||||||
|
Message: message,
|
||||||
|
Status: status,
|
||||||
|
}
|
||||||
|
|
||||||
|
entries = append(entries, entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(entries, func(i, j int) bool {
|
||||||
|
return entries[i].Attribute < entries[j].Attribute
|
||||||
|
})
|
||||||
|
|
||||||
|
aH.Respond(w, entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) onboardConsumers(
|
||||||
|
|
||||||
|
w http.ResponseWriter, r *http.Request,
|
||||||
|
|
||||||
|
) {
|
||||||
|
messagingQueue, apiErr := ParseMessagingQueueBody(r)
|
||||||
|
if apiErr != nil {
|
||||||
|
zap.L().Error(apiErr.Err.Error())
|
||||||
|
RespondError(w, apiErr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := mq.BuildClickHouseQuery(messagingQueue, mq.KafkaQueue, "onboard_consumers")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
zap.L().Error(err.Error())
|
||||||
|
RespondError(w, apiErr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
apiErrObj := &model.ApiError{Typ: model.ErrorBadData, Err: err}
|
||||||
|
RespondError(w, apiErrObj, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var entries []mq.OnboardingResponse
|
||||||
|
|
||||||
|
for _, result := range result {
|
||||||
|
for key, value := range result.Data {
|
||||||
|
var message, attribute, status string
|
||||||
|
|
||||||
|
intValue := int(*value.(*uint8))
|
||||||
|
|
||||||
|
if key == "entries" {
|
||||||
|
attribute = "telemetry ingestion"
|
||||||
|
if intValue != 0 {
|
||||||
|
entries = nil
|
||||||
|
entry := mq.OnboardingResponse{
|
||||||
|
Attribute: attribute,
|
||||||
|
Message: "No data available in the given time range",
|
||||||
|
Status: "0",
|
||||||
|
}
|
||||||
|
entries = append(entries, entry)
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "queue" {
|
||||||
|
attribute = "messaging.system"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.system attribute is not present or not equal to kafka in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "kind" {
|
||||||
|
attribute = "kind"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "check if your consumer spans has kind=5 as attribute"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "destination" {
|
||||||
|
attribute = "messaging.destination.name"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.destination.name attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "partition" {
|
||||||
|
attribute = "messaging.destination.partition.id"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.destination.partition.id attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "svc" {
|
||||||
|
attribute = "service_name"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "service_name attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "cgroup" {
|
||||||
|
attribute = "messaging.kafka.consumer.group"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.kafka.consumer.group attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "bodysize" {
|
||||||
|
attribute = "messaging.message.body.size"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.message.body.size attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "clientid" {
|
||||||
|
attribute = "messaging.client_id"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "messaging.client_id attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "instanceid" {
|
||||||
|
attribute = "service.instance.id"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "service.instance.id attribute is not present in your spans"
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := mq.OnboardingResponse{
|
||||||
|
Attribute: attribute,
|
||||||
|
Message: message,
|
||||||
|
Status: status,
|
||||||
|
}
|
||||||
|
entries = append(entries, entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(entries, func(i, j int) bool {
|
||||||
|
return entries[i].Attribute < entries[j].Attribute
|
||||||
|
})
|
||||||
|
|
||||||
|
aH.Respond(w, entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) onboardKafka(
|
||||||
|
|
||||||
|
w http.ResponseWriter, r *http.Request,
|
||||||
|
|
||||||
|
) {
|
||||||
|
messagingQueue, apiErr := ParseMessagingQueueBody(r)
|
||||||
|
if apiErr != nil {
|
||||||
|
zap.L().Error(apiErr.Err.Error())
|
||||||
|
RespondError(w, apiErr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := mq.BuildClickHouseQuery(messagingQueue, mq.KafkaQueue, "onboard_kafka")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
zap.L().Error(err.Error())
|
||||||
|
RespondError(w, apiErr, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
apiErrObj := &model.ApiError{Typ: model.ErrorBadData, Err: err}
|
||||||
|
RespondError(w, apiErrObj, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var entries []mq.OnboardingResponse
|
||||||
|
|
||||||
|
for _, result := range result {
|
||||||
|
for key, value := range result.Data {
|
||||||
|
var message, attribute, status string
|
||||||
|
|
||||||
|
intValue := int(*value.(*uint8))
|
||||||
|
|
||||||
|
if key == "entries" {
|
||||||
|
attribute = "telemetry ingestion"
|
||||||
|
if intValue != 0 {
|
||||||
|
entries = nil
|
||||||
|
entry := mq.OnboardingResponse{
|
||||||
|
Attribute: attribute,
|
||||||
|
Message: "No data available in the given time range",
|
||||||
|
Status: "0",
|
||||||
|
}
|
||||||
|
entries = append(entries, entry)
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "fetchlatency" {
|
||||||
|
attribute = "kafka_consumer_fetch_latency_avg"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "Metric kafka_consumer_fetch_latency_avg is not present in the given time range."
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
} else if key == "grouplag" {
|
||||||
|
attribute = "kafka_consumer_group_lag"
|
||||||
|
if intValue != 0 {
|
||||||
|
status = "0"
|
||||||
|
message = "Metric kafka_consumer_group_lag is not present in the given time range."
|
||||||
|
} else {
|
||||||
|
status = "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := mq.OnboardingResponse{
|
||||||
|
Attribute: attribute,
|
||||||
|
Message: message,
|
||||||
|
Status: status,
|
||||||
|
}
|
||||||
|
entries = append(entries, entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(entries, func(i, j int) bool {
|
||||||
|
return entries[i].Attribute < entries[j].Attribute
|
||||||
|
})
|
||||||
|
|
||||||
|
aH.Respond(w, entries)
|
||||||
|
}
|
||||||
|
|
||||||
func (aH *APIHandler) getNetworkData(
|
func (aH *APIHandler) getNetworkData(
|
||||||
w http.ResponseWriter, r *http.Request,
|
w http.ResponseWriter, r *http.Request,
|
||||||
) {
|
) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user