Compare commits

..

2 Commits

Author SHA1 Message Date
Srikanth Chekuri
cd5df748d8 chore: less spam 2025-03-19 08:11:46 +05:30
Srikanth Chekuri
9e6e550723 chore: change log level to reduce noise 2025-03-19 07:45:54 +05:30
566 changed files with 3480 additions and 14795 deletions

View File

@@ -1,122 +1,48 @@
name: build
name: build-pipeline
on:
push:
pull_request:
branches:
- main
tags:
- v*
- release/v*
jobs:
enterprise:
build-frontend:
runs-on: ubuntu-latest
steps:
- name: checkout
- name: Checkout code
uses: actions/checkout@v4
- name: setup
uses: actions/setup-go@v5
with:
go-version: "1.22"
- name: setup-qemu
uses: docker/setup-qemu-action@v3
- name: setup-buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: docker-login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: create-env-file
run: |
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
echo 'SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> frontend/.env
echo 'SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> frontend/.env
echo 'SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> frontend/.env
echo 'SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> frontend/.env
echo 'TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> frontend/.env
echo 'TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> frontend/.env
echo 'POSTHOG_KEY="${{ secrets.POSTHOG_KEY }}"' >> frontend/.env
echo 'CUSTOMERIO_ID="${{ secrets.CUSTOMERIO_ID }}"' >> frontend/.env
echo 'CUSTOMERIO_SITE_ID="${{ secrets.CUSTOMERIO_SITE_ID }}"' >> frontend/.env
- name: github-ref-info
- name: Install dependencies
run: cd frontend && yarn install
- name: Build frontend static files
shell: bash
run: |
GH_REF=${{ github.ref }}
if [[ "${{ github.ref_type }}" == "tag" ]]; then
PREFIX="refs/tags/"
echo "GH_IS_TAG=true" >> $GITHUB_ENV
echo "GH_TAG=${GH_REF#$PREFIX}" >> $GITHUB_ENV
else
PREFIX="refs/heads/"
echo "GH_IS_TAG=false" >> $GITHUB_ENV
echo "GH_BRANCH_NAME=${GH_REF#$PREFIX}" >> $GITHUB_ENV
fi
- name: set-version
run: |
if [ '${{ env.GH_IS_TAG }}' == 'true' ]; then
echo "VERSION=${{ env.GH_TAG }}" >> $GITHUB_ENV
elif [ '${{ env.GH_BRANCH_NAME }}' == 'main' ]; then
echo "VERSION=latest" >> $GITHUB_ENV
else
echo "VERSION=${{ env.GH_BRANCH_NAME }}" >> $GITHUB_ENV
fi
- name: cross-compilation-tools
run: |
set -ex
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
- name: publish
run: make docker-buildx-enterprise
make build-frontend-static
community:
build-signoz:
runs-on: ubuntu-latest
steps:
- name: checkout
- name: Checkout code
uses: actions/checkout@v4
- name: setup-go
uses: actions/setup-go@v5
- name: Setup golang
uses: actions/setup-go@v4
with:
go-version: "1.22"
- name: setup-qemu
uses: docker/setup-qemu-action@v3
- name: setup-buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: docker-login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: github-ref-info
- name: Build signoz image
shell: bash
run: |
GH_REF=${{ github.ref }}
if [[ "${{ github.ref_type }}" == "tag" ]]; then
PREFIX="refs/tags/"
echo "GH_IS_TAG=true" >> $GITHUB_ENV
echo "GH_TAG=${GH_REF#$PREFIX}" >> $GITHUB_ENV
else
PREFIX="refs/heads/"
echo "GH_IS_TAG=false" >> $GITHUB_ENV
echo "GH_BRANCH_NAME=${GH_REF#$PREFIX}" >> $GITHUB_ENV
fi
- name: set-version
make build-signoz-amd64
build-signoz-community:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup golang
uses: actions/setup-go@v4
with:
go-version: "1.22"
- name: Build signoz community image
shell: bash
run: |
if [ '${{ env.GH_IS_TAG }}' == 'true' ]; then
echo "VERSION=${{ env.GH_TAG }}" >> $GITHUB_ENV
elif [ '${{ env.GH_BRANCH_NAME }}' == 'main' ]; then
echo "VERSION=latest" >> $GITHUB_ENV
else
echo "VERSION=${{ env.GH_BRANCH_NAME }}" >> $GITHUB_ENV
fi
- name: cross-compilation-tools
run: |
set -ex
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
- name: publish
run: make docker-buildx-community
make build-signoz-community-amd64

View File

@@ -25,3 +25,15 @@ jobs:
else
echo "No references to 'ee' packages found in 'pkg' directory"
fi
lint:
if: |
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: lint
uses: wagoid/commitlint-github-action@v5

View File

@@ -34,30 +34,3 @@ jobs:
secrets: inherit
with:
PRIMUS_REF: main
build:
if: |
(github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork && github.event.pull_request.user.login != 'dependabot[bot]' && ! contains(github.event.pull_request.labels.*.name, 'safe-to-test')) ||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-test'))
runs-on: ubuntu-latest
steps:
- name: self-checkout
uses: actions/checkout@v4
- name: go-install
uses: actions/setup-go@v5
with:
go-version: "1.22"
- name: qemu-install
uses: docker/setup-qemu-action@v3
- name: aarch64-install
run: |
set -ex
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
- name: docker-community
shell: bash
run: |
make docker-build-community
- name: docker-enterprise
shell: bash
run: |
make docker-build-enterprise

View File

@@ -22,7 +22,7 @@ jobs:
run: |
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: build-frontend
run: make js-build
run: make build-frontend-static
- name: upload-frontend-artifact
uses: actions/upload-artifact@v4
with:

View File

@@ -36,7 +36,7 @@ jobs:
echo 'CUSTOMERIO_ID="${{ secrets.CUSTOMERIO_ID }}"' >> .env
echo 'CUSTOMERIO_SITE_ID="${{ secrets.CUSTOMERIO_SITE_ID }}"' >> .env
- name: build-frontend
run: make js-build
run: make build-frontend-static
- name: upload-frontend-artifact
uses: actions/upload-artifact@v4
with:

134
.github/workflows/push.yaml vendored Normal file
View File

@@ -0,0 +1,134 @@
name: push
on:
push:
branches:
- main
tags:
- v*
jobs:
image-build-and-push-signoz:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
- name: setup
uses: actions/setup-go@v4
with:
go-version: "1.22"
- name: setup-qemu
uses: docker/setup-qemu-action@v3
- name: setup-buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: docker-login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: create-env-file
run: |
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
echo 'SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> frontend/.env
echo 'SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> frontend/.env
echo 'SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> frontend/.env
echo 'SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> frontend/.env
echo 'TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> frontend/.env
echo 'TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> frontend/.env
echo 'POSTHOG_KEY="${{ secrets.POSTHOG_KEY }}"' >> frontend/.env
echo 'CUSTOMERIO_ID="${{ secrets.CUSTOMERIO_ID }}"' >> frontend/.env
echo 'CUSTOMERIO_SITE_ID="${{ secrets.CUSTOMERIO_SITE_ID }}"' >> frontend/.env
- uses: benjlevesque/short-sha@v2.2
id: short-sha
- name: branch-name
id: branch-name
uses: tj-actions/branch-names@v7.0.7
- name: docker-tag
run: |
if [ '${{ steps.branch-name.outputs.is_tag }}' == 'true' ]; then
echo "DOCKER_TAG=${{ steps.branch-name.outputs.tag }}" >> $GITHUB_ENV
elif [ '${{ steps.branch-name.outputs.current_branch }}' == 'main' ]; then
echo "DOCKER_TAG=latest" >> $GITHUB_ENV
else
echo "DOCKER_TAG=${{ steps.branch-name.outputs.current_branch }}" >> $GITHUB_ENV
fi
- name: cross-compilation-tools
run: |
set -ex
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
- name: publish-signoz
run: make build-push-signoz
- name: qs-docker-tag
run: |
if [ '${{ steps.branch-name.outputs.is_tag }}' == 'true' ]; then
tag="${{ steps.branch-name.outputs.tag }}"
tag="${tag:1}"
echo "DOCKER_TAG=${tag}" >> $GITHUB_ENV
elif [ '${{ steps.branch-name.outputs.current_branch }}' == 'main' ]; then
echo "DOCKER_TAG=latest" >> $GITHUB_ENV
else
echo "DOCKER_TAG=${{ steps.branch-name.outputs.current_branch }}" >> $GITHUB_ENV
fi
- name: publish-query-service
run: |
SIGNOZ_DOCKER_IMAGE=query-service make build-push-signoz
image-build-and-push-signoz-community:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4
- name: setup-go
uses: actions/setup-go@v4
with:
go-version: "1.22"
- name: setup-qemu
uses: docker/setup-qemu-action@v3
- name: setup-buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: docker-login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: benjlevesque/short-sha@v2.2
id: short-sha
- name: branch-name
id: branch-name
uses: tj-actions/branch-names@v7.0.7
- name: docker-tag
run: |
if [ '${{ steps.branch-name.outputs.is_tag }}' == 'true' ]; then
echo "DOCKER_TAG=${{ steps.branch-name.outputs.tag }}" >> $GITHUB_ENV
elif [ '${{ steps.branch-name.outputs.current_branch }}' == 'main' ]; then
echo "DOCKER_TAG=latest" >> $GITHUB_ENV
else
echo "DOCKER_TAG=${{ steps.branch-name.outputs.current_branch }}" >> $GITHUB_ENV
fi
- name: cross-compilation-tools
run: |
set -ex
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu musl-tools
- name: publish-signoz-community
run: make build-push-signoz-community
- name: qs-docker-tag
run: |
if [ '${{ steps.branch-name.outputs.is_tag }}' == 'true' ]; then
tag="${{ steps.branch-name.outputs.tag }}"
tag="${tag:1}"
echo "DOCKER_TAG=${tag}-oss" >> $GITHUB_ENV
elif [ '${{ steps.branch-name.outputs.current_branch }}' == 'main' ]; then
echo "DOCKER_TAG=latest-oss" >> $GITHUB_ENV
else
echo "DOCKER_TAG=${{ steps.branch-name.outputs.current_branch }}-oss" >> $GITHUB_ENV
fi
- name: publish-query-service-oss
run: |
SIGNOZ_COMMUNITY_DOCKER_IMAGE=query-service make build-push-signoz-community

View File

@@ -35,7 +35,7 @@ jobs:
read -r -d '' COMMAND <<EOF || true
echo "GITHUB_BRANCH: ${GITHUB_BRANCH}"
echo "GITHUB_SHA: ${GITHUB_SHA}"
export VERSION="${GITHUB_SHA:0:7}" # needed for child process to access it
export DOCKER_TAG="${GITHUB_SHA:0:7}" # needed for child process to access it
export OTELCOL_TAG="main"
export PATH="/usr/local/go/bin/:$PATH" # needed for Golang to work
export KAFKA_SPAN_EVAL="true"
@@ -49,8 +49,7 @@ jobs:
git fetch origin
git checkout ${GITHUB_BRANCH}
git pull
make docker-build-enterprise-amd64
export VERSION="${GITHUB_SHA:0:7}-amd64"
docker-compose -f deploy/docker/docker-compose.testing.yaml up --build -d
make build-signoz-amd64
make run-testing
EOF
gcloud beta compute ssh ${GCP_INSTANCE} --zone ${GCP_ZONE} --ssh-key-expire-after=15m --tunnel-through-iap --project ${GCP_PROJECT} --command "${COMMAND}"

View File

@@ -35,7 +35,7 @@ jobs:
read -r -d '' COMMAND <<EOF || true
echo "GITHUB_BRANCH: ${GITHUB_BRANCH}"
echo "GITHUB_SHA: ${GITHUB_SHA}"
export VERSION="${GITHUB_SHA:0:7}" # needed for child process to access it
export DOCKER_TAG="${GITHUB_SHA:0:7}" # needed for child process to access it
export DEV_BUILD="1"
export PATH="/usr/local/go/bin/:$PATH" # needed for Golang to work
docker system prune --force
@@ -49,8 +49,7 @@ jobs:
# This is added to include the scenerio when new commit in PR is force-pushed
git branch -D ${GITHUB_BRANCH}
git checkout --track origin/${GITHUB_BRANCH}
make docker-build-enterprise-amd64
export VERSION="${GITHUB_SHA:0:7}-amd64"
docker-compose -f deploy/docker/docker-compose.testing.yaml up --build -d
make build-signoz-amd64
make run-testing
EOF
gcloud beta compute ssh ${GCP_INSTANCE} --zone ${GCP_ZONE} --ssh-key-expire-after=15m --tunnel-through-iap --project ${GCP_PROJECT} --command "${COMMAND}"

View File

@@ -77,4 +77,3 @@ Need assistance? Join our Slack community:
## Where do I go from here?
- Set up your [development environment](docs/contributing/development.md)
- Deploy and observe [SigNoz in action with OpenTelemetry Demo Application](docs/otel-demo/otel-demo-docs.md)

292
Makefile
View File

@@ -1,44 +1,49 @@
##############################################################
# variables
##############################################################
SHELL := /bin/bash
SRC ?= $(shell pwd)
NAME ?= signoz
OS ?= $(shell uname -s | tr '[A-Z]' '[a-z]')
ARCH ?= $(shell uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g')
COMMIT_SHORT_SHA ?= $(shell git rev-parse --short HEAD)
BRANCH_NAME ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))
VERSION ?= $(BRANCH_NAME)-$(COMMIT_SHORT_SHA)
TIMESTAMP ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
ARCHS = amd64 arm64
TARGET_DIR ?= $(shell pwd)/target
#
# Reference Guide - https://www.gnu.org/software/make/manual/make.html
#
ZEUS_URL ?= https://api.signoz.cloud
GO_BUILD_LDFLAG_ZEUS_URL = -X github.com/SigNoz/signoz/ee/query-service/constants.ZeusURL=$(ZEUS_URL)
LICENSE_URL ?= https://license.signoz.io/api/v1
GO_BUILD_LDFLAG_LICENSE_SIGNOZ_IO = -X github.com/SigNoz/signoz/ee/query-service/constants.LicenseSignozIo=$(LICENSE_URL)
# Build variables
BUILD_VERSION ?= $(shell git describe --always --tags)
BUILD_HASH ?= $(shell git rev-parse --short HEAD)
BUILD_TIME ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
BUILD_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
LICENSE_SIGNOZ_IO ?= https://license.signoz.io/api/v1
DEV_LICENSE_SIGNOZ_IO ?= https://staging-license.signoz.io/api/v1
ZEUS_URL ?= https://api.signoz.cloud
DEV_ZEUS_URL ?= https://api.staging.signoz.cloud
DEV_BUILD ?= "" # set to any non-empty value to enable dev build
GO_BUILD_VERSION_LDFLAGS = -X github.com/SigNoz/signoz/pkg/version.version=$(VERSION) -X github.com/SigNoz/signoz/pkg/version.hash=$(COMMIT_SHORT_SHA) -X github.com/SigNoz/signoz/pkg/version.time=$(TIMESTAMP) -X github.com/SigNoz/signoz/pkg/version.branch=$(BRANCH_NAME)
GO_BUILD_ARCHS_COMMUNITY = $(addprefix go-build-community-,$(ARCHS))
GO_BUILD_CONTEXT_COMMUNITY = $(SRC)/pkg/query-service
GO_BUILD_LDFLAGS_COMMUNITY = $(GO_BUILD_VERSION_LDFLAGS) -X github.com/SigNoz/signoz/pkg/version.variant=community
GO_BUILD_ARCHS_ENTERPRISE = $(addprefix go-build-enterprise-,$(ARCHS))
GO_BUILD_CONTEXT_ENTERPRISE = $(SRC)/ee/query-service
GO_BUILD_LDFLAGS_ENTERPRISE = $(GO_BUILD_VERSION_LDFLAGS) -X github.com/SigNoz/signoz/pkg/version.variant=enterprise $(GO_BUILD_LDFLAG_ZEUS_URL) $(GO_BUILD_LDFLAG_LICENSE_SIGNOZ_IO)
# Internal variables or constants.
FRONTEND_DIRECTORY ?= frontend
QUERY_SERVICE_DIRECTORY ?= pkg/query-service
EE_QUERY_SERVICE_DIRECTORY ?= ee/query-service
STANDALONE_DIRECTORY ?= deploy/docker
SWARM_DIRECTORY ?= deploy/docker-swarm
CH_HISTOGRAM_QUANTILE_DIRECTORY ?= scripts/clickhouse/histogramquantile
GORELEASER_BIN ?= goreleaser
DOCKER_BUILD_ARCHS_COMMUNITY = $(addprefix docker-build-community-,$(ARCHS))
DOCKERFILE_COMMUNITY = $(SRC)/pkg/query-service/Dockerfile
DOCKER_REGISTRY_COMMUNITY ?= docker.io/signoz/signoz-community
DOCKER_BUILD_ARCHS_ENTERPRISE = $(addprefix docker-build-enterprise-,$(ARCHS))
DOCKERFILE_ENTERPRISE = $(SRC)/ee/query-service/Dockerfile
DOCKER_REGISTRY_ENTERPRISE ?= docker.io/signoz/signoz
JS_BUILD_CONTEXT = $(SRC)/frontend
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
GOPATH ?= $(shell go env GOPATH)
REPONAME ?= signoz
DOCKER_TAG ?= $(BUILD_VERSION)
SIGNOZ_DOCKER_IMAGE ?= signoz
SIGNOZ_COMMUNITY_DOCKER_IMAGE ?= signoz-community
# Build-time Go variables
PACKAGE?=go.signoz.io/signoz
buildVersion=${PACKAGE}/pkg/query-service/version.buildVersion
buildHash=${PACKAGE}/pkg/query-service/version.buildHash
buildTime=${PACKAGE}/pkg/query-service/version.buildTime
gitBranch=${PACKAGE}/pkg/query-service/version.gitBranch
licenseSignozIo=${PACKAGE}/ee/query-service/constants.LicenseSignozIo
zeusURL=${PACKAGE}/ee/query-service/constants.ZeusURL
LD_FLAGS=-X ${buildHash}=${BUILD_HASH} -X ${buildTime}=${BUILD_TIME} -X ${buildVersion}=${BUILD_VERSION} -X ${gitBranch}=${BUILD_BRANCH}
PROD_LD_FLAGS=-X ${zeusURL}=${ZEUS_URL} -X ${licenseSignozIo}=${LICENSE_SIGNOZ_IO}
DEV_LD_FLAGS=-X ${zeusURL}=${DEV_ZEUS_URL} -X ${licenseSignozIo}=${DEV_LICENSE_SIGNOZ_IO}
##############################################################
# directories
##############################################################
$(TARGET_DIR):
mkdir -p $(TARGET_DIR)
##############################################################
# common commands
@@ -56,10 +61,10 @@ devenv-clickhouse: ## Run clickhouse in devenv
docker compose -f compose.yaml up -d
##############################################################
# go commands
# run commands
##############################################################
.PHONY: go-run-enterprise
go-run-enterprise: ## Runs the enterprise go backend server
.PHONY: run-go
run-go: ## Runs the go backend server
@SIGNOZ_INSTRUMENTATION_LOGS_LEVEL=debug \
SIGNOZ_SQLSTORE_SQLITE_PATH=signoz.db \
SIGNOZ_WEB_ENABLED=false \
@@ -68,98 +73,147 @@ go-run-enterprise: ## Runs the enterprise go backend server
SIGNOZ_TELEMETRYSTORE_PROVIDER=clickhouse \
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://127.0.0.1:9000 \
go run -race \
$(GO_BUILD_CONTEXT_ENTERPRISE)/main.go \
--config ./conf/prometheus.yml \
./ee/query-service/main.go \
--config ./pkg/query-service/config/prometheus.yml \
--cluster cluster \
--use-logs-new-schema true \
--use-trace-new-schema true
.PHONY: go-run-community
go-run-community: ## Runs the community go backend server
@SIGNOZ_INSTRUMENTATION_LOGS_LEVEL=debug \
SIGNOZ_SQLSTORE_SQLITE_PATH=signoz.db \
SIGNOZ_WEB_ENABLED=false \
SIGNOZ_JWT_SECRET=secret \
SIGNOZ_ALERTMANAGER_PROVIDER=signoz \
SIGNOZ_TELEMETRYSTORE_PROVIDER=clickhouse \
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://127.0.0.1:9000 \
go run -race \
$(GO_BUILD_CONTEXT_COMMUNITY)/main.go \
--config ./conf/prometheus.yml \
--cluster cluster \
--use-logs-new-schema true \
--use-trace-new-schema true
all: build-push-frontend build-push-signoz
.PHONY: go-build-community $(GO_BUILD_ARCHS_COMMUNITY)
go-build-community: ## Builds the go backend server for community
go-build-community: $(GO_BUILD_ARCHS_COMMUNITY)
$(GO_BUILD_ARCHS_COMMUNITY): go-build-community-%: $(TARGET_DIR)
@mkdir -p $(TARGET_DIR)/$(OS)-$*
@echo ">> building binary $(TARGET_DIR)/$(OS)-$*/$(NAME)-community"
@if [ $* = "arm64" ]; then \
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOARCH=$* GOOS=$(OS) go build -C $(GO_BUILD_CONTEXT_COMMUNITY) -tags timetzdata -o $(TARGET_DIR)/$(OS)-$*/$(NAME)-community -ldflags "-linkmode external -extldflags '-static' -s -w $(GO_BUILD_LDFLAGS_COMMUNITY)"; \
# Steps to build static files of frontend
build-frontend-static:
@echo "------------------"
@echo "--> Building frontend static files"
@echo "------------------"
@cd $(FRONTEND_DIRECTORY) && \
rm -rf build && \
CI=1 yarn install && \
yarn build && \
ls -l build
# Steps to build static binary of signoz
.PHONY: build-signoz-static
build-signoz-static:
@echo "------------------"
@echo "--> Building signoz static binary"
@echo "------------------"
@if [ $(DEV_BUILD) != "" ]; then \
cd $(EE_QUERY_SERVICE_DIRECTORY) && \
CGO_ENABLED=1 go build -tags timetzdata -a -o ./bin/signoz-${GOOS}-${GOARCH} \
-ldflags "-linkmode external -extldflags '-static' -s -w ${LD_FLAGS} ${DEV_LD_FLAGS}"; \
else \
CGO_ENABLED=1 GOARCH=$* GOOS=$(OS) go build -C $(GO_BUILD_CONTEXT_COMMUNITY) -tags timetzdata -o $(TARGET_DIR)/$(OS)-$*/$(NAME)-community -ldflags "-linkmode external -extldflags '-static' -s -w $(GO_BUILD_LDFLAGS_COMMUNITY)"; \
cd $(EE_QUERY_SERVICE_DIRECTORY) && \
CGO_ENABLED=1 go build -tags timetzdata -a -o ./bin/signoz-${GOOS}-${GOARCH} \
-ldflags "-linkmode external -extldflags '-static' -s -w ${LD_FLAGS} ${PROD_LD_FLAGS}"; \
fi
.PHONY: build-signoz-static-amd64
build-signoz-static-amd64:
make GOARCH=amd64 build-signoz-static
.PHONY: go-build-enterprise $(GO_BUILD_ARCHS_ENTERPRISE)
go-build-enterprise: ## Builds the go backend server for enterprise
go-build-enterprise: $(GO_BUILD_ARCHS_ENTERPRISE)
$(GO_BUILD_ARCHS_ENTERPRISE): go-build-enterprise-%: $(TARGET_DIR)
@mkdir -p $(TARGET_DIR)/$(OS)-$*
@echo ">> building binary $(TARGET_DIR)/$(OS)-$*/$(NAME)"
@if [ $* = "arm64" ]; then \
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOARCH=$* GOOS=$(OS) go build -C $(GO_BUILD_CONTEXT_ENTERPRISE) -tags timetzdata -o $(TARGET_DIR)/$(OS)-$*/$(NAME) -ldflags "-linkmode external -extldflags '-static' -s -w $(GO_BUILD_LDFLAGS_ENTERPRISE)"; \
.PHONY: build-signoz-static-arm64
build-signoz-static-arm64:
make CC=aarch64-linux-gnu-gcc GOARCH=arm64 build-signoz-static
# Steps to build static binary of signoz for all platforms
.PHONY: build-signoz-static-all
build-signoz-static-all: build-signoz-static-amd64 build-signoz-static-arm64 build-frontend-static
# Steps to build and push docker image of signoz
.PHONY: build-signoz-amd64 build-push-signoz
# Step to build docker image of signoz in amd64 (used in build pipeline)
build-signoz-amd64: build-signoz-static-amd64 build-frontend-static
@echo "------------------"
@echo "--> Building signoz docker image for amd64"
@echo "------------------"
@docker build --file $(EE_QUERY_SERVICE_DIRECTORY)/Dockerfile \
--tag $(REPONAME)/$(SIGNOZ_DOCKER_IMAGE):$(DOCKER_TAG) \
--build-arg TARGETPLATFORM="linux/amd64" .
# Step to build and push docker image of query in amd64 and arm64 (used in push pipeline)
build-push-signoz: build-signoz-static-all
@echo "------------------"
@echo "--> Building and pushing signoz docker image"
@echo "------------------"
@docker buildx build --file $(EE_QUERY_SERVICE_DIRECTORY)/Dockerfile --progress plain \
--push --platform linux/arm64,linux/amd64 \
--tag $(REPONAME)/$(SIGNOZ_DOCKER_IMAGE):$(DOCKER_TAG) .
# Step to build docker image of signoz community in amd64 (used in build pipeline)
build-signoz-community-amd64:
@echo "------------------"
@echo "--> Building signoz docker image for amd64"
@echo "------------------"
make EE_QUERY_SERVICE_DIRECTORY=${QUERY_SERVICE_DIRECTORY} SIGNOZ_DOCKER_IMAGE=${SIGNOZ_COMMUNITY_DOCKER_IMAGE} build-signoz-amd64
# Step to build and push docker image of signoz community in amd64 and arm64 (used in push pipeline)
build-push-signoz-community:
@echo "------------------"
@echo "--> Building and pushing signoz community docker image"
@echo "------------------"
make EE_QUERY_SERVICE_DIRECTORY=${QUERY_SERVICE_DIRECTORY} SIGNOZ_DOCKER_IMAGE=${SIGNOZ_COMMUNITY_DOCKER_IMAGE} build-push-signoz
pull-signoz:
@docker-compose -f $(STANDALONE_DIRECTORY)/docker-compose.yaml pull
run-signoz:
@docker-compose -f $(STANDALONE_DIRECTORY)/docker-compose.yaml up --build -d
run-testing:
@docker-compose -f $(STANDALONE_DIRECTORY)/docker-compose.testing.yaml up --build -d
down-signoz:
@docker-compose -f $(STANDALONE_DIRECTORY)/docker-compose.yaml down -v
check-no-ee-references:
@echo "Checking for 'ee' package references in 'pkg' directory..."
@if grep -R --include="*.go" '.*/ee/.*' pkg/; then \
echo "Error: Found references to 'ee' packages in 'pkg' directory"; \
exit 1; \
else \
CGO_ENABLED=1 GOARCH=$* GOOS=$(OS) go build -C $(GO_BUILD_CONTEXT_ENTERPRISE) -tags timetzdata -o $(TARGET_DIR)/$(OS)-$*/$(NAME) -ldflags "-linkmode external -extldflags '-static' -s -w $(GO_BUILD_LDFLAGS_ENTERPRISE)"; \
echo "No references to 'ee' packages found in 'pkg' directory"; \
fi
##############################################################
# js commands
##############################################################
.PHONY: js-build
js-build: ## Builds the js frontend
@echo ">> building js frontend"
@cd $(JS_BUILD_CONTEXT) && CI=1 yarn install && yarn build
test:
go test ./pkg/...
##############################################################
# docker commands
##############################################################
.PHONY: docker-build-community $(DOCKER_BUILD_ARCHS_COMMUNITY)
docker-build-community: ## Builds the docker image for community
docker-build-community: $(DOCKER_BUILD_ARCHS_COMMUNITY)
$(DOCKER_BUILD_ARCHS_COMMUNITY): docker-build-community-%: go-build-community-% js-build
@echo ">> building docker image for $(NAME)-community"
@docker build -t "$(DOCKER_REGISTRY_COMMUNITY):$(VERSION)-$*" \
--build-arg TARGETARCH="$*" \
-f $(DOCKERFILE_COMMUNITY) $(SRC)
########################################################
# Goreleaser
########################################################
.PHONY: gor-snapshot gor-snapshot-histogram-quantile gor-snapshot-signoz gor-snapshot-signoz-community gor-split gor-split-histogram-quantile gor-split-signoz gor-split-signoz-community gor-merge
.PHONY: docker-buildx-community
docker-buildx-community: ## Builds the docker image for community using buildx
docker-buildx-community: go-build-community js-build
@echo ">> building docker image for $(NAME)-community"
@docker buildx build --file $(DOCKERFILE_COMMUNITY) \
--progress plain \
--platform linux/arm64,linux/amd64 \
--push \
--tag $(DOCKER_REGISTRY_COMMUNITY):$(VERSION) $(SRC)
gor-snapshot:
@if [[ ${GORELEASER_WORKDIR} ]]; then \
${GORELEASER_BIN} release --config ${GORELEASER_WORKDIR}/.goreleaser.yaml --clean --snapshot; \
else \
${GORELEASER_BIN} release --clean --snapshot; \
fi
.PHONY: docker-build-enterprise $(DOCKER_BUILD_ARCHS_ENTERPRISE)
docker-build-enterprise: ## Builds the docker image for enterprise
docker-build-enterprise: $(DOCKER_BUILD_ARCHS_ENTERPRISE)
$(DOCKER_BUILD_ARCHS_ENTERPRISE): docker-build-enterprise-%: go-build-enterprise-% js-build
@echo ">> building docker image for $(NAME)"
@docker build -t "$(DOCKER_REGISTRY_ENTERPRISE):$(VERSION)-$*" \
--build-arg TARGETARCH="$*" \
-f $(DOCKERFILE_ENTERPRISE) $(SRC)
gor-snapshot-histogram-quantile:
make GORELEASER_WORKDIR=$(CH_HISTOGRAM_QUANTILE_DIRECTORY) goreleaser-snapshot
.PHONY: docker-buildx-enterprise
docker-buildx-enterprise: ## Builds the docker image for enterprise using buildx
docker-buildx-enterprise: go-build-enterprise js-build
@echo ">> building docker image for $(NAME)"
@docker buildx build --file $(DOCKERFILE_ENTERPRISE) \
--progress plain \
--platform linux/arm64,linux/amd64 \
--push \
--tag $(DOCKER_REGISTRY_ENTERPRISE):$(VERSION) $(SRC)
gor-snapshot-signoz: build-frontend-static
make GORELEASER_WORKDIR=$(EE_QUERY_SERVICE_DIRECTORY) goreleaser-snapshot
gor-snapshot-signoz-community: build-frontend-static
make GORELEASER_WORKDIR=$(QUERY_SERVICE_DIRECTORY) goreleaser-snapshot
gor-split:
@if [[ ${GORELEASER_WORKDIR} ]]; then \
${GORELEASER_BIN} release --config ${GORELEASER_WORKDIR}/.goreleaser.yaml --clean --split; \
else \
${GORELEASER_BIN} release --clean --split; \
fi
gor-split-histogram-quantile:
make GORELEASER_WORKDIR=$(CH_HISTOGRAM_QUANTILE_DIRECTORY) goreleaser-split
gor-split-signoz: build-frontend-static
make GORELEASER_WORKDIR=$(EE_QUERY_SERVICE_DIRECTORY) goreleaser-split
gor-split-signoz-community: build-frontend-static
make GORELEASER_WORKDIR=$(QUERY_SERVICE_DIRECTORY) goreleaser-split
gor-merge:
${GORELEASER_BIN} continue --merge

View File

@@ -3,12 +3,6 @@
# Do not modify this file
#
##################### Version #####################
version:
banner:
# Whether to enable the version banner on startup.
enabled: true
##################### Instrumentation #####################
instrumentation:
logs:
@@ -88,8 +82,6 @@ apiserver:
# List of routes to exclude from request responselogging.
excluded_routes:
- /api/v1/health
- /api/v1/version
- /
##################### TelemetryStore #####################

View File

@@ -177,7 +177,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.76.2}
image: signoz/signoz:${DOCKER_TAG:-v0.76.2}
container_name: signoz
command:
- --config=/root/config/prometheus.yml

View File

@@ -110,7 +110,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.76.2}
image: signoz/signoz:${DOCKER_TAG:-v0.76.2}
container_name: signoz
command:
- --config=/root/config/prometheus.yml

View File

@@ -110,7 +110,7 @@ services:
# - ../common/clickhouse/storage.xml:/etc/clickhouse-server/config.d/storage.xml
signoz:
!!merge <<: *db-depend
image: signoz/signoz:${VERSION:-v0.76.2}
image: signoz/signoz:${DOCKER_TAG:-v0.76.2}
container_name: signoz
command:
- --config=/root/config/prometheus.yml

View File

@@ -61,7 +61,7 @@ This command:
1. Run the backend server:
```bash
make go-run-community
make run-go
```
2. Verify it's working:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 KiB

View File

@@ -1,246 +0,0 @@
# Configuring OpenTelemetry Demo App with SigNoz
[The OpenTelemetry Astronomy Shop](https://github.com/open-telemetry/opentelemetry-demo) is an e-commerce web application, with **15 core microservices** in a **distributed system** which communicate over gRPC. Designed as a **polyglot** environment, it leverages a diverse set of programming languages, including Go, Python, .NET, Java, and others, showcasing cross-language instrumentation with OpenTelemetry. The intention is to get a quickstart application to send data and experience SigNoz firsthand.
This guide provides a step-by-step walkthrough for setting up the **OpenTelemetry Demo App** with **SigNoz** as backend for observability. It outlines steps to export telemetry data to **SigNoz self-hosted with Docker**, **SigNoz self-hosted with Kubernetes** and **SigNoz cloud**.
<br/>
__Table of Contents__
- [Send data to SigNoz Self-hosted with Docker](#send-data-to-signoz-self-hosted-with-docker)
- [Prerequisites](#prerequisites)
- [Clone the OpenTelemetry Demo App Repository](#clone-the-opentelemetry-demo-app-repository)
- [Modify OpenTelemetry Collector Config](#modify-opentelemetry-collector-config)
- [Start the OpenTelemetry Demo App](#start-the-opentelemetry-demo-app)
- [Monitor with SigNoz (Docker)](#monitor-with-signoz-docker)
- [Send data to SigNoz Self-hosted with Kubernetes](#send-data-to-signoz-self-hosted-with-kubernetes)
- [Prerequisites](#prerequisites-1)
- [Install Helm Repo and Charts](#install-helm-repo-and-charts)
- [Start the OpenTelemetry Demo App](#start-the-opentelemetry-demo-app-1)
- [Moniitor with SigNoz (Kubernetes)](#monitor-with-signoz-kubernetes)
- [What's next](#whats-next)
# Send data to SigNoz Self-hosted with Docker
In this guide you will install the OTel demo application using Docker and send telemetry data to SigNoz hosted with Docker, referred as SigNoz [Docker] from now.
## Prerequisites
- Docker and Docker Compose installed
- 6 GB of RAM for the application [as per OpenTelemetry documentation]
- Nice to have Docker Desktop, for easy monitoring
## Clone the OpenTelemetry Demo App Repository
Clone the OTel demo app to any folder of your choice.
```sh
# Clone the OpenTelemetry Demo repository
git clone https://github.com/open-telemetry/opentelemetry-demo.git
cd opentelemetry-demo
```
## Modify OpenTelemetry Collector Config
By default, the collector in the demo application will merge the configuration from two files:
1. otelcol-config.yml &nbsp;&nbsp;[we don't touch this]
2. otelcol-config-extras.yml &nbsp;&nbsp; [we modify this]
To add SigNoz [Docker] as the backend, open the file `src/otel-collector/otelcol-config-extras.yml` and add the following,
```yaml
exporters:
otlp:
endpoint: "http://host.docker.internal:4317"
tls:
insecure: true
debug:
verbosity: detailed
service:
pipelines:
metrics:
exporters: [otlp]
traces:
exporters: [spanmetrics, otlp]
logs:
exporters: [otlp]
```
The SigNoz OTel collector [sigNoz's otel-collector service] listens at 4317 port on localhost. When the OTel demo app is running within a Docker container and needs to transmit telemetry data to SigNoz, it cannot directly reference 'localhost' as this would refer to the container's own internal network. Instead, Docker provides a special DNS name, `host.docker.internal`, which resolves to the host machine's IP address from within containers. By configuring the OpenTelemetry Demo application to send data to `host.docker.internal:4317`, we establish a network path that allows the containerized application to transmit telemetry data across the container boundary to the SigNoz OTel collector running on the host machine's port 4317.
>
> Note: When merging extra configuration values with the existing collector config (`src/otel-collector/otelcol-config.yml`), objects are merged and arrays are replaced resulting in previous pipeline configurations getting overridden.
The spanmetrics exporter must be included in the array of exporters for the traces pipeline if overridden. Not including this exporter will result in an error.
>
<br>
<u>To send data to SigNoz Cloud</u>
If you want to send data to cloud instead, open the file `src/otel-collector/otelcol-config-extras.yml` and add the following,
```yaml
exporters:
otlp:
endpoint: "https://ingest.{your-region}.signoz.cloud:443"
tls:
insecure: false
headers:
signoz-access-token: <SIGNOZ-KEY>
debug:
verbosity: detailed
service:
pipelines:
metrics:
exporters: [otlp]
traces:
exporters: [spanmetrics, otlp]
logs:
exporters: [otlp]
```
Remember to replace the region and ingestion key with proper values as obtained from your account.
## Start the OpenTelemetry Demo App
Both SigNoz and OTel demo app [frontend-proxy service, to be accurate] share common port allocation at 8080. To prevent port allocation conflicts, modify the OTel demo application config to use port 8081 as the `ENVOY_PORT` value as shown below, and run docker compose command.
```sh
ENVOY_PORT=8081 docker compose up -d
```
This spins up multiple microservices, with OpenTelemetry instrumentation enabled. you can verify this by,
```sh
docker compose ps -a
```
The result should look similar to this,
![](/docs/img/otel-demo-docker-containers.png)
Navigate to `http://localhost:8081/` where you can access OTel demo app UI. Generate some traffic to send to SigNoz [Docker].
## Monitor with SigNoz [Docker]
Signoz exposes its UI at `http://localhost:8080/`. You should be able to see multiple services listed down as shown in the snapshot below.
![](/docs/img/otel-demo-services.png)
This verifies that your OTel demo app is successfully sending telemetry data to SigNoz [Docker] as expected.
# Send data to SigNoz Self-hosted with Kubernetes
In this guide you will install the OTel demo application using Helm and send telemetry data to SigNoz hosted with Kubernetes, referred as SigNoz [Kubernetes] from now.
## Prerequisites
- Helm charts installed
- 6 GB of free RAM for the application [as per OpenTelemetry documentation]
- A kubernetes cluster (EKS, GKE, Minikube)
- kubectl [CLI for Kubernetes]
>Note: We will be installing OTel demo app using Helm charts, since it is recommended by OpenTelemetry. If you wish to install using kubectl, follow [this](https://opentelemetry.io/docs/demo/kubernetes-deployment/#install-using-kubectl).
## Install Helm Repo and Charts
Youll need to **install the Helm repository** to start sending data to SigNoz cloud.
```sh
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
```
The OpenTelemetry Collectors configuration is exposed in the Helm chart. All additions made will be merged into the default configuration. We use this capability to add SigNoz as an exporter, and make pipelines as desired.
For this we have to create a `values.yaml` which will override the existing configurations that comes with the Helm chart.
```yaml
default:
env:
- name: OTEL_SERVICE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: "metadata.labels['app.kubernetes.io/component']"
- name: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
value: cumulative
- name: OTEL_RESOURCE_ATTRIBUTES
value: 'service.name=$(OTEL_SERVICE_NAME),service.namespace=opentelemetry-demo'
- name: OTEL_COLLECTOR_NAME
value: signoz-otel-collector.<namespace>.svc.cluster.local
```
Replace namespace with your appropriate namespace. This file will replace the charts existing settings with our new ones, ensuring telemetry data is sent to SigNoz [Kubernetes].
> Note: When merging YAML values with Helm, objects are merged and arrays are replaced. The spanmetrics exporter must be included in the array of exporters for the traces pipeline if overridden. Not including this exporter will result in an error.
<br>
<u>To send data to SigNoz cloud</u>
If you wish to send data to cloud instance of SigNoz, we have to create a `values.yaml` which will override the existing configurations that comes with the Helm chart.
```sh
opentelemetry-collector:
config:
exporters:
otlp:
endpoint: "https://ingest.{your-region}.signoz.cloud:443"
tls:
insecure: false
headers:
signoz-access-token: <SIGNOZ-KEY>
debug:
verbosity: detailed
service:
pipelines:
traces:
exporters: [spanmetrics, otlp]
metrics:
exporters: [otlp]
logs:
exporters: [otlp]
```
Make sure to replace the region and key with values obtained from the account
Now **install the helm chart** with a release name and namespace of your choice. Let's take *my-otel-demo* as the release name and *otel-demo* as the namespace for the context of the code snippet below,
```sh
# Create a new Kubernetes namespace called "otel-demo"
kubectl create namespace otel-demo
# Install the OpenTelemetry Demo Helm chart with the release name "my-otel-demo"
helm install my-otel-demo open-telemetry/opentelemetry-demo --namespace otel-demo -f values.yaml
```
You should see a similar output on your terminal,
![](/docs/img/otel-demo-helm.png)
To verify if all the pods are running,
```sh
kubectl get pods -n otel-demo
```
The output should look similar to this,
![](/docs/img/otel-demo-pods.png)
## Start the OpenTelemetry Demo App
To expose the OTel demo app UI [frontend-proxy service] use the following command (replace my-otel-demo with your Helm chart release name):
```sh
kubectl port-forward svc/my-otel-demo-frontend-proxy 8080:8081
```
Navigate to `http://localhost:8081/` where you can access OTel demo app UI. Generate some traffic to send to SigNoz [Kubernetes].
## Monitor with SigNoz [Kubernetes]
Signoz exposes it's UI at `http://localhost:8080/`. You should be able to see multiple services listed down as shown in the snapshot below.
![](/docs/img/otel-demo-services.png)
This verifies that your OTel demo app is successfully sending telemetry data to SigNoz [Kubernetes] as expected.
# What's next?
Don't forget to check our OpenTelemetry [track](https://signoz.io/resource-center/opentelemetry/), guaranteed to take you from a newbie to sensei in no time!
Also from a fellow OTel fan to another, we at [SigNoz](https://signoz.io/) are building an open-source, OTel native, observability platform (one of its kind). So, show us love - star us on [GitHub](https://github.com/SigNoz/signoz), nitpick our [docs](https://signoz.io/docs/introduction/), or just tell your app were the ones wholl catch its crashes mid-flight and finally shush all the 3am panic calls!

View File

@@ -2,30 +2,22 @@ package middleware
import (
"net/http"
"time"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"go.uber.org/zap"
"go.signoz.io/signoz/pkg/types/authtypes"
)
type Pat struct {
store sqlstore.SQLStore
uuid *authtypes.UUID
headers []string
}
func NewPat(store sqlstore.SQLStore, headers []string) *Pat {
return &Pat{store: store, uuid: authtypes.NewUUID(), headers: headers}
func NewPat(headers []string) *Pat {
return &Pat{uuid: authtypes.NewUUID(), headers: headers}
}
func (p *Pat) Wrap(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var values []string
var patToken string
var pat types.StorablePersonalAccessToken
for _, header := range p.headers {
values = append(values, r.Header.Get(header))
}
@@ -35,50 +27,10 @@ func (p *Pat) Wrap(next http.Handler) http.Handler {
next.ServeHTTP(w, r)
return
}
patToken, ok := authtypes.UUIDFromContext(ctx)
if !ok {
next.ServeHTTP(w, r)
return
}
err = p.store.BunDB().NewSelect().Model(&pat).Where("token = ?", patToken).Scan(r.Context())
if err != nil {
next.ServeHTTP(w, r)
return
}
if pat.ExpiresAt < time.Now().Unix() && pat.ExpiresAt != 0 {
next.ServeHTTP(w, r)
return
}
// get user from db
user := types.User{}
err = p.store.BunDB().NewSelect().Model(&user).Where("id = ?", pat.UserID).Scan(r.Context())
if err != nil {
next.ServeHTTP(w, r)
return
}
jwt := authtypes.Claims{
UserID: user.ID,
GroupID: user.GroupID,
Email: user.Email,
OrgID: user.OrgID,
}
ctx = authtypes.NewContextWithClaims(ctx, jwt)
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
pat.LastUsed = time.Now().Unix()
_, err = p.store.BunDB().NewUpdate().Model(&pat).Column("last_used").Where("token = ?", patToken).Where("revoked = false").Exec(r.Context())
if err != nil {
zap.L().Error("Failed to update PAT last used in db, err: %v", zap.Error(err))
}
})
}

View File

@@ -30,13 +30,15 @@ builds:
- v8.0
ldflags:
- -s -w
- -X github.com/SigNoz/signoz/pkg/version.version=v{{ .Version }}
- -X github.com/SigNoz/signoz/pkg/version.variant=enterprise
- -X github.com/SigNoz/signoz/pkg/version.hash={{ .ShortCommit }}
- -X github.com/SigNoz/signoz/pkg/version.time={{ .CommitTimestamp }}
- -X github.com/SigNoz/signoz/pkg/version.branch={{ .Branch }}
- -X github.com/SigNoz/signoz/ee/query-service/constants.ZeusURL=https://api.signoz.cloud
- -X github.com/SigNoz/signoz/ee/query-service/constants.LicenseSignozIo=https://license.signoz.io/api/v1
- -X github.com/SigNoz/signoz/pkg/query-service/version.version={{ .Version }}
- -X main.commit={{ .Commit }} -X main.date={{ .CommitDate }}
- -X main.builtBy=goreleaser
- -X go.signoz.io/signoz/pkg/query-service/version.buildVersion={{ .Version }}
- -X go.signoz.io/signoz/pkg/query-service/version.buildHash={{ .ShortCommit }}
- -X go.signoz.io/signoz/pkg/query-service/version.buildTime={{ .Date }}
- -X go.signoz.io/signoz/pkg/query-service/version.gitBranch={{ .Branch }}
- -X go.signoz.io/signoz/ee/query-service/constants.ZeusURL=https://api.signoz.cloud
- -X go.signoz.io/signoz/ee/query-service/constants.LicenseSignozIo=https://license.signoz.io/api/v1
- >-
{{- if eq .Os "linux" }}-linkmode external -extldflags '-static'{{- end }}
mod_timestamp: "{{ .CommitTimestamp }}"

View File

@@ -1,21 +1,34 @@
# use a minimal alpine image
FROM alpine:3.20.3
# Add Maintainer Info
LABEL maintainer="signoz"
# define arguments that can be passed during build time
ARG TARGETOS TARGETARCH
# add ca-certificates in case you need them
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
# set working directory
WORKDIR /root
ARG OS="linux"
ARG TARGETARCH
# copy the signoz binary
COPY ee/query-service/bin/signoz-${TARGETOS}-${TARGETARCH} /root/signoz
RUN apk update && \
apk add ca-certificates && \
rm -rf /var/cache/apk/*
COPY ./target/${OS}-${TARGETARCH}/signoz /root/signoz
COPY ./conf/prometheus.yml /root/config/prometheus.yml
COPY ./templates/email /root/templates
COPY frontend/build/ /etc/signoz/web/
# copy prometheus YAML config
COPY pkg/query-service/config/prometheus.yml /root/config/prometheus.yml
COPY pkg/query-service/templates /root/templates
# Make signoz executable for non-root users
RUN chmod 755 /root /root/signoz
# Copy frontend
COPY frontend/build/ /etc/signoz/web/
# run the binary
ENTRYPOINT ["./signoz"]
CMD ["-config", "/root/config/prometheus.yml"]
EXPOSE 8080

View File

@@ -3,8 +3,8 @@ package anomaly
import (
"context"
querierV2 "github.com/SigNoz/signoz/pkg/query-service/app/querier/v2"
"github.com/SigNoz/signoz/pkg/query-service/app/queryBuilder"
querierV2 "go.signoz.io/signoz/pkg/query-service/app/querier/v2"
"go.signoz.io/signoz/pkg/query-service/app/queryBuilder"
)
type DailyProvider struct {

View File

@@ -3,8 +3,8 @@ package anomaly
import (
"context"
querierV2 "github.com/SigNoz/signoz/pkg/query-service/app/querier/v2"
"github.com/SigNoz/signoz/pkg/query-service/app/queryBuilder"
querierV2 "go.signoz.io/signoz/pkg/query-service/app/querier/v2"
"go.signoz.io/signoz/pkg/query-service/app/queryBuilder"
)
type HourlyProvider struct {

View File

@@ -4,8 +4,8 @@ import (
"math"
"time"
"github.com/SigNoz/signoz/pkg/query-service/common"
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
"go.signoz.io/signoz/pkg/query-service/common"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
)
type Seasonality string

View File

@@ -5,11 +5,11 @@ import (
"math"
"time"
"github.com/SigNoz/signoz/pkg/query-service/cache"
"github.com/SigNoz/signoz/pkg/query-service/interfaces"
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
"github.com/SigNoz/signoz/pkg/query-service/postprocess"
"github.com/SigNoz/signoz/pkg/query-service/utils/labels"
"go.signoz.io/signoz/pkg/query-service/cache"
"go.signoz.io/signoz/pkg/query-service/interfaces"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
"go.signoz.io/signoz/pkg/query-service/postprocess"
"go.signoz.io/signoz/pkg/query-service/utils/labels"
"go.uber.org/zap"
)

View File

@@ -3,8 +3,8 @@ package anomaly
import (
"context"
querierV2 "github.com/SigNoz/signoz/pkg/query-service/app/querier/v2"
"github.com/SigNoz/signoz/pkg/query-service/app/queryBuilder"
querierV2 "go.signoz.io/signoz/pkg/query-service/app/querier/v2"
"go.signoz.io/signoz/pkg/query-service/app/queryBuilder"
)
type WeeklyProvider struct {

View File

@@ -5,24 +5,24 @@ import (
"net/http/httputil"
"time"
"github.com/SigNoz/signoz/ee/query-service/dao"
"github.com/SigNoz/signoz/ee/query-service/integrations/gateway"
"github.com/SigNoz/signoz/ee/query-service/interfaces"
"github.com/SigNoz/signoz/ee/query-service/license"
"github.com/SigNoz/signoz/ee/query-service/usage"
"github.com/SigNoz/signoz/pkg/alertmanager"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations"
"github.com/SigNoz/signoz/pkg/query-service/app/logparsingpipeline"
"github.com/SigNoz/signoz/pkg/query-service/cache"
baseint "github.com/SigNoz/signoz/pkg/query-service/interfaces"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
rules "github.com/SigNoz/signoz/pkg/query-service/rules"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/version"
"github.com/gorilla/mux"
"go.signoz.io/signoz/ee/query-service/dao"
"go.signoz.io/signoz/ee/query-service/integrations/gateway"
"go.signoz.io/signoz/ee/query-service/interfaces"
"go.signoz.io/signoz/ee/query-service/license"
"go.signoz.io/signoz/ee/query-service/usage"
"go.signoz.io/signoz/pkg/alertmanager"
baseapp "go.signoz.io/signoz/pkg/query-service/app"
"go.signoz.io/signoz/pkg/query-service/app/cloudintegrations"
"go.signoz.io/signoz/pkg/query-service/app/integrations"
"go.signoz.io/signoz/pkg/query-service/app/logparsingpipeline"
"go.signoz.io/signoz/pkg/query-service/cache"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
rules "go.signoz.io/signoz/pkg/query-service/rules"
"go.signoz.io/signoz/pkg/query-service/version"
"go.signoz.io/signoz/pkg/signoz"
"go.signoz.io/signoz/pkg/types/authtypes"
)
type APIHandlerOptions struct {
@@ -200,8 +200,9 @@ func (ah *APIHandler) RegisterCloudIntegrationsRoutes(router *mux.Router, am *ba
}
func (ah *APIHandler) getVersion(w http.ResponseWriter, r *http.Request) {
version := version.GetVersion()
versionResponse := basemodel.GetVersionResponse{
Version: version.Info.Version(),
Version: version,
EE: "Y",
SetupCompleted: ah.SetupCompleted,
}

View File

@@ -12,10 +12,10 @@ import (
"github.com/gorilla/mux"
"go.uber.org/zap"
"github.com/SigNoz/signoz/ee/query-service/constants"
"github.com/SigNoz/signoz/ee/query-service/model"
baseauth "github.com/SigNoz/signoz/pkg/query-service/auth"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/model"
baseauth "go.signoz.io/signoz/pkg/query-service/auth"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
)
func parseRequest(r *http.Request, req interface{}) error {

View File

@@ -10,15 +10,15 @@ import (
"strings"
"time"
"github.com/SigNoz/signoz/ee/query-service/constants"
"github.com/SigNoz/signoz/ee/query-service/model"
"github.com/SigNoz/signoz/pkg/query-service/auth"
baseconstants "github.com/SigNoz/signoz/pkg/query-service/constants"
"github.com/SigNoz/signoz/pkg/query-service/dao"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/types"
"github.com/google/uuid"
"github.com/gorilla/mux"
"go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/model"
"go.signoz.io/signoz/pkg/query-service/auth"
baseconstants "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/dao"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/types"
"go.uber.org/zap"
)
@@ -118,7 +118,7 @@ func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId
return "", apiErr
}
allPats, err := ah.AppDao().ListPATs(ctx, orgId)
allPats, err := ah.AppDao().ListPATs(ctx)
if err != nil {
return "", basemodel.InternalError(fmt.Errorf(
"couldn't list PATs: %w", err,
@@ -136,19 +136,15 @@ func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId
)
newPAT := model.PAT{
StorablePersonalAccessToken: types.StorablePersonalAccessToken{
Token: generatePATToken(),
UserID: integrationUser.ID,
Name: integrationPATName,
Role: baseconstants.ViewerGroup,
ExpiresAt: 0,
TimeAuditable: types.TimeAuditable{
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
},
Token: generatePATToken(),
UserID: integrationUser.ID,
Name: integrationPATName,
Role: baseconstants.ViewerGroup,
ExpiresAt: 0,
CreatedAt: time.Now().Unix(),
UpdatedAt: time.Now().Unix(),
}
integrationPAT, err := ah.AppDao().CreatePAT(ctx, orgId, newPAT)
integrationPAT, err := ah.AppDao().CreatePAT(ctx, newPAT)
if err != nil {
return "", basemodel.InternalError(fmt.Errorf(
"couldn't create cloud integration PAT: %w", err,

View File

@@ -4,12 +4,12 @@ import (
"net/http"
"strings"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/query-service/app/dashboards"
"github.com/SigNoz/signoz/pkg/query-service/auth"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/gorilla/mux"
"go.signoz.io/signoz/pkg/errors"
"go.signoz.io/signoz/pkg/http/render"
"go.signoz.io/signoz/pkg/query-service/app/dashboards"
"go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/types/authtypes"
)
func (ah *APIHandler) lockDashboard(w http.ResponseWriter, r *http.Request) {

View File

@@ -6,10 +6,9 @@ import (
"fmt"
"net/http"
"github.com/SigNoz/signoz/ee/query-service/model"
"github.com/SigNoz/signoz/ee/types"
"github.com/google/uuid"
"github.com/gorilla/mux"
"go.signoz.io/signoz/ee/query-service/model"
)
func (ah *APIHandler) listDomainsByOrg(w http.ResponseWriter, r *http.Request) {
@@ -25,7 +24,7 @@ func (ah *APIHandler) listDomainsByOrg(w http.ResponseWriter, r *http.Request) {
func (ah *APIHandler) postDomain(w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
req := types.GettableOrgDomain{}
req := model.OrgDomain{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
RespondError(w, model.BadRequest(err), nil)
@@ -55,12 +54,12 @@ func (ah *APIHandler) putDomain(w http.ResponseWriter, r *http.Request) {
return
}
req := types.GettableOrgDomain{StorableOrgDomain: types.StorableOrgDomain{ID: domainId}}
req := model.OrgDomain{Id: domainId}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
RespondError(w, model.BadRequest(err), nil)
return
}
req.ID = domainId
req.Id = domainId
if err := req.Valid(nil); err != nil {
RespondError(w, model.BadRequest(err), nil)
}

View File

@@ -8,8 +8,8 @@ import (
"net/http"
"time"
"github.com/SigNoz/signoz/ee/query-service/constants"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"go.signoz.io/signoz/ee/query-service/constants"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)

View File

@@ -3,8 +3,8 @@ package api
import (
"testing"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/stretchr/testify/assert"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
)
func TestMergeFeatureSets(t *testing.T) {

View File

@@ -4,7 +4,7 @@ import (
"net/http"
"strings"
"github.com/SigNoz/signoz/ee/query-service/integrations/gateway"
"go.signoz.io/signoz/ee/query-service/integrations/gateway"
)
func (ah *APIHandler) ServeGatewayHTTP(rw http.ResponseWriter, req *http.Request) {

View File

@@ -5,10 +5,10 @@ import (
"fmt"
"net/http"
"github.com/SigNoz/signoz/ee/query-service/constants"
"github.com/SigNoz/signoz/ee/query-service/integrations/signozio"
"github.com/SigNoz/signoz/ee/query-service/model"
"github.com/SigNoz/signoz/pkg/http/render"
"go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/integrations/signozio"
"go.signoz.io/signoz/ee/query-service/model"
"go.signoz.io/signoz/pkg/http/render"
)
type DayWiseBreakdown struct {

View File

@@ -9,12 +9,11 @@ import (
"net/http"
"time"
"github.com/SigNoz/signoz/ee/query-service/model"
"github.com/SigNoz/signoz/pkg/query-service/auth"
baseconstants "github.com/SigNoz/signoz/pkg/query-service/constants"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/types"
"github.com/gorilla/mux"
"go.signoz.io/signoz/ee/query-service/model"
"go.signoz.io/signoz/pkg/query-service/auth"
baseconstants "go.signoz.io/signoz/pkg/query-service/constants"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)
@@ -44,11 +43,9 @@ func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
return
}
pat := model.PAT{
StorablePersonalAccessToken: types.StorablePersonalAccessToken{
Name: req.Name,
Role: req.Role,
ExpiresAt: req.ExpiresInDays,
},
Name: req.Name,
Role: req.Role,
ExpiresAt: req.ExpiresInDays,
}
err = validatePATRequest(pat)
if err != nil {
@@ -58,8 +55,8 @@ func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
// All the PATs are associated with the user creating the PAT.
pat.UserID = user.ID
pat.CreatedAt = time.Now()
pat.UpdatedAt = time.Now()
pat.CreatedAt = time.Now().Unix()
pat.UpdatedAt = time.Now().Unix()
pat.LastUsed = 0
pat.Token = generatePATToken()
@@ -70,7 +67,7 @@ func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
zap.L().Info("Got Create PAT request", zap.Any("pat", pat))
var apierr basemodel.BaseApiError
if pat, apierr = ah.AppDao().CreatePAT(ctx, user.OrgID, pat); apierr != nil {
if pat, apierr = ah.AppDao().CreatePAT(ctx, pat); apierr != nil {
RespondError(w, apierr, nil)
return
}
@@ -117,10 +114,10 @@ func (ah *APIHandler) updatePAT(w http.ResponseWriter, r *http.Request) {
req.UpdatedByUserID = user.ID
id := mux.Vars(r)["id"]
req.UpdatedAt = time.Now()
req.UpdatedAt = time.Now().Unix()
zap.L().Info("Got Update PAT request", zap.Any("pat", req))
var apierr basemodel.BaseApiError
if apierr = ah.AppDao().UpdatePAT(ctx, user.OrgID, req, id); apierr != nil {
if apierr = ah.AppDao().UpdatePAT(ctx, req, id); apierr != nil {
RespondError(w, apierr, nil)
return
}
@@ -139,7 +136,7 @@ func (ah *APIHandler) getPATs(w http.ResponseWriter, r *http.Request) {
return
}
zap.L().Info("Get PATs for user", zap.String("user_id", user.ID))
pats, apierr := ah.AppDao().ListPATs(ctx, user.OrgID)
pats, apierr := ah.AppDao().ListPATs(ctx)
if apierr != nil {
RespondError(w, apierr, nil)
return
@@ -160,7 +157,7 @@ func (ah *APIHandler) revokePAT(w http.ResponseWriter, r *http.Request) {
}
zap.L().Info("Revoke PAT with id", zap.String("id", id))
if apierr := ah.AppDao().RevokePAT(ctx, user.OrgID, id, user.ID); apierr != nil {
if apierr := ah.AppDao().RevokePAT(ctx, id, user.ID); apierr != nil {
RespondError(w, apierr, nil)
return
}

View File

@@ -6,11 +6,11 @@ import (
"io"
"net/http"
"github.com/SigNoz/signoz/ee/query-service/anomaly"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
"github.com/SigNoz/signoz/pkg/query-service/app/queryBuilder"
"github.com/SigNoz/signoz/pkg/query-service/model"
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
"go.signoz.io/signoz/ee/query-service/anomaly"
baseapp "go.signoz.io/signoz/pkg/query-service/app"
"go.signoz.io/signoz/pkg/query-service/app/queryBuilder"
"go.signoz.io/signoz/pkg/query-service/model"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
"go.uber.org/zap"
)

View File

@@ -3,8 +3,8 @@ package api
import (
"net/http"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
baseapp "go.signoz.io/signoz/pkg/query-service/app"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
)
func RespondError(w http.ResponseWriter, apiErr basemodel.BaseApiError, data interface{}) {

View File

@@ -3,10 +3,10 @@ package api
import (
"net/http"
"github.com/SigNoz/signoz/ee/query-service/app/db"
"github.com/SigNoz/signoz/ee/query-service/model"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"go.signoz.io/signoz/ee/query-service/app/db"
"go.signoz.io/signoz/ee/query-service/model"
baseapp "go.signoz.io/signoz/pkg/query-service/app"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)

View File

@@ -7,9 +7,9 @@ import (
"github.com/jmoiron/sqlx"
"github.com/SigNoz/signoz/pkg/cache"
basechr "github.com/SigNoz/signoz/pkg/query-service/app/clickhouseReader"
"github.com/SigNoz/signoz/pkg/query-service/interfaces"
"go.signoz.io/signoz/pkg/cache"
basechr "go.signoz.io/signoz/pkg/query-service/app/clickhouseReader"
"go.signoz.io/signoz/pkg/query-service/interfaces"
)
type ClickhouseReader struct {

View File

@@ -4,8 +4,8 @@ import (
"errors"
"strconv"
"github.com/SigNoz/signoz/ee/query-service/model"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)

View File

@@ -12,47 +12,47 @@ import (
"github.com/gorilla/handlers"
"github.com/jmoiron/sqlx"
eemiddleware "github.com/SigNoz/signoz/ee/http/middleware"
"github.com/SigNoz/signoz/ee/query-service/app/api"
"github.com/SigNoz/signoz/ee/query-service/app/db"
"github.com/SigNoz/signoz/ee/query-service/constants"
"github.com/SigNoz/signoz/ee/query-service/dao"
"github.com/SigNoz/signoz/ee/query-service/integrations/gateway"
"github.com/SigNoz/signoz/ee/query-service/interfaces"
"github.com/SigNoz/signoz/ee/query-service/rules"
"github.com/SigNoz/signoz/pkg/alertmanager"
"github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/query-service/auth"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/web"
"github.com/rs/cors"
"github.com/soheilhy/cmux"
eemiddleware "go.signoz.io/signoz/ee/http/middleware"
"go.signoz.io/signoz/ee/query-service/app/api"
"go.signoz.io/signoz/ee/query-service/app/db"
"go.signoz.io/signoz/ee/query-service/auth"
"go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/dao"
"go.signoz.io/signoz/ee/query-service/integrations/gateway"
"go.signoz.io/signoz/ee/query-service/interfaces"
"go.signoz.io/signoz/ee/query-service/rules"
"go.signoz.io/signoz/pkg/alertmanager"
"go.signoz.io/signoz/pkg/http/middleware"
"go.signoz.io/signoz/pkg/signoz"
"go.signoz.io/signoz/pkg/sqlstore"
"go.signoz.io/signoz/pkg/types"
"go.signoz.io/signoz/pkg/types/authtypes"
"go.signoz.io/signoz/pkg/web"
licensepkg "github.com/SigNoz/signoz/ee/query-service/license"
"github.com/SigNoz/signoz/ee/query-service/usage"
licensepkg "go.signoz.io/signoz/ee/query-service/license"
"go.signoz.io/signoz/ee/query-service/usage"
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
"github.com/SigNoz/signoz/pkg/query-service/app/dashboards"
baseexplorer "github.com/SigNoz/signoz/pkg/query-service/app/explorer"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations"
"github.com/SigNoz/signoz/pkg/query-service/app/logparsingpipeline"
"github.com/SigNoz/signoz/pkg/query-service/app/opamp"
opAmpModel "github.com/SigNoz/signoz/pkg/query-service/app/opamp/model"
"github.com/SigNoz/signoz/pkg/query-service/app/preferences"
"github.com/SigNoz/signoz/pkg/query-service/cache"
baseconst "github.com/SigNoz/signoz/pkg/query-service/constants"
"github.com/SigNoz/signoz/pkg/query-service/healthcheck"
baseint "github.com/SigNoz/signoz/pkg/query-service/interfaces"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
pqle "github.com/SigNoz/signoz/pkg/query-service/pqlEngine"
baserules "github.com/SigNoz/signoz/pkg/query-service/rules"
"github.com/SigNoz/signoz/pkg/query-service/telemetry"
"github.com/SigNoz/signoz/pkg/query-service/utils"
"go.signoz.io/signoz/pkg/query-service/agentConf"
baseapp "go.signoz.io/signoz/pkg/query-service/app"
"go.signoz.io/signoz/pkg/query-service/app/cloudintegrations"
"go.signoz.io/signoz/pkg/query-service/app/dashboards"
baseexplorer "go.signoz.io/signoz/pkg/query-service/app/explorer"
"go.signoz.io/signoz/pkg/query-service/app/integrations"
"go.signoz.io/signoz/pkg/query-service/app/logparsingpipeline"
"go.signoz.io/signoz/pkg/query-service/app/opamp"
opAmpModel "go.signoz.io/signoz/pkg/query-service/app/opamp/model"
"go.signoz.io/signoz/pkg/query-service/app/preferences"
"go.signoz.io/signoz/pkg/query-service/cache"
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/healthcheck"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
pqle "go.signoz.io/signoz/pkg/query-service/pqlEngine"
baserules "go.signoz.io/signoz/pkg/query-service/rules"
"go.signoz.io/signoz/pkg/query-service/telemetry"
"go.signoz.io/signoz/pkg/query-service/utils"
"go.uber.org/zap"
)
@@ -112,7 +112,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
return nil, err
}
if err := baseexplorer.InitWithDSN(serverOptions.SigNoz.SQLStore); err != nil {
if err := baseexplorer.InitWithDSN(serverOptions.SigNoz.SQLStore.BunDB()); err != nil {
return nil, err
}
@@ -120,7 +120,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
return nil, err
}
if err := dashboards.InitDB(serverOptions.SigNoz.SQLStore); err != nil {
if err := dashboards.InitDB(serverOptions.SigNoz.SQLStore.BunDB()); err != nil {
return nil, err
}
@@ -130,7 +130,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
}
// initiate license manager
lm, err := licensepkg.StartManager(serverOptions.SigNoz.SQLStore.SQLxDB(), serverOptions.SigNoz.SQLStore)
lm, err := licensepkg.StartManager(serverOptions.SigNoz.SQLStore.SQLxDB(), serverOptions.SigNoz.SQLStore.BunDB())
if err != nil {
return nil, err
}
@@ -217,7 +217,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
// ingestion pipelines manager
logParsingPipelineController, err := logparsingpipeline.NewLogParsingPipelinesController(
serverOptions.SigNoz.SQLStore, integrationsController.GetPipelinesForInstalledIntegrations,
serverOptions.SigNoz.SQLStore.SQLxDB(), integrationsController.GetPipelinesForInstalledIntegrations,
)
if err != nil {
return nil, err
@@ -317,7 +317,7 @@ func (s *Server) createPrivateServer(apiHandler *api.APIHandler) (*http.Server,
r := baseapp.NewRouter()
r.Use(middleware.NewAuth(zap.L(), s.serverOptions.Jwt, []string{"Authorization", "Sec-WebSocket-Protocol"}).Wrap)
r.Use(eemiddleware.NewPat(s.serverOptions.SigNoz.SQLStore, []string{"SIGNOZ-API-KEY"}).Wrap)
r.Use(eemiddleware.NewPat([]string{"SIGNOZ-API-KEY"}).Wrap)
r.Use(middleware.NewTimeout(zap.L(),
s.serverOptions.Config.APIServer.Timeout.ExcludedRoutes,
s.serverOptions.Config.APIServer.Timeout.Default,
@@ -350,7 +350,7 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler, web web.Web) (*h
// add auth middleware
getUserFromRequest := func(ctx context.Context) (*types.GettableUser, error) {
user, err := auth.GetUserFromReqContext(ctx)
user, err := auth.GetUserFromRequestContext(ctx, apiHandler)
if err != nil {
return nil, err
@@ -365,7 +365,7 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler, web web.Web) (*h
am := baseapp.NewAuthMiddleware(getUserFromRequest)
r.Use(middleware.NewAuth(zap.L(), s.serverOptions.Jwt, []string{"Authorization", "Sec-WebSocket-Protocol"}).Wrap)
r.Use(eemiddleware.NewPat(s.serverOptions.SigNoz.SQLStore, []string{"SIGNOZ-API-KEY"}).Wrap)
r.Use(eemiddleware.NewPat([]string{"SIGNOZ-API-KEY"}).Wrap)
r.Use(middleware.NewTimeout(zap.L(),
s.serverOptions.Config.APIServer.Timeout.ExcludedRoutes,
s.serverOptions.Config.APIServer.Timeout.Default,

View File

@@ -0,0 +1,56 @@
package auth
import (
"context"
"fmt"
"time"
"go.signoz.io/signoz/ee/query-service/app/api"
baseauth "go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/query-service/telemetry"
"go.signoz.io/signoz/pkg/types"
"go.signoz.io/signoz/pkg/types/authtypes"
"go.uber.org/zap"
)
func GetUserFromRequestContext(ctx context.Context, apiHandler *api.APIHandler) (*types.GettableUser, error) {
patToken, ok := authtypes.UUIDFromContext(ctx)
if ok && patToken != "" {
zap.L().Debug("Received a non-zero length PAT token")
ctx := context.Background()
dao := apiHandler.AppDao()
pat, err := dao.GetPAT(ctx, patToken)
if err == nil && pat != nil {
zap.L().Debug("Found valid PAT: ", zap.Any("pat", pat))
if pat.ExpiresAt < time.Now().Unix() && pat.ExpiresAt != 0 {
zap.L().Info("PAT has expired: ", zap.Any("pat", pat))
return nil, fmt.Errorf("PAT has expired")
}
group, apiErr := dao.GetGroupByName(ctx, pat.Role)
if apiErr != nil {
zap.L().Error("Error while getting group for PAT: ", zap.Any("apiErr", apiErr))
return nil, apiErr
}
user, err := dao.GetUser(ctx, pat.UserID)
if err != nil {
zap.L().Error("Error while getting user for PAT: ", zap.Error(err))
return nil, err
}
telemetry.GetInstance().SetPatTokenUser()
dao.UpdatePATLastUsed(ctx, patToken, time.Now().Unix())
user.User.GroupID = group.ID
user.User.ID = pat.Id
return &types.GettableUser{
User: user.User,
Role: pat.Role,
}, nil
}
if err != nil {
zap.L().Error("Error while getting user for PAT: ", zap.Error(err))
return nil, err
}
}
return baseauth.GetUserFromReqContext(ctx)
}

View File

@@ -1,8 +1,8 @@
package dao
import (
"github.com/SigNoz/signoz/ee/query-service/dao/sqlite"
"github.com/SigNoz/signoz/pkg/sqlstore"
"go.signoz.io/signoz/ee/query-service/dao/sqlite"
"go.signoz.io/signoz/pkg/sqlstore"
)
func InitDao(sqlStore sqlstore.SQLStore) (ModelDao, error) {

View File

@@ -4,15 +4,14 @@ import (
"context"
"net/url"
"github.com/SigNoz/signoz/ee/query-service/model"
"github.com/SigNoz/signoz/ee/types"
basedao "github.com/SigNoz/signoz/pkg/query-service/dao"
baseint "github.com/SigNoz/signoz/pkg/query-service/interfaces"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
ossTypes "github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/google/uuid"
"github.com/uptrace/bun"
"github.com/jmoiron/sqlx"
"go.signoz.io/signoz/ee/query-service/model"
basedao "go.signoz.io/signoz/pkg/query-service/dao"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/types"
"go.signoz.io/signoz/pkg/types/authtypes"
)
type ModelDao interface {
@@ -21,26 +20,27 @@ type ModelDao interface {
// SetFlagProvider sets the feature lookup provider
SetFlagProvider(flags baseint.FeatureLookup)
DB() *bun.DB
DB() *sqlx.DB
// auth methods
CanUsePassword(ctx context.Context, email string) (bool, basemodel.BaseApiError)
PrepareSsoRedirect(ctx context.Context, redirectUri, email string, jwt *authtypes.JWT) (redirectURL string, apierr basemodel.BaseApiError)
GetDomainFromSsoResponse(ctx context.Context, relayState *url.URL) (*types.GettableOrgDomain, error)
GetDomainFromSsoResponse(ctx context.Context, relayState *url.URL) (*model.OrgDomain, error)
// org domain (auth domains) CRUD ops
ListDomains(ctx context.Context, orgId string) ([]types.GettableOrgDomain, basemodel.BaseApiError)
GetDomain(ctx context.Context, id uuid.UUID) (*types.GettableOrgDomain, basemodel.BaseApiError)
CreateDomain(ctx context.Context, d *types.GettableOrgDomain) basemodel.BaseApiError
UpdateDomain(ctx context.Context, domain *types.GettableOrgDomain) basemodel.BaseApiError
ListDomains(ctx context.Context, orgId string) ([]model.OrgDomain, basemodel.BaseApiError)
GetDomain(ctx context.Context, id uuid.UUID) (*model.OrgDomain, basemodel.BaseApiError)
CreateDomain(ctx context.Context, d *model.OrgDomain) basemodel.BaseApiError
UpdateDomain(ctx context.Context, domain *model.OrgDomain) basemodel.BaseApiError
DeleteDomain(ctx context.Context, id uuid.UUID) basemodel.BaseApiError
GetDomainByEmail(ctx context.Context, email string) (*types.GettableOrgDomain, basemodel.BaseApiError)
GetDomainByEmail(ctx context.Context, email string) (*model.OrgDomain, basemodel.BaseApiError)
CreatePAT(ctx context.Context, orgID string, p model.PAT) (model.PAT, basemodel.BaseApiError)
UpdatePAT(ctx context.Context, orgID string, p model.PAT, id string) basemodel.BaseApiError
CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basemodel.BaseApiError)
UpdatePAT(ctx context.Context, p model.PAT, id string) basemodel.BaseApiError
GetPAT(ctx context.Context, pat string) (*model.PAT, basemodel.BaseApiError)
GetPATByID(ctx context.Context, orgID string, id string) (*model.PAT, basemodel.BaseApiError)
GetUserByPAT(ctx context.Context, orgID string, token string) (*ossTypes.GettableUser, basemodel.BaseApiError)
ListPATs(ctx context.Context, orgID string) ([]model.PAT, basemodel.BaseApiError)
RevokePAT(ctx context.Context, orgID string, id string, userID string) basemodel.BaseApiError
UpdatePATLastUsed(ctx context.Context, pat string, lastUsed int64) basemodel.BaseApiError
GetPATByID(ctx context.Context, id string) (*model.PAT, basemodel.BaseApiError)
GetUserByPAT(ctx context.Context, token string) (*types.GettableUser, basemodel.BaseApiError)
ListPATs(ctx context.Context) ([]model.PAT, basemodel.BaseApiError)
RevokePAT(ctx context.Context, id string, userID string) basemodel.BaseApiError
}

View File

@@ -7,15 +7,15 @@ import (
"strings"
"time"
"github.com/SigNoz/signoz/ee/query-service/constants"
"github.com/SigNoz/signoz/ee/query-service/model"
baseauth "github.com/SigNoz/signoz/pkg/query-service/auth"
baseconst "github.com/SigNoz/signoz/pkg/query-service/constants"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/query-service/utils"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/google/uuid"
"go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/model"
baseauth "go.signoz.io/signoz/pkg/query-service/auth"
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/query-service/utils"
"go.signoz.io/signoz/pkg/types"
"go.signoz.io/signoz/pkg/types/authtypes"
"go.uber.org/zap"
)
@@ -53,7 +53,7 @@ func (m *modelDao) createUserForSAMLRequest(ctx context.Context, email string) (
},
ProfilePictureURL: "", // Currently unused
GroupID: group.ID,
OrgID: domain.OrgID,
OrgID: domain.OrgId,
}
user, apiErr = m.CreateUser(ctx, user, false)

View File

@@ -9,23 +9,32 @@ import (
"strings"
"time"
"github.com/SigNoz/signoz/ee/query-service/model"
"github.com/SigNoz/signoz/ee/types"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
ossTypes "github.com/SigNoz/signoz/pkg/types"
"github.com/google/uuid"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)
// StoredDomain represents stored database record for org domain
type StoredDomain struct {
Id uuid.UUID `db:"id"`
Name string `db:"name"`
OrgId string `db:"org_id"`
Data string `db:"data"`
CreatedAt int64 `db:"created_at"`
UpdatedAt int64 `db:"updated_at"`
}
// GetDomainFromSsoResponse uses relay state received from IdP to fetch
// user domain. The domain is further used to process validity of the response.
// when sending login request to IdP we send relay state as URL (site url)
// with domainId or domainName as query parameter.
func (m *modelDao) GetDomainFromSsoResponse(ctx context.Context, relayState *url.URL) (*types.GettableOrgDomain, error) {
func (m *modelDao) GetDomainFromSsoResponse(ctx context.Context, relayState *url.URL) (*model.OrgDomain, error) {
// derive domain id from relay state now
var domainIdStr string
var domainNameStr string
var domain *types.GettableOrgDomain
var domain *model.OrgDomain
for k, v := range relayState.Query() {
if k == "domainId" && len(v) > 0 {
@@ -67,14 +76,10 @@ func (m *modelDao) GetDomainFromSsoResponse(ctx context.Context, relayState *url
}
// GetDomainByName returns org domain for a given domain name
func (m *modelDao) GetDomainByName(ctx context.Context, name string) (*types.GettableOrgDomain, basemodel.BaseApiError) {
func (m *modelDao) GetDomainByName(ctx context.Context, name string) (*model.OrgDomain, basemodel.BaseApiError) {
stored := types.StorableOrgDomain{}
err := m.DB().NewSelect().
Model(&stored).
Where("name = ?", name).
Limit(1).
Scan(ctx)
stored := StoredDomain{}
err := m.DB().Get(&stored, `SELECT * FROM org_domains WHERE name=$1 LIMIT 1`, name)
if err != nil {
if err == sql.ErrNoRows {
@@ -83,7 +88,7 @@ func (m *modelDao) GetDomainByName(ctx context.Context, name string) (*types.Get
return nil, model.InternalError(err)
}
domain := &types.GettableOrgDomain{StorableOrgDomain: stored}
domain := &model.OrgDomain{Id: stored.Id, Name: stored.Name, OrgId: stored.OrgId}
if err := domain.LoadConfig(stored.Data); err != nil {
return nil, model.InternalError(err)
}
@@ -91,14 +96,10 @@ func (m *modelDao) GetDomainByName(ctx context.Context, name string) (*types.Get
}
// GetDomain returns org domain for a given domain id
func (m *modelDao) GetDomain(ctx context.Context, id uuid.UUID) (*types.GettableOrgDomain, basemodel.BaseApiError) {
func (m *modelDao) GetDomain(ctx context.Context, id uuid.UUID) (*model.OrgDomain, basemodel.BaseApiError) {
stored := types.StorableOrgDomain{}
err := m.DB().NewSelect().
Model(&stored).
Where("id = ?", id).
Limit(1).
Scan(ctx)
stored := StoredDomain{}
err := m.DB().Get(&stored, `SELECT * FROM org_domains WHERE id=$1 LIMIT 1`, id)
if err != nil {
if err == sql.ErrNoRows {
@@ -107,7 +108,7 @@ func (m *modelDao) GetDomain(ctx context.Context, id uuid.UUID) (*types.Gettable
return nil, model.InternalError(err)
}
domain := &types.GettableOrgDomain{StorableOrgDomain: stored}
domain := &model.OrgDomain{Id: stored.Id, Name: stored.Name, OrgId: stored.OrgId}
if err := domain.LoadConfig(stored.Data); err != nil {
return nil, model.InternalError(err)
}
@@ -115,24 +116,21 @@ func (m *modelDao) GetDomain(ctx context.Context, id uuid.UUID) (*types.Gettable
}
// ListDomains gets the list of auth domains by org id
func (m *modelDao) ListDomains(ctx context.Context, orgId string) ([]types.GettableOrgDomain, basemodel.BaseApiError) {
domains := []types.GettableOrgDomain{}
func (m *modelDao) ListDomains(ctx context.Context, orgId string) ([]model.OrgDomain, basemodel.BaseApiError) {
domains := []model.OrgDomain{}
stored := []types.StorableOrgDomain{}
err := m.DB().NewSelect().
Model(&stored).
Where("org_id = ?", orgId).
Scan(ctx)
stored := []StoredDomain{}
err := m.DB().SelectContext(ctx, &stored, `SELECT * FROM org_domains WHERE org_id=$1`, orgId)
if err != nil {
if err == sql.ErrNoRows {
return domains, nil
return []model.OrgDomain{}, nil
}
return nil, model.InternalError(err)
}
for _, s := range stored {
domain := types.GettableOrgDomain{StorableOrgDomain: s}
domain := model.OrgDomain{Id: s.Id, Name: s.Name, OrgId: s.OrgId}
if err := domain.LoadConfig(s.Data); err != nil {
zap.L().Error("ListDomains() failed", zap.Error(err))
}
@@ -143,14 +141,14 @@ func (m *modelDao) ListDomains(ctx context.Context, orgId string) ([]types.Getta
}
// CreateDomain creates a new auth domain
func (m *modelDao) CreateDomain(ctx context.Context, domain *types.GettableOrgDomain) basemodel.BaseApiError {
func (m *modelDao) CreateDomain(ctx context.Context, domain *model.OrgDomain) basemodel.BaseApiError {
if domain.ID == uuid.Nil {
domain.ID = uuid.New()
if domain.Id == uuid.Nil {
domain.Id = uuid.New()
}
if domain.OrgID == "" || domain.Name == "" {
return model.BadRequest(fmt.Errorf("domain creation failed, missing fields: OrgID, Name "))
if domain.OrgId == "" || domain.Name == "" {
return model.BadRequest(fmt.Errorf("domain creation failed, missing fields: OrgId, Name "))
}
configJson, err := json.Marshal(domain)
@@ -159,17 +157,14 @@ func (m *modelDao) CreateDomain(ctx context.Context, domain *types.GettableOrgDo
return model.InternalError(fmt.Errorf("domain creation failed"))
}
storableDomain := types.StorableOrgDomain{
ID: domain.ID,
Name: domain.Name,
OrgID: domain.OrgID,
Data: string(configJson),
TimeAuditable: ossTypes.TimeAuditable{CreatedAt: time.Now(), UpdatedAt: time.Now()},
}
_, err = m.DB().NewInsert().
Model(&storableDomain).
Exec(ctx)
_, err = m.DB().ExecContext(ctx,
"INSERT INTO org_domains (id, name, org_id, data, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6)",
domain.Id,
domain.Name,
domain.OrgId,
configJson,
time.Now().Unix(),
time.Now().Unix())
if err != nil {
zap.L().Error("failed to insert domain in db", zap.Error(err))
@@ -180,9 +175,9 @@ func (m *modelDao) CreateDomain(ctx context.Context, domain *types.GettableOrgDo
}
// UpdateDomain updates stored config params for a domain
func (m *modelDao) UpdateDomain(ctx context.Context, domain *types.GettableOrgDomain) basemodel.BaseApiError {
func (m *modelDao) UpdateDomain(ctx context.Context, domain *model.OrgDomain) basemodel.BaseApiError {
if domain.ID == uuid.Nil {
if domain.Id == uuid.Nil {
zap.L().Error("domain update failed", zap.Error(fmt.Errorf("OrgDomain.Id is null")))
return model.InternalError(fmt.Errorf("domain update failed"))
}
@@ -193,19 +188,11 @@ func (m *modelDao) UpdateDomain(ctx context.Context, domain *types.GettableOrgDo
return model.InternalError(fmt.Errorf("domain update failed"))
}
storableDomain := &types.StorableOrgDomain{
ID: domain.ID,
Name: domain.Name,
OrgID: domain.OrgID,
Data: string(configJson),
TimeAuditable: ossTypes.TimeAuditable{UpdatedAt: time.Now()},
}
_, err = m.DB().NewUpdate().
Model(storableDomain).
Column("data", "updated_at").
WherePK().
Exec(ctx)
_, err = m.DB().ExecContext(ctx,
"UPDATE org_domains SET data = $1, updated_at = $2 WHERE id = $3",
configJson,
time.Now().Unix(),
domain.Id)
if err != nil {
zap.L().Error("domain update failed", zap.Error(err))
@@ -223,11 +210,9 @@ func (m *modelDao) DeleteDomain(ctx context.Context, id uuid.UUID) basemodel.Bas
return model.InternalError(fmt.Errorf("domain delete failed"))
}
storableDomain := &types.StorableOrgDomain{ID: id}
_, err := m.DB().NewDelete().
Model(storableDomain).
WherePK().
Exec(ctx)
_, err := m.DB().ExecContext(ctx,
"DELETE FROM org_domains WHERE id = $1",
id)
if err != nil {
zap.L().Error("domain delete failed", zap.Error(err))
@@ -237,7 +222,7 @@ func (m *modelDao) DeleteDomain(ctx context.Context, id uuid.UUID) basemodel.Bas
return nil
}
func (m *modelDao) GetDomainByEmail(ctx context.Context, email string) (*types.GettableOrgDomain, basemodel.BaseApiError) {
func (m *modelDao) GetDomainByEmail(ctx context.Context, email string) (*model.OrgDomain, basemodel.BaseApiError) {
if email == "" {
return nil, model.BadRequest(fmt.Errorf("could not find auth domain, missing fields: email "))
@@ -250,12 +235,8 @@ func (m *modelDao) GetDomainByEmail(ctx context.Context, email string) (*types.G
parsedDomain := components[1]
stored := types.StorableOrgDomain{}
err := m.DB().NewSelect().
Model(&stored).
Where("name = ?", parsedDomain).
Limit(1).
Scan(ctx)
stored := StoredDomain{}
err := m.DB().Get(&stored, `SELECT * FROM org_domains WHERE name=$1 LIMIT 1`, parsedDomain)
if err != nil {
if err == sql.ErrNoRows {
@@ -264,7 +245,7 @@ func (m *modelDao) GetDomainByEmail(ctx context.Context, email string) (*types.G
return nil, model.InternalError(err)
}
domain := &types.GettableOrgDomain{StorableOrgDomain: stored}
domain := &model.OrgDomain{Id: stored.Id, Name: stored.Name, OrgId: stored.OrgId}
if err := domain.LoadConfig(stored.Data); err != nil {
return nil, model.InternalError(err)
}

View File

@@ -3,11 +3,11 @@ package sqlite
import (
"fmt"
basedao "github.com/SigNoz/signoz/pkg/query-service/dao"
basedsql "github.com/SigNoz/signoz/pkg/query-service/dao/sqlite"
baseint "github.com/SigNoz/signoz/pkg/query-service/interfaces"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/uptrace/bun"
"github.com/jmoiron/sqlx"
basedao "go.signoz.io/signoz/pkg/query-service/dao"
basedsql "go.signoz.io/signoz/pkg/query-service/dao/sqlite"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
"go.signoz.io/signoz/pkg/sqlstore"
)
type modelDao struct {
@@ -41,6 +41,6 @@ func InitDB(sqlStore sqlstore.SQLStore) (*modelDao, error) {
return m, nil
}
func (m *modelDao) DB() *bun.DB {
func (m *modelDao) DB() *sqlx.DB {
return m.ModelDaoSqlite.DB()
}

View File

@@ -3,25 +3,39 @@ package sqlite
import (
"context"
"fmt"
"strconv"
"time"
"github.com/SigNoz/signoz/ee/query-service/model"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/types"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/types"
"go.uber.org/zap"
)
func (m *modelDao) CreatePAT(ctx context.Context, orgID string, p model.PAT) (model.PAT, basemodel.BaseApiError) {
p.StorablePersonalAccessToken.OrgID = orgID
_, err := m.DB().NewInsert().
Model(&p.StorablePersonalAccessToken).
Returning("id").
Exec(ctx)
func (m *modelDao) CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basemodel.BaseApiError) {
result, err := m.DB().ExecContext(ctx,
"INSERT INTO personal_access_tokens (user_id, token, role, name, created_at, expires_at, updated_at, updated_by_user_id, last_used, revoked) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
p.UserID,
p.Token,
p.Role,
p.Name,
p.CreatedAt,
p.ExpiresAt,
p.UpdatedAt,
p.UpdatedByUserID,
p.LastUsed,
p.Revoked,
)
if err != nil {
zap.L().Error("Failed to insert PAT in db, err: %v", zap.Error(err))
return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed"))
}
id, err := result.LastInsertId()
if err != nil {
zap.L().Error("Failed to get last inserted id, err: %v", zap.Error(err))
return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed"))
}
p.Id = strconv.Itoa(int(id))
createdByUser, _ := m.GetUser(ctx, p.UserID)
if createdByUser == nil {
p.CreatedByUser = model.User{
@@ -40,14 +54,14 @@ func (m *modelDao) CreatePAT(ctx context.Context, orgID string, p model.PAT) (mo
return p, nil
}
func (m *modelDao) UpdatePAT(ctx context.Context, orgID string, p model.PAT, id string) basemodel.BaseApiError {
_, err := m.DB().NewUpdate().
Model(&p.StorablePersonalAccessToken).
Column("role", "name", "updated_at", "updated_by_user_id").
Where("id = ?", id).
Where("org_id = ?", orgID).
Where("revoked = false").
Exec(ctx)
func (m *modelDao) UpdatePAT(ctx context.Context, p model.PAT, id string) basemodel.BaseApiError {
_, err := m.DB().ExecContext(ctx,
"UPDATE personal_access_tokens SET role=$1, name=$2, updated_at=$3, updated_by_user_id=$4 WHERE id=$5 and revoked=false;",
p.Role,
p.Name,
p.UpdatedAt,
p.UpdatedByUserID,
id)
if err != nil {
zap.L().Error("Failed to update PAT in db, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("PAT update failed"))
@@ -55,32 +69,33 @@ func (m *modelDao) UpdatePAT(ctx context.Context, orgID string, p model.PAT, id
return nil
}
func (m *modelDao) ListPATs(ctx context.Context, orgID string) ([]model.PAT, basemodel.BaseApiError) {
pats := []types.StorablePersonalAccessToken{}
func (m *modelDao) UpdatePATLastUsed(ctx context.Context, token string, lastUsed int64) basemodel.BaseApiError {
_, err := m.DB().ExecContext(ctx,
"UPDATE personal_access_tokens SET last_used=$1 WHERE token=$2 and revoked=false;",
lastUsed,
token)
if err != nil {
zap.L().Error("Failed to update PAT last used in db, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("PAT last used update failed"))
}
return nil
}
if err := m.DB().NewSelect().
Model(&pats).
Where("revoked = false").
Where("org_id = ?", orgID).
Order("updated_at DESC").
Scan(ctx); err != nil {
func (m *modelDao) ListPATs(ctx context.Context) ([]model.PAT, basemodel.BaseApiError) {
pats := []model.PAT{}
if err := m.DB().Select(&pats, "SELECT * FROM personal_access_tokens WHERE revoked=false ORDER by updated_at DESC;"); err != nil {
zap.L().Error("Failed to fetch PATs err: %v", zap.Error(err))
return nil, model.InternalError(fmt.Errorf("failed to fetch PATs"))
}
patsWithUsers := []model.PAT{}
for i := range pats {
patWithUser := model.PAT{
StorablePersonalAccessToken: pats[i],
}
createdByUser, _ := m.GetUser(ctx, pats[i].UserID)
if createdByUser == nil {
patWithUser.CreatedByUser = model.User{
pats[i].CreatedByUser = model.User{
NotFound: true,
}
} else {
patWithUser.CreatedByUser = model.User{
pats[i].CreatedByUser = model.User{
Id: createdByUser.ID,
Name: createdByUser.Name,
Email: createdByUser.Email,
@@ -92,11 +107,11 @@ func (m *modelDao) ListPATs(ctx context.Context, orgID string) ([]model.PAT, bas
updatedByUser, _ := m.GetUser(ctx, pats[i].UpdatedByUserID)
if updatedByUser == nil {
patWithUser.UpdatedByUser = model.User{
pats[i].UpdatedByUser = model.User{
NotFound: true,
}
} else {
patWithUser.UpdatedByUser = model.User{
pats[i].UpdatedByUser = model.User{
Id: updatedByUser.ID,
Name: updatedByUser.Name,
Email: updatedByUser.Email,
@@ -105,22 +120,15 @@ func (m *modelDao) ListPATs(ctx context.Context, orgID string) ([]model.PAT, bas
NotFound: false,
}
}
patsWithUsers = append(patsWithUsers, patWithUser)
}
return patsWithUsers, nil
return pats, nil
}
func (m *modelDao) RevokePAT(ctx context.Context, orgID string, id string, userID string) basemodel.BaseApiError {
func (m *modelDao) RevokePAT(ctx context.Context, id string, userID string) basemodel.BaseApiError {
updatedAt := time.Now().Unix()
_, err := m.DB().NewUpdate().
Model(&types.StorablePersonalAccessToken{}).
Set("revoked = ?", true).
Set("updated_by_user_id = ?", userID).
Set("updated_at = ?", updatedAt).
Where("id = ?", id).
Where("org_id = ?", orgID).
Exec(ctx)
_, err := m.DB().ExecContext(ctx,
"UPDATE personal_access_tokens SET revoked=true, updated_by_user_id = $1, updated_at=$2 WHERE id=$3",
userID, updatedAt, id)
if err != nil {
zap.L().Error("Failed to revoke PAT in db, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("PAT revoke failed"))
@@ -129,13 +137,9 @@ func (m *modelDao) RevokePAT(ctx context.Context, orgID string, id string, userI
}
func (m *modelDao) GetPAT(ctx context.Context, token string) (*model.PAT, basemodel.BaseApiError) {
pats := []types.StorablePersonalAccessToken{}
pats := []model.PAT{}
if err := m.DB().NewSelect().
Model(&pats).
Where("token = ?", token).
Where("revoked = false").
Scan(ctx); err != nil {
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE token=? and revoked=false;`, token); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch PAT"))
}
@@ -146,22 +150,13 @@ func (m *modelDao) GetPAT(ctx context.Context, token string) (*model.PAT, basemo
}
}
patWithUser := model.PAT{
StorablePersonalAccessToken: pats[0],
}
return &patWithUser, nil
return &pats[0], nil
}
func (m *modelDao) GetPATByID(ctx context.Context, orgID string, id string) (*model.PAT, basemodel.BaseApiError) {
pats := []types.StorablePersonalAccessToken{}
func (m *modelDao) GetPATByID(ctx context.Context, id string) (*model.PAT, basemodel.BaseApiError) {
pats := []model.PAT{}
if err := m.DB().NewSelect().
Model(&pats).
Where("id = ?", id).
Where("org_id = ?", orgID).
Where("revoked = false").
Scan(ctx); err != nil {
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE id=? and revoked=false;`, id); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch PAT"))
}
@@ -172,25 +167,26 @@ func (m *modelDao) GetPATByID(ctx context.Context, orgID string, id string) (*mo
}
}
patWithUser := model.PAT{
StorablePersonalAccessToken: pats[0],
}
return &patWithUser, nil
return &pats[0], nil
}
// deprecated
func (m *modelDao) GetUserByPAT(ctx context.Context, orgID string, token string) (*types.GettableUser, basemodel.BaseApiError) {
func (m *modelDao) GetUserByPAT(ctx context.Context, token string) (*types.GettableUser, basemodel.BaseApiError) {
users := []types.GettableUser{}
if err := m.DB().NewSelect().
Model(&users).
Column("u.id", "u.name", "u.email", "u.password", "u.created_at", "u.profile_picture_url", "u.org_id", "u.group_id").
Join("JOIN personal_access_tokens p ON u.id = p.user_id").
Where("p.token = ?", token).
Where("p.expires_at >= strftime('%s', 'now')").
Where("p.org_id = ?", orgID).
Scan(ctx); err != nil {
query := `SELECT
u.id,
u.name,
u.email,
u.password,
u.created_at,
u.profile_picture_url,
u.org_id,
u.group_id
FROM users u, personal_access_tokens p
WHERE u.id = p.user_id and p.token=? and p.expires_at >= strftime('%s', 'now');`
if err := m.DB().Select(&users, query, token); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch user from PAT, err: %v", err))
}

View File

@@ -11,8 +11,8 @@ import (
"github.com/pkg/errors"
"github.com/SigNoz/signoz/ee/query-service/constants"
"github.com/SigNoz/signoz/ee/query-service/model"
"go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/model"
)
var C *Client

View File

@@ -1,7 +1,7 @@
package interfaces
import (
baseint "github.com/SigNoz/signoz/pkg/query-service/interfaces"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
)
// Connector defines methods for interaction

View File

@@ -9,25 +9,25 @@ import (
"github.com/jmoiron/sqlx"
"github.com/mattn/go-sqlite3"
"github.com/uptrace/bun"
"github.com/SigNoz/signoz/ee/query-service/model"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/types"
"go.uber.org/zap"
)
// Repo is license repo. stores license keys in a secured DB
type Repo struct {
db *sqlx.DB
store sqlstore.SQLStore
bundb *bun.DB
}
// NewLicenseRepo initiates a new license repo
func NewLicenseRepo(db *sqlx.DB, store sqlstore.SQLStore) Repo {
func NewLicenseRepo(db *sqlx.DB, bundb *bun.DB) Repo {
return Repo{
db: db,
store: store,
bundb: bundb,
}
}
@@ -171,7 +171,7 @@ func (r *Repo) UpdateLicenseV3(ctx context.Context, l *model.LicenseV3) error {
func (r *Repo) CreateFeature(req *types.FeatureStatus) *basemodel.ApiError {
_, err := r.store.BunDB().NewInsert().
_, err := r.bundb.NewInsert().
Model(req).
Exec(context.Background())
if err != nil {
@@ -183,7 +183,7 @@ func (r *Repo) CreateFeature(req *types.FeatureStatus) *basemodel.ApiError {
func (r *Repo) GetFeature(featureName string) (types.FeatureStatus, error) {
var feature types.FeatureStatus
err := r.store.BunDB().NewSelect().
err := r.bundb.NewSelect().
Model(&feature).
Where("name = ?", featureName).
Scan(context.Background())
@@ -212,7 +212,7 @@ func (r *Repo) GetAllFeatures() ([]basemodel.Feature, error) {
func (r *Repo) UpdateFeature(req types.FeatureStatus) error {
_, err := r.store.BunDB().NewUpdate().
_, err := r.bundb.NewUpdate().
Model(&req).
Where("name = ?", req.Name).
Exec(context.Background())

View File

@@ -7,18 +7,18 @@ import (
"github.com/jmoiron/sqlx"
"github.com/pkg/errors"
"github.com/uptrace/bun"
"sync"
baseconstants "github.com/SigNoz/signoz/pkg/query-service/constants"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
baseconstants "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/types"
"go.signoz.io/signoz/pkg/types/authtypes"
validate "github.com/SigNoz/signoz/ee/query-service/integrations/signozio"
"github.com/SigNoz/signoz/ee/query-service/model"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/query-service/telemetry"
validate "go.signoz.io/signoz/ee/query-service/integrations/signozio"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/query-service/telemetry"
"go.uber.org/zap"
)
@@ -45,12 +45,12 @@ type Manager struct {
activeFeatures basemodel.FeatureSet
}
func StartManager(db *sqlx.DB, store sqlstore.SQLStore, features ...basemodel.Feature) (*Manager, error) {
func StartManager(db *sqlx.DB, bundb *bun.DB, features ...basemodel.Feature) (*Manager, error) {
if LM != nil {
return LM, nil
}
repo := NewLicenseRepo(db, store)
repo := NewLicenseRepo(db, bundb)
m := &Manager{
repo: &repo,
}

View File

@@ -3,30 +3,82 @@ package main
import (
"context"
"flag"
"log"
"os"
"os/signal"
"strconv"
"time"
"github.com/SigNoz/signoz/ee/query-service/app"
"github.com/SigNoz/signoz/pkg/config"
"github.com/SigNoz/signoz/pkg/config/envprovider"
"github.com/SigNoz/signoz/pkg/config/fileprovider"
"github.com/SigNoz/signoz/pkg/query-service/auth"
baseconst "github.com/SigNoz/signoz/pkg/query-service/constants"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/version"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"go.signoz.io/signoz/ee/query-service/app"
"go.signoz.io/signoz/pkg/config"
"go.signoz.io/signoz/pkg/config/envprovider"
"go.signoz.io/signoz/pkg/config/fileprovider"
"go.signoz.io/signoz/pkg/query-service/auth"
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/version"
"go.signoz.io/signoz/pkg/signoz"
"go.signoz.io/signoz/pkg/types/authtypes"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
prommodel "github.com/prometheus/common/model"
zapotlpencoder "github.com/SigNoz/zap_otlp/zap_otlp_encoder"
zapotlpsync "github.com/SigNoz/zap_otlp/zap_otlp_sync"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func initZapLog() *zap.Logger {
func initZapLog(enableQueryServiceLogOTLPExport bool) *zap.Logger {
config := zap.NewProductionConfig()
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
config.EncoderConfig.EncodeDuration = zapcore.MillisDurationEncoder
config.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
config.EncoderConfig.TimeKey = "timestamp"
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
logger, _ := config.Build()
otlpEncoder := zapotlpencoder.NewOTLPEncoder(config.EncoderConfig)
consoleEncoder := zapcore.NewJSONEncoder(config.EncoderConfig)
defaultLogLevel := zapcore.InfoLevel
res := resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("query-service"),
)
core := zapcore.NewTee(
zapcore.NewCore(consoleEncoder, os.Stdout, defaultLogLevel),
)
if enableQueryServiceLogOTLPExport {
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
defer cancel()
conn, err := grpc.DialContext(ctx, baseconst.OTLPTarget, grpc.WithBlock(), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("failed to establish connection: %v", err)
} else {
logExportBatchSizeInt, err := strconv.Atoi(baseconst.LogExportBatchSize)
if err != nil {
logExportBatchSizeInt = 512
}
ws := zapcore.AddSync(zapotlpsync.NewOtlpSyncer(conn, zapotlpsync.Options{
BatchSize: logExportBatchSizeInt,
ResourceSchema: semconv.SchemaURL,
Resource: res,
}))
core = zapcore.NewTee(
zapcore.NewCore(consoleEncoder, os.Stdout, defaultLogLevel),
zapcore.NewCore(otlpEncoder, zapcore.NewMultiWriteSyncer(ws), defaultLogLevel),
)
}
}
logger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
return logger
}
@@ -47,6 +99,7 @@ func main() {
var useLogsNewSchema bool
var useTraceNewSchema bool
var cacheConfigPath, fluxInterval, fluxIntervalForTraceDetail string
var enableQueryServiceLogOTLPExport bool
var preferSpanMetrics bool
var maxIdleConns int
@@ -68,15 +121,19 @@ func main() {
flag.StringVar(&cacheConfigPath, "experimental.cache-config", "", "(cache config to use)")
flag.StringVar(&fluxInterval, "flux-interval", "5m", "(the interval to exclude data from being cached to avoid incorrect cache for data in motion)")
flag.StringVar(&fluxIntervalForTraceDetail, "flux-interval-trace-detail", "2m", "(the interval to exclude data from being cached to avoid incorrect cache for trace data in motion)")
flag.BoolVar(&enableQueryServiceLogOTLPExport, "enable.query.service.log.otlp.export", false, "(enable query service log otlp export)")
flag.StringVar(&cluster, "cluster", "cluster", "(cluster name - defaults to 'cluster')")
flag.StringVar(&gatewayUrl, "gateway-url", "", "(url to the gateway)")
flag.BoolVar(&useLicensesV3, "use-licenses-v3", false, "use licenses_v3 schema for licenses")
flag.Parse()
loggerMgr := initZapLog()
loggerMgr := initZapLog(enableQueryServiceLogOTLPExport)
zap.ReplaceGlobals(loggerMgr)
defer loggerMgr.Sync() // flushes buffer, if any
version.PrintVersion()
config, err := signoz.NewConfig(context.Background(), config.ResolverConfig{
Uris: []string{"env:"},
ProviderFactories: []config.ProviderFactory{
@@ -92,8 +149,6 @@ func main() {
zap.L().Fatal("Failed to create config", zap.Error(err))
}
version.Info.PrettyPrint(config.Version)
signoz, err := signoz.New(
context.Background(),
config,

View File

@@ -1,7 +1,7 @@
package model
import (
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
)
// GettableInvitation overrides base object and adds precheck into

View File

@@ -1,4 +1,4 @@
package types
package model
import (
"encoding/json"
@@ -6,26 +6,15 @@ import (
"net/url"
"strings"
"github.com/SigNoz/signoz/ee/query-service/sso"
"github.com/SigNoz/signoz/ee/query-service/sso/saml"
"github.com/SigNoz/signoz/pkg/types"
"github.com/google/uuid"
"github.com/pkg/errors"
saml2 "github.com/russellhaering/gosaml2"
"github.com/uptrace/bun"
"go.signoz.io/signoz/ee/query-service/sso"
"go.signoz.io/signoz/ee/query-service/sso/saml"
"go.signoz.io/signoz/pkg/types"
"go.uber.org/zap"
)
type StorableOrgDomain struct {
bun.BaseModel `bun:"table:org_domains"`
types.TimeAuditable
ID uuid.UUID `json:"id" bun:"id,pk,type:text"`
OrgID string `json:"orgId" bun:"org_id,type:text,notnull"`
Name string `json:"name" bun:"name,type:varchar(50),notnull,unique"`
Data string `json:"-" bun:"data,type:text,notnull"`
}
type SSOType string
const (
@@ -33,12 +22,13 @@ const (
GoogleAuth SSOType = "GOOGLE_AUTH"
)
// GettableOrgDomain identify org owned web domains for auth and other purposes
type GettableOrgDomain struct {
StorableOrgDomain
SsoEnabled bool `json:"ssoEnabled"`
SsoType SSOType `json:"ssoType"`
// OrgDomain identify org owned web domains for auth and other purposes
type OrgDomain struct {
Id uuid.UUID `json:"id"`
Name string `json:"name"`
OrgId string `json:"orgId"`
SsoEnabled bool `json:"ssoEnabled"`
SsoType SSOType `json:"ssoType"`
SamlConfig *SamlConfig `json:"samlConfig"`
GoogleAuthConfig *GoogleOAuthConfig `json:"googleAuthConfig"`
@@ -46,18 +36,18 @@ type GettableOrgDomain struct {
Org *types.Organization
}
func (od *GettableOrgDomain) String() string {
return fmt.Sprintf("[%s]%s-%s ", od.Name, od.ID.String(), od.SsoType)
func (od *OrgDomain) String() string {
return fmt.Sprintf("[%s]%s-%s ", od.Name, od.Id.String(), od.SsoType)
}
// Valid is used a pipeline function to check if org domain
// loaded from db is valid
func (od *GettableOrgDomain) Valid(err error) error {
func (od *OrgDomain) Valid(err error) error {
if err != nil {
return err
}
if od.ID == uuid.Nil || od.OrgID == "" {
if od.Id == uuid.Nil || od.OrgId == "" {
return fmt.Errorf("both id and orgId are required")
}
@@ -65,9 +55,9 @@ func (od *GettableOrgDomain) Valid(err error) error {
}
// ValidNew cheks if the org domain is valid for insertion in db
func (od *GettableOrgDomain) ValidNew() error {
func (od *OrgDomain) ValidNew() error {
if od.OrgID == "" {
if od.OrgId == "" {
return fmt.Errorf("orgId is required")
}
@@ -79,7 +69,7 @@ func (od *GettableOrgDomain) ValidNew() error {
}
// LoadConfig loads config params from json text
func (od *GettableOrgDomain) LoadConfig(jsondata string) error {
func (od *OrgDomain) LoadConfig(jsondata string) error {
d := *od
err := json.Unmarshal([]byte(jsondata), &d)
if err != nil {
@@ -89,21 +79,21 @@ func (od *GettableOrgDomain) LoadConfig(jsondata string) error {
return nil
}
func (od *GettableOrgDomain) GetSAMLEntityID() string {
func (od *OrgDomain) GetSAMLEntityID() string {
if od.SamlConfig != nil {
return od.SamlConfig.SamlEntity
}
return ""
}
func (od *GettableOrgDomain) GetSAMLIdpURL() string {
func (od *OrgDomain) GetSAMLIdpURL() string {
if od.SamlConfig != nil {
return od.SamlConfig.SamlIdp
}
return ""
}
func (od *GettableOrgDomain) GetSAMLCert() string {
func (od *OrgDomain) GetSAMLCert() string {
if od.SamlConfig != nil {
return od.SamlConfig.SamlCert
}
@@ -112,7 +102,7 @@ func (od *GettableOrgDomain) GetSAMLCert() string {
// PrepareGoogleOAuthProvider creates GoogleProvider that is used in
// requesting OAuth and also used in processing response from google
func (od *GettableOrgDomain) PrepareGoogleOAuthProvider(siteUrl *url.URL) (sso.OAuthCallbackProvider, error) {
func (od *OrgDomain) PrepareGoogleOAuthProvider(siteUrl *url.URL) (sso.OAuthCallbackProvider, error) {
if od.GoogleAuthConfig == nil {
return nil, fmt.Errorf("GOOGLE OAUTH is not setup correctly for this domain")
}
@@ -121,7 +111,7 @@ func (od *GettableOrgDomain) PrepareGoogleOAuthProvider(siteUrl *url.URL) (sso.O
}
// PrepareSamlRequest creates a request accordingly gosaml2
func (od *GettableOrgDomain) PrepareSamlRequest(siteUrl *url.URL) (*saml2.SAMLServiceProvider, error) {
func (od *OrgDomain) PrepareSamlRequest(siteUrl *url.URL) (*saml2.SAMLServiceProvider, error) {
// this is the url Idp will call after login completion
acs := fmt.Sprintf("%s://%s/%s",
@@ -146,9 +136,9 @@ func (od *GettableOrgDomain) PrepareSamlRequest(siteUrl *url.URL) (*saml2.SAMLSe
return saml.PrepareRequest(issuer, acs, sourceUrl, od.GetSAMLEntityID(), od.GetSAMLIdpURL(), od.GetSAMLCert())
}
func (od *GettableOrgDomain) BuildSsoUrl(siteUrl *url.URL) (ssoUrl string, err error) {
func (od *OrgDomain) BuildSsoUrl(siteUrl *url.URL) (ssoUrl string, err error) {
fmtDomainId := strings.Replace(od.ID.String(), "-", ":", -1)
fmtDomainId := strings.Replace(od.Id.String(), "-", ":", -1)
// build redirect url from window.location sent by frontend
redirectURL := fmt.Sprintf("%s://%s%s", siteUrl.Scheme, siteUrl.Host, siteUrl.Path)

View File

@@ -3,7 +3,7 @@ package model
import (
"fmt"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
)
type ApiError struct {

View File

@@ -6,8 +6,8 @@ import (
"reflect"
"time"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/pkg/errors"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
)
type License struct {

View File

@@ -4,10 +4,10 @@ import (
"encoding/json"
"testing"
"github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.signoz.io/signoz/pkg/query-service/model"
)
func TestNewLicenseV3(t *testing.T) {

View File

@@ -1,7 +1,5 @@
package model
import "github.com/SigNoz/signoz/pkg/types"
type User struct {
Id string `json:"id" db:"id"`
Name string `json:"name" db:"name"`
@@ -18,8 +16,17 @@ type CreatePATRequestBody struct {
}
type PAT struct {
CreatedByUser User `json:"createdByUser"`
UpdatedByUser User `json:"updatedByUser"`
types.StorablePersonalAccessToken
Id string `json:"id" db:"id"`
UserID string `json:"userId" db:"user_id"`
CreatedByUser User `json:"createdByUser"`
UpdatedByUser User `json:"updatedByUser"`
Token string `json:"token" db:"token"`
Role string `json:"role" db:"role"`
Name string `json:"name" db:"name"`
CreatedAt int64 `json:"createdAt" db:"created_at"`
ExpiresAt int64 `json:"expiresAt" db:"expires_at"`
UpdatedAt int64 `json:"updatedAt" db:"updated_at"`
LastUsed int64 `json:"lastUsed" db:"last_used"`
Revoked bool `json:"revoked" db:"revoked"`
UpdatedByUserID string `json:"updatedByUserId" db:"updated_by_user_id"`
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/SigNoz/signoz/pkg/query-service/constants"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/query-service/constants"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
)
const SSO = "SSO"

View File

@@ -1,28 +1,30 @@
package types
package model
import (
"context"
"fmt"
"context"
"net/url"
"github.com/SigNoz/signoz/ee/query-service/sso"
"github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2"
"github.com/coreos/go-oidc/v3/oidc"
"go.signoz.io/signoz/ee/query-service/sso"
)
// SamlConfig contans SAML params to generate and respond to the requests
// from SAML provider
type SamlConfig struct {
SamlEntity string `json:"samlEntity"`
SamlIdp string `json:"samlIdp"`
SamlCert string `json:"samlCert"`
}
// GoogleOauthConfig contains a generic config to support oauth
// GoogleOauthConfig contains a generic config to support oauth
type GoogleOAuthConfig struct {
ClientID string `json:"clientId"`
ClientSecret string `json:"clientSecret"`
RedirectURI string `json:"redirectURI"`
}
const (
googleIssuerURL = "https://accounts.google.com"
)
@@ -38,7 +40,7 @@ func (g *GoogleOAuthConfig) GetProvider(domain string, siteUrl *url.URL) (sso.OA
}
// default to email and profile scope as we just use google auth
// to verify identity and start a session.
// to verify identity and start a session.
scopes := []string{"email"}
// this is the url google will call after login completion
@@ -59,7 +61,8 @@ func (g *GoogleOAuthConfig) GetProvider(domain string, siteUrl *url.URL) (sso.OA
Verifier: provider.Verifier(
&oidc.Config{ClientID: g.ClientID},
),
Cancel: cancel,
HostedDomain: domain,
Cancel: cancel,
HostedDomain: domain,
}, nil
}

View File

@@ -11,22 +11,22 @@ import (
"go.uber.org/zap"
"github.com/SigNoz/signoz/ee/query-service/anomaly"
"github.com/SigNoz/signoz/pkg/query-service/cache"
"github.com/SigNoz/signoz/pkg/query-service/common"
"github.com/SigNoz/signoz/pkg/query-service/model"
"go.signoz.io/signoz/ee/query-service/anomaly"
"go.signoz.io/signoz/pkg/query-service/cache"
"go.signoz.io/signoz/pkg/query-service/common"
"go.signoz.io/signoz/pkg/query-service/model"
querierV2 "github.com/SigNoz/signoz/pkg/query-service/app/querier/v2"
"github.com/SigNoz/signoz/pkg/query-service/app/queryBuilder"
"github.com/SigNoz/signoz/pkg/query-service/interfaces"
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
"github.com/SigNoz/signoz/pkg/query-service/utils/labels"
"github.com/SigNoz/signoz/pkg/query-service/utils/times"
"github.com/SigNoz/signoz/pkg/query-service/utils/timestamp"
querierV2 "go.signoz.io/signoz/pkg/query-service/app/querier/v2"
"go.signoz.io/signoz/pkg/query-service/app/queryBuilder"
"go.signoz.io/signoz/pkg/query-service/interfaces"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
"go.signoz.io/signoz/pkg/query-service/utils/labels"
"go.signoz.io/signoz/pkg/query-service/utils/times"
"go.signoz.io/signoz/pkg/query-service/utils/timestamp"
"github.com/SigNoz/signoz/pkg/query-service/formatter"
"go.signoz.io/signoz/pkg/query-service/formatter"
baserules "github.com/SigNoz/signoz/pkg/query-service/rules"
baserules "go.signoz.io/signoz/pkg/query-service/rules"
yaml "gopkg.in/yaml.v2"
)

View File

@@ -5,10 +5,10 @@ import (
"fmt"
"time"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
baserules "github.com/SigNoz/signoz/pkg/query-service/rules"
"github.com/SigNoz/signoz/pkg/query-service/utils/labels"
"github.com/google/uuid"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
baserules "go.signoz.io/signoz/pkg/query-service/rules"
"go.signoz.io/signoz/pkg/query-service/utils/labels"
"go.uber.org/zap"
)

View File

@@ -7,9 +7,9 @@ import (
"fmt"
"strings"
"github.com/SigNoz/signoz/pkg/query-service/constants"
saml2 "github.com/russellhaering/gosaml2"
dsig "github.com/russellhaering/goxmldsig"
"go.signoz.io/signoz/pkg/query-service/constants"
"go.uber.org/zap"
)

View File

@@ -15,11 +15,11 @@ import (
"go.uber.org/zap"
"github.com/SigNoz/signoz/ee/query-service/dao"
licenseserver "github.com/SigNoz/signoz/ee/query-service/integrations/signozio"
"github.com/SigNoz/signoz/ee/query-service/license"
"github.com/SigNoz/signoz/ee/query-service/model"
"github.com/SigNoz/signoz/pkg/query-service/utils/encryption"
"go.signoz.io/signoz/ee/query-service/dao"
licenseserver "go.signoz.io/signoz/ee/query-service/integrations/signozio"
"go.signoz.io/signoz/ee/query-service/license"
"go.signoz.io/signoz/ee/query-service/model"
"go.signoz.io/signoz/pkg/query-service/utils/encryption"
)
const (

View File

@@ -90,7 +90,7 @@
"less": "^4.1.2",
"less-loader": "^10.2.0",
"lodash-es": "^4.17.21",
"lucide-react": "0.427.0",
"lucide-react": "0.379.0",
"mini-css-extract-plugin": "2.4.5",
"motion": "12.4.13",
"overlayscrollbars": "^2.8.1",

View File

@@ -54,7 +54,6 @@
"SUPPORT": "SigNoz | Support",
"LOGS_SAVE_VIEWS": "SigNoz | Logs Saved Views",
"TRACES_SAVE_VIEWS": "SigNoz | Traces Saved Views",
"TRACES_FUNNELS": "SigNoz | Traces Funnels",
"DEFAULT": "Open source Observability Platform | SigNoz",
"SHORTCUTS": "SigNoz | Shortcuts",
"INTEGRATIONS": "SigNoz | Integrations",

View File

@@ -42,17 +42,6 @@ export const TracesSaveViews = Loadable(
import(/* webpackChunkName: "Traces Save Views" */ 'pages/TracesModulePage'),
);
export const TracesFunnels = Loadable(
() =>
import(/* webpackChunkName: "Traces Funnels" */ 'pages/TracesModulePage'),
);
export const TracesFunnelDetails = Loadable(
() =>
import(
/* webpackChunkName: "Traces Funnel Details" */ 'pages/TracesFunnelDetails'
),
);
export const TraceFilter = Loadable(
() => import(/* webpackChunkName: "Trace Filter Page" */ 'pages/Trace'),
);
@@ -295,7 +284,3 @@ export const MetricsExplorer = Loadable(
() =>
import(/* webpackChunkName: "MetricsExplorer" */ 'pages/MetricsExplorer'),
);
export const ApiMonitoring = Loadable(
() => import(/* webpackChunkName: "ApiMonitoring" */ 'pages/ApiMonitoring'),
);

View File

@@ -8,7 +8,6 @@ import {
AllAlertChannels,
AllErrors,
APIKeys,
ApiMonitoring,
BillingPage,
CreateAlertChannelAlerts,
CreateNewAlerts,
@@ -53,8 +52,6 @@ import {
TraceDetail,
TraceFilter,
TracesExplorer,
TracesFunnelDetails,
TracesFunnels,
TracesSaveViews,
UnAuthorized,
UsageExplorerPage,
@@ -239,20 +236,6 @@ const routes: AppRoutes[] = [
isPrivate: true,
key: 'TRACES_SAVE_VIEWS',
},
{
path: ROUTES.TRACES_FUNNELS,
exact: true,
component: TracesFunnels,
isPrivate: true,
key: 'TRACES_FUNNELS',
},
{
path: ROUTES.TRACES_FUNNELS_DETAIL,
exact: true,
component: TracesFunnelDetails,
isPrivate: true,
key: 'TRACES_FUNNELS_DETAIL',
},
{
path: ROUTES.CHANNELS_NEW,
exact: true,
@@ -498,13 +481,6 @@ const routes: AppRoutes[] = [
key: 'METRICS_EXPLORER_VIEWS',
isPrivate: true,
},
{
path: ROUTES.API_MONITORING,
exact: true,
component: ApiMonitoring,
key: 'API_MONITORING',
isPrivate: true,
},
];
export const SUPPORT_ROUTE: AppRoutes = {

View File

@@ -20,7 +20,7 @@ export interface MetricDetails {
metric_type: MetricType;
description: string;
unit: string;
temporality?: Temporality;
temporality: Temporality;
};
alerts: MetricDetailsAlert[] | null;
dashboards: MetricDetailsDashboard[] | null;

View File

@@ -12,22 +12,12 @@ export interface MetricsListFilterKeysResponse {
};
}
export interface GetMetricsListFilterKeysParams {
searchText: string;
limit?: number;
}
export const getMetricsListFilterKeys = async (
params: GetMetricsListFilterKeysParams,
signal?: AbortSignal,
headers?: Record<string, string>,
): Promise<SuccessResponse<MetricsListFilterKeysResponse> | ErrorResponse> => {
try {
const response = await axios.get('/metrics/filters/keys', {
params: {
searchText: params.searchText,
limit: params.limit,
},
signal,
headers,
});

View File

@@ -2,6 +2,7 @@ import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
export interface MetricsListFilterValuesPayload {
filterAttributeKeyDataType: string;
@@ -13,7 +14,7 @@ export interface MetricsListFilterValuesPayload {
export interface MetricsListFilterValuesResponse {
status: string;
data: {
filterValues: string[];
FilterValues: BaseAutocompleteData[];
};
}

View File

@@ -7,7 +7,7 @@ import { MetricType } from './getMetricsList';
export interface UpdateMetricMetadataProps {
description: string;
metricType: MetricType;
temporality?: Temporality;
temporality: Temporality;
isMonotonic?: boolean;
}

View File

@@ -1,109 +0,0 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
CreateFunnelPayload,
CreateFunnelResponse,
FunnelData,
} from 'types/api/traceFunnels';
const FUNNELS_BASE_PATH = '/trace-funnels';
export const createFunnel = async (
payload: CreateFunnelPayload,
): Promise<SuccessResponse<CreateFunnelResponse> | ErrorResponse> => {
const response: AxiosResponse = await axios.post(
`${FUNNELS_BASE_PATH}/new-funnel`,
payload,
);
return {
statusCode: 200,
error: null,
message: 'Funnel created successfully',
payload: response.data,
};
};
interface GetFunnelsListParams {
search?: string;
}
export const getFunnelsList = async ({
search = '',
}: GetFunnelsListParams = {}): Promise<
SuccessResponse<FunnelData[]> | ErrorResponse
> => {
const params = new URLSearchParams();
if (search.length) {
params.set('search', search);
}
const response: AxiosResponse = await axios.get(
`${FUNNELS_BASE_PATH}/list${
params.toString() ? `?${params.toString()}` : ''
}`,
);
return {
statusCode: 200,
error: null,
message: '',
payload: response.data,
};
};
export const getFunnelById = async (
funnelId: string,
): Promise<SuccessResponse<FunnelData> | ErrorResponse> => {
const response: AxiosResponse = await axios.get(
`${FUNNELS_BASE_PATH}/get/${funnelId}`,
);
return {
statusCode: 200,
error: null,
message: '',
payload: response.data,
};
};
interface RenameFunnelPayload {
id: string;
funnel_name: string;
}
export const renameFunnel = async (
payload: RenameFunnelPayload,
): Promise<SuccessResponse<FunnelData> | ErrorResponse> => {
const response: AxiosResponse = await axios.put(
`${FUNNELS_BASE_PATH}/${payload.id}/update`,
{ funnel_name: payload.funnel_name },
);
return {
statusCode: 200,
error: null,
message: 'Funnel renamed successfully',
payload: response.data,
};
};
interface DeleteFunnelPayload {
id: string;
}
export const deleteFunnel = async (
payload: DeleteFunnelPayload,
): Promise<SuccessResponse<FunnelData> | ErrorResponse> => {
const response: AxiosResponse = await axios.delete(
`${FUNNELS_BASE_PATH}/delete/${payload.id}`,
);
return {
statusCode: 200,
error: null,
message: 'Funnel deleted successfully',
payload: response.data,
};
};

View File

@@ -10,11 +10,10 @@ import { X } from 'lucide-react';
import { useState } from 'react';
import { Widgets } from 'types/api/dashboard/getAll';
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
import { DataSource } from 'types/common/queryBuilder';
import CeleryTaskGraph from '../CeleryTaskGraph/CeleryTaskGraph';
import { createFiltersFromData } from '../CeleryUtils';
import { useNavigateToExplorer } from '../useNavigateToExplorer';
import { useNavigateToTraces } from '../useNavigateToTraces';
export type CeleryTaskData = {
entity: string;
@@ -56,7 +55,7 @@ export default function CeleryTaskDetail({
const startTime = taskData.timeRange[0];
const endTime = taskData.timeRange[1];
const navigateToExplorer = useNavigateToExplorer();
const navigateToTrace = useNavigateToTraces();
return (
<Drawer
@@ -106,12 +105,7 @@ export default function CeleryTaskDetail({
endTime,
source: widgetData.title,
});
navigateToExplorer({
filters,
dataSource: DataSource.TRACES,
startTime,
endTime,
});
navigateToTrace(filters, startTime, endTime);
}}
start={startTime}
end={endTime}

View File

@@ -185,15 +185,8 @@ function CeleryTaskBar({
headerMenuList={[...ViewMenuAction]}
onDragSelect={onDragSelect}
isQueryEnabled={queryEnabled}
onClickHandler={(xValue, yValue, mouseX, mouseY, data): void =>
onGraphClick(
celerySlowestTasksTableWidgetData,
xValue,
yValue,
mouseX,
mouseY,
data,
)
onClickHandler={(...args): void =>
onGraphClick(celerySlowestTasksTableWidgetData, ...args)
}
customSeries={getCustomSeries}
dataAvailable={checkIfDataExists}
@@ -205,15 +198,8 @@ function CeleryTaskBar({
headerMenuList={[...ViewMenuAction]}
onDragSelect={onDragSelect}
isQueryEnabled={queryEnabled}
onClickHandler={(xValue, yValue, mouseX, mouseY, data): void =>
onGraphClick(
celeryFailedTasksTableWidgetData,
xValue,
yValue,
mouseX,
mouseY,
data,
)
onClickHandler={(...args): void =>
onGraphClick(celeryFailedTasksTableWidgetData, ...args)
}
customSeries={getCustomSeries}
/>
@@ -224,15 +210,8 @@ function CeleryTaskBar({
headerMenuList={[...ViewMenuAction]}
onDragSelect={onDragSelect}
isQueryEnabled={queryEnabled}
onClickHandler={(xValue, yValue, mouseX, mouseY, data): void =>
onGraphClick(
celeryRetryTasksTableWidgetData,
xValue,
yValue,
mouseX,
mouseY,
data,
)
onClickHandler={(...args): void =>
onGraphClick(celeryRetryTasksTableWidgetData, ...args)
}
customSeries={getCustomSeries}
/>
@@ -243,15 +222,8 @@ function CeleryTaskBar({
headerMenuList={[...ViewMenuAction]}
onDragSelect={onDragSelect}
isQueryEnabled={queryEnabled}
onClickHandler={(xValue, yValue, mouseX, mouseY, data): void =>
onGraphClick(
celerySuccessTasksTableWidgetData,
xValue,
yValue,
mouseX,
mouseY,
data,
)
onClickHandler={(...args): void =>
onGraphClick(celerySuccessTasksTableWidgetData, ...args)
}
customSeries={getCustomSeries}
/>

View File

@@ -18,7 +18,6 @@ import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useLocation } from 'react-router-dom';
import { UpdateTimeInterval } from 'store/actions';
import { AppState } from 'store/reducers';
import { DataSource } from 'types/common/queryBuilder';
import { GlobalReducer } from 'types/reducer/globalTime';
import {
@@ -26,7 +25,7 @@ import {
createFiltersFromData,
getFiltersFromQueryParams,
} from '../CeleryUtils';
import { useNavigateToExplorer } from '../useNavigateToExplorer';
import { useNavigateToTraces } from '../useNavigateToTraces';
import { celeryTaskLatencyWidgetData } from './CeleryTaskGraphUtils';
interface TabData {
@@ -146,21 +145,15 @@ function CeleryTaskLatencyGraph({
[handleSetTimeStamp],
);
const navigateToExplorer = useNavigateToExplorer();
const navigateToTraces = useNavigateToTraces();
const goToTraces = useCallback(() => {
const { start, end } = getStartAndEndTimesInMilliseconds(selectedTimeStamp);
const filters = createFiltersFromData({
[entityData?.entity as string]: entityData?.value,
});
navigateToExplorer({
filters,
dataSource: DataSource.TRACES,
startTime: start,
endTime: end,
sameTab: true,
});
}, [entityData, navigateToExplorer, selectedTimeStamp]);
navigateToTraces(filters, start, end, true);
}, [entityData, navigateToTraces, selectedTimeStamp]);
return (
<Card

View File

@@ -1,121 +0,0 @@
import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
import useUpdatedQuery from 'container/GridCardLayout/useResolveQuery';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useNotifications } from 'hooks/useNotifications';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource, MetricAggregateOperator } from 'types/common/queryBuilder';
import { GlobalReducer } from 'types/reducer/globalTime';
export interface NavigateToExplorerProps {
filters: TagFilterItem[];
dataSource: DataSource;
startTime?: number;
endTime?: number;
sameTab?: boolean;
shouldResolveQuery?: boolean;
}
export function useNavigateToExplorer(): (
props: NavigateToExplorerProps,
) => void {
const { currentQuery } = useQueryBuilder();
const { minTime, maxTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const prepareQuery = useCallback(
(selectedFilters: TagFilterItem[], dataSource: DataSource): Query => ({
...currentQuery,
builder: {
...currentQuery.builder,
queryData: currentQuery.builder.queryData
.map((item) => ({
...item,
dataSource,
aggregateOperator: MetricAggregateOperator.NOOP,
filters: {
...item.filters,
items: selectedFilters,
},
groupBy: [],
disabled: false,
}))
.slice(0, 1),
queryFormulas: [],
},
}),
[currentQuery],
);
const { getUpdatedQuery } = useUpdatedQuery();
const { selectedDashboard } = useDashboard();
const { notifications } = useNotifications();
return useCallback(
async (props: NavigateToExplorerProps): Promise<void> => {
const {
filters,
dataSource,
startTime,
endTime,
sameTab,
shouldResolveQuery,
} = props;
const urlParams = new URLSearchParams();
if (startTime && endTime) {
urlParams.set(QueryParams.startTime, startTime.toString());
urlParams.set(QueryParams.endTime, endTime.toString());
} else {
urlParams.set(QueryParams.startTime, (minTime / 1000000).toString());
urlParams.set(QueryParams.endTime, (maxTime / 1000000).toString());
}
let preparedQuery = prepareQuery(filters, dataSource);
if (shouldResolveQuery) {
await getUpdatedQuery({
widgetConfig: {
query: preparedQuery,
panelTypes: PANEL_TYPES.TIME_SERIES,
timePreferance: 'GLOBAL_TIME',
},
selectedDashboard,
})
.then((query) => {
preparedQuery = query;
})
.catch(() => {
notifications.error({
message: 'Unable to resolve variables',
});
});
}
const JSONCompositeQuery = encodeURIComponent(JSON.stringify(preparedQuery));
const basePath =
dataSource === DataSource.TRACES
? ROUTES.TRACES_EXPLORER
: ROUTES.LOGS_EXPLORER;
const newExplorerPath = `${basePath}?${urlParams.toString()}&${
QueryParams.compositeQuery
}=${JSONCompositeQuery}`;
window.open(newExplorerPath, sameTab ? '_self' : '_blank');
},
[
prepareQuery,
minTime,
maxTime,
getUpdatedQuery,
selectedDashboard,
notifications,
],
);
}

View File

@@ -0,0 +1,71 @@
import { QueryParams } from 'constants/query';
import ROUTES from 'constants/routes';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource, MetricAggregateOperator } from 'types/common/queryBuilder';
import { GlobalReducer } from 'types/reducer/globalTime';
export function useNavigateToTraces(): (
filters: TagFilterItem[],
startTime?: number,
endTime?: number,
sameTab?: boolean,
) => void {
const { currentQuery } = useQueryBuilder();
const { minTime, maxTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const prepareQuery = useCallback(
(selectedFilters: TagFilterItem[]): Query => ({
...currentQuery,
builder: {
...currentQuery.builder,
queryData: currentQuery.builder.queryData.map((item) => ({
...item,
dataSource: DataSource.TRACES,
aggregateOperator: MetricAggregateOperator.NOOP,
filters: {
...item.filters,
items: selectedFilters,
},
})),
},
}),
[currentQuery],
);
return useCallback(
(
filters: TagFilterItem[],
startTime?: number,
endTime?: number,
sameTab?: boolean,
): void => {
const urlParams = new URLSearchParams();
if (startTime && endTime) {
urlParams.set(QueryParams.startTime, startTime.toString());
urlParams.set(QueryParams.endTime, endTime.toString());
} else {
urlParams.set(QueryParams.startTime, (minTime / 1000000).toString());
urlParams.set(QueryParams.endTime, (maxTime / 1000000).toString());
}
const JSONCompositeQuery = encodeURIComponent(
JSON.stringify(prepareQuery(filters)),
);
const newTraceExplorerPath = `${
ROUTES.TRACES_EXPLORER
}?${urlParams.toString()}&${
QueryParams.compositeQuery
}=${JSONCompositeQuery}`;
window.open(newTraceExplorerPath, sameTab ? '_self' : '_blank');
},
[minTime, maxTime, prepareQuery],
);
}

View File

@@ -199,12 +199,12 @@ function ExplorerCard({
value={viewName || undefined}
>
{viewsData?.data.data.map((view) => (
<Select.Option key={view.id} value={view.name}>
<Select.Option key={view.uuid} value={view.name}>
<MenuItemGenerator
viewName={view.name}
viewKey={viewKey}
createdBy={view.createdBy}
uuid={view.id}
uuid={view.uuid}
refetchAllView={refetchAllView}
viewData={viewsData.data.data}
sourcePage={sourcepage}

View File

@@ -53,12 +53,17 @@ function MenuItemGenerator({
({ key }: { key: string }): void => {
const currentViewDetails = getViewDetailsUsingViewKey(key, viewData);
if (!currentViewDetails) return;
const { query, name, id, panelType: currentPanelType } = currentViewDetails;
const {
query,
name,
uuid,
panelType: currentPanelType,
} = currentViewDetails;
handleExplorerTabChange(currentPanelType, {
query,
name,
id,
uuid,
});
},
[viewData, handleExplorerTabChange],

View File

@@ -4,7 +4,7 @@ import { DataSource } from 'types/common/queryBuilder';
export const viewMockData: ViewProps[] = [
{
id: 'view1',
uuid: 'view1',
name: 'View 1',
createdBy: 'User 1',
category: 'category 1',
@@ -17,7 +17,7 @@ export const viewMockData: ViewProps[] = [
updatedBy: 'User 1',
},
{
id: 'view2',
uuid: 'view2',
name: 'View 2',
createdBy: 'User 2',
category: 'category 2',

View File

@@ -25,9 +25,9 @@ describe('MenuItemGenerator', () => {
<MockQueryClientProvider>
<MenuItemGenerator
viewName={viewMockData[0].name}
viewKey={viewMockData[0].id}
viewKey={viewMockData[0].uuid}
createdBy={viewMockData[0].createdBy}
uuid={viewMockData[0].id}
uuid={viewMockData[0].uuid}
refetchAllView={jest.fn()}
viewData={viewMockData}
sourcePage={DataSource.TRACES}
@@ -43,9 +43,9 @@ describe('MenuItemGenerator', () => {
<MockQueryClientProvider>
<MenuItemGenerator
viewName={viewMockData[0].name}
viewKey={viewMockData[0].id}
viewKey={viewMockData[0].uuid}
createdBy={viewMockData[0].createdBy}
uuid={viewMockData[0].id}
uuid={viewMockData[0].uuid}
refetchAllView={jest.fn()}
viewData={viewMockData}
sourcePage={DataSource.TRACES}

View File

@@ -26,7 +26,7 @@ export type GetViewDetailsUsingViewKey = (
| {
query: Query;
name: string;
id: string;
uuid: string;
panelType: PANEL_TYPES;
extraData?: string;
}

View File

@@ -27,11 +27,11 @@ export const getViewDetailsUsingViewKey: GetViewDetailsUsingViewKey = (
viewKey,
data,
) => {
const selectedView = data?.find((view) => view.id === viewKey);
const selectedView = data?.find((view) => view.uuid === viewKey);
if (selectedView) {
const { compositeQuery, name, id, extraData } = selectedView;
const { compositeQuery, name, uuid, extraData } = selectedView;
const query = mapQueryDataFromApi(compositeQuery);
return { query, name, id, panelType: compositeQuery.panelType, extraData };
return { query, name, uuid, panelType: compositeQuery.panelType, extraData };
}
return undefined;
};

View File

@@ -1,9 +1,7 @@
import './HostMetricTraces.styles.scss';
import logEvent from 'api/common/logEvent';
import { ResizeTable } from 'components/ResizeTable';
import { DEFAULT_ENTITY_VERSION } from 'constants/app';
import { InfraMonitoringEvents } from 'constants/events';
import { QueryParams } from 'constants/query';
import EmptyLogsSearch from 'container/EmptyLogsSearch/EmptyLogsSearch';
import NoLogs from 'container/NoLogs/NoLogs';
@@ -21,7 +19,7 @@ import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { Pagination } from 'hooks/queryPagination';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useQuery } from 'react-query';
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { DataSource } from 'types/common/queryBuilder';
@@ -139,13 +137,6 @@ function HostMetricTraces({
const totalCount =
data?.payload?.data?.newResult?.data?.result?.[0]?.list?.length || 0;
const handleRowClick = useCallback(() => {
logEvent(InfraMonitoringEvents.ItemClicked, {
entity: InfraMonitoringEvents.HostEntity,
view: InfraMonitoringEvents.TracesView,
});
}, []);
return (
<div className="host-metric-traces">
<div className="host-metric-traces-header">
@@ -198,9 +189,6 @@ function HostMetricTraces({
loading={isFetching}
dataSource={traces}
columns={traceListColumns}
onRow={(): Record<string, unknown> => ({
onClick: (): void => handleRowClick(),
})}
/>
</div>
)}

View File

@@ -149,10 +149,6 @@ function HostMetricsDetails({
const handleTabChange = (e: RadioChangeEvent): void => {
setSelectedView(e.target.value);
logEvent(InfraMonitoringEvents.TabChanged, {
entity: InfraMonitoringEvents.HostEntity,
view: e.target.value,
});
};
const handleTimeChange = useCallback(

View File

@@ -1,14 +0,0 @@
.learn-more {
display: flex;
align-items: center;
gap: 4px;
padding: 0;
font-family: Inter;
font-size: 14px;
font-weight: 500;
line-height: 18px; /* 128.571% */
letter-spacing: -0.07px;
&,&:hover {
color: var(--bg-robin-400) !important;
}
}

View File

@@ -1,34 +0,0 @@
import './LearnMore.styles.scss';
import { Color } from '@signozhq/design-tokens';
import { Button } from 'antd';
import { ArrowUpRight } from 'lucide-react';
type LearnMoreProps = {
text?: string;
url?: string;
onClick?: () => void;
};
function LearnMore({ text, url, onClick }: LearnMoreProps): JSX.Element {
const handleClick = (): void => {
onClick?.();
if (url) {
window.open(url, '_blank');
}
};
return (
<Button type="link" className="learn-more" onClick={handleClick}>
<div className="learn-more__text">{text}</div>
<ArrowUpRight size={16} color={Color.BG_ROBIN_400} />
</Button>
);
}
LearnMore.defaultProps = {
text: 'Learn more',
url: '',
onClick: (): void => {},
};
export default LearnMore;

View File

@@ -63,31 +63,30 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
return (
<div className="quick-filters">
{source !== QuickFiltersSource.INFRA_MONITORING &&
source !== QuickFiltersSource.API_MONITORING && (
<section className="header">
<section className="left-actions">
<FilterOutlined />
<Typography.Text className="text">Filters for</Typography.Text>
<Tooltip title={`Filter currently in sync with query ${lastQueryName}`}>
<Typography.Text className="sync-tag">{lastQueryName}</Typography.Text>
</Tooltip>
</section>
<section className="right-actions">
<Tooltip title="Reset All">
<SyncOutlined className="sync-icon" onClick={handleReset} />
</Tooltip>
<div className="divider-filter" />
<Tooltip title="Collapse Filters">
<VerticalAlignTopOutlined
rotate={270}
onClick={handleFilterVisibilityChange}
/>
</Tooltip>
</section>
{source !== QuickFiltersSource.INFRA_MONITORING && (
<section className="header">
<section className="left-actions">
<FilterOutlined />
<Typography.Text className="text">Filters for</Typography.Text>
<Tooltip title={`Filter currently in sync with query ${lastQueryName}`}>
<Typography.Text className="sync-tag">{lastQueryName}</Typography.Text>
</Tooltip>
</section>
)}
<section className="right-actions">
<Tooltip title="Reset All">
<SyncOutlined className="sync-icon" onClick={handleReset} />
</Tooltip>
<div className="divider-filter" />
<Tooltip title="Collapse Filters">
<VerticalAlignTopOutlined
rotate={270}
onClick={handleFilterVisibilityChange}
/>
</Tooltip>
</section>
</section>
)}
<section className="filters">
{config.map((filter) => {

View File

@@ -39,5 +39,4 @@ export enum QuickFiltersSource {
LOGS_EXPLORER = 'logs-explorer',
INFRA_MONITORING = 'infra-monitoring',
TRACES_EXPLORER = 'traces-explorer',
API_MONITORING = 'api-monitoring',
}

View File

@@ -67,17 +67,6 @@
background: var(--bg-ink-300);
}
}
.ant-modal-footer {
.ant-btn {
display: flex;
align-items: center;
gap: 4px;
&-icon {
margin: 0 !important;
}
}
}
}
.lightMode {

View File

@@ -4,14 +4,14 @@ import { Modal, ModalProps } from 'antd';
function SignozModal({
children,
width = 672,
rootClassName = '',
...rest
}: ModalProps): JSX.Element {
return (
<Modal
centered
width={width}
width={672}
cancelText="Close"
rootClassName={`signoz-modal ${rootClassName}`}
// eslint-disable-next-line react/jsx-props-no-spreading

View File

@@ -56,7 +56,6 @@ export const DATE_TIME_FORMATS = {
// Formats with dash separator
DASH_DATETIME: 'MMM D, YYYY ⎯ HH:mm:ss',
FUNNELS_LIST_DATE: 'MMM D ⎯ HH:mm:ss',
DASH_DATETIME_UTC: 'MMM D, YYYY ⎯ HH:mm:ss (UTC Z)',
DASH_TIME_DATE: 'HH:mm:ss ⎯ MMM D, YYYY (UTC Z)',
} as const;

View File

@@ -51,21 +51,4 @@ export const REACT_QUERY_KEY = {
GET_METRICS_LIST_FILTER_VALUES: 'GET_METRICS_LIST_FILTER_VALUES',
GET_METRIC_DETAILS: 'GET_METRIC_DETAILS',
GET_RELATED_METRICS: 'GET_RELATED_METRICS',
// API Monitoring Query Keys
GET_DOMAINS_LIST: 'GET_DOMAINS_LIST',
GET_ENDPOINTS_LIST_BY_DOMAIN: 'GET_ENDPOINTS_LIST_BY_DOMAIN',
GET_NESTED_ENDPOINTS_LIST: 'GET_NESTED_ENDPOINTS_LIST',
GET_ENDPOINT_METRICS_DATA: 'GET_ENDPOINT_METRICS_DATA',
GET_ENDPOINT_STATUS_CODE_DATA: 'GET_ENDPOINT_STATUS_CODE_DATA',
GET_ENDPOINT_RATE_OVER_TIME_DATA: 'GET_ENDPOINT_RATE_OVER_TIME_DATA',
GET_ENDPOINT_LATENCY_OVER_TIME_DATA: 'GET_ENDPOINT_LATENCY_OVER_TIME_DATA',
GET_ENDPOINT_DROPDOWN_DATA: 'GET_ENDPOINT_DROPDOWN_DATA',
GET_ENDPOINT_DEPENDENT_SERVICES_DATA: 'GET_ENDPOINT_DEPENDENT_SERVICES_DATA',
GET_ENDPOINT_STATUS_CODE_BAR_CHARTS_DATA:
'GET_ENDPOINT_STATUS_CODE_BAR_CHARTS_DATA',
GET_ENDPOINT_STATUS_CODE_LATENCY_BAR_CHARTS_DATA:
'GET_ENDPOINT_STATUS_CODE_LATENCY_BAR_CHARTS_DATA',
GET_FUNNELS_LIST: 'GET_FUNNELS_LIST',
GET_FUNNEL_DETAILS: 'GET_FUNNEL_DETAILS',
} as const;
};

View File

@@ -56,8 +56,6 @@ const ROUTES = {
SUPPORT: '/support',
LOGS_SAVE_VIEWS: '/logs/saved-views',
TRACES_SAVE_VIEWS: '/traces/saved-views',
TRACES_FUNNELS: '/traces/funnels',
TRACES_FUNNELS_DETAIL: '/traces/funnels/:funnelId',
WORKSPACE_LOCKED: '/workspace-locked',
WORKSPACE_SUSPENDED: '/workspace-suspended',
SHORTCUTS: '/shortcuts',
@@ -71,8 +69,6 @@ const ROUTES = {
METRICS_EXPLORER: '/metrics-explorer/summary',
METRICS_EXPLORER_EXPLORER: '/metrics-explorer/explorer',
METRICS_EXPLORER_VIEWS: '/metrics-explorer/views',
API_MONITORING: '/api-monitoring/explorer',
METRICS_EXPLORER_BASE: '/metrics-explorer',
WORKSPACE_ACCESS_RESTRICTED: '/workspace-access-restricted',
HOME_PAGE: '/',
} as const;

View File

@@ -339,15 +339,12 @@ function APIKeys(): JSX.Element {
? getFormattedTime(APIKey?.lastUsed)
: 'Never';
const createdOn = new Date(APIKey.createdAt).toLocaleString();
const createdOn = getFormattedTime(APIKey.createdAt);
const expiresIn =
APIKey.expiresAt === 0
? Number.POSITIVE_INFINITY
: getDateDifference(
new Date(APIKey?.createdAt).getTime() / 1000,
APIKey?.expiresAt,
);
: getDateDifference(APIKey?.createdAt, APIKey?.expiresAt);
const isExpired = isExpiredToken(APIKey.expiresAt);
@@ -357,9 +354,9 @@ function APIKeys(): JSX.Element {
: getFormattedTime(APIKey.expiresAt);
const updatedOn =
!APIKey.updatedAt || APIKey.updatedAt === ''
!APIKey.updatedAt || APIKey.updatedAt === 0
? null
: new Date(APIKey.updatedAt).toLocaleString();
: getFormattedTime(APIKey?.updatedAt);
const items: CollapseProps['items'] = [
{
@@ -838,9 +835,7 @@ function APIKeys(): JSX.Element {
{activeAPIKey?.createdAt && (
<Row>
<Col span={8}>Created on</Col>
<Col span={16}>
{new Date(activeAPIKey?.createdAt).toLocaleString()}
</Col>
<Col span={16}>{getFormattedTime(activeAPIKey?.createdAt)}</Col>
</Row>
)}

Some files were not shown because too many files have changed in this diff Show More