ci: add golangci to workflow (#1369)

* style: reformat the code to follow go guidelines
* chore: add golangci lint
* chore: remove context check
* chore: go fmt
This commit is contained in:
Srikanth Chekuri 2022-07-13 23:44:42 +05:30 committed by GitHub
parent 64e638fd58
commit 7aeaecaf1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 500 additions and 394 deletions

View File

@ -8,6 +8,21 @@ on:
- release/v* - release/v*
jobs: jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.4.0
- uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Install tools
run: make install-ci
- name: Run unit tests
run: make test-ci
build-frontend: build-frontend:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

37
.golangci.yml Normal file
View File

@ -0,0 +1,37 @@
run:
timeout: 10m
linters-settings:
depguard:
list-type: blacklist
include-go-root: true
gofmt:
simplify: true
gosimple:
go: '1.17'
linters:
enable:
- gofmt
- goimports
- misspell
disable:
- staticcheck
- typecheck
- gosec
- govet
- errcheck
- gocritic
- revive
- deadcode
- gosimple
- ineffassign
- depguard
- errorlint
- structcheck
- varcheck
- unused
issues:
exclude-rules:
- path: _test\.go
linters:
- gosec

View File

@ -14,6 +14,14 @@ QUERY_SERVICE_DIRECTORY ?= pkg/query-service
STANDALONE_DIRECTORY ?= deploy/docker/clickhouse-setup STANDALONE_DIRECTORY ?= deploy/docker/clickhouse-setup
SWARM_DIRECTORY ?= deploy/docker-swarm/clickhouse-setup SWARM_DIRECTORY ?= deploy/docker-swarm/clickhouse-setup
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
GOPATH ?= $(shell go env GOPATH)
GOTEST=go test -v $(RACE)
GOFMT=gofmt
FMT_LOG=.fmt.log
IMPORT_LOG=.import.log
REPONAME ?= signoz REPONAME ?= signoz
DOCKER_TAG ?= latest DOCKER_TAG ?= latest
@ -30,6 +38,12 @@ gitBranch=${PACKAGE}/version.gitBranch
LD_FLAGS="-X ${buildHash}=${BUILD_HASH} -X ${buildTime}=${BUILD_TIME} -X ${buildVersion}=${BUILD_VERSION} -X ${gitBranch}=${BUILD_BRANCH}" LD_FLAGS="-X ${buildHash}=${BUILD_HASH} -X ${buildTime}=${BUILD_TIME} -X ${buildVersion}=${BUILD_VERSION} -X ${gitBranch}=${BUILD_BRANCH}"
all: build-push-frontend build-push-query-service all: build-push-frontend build-push-query-service
.DEFAULT_GOAL := test-and-lint
.PHONY: test-and-lint
test-and-lint: fmt lint
# Steps to build and push docker image of frontend # Steps to build and push docker image of frontend
.PHONY: build-frontend-amd64 build-push-frontend .PHONY: build-frontend-amd64 build-push-frontend
# Step to build docker image of frontend in amd64 (used in build pipeline) # Step to build docker image of frontend in amd64 (used in build pipeline)
@ -92,3 +106,23 @@ clear-standalone-data:
clear-swarm-data: clear-swarm-data:
@docker run --rm -v "$(PWD)/$(SWARM_DIRECTORY)/data:/pwd" busybox \ @docker run --rm -v "$(PWD)/$(SWARM_DIRECTORY)/data:/pwd" busybox \
sh -c "cd /pwd && rm -rf alertmanager/* clickhouse/* signoz/*" sh -c "cd /pwd && rm -rf alertmanager/* clickhouse/* signoz/*"
.PHONY: install-tools
install-tools:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.42.0
.PHONY: lint
lint:
@cd $(QUERY_SERVICE_DIRECTORY) && \
$(GOPATH)/bin/golangci-lint -v run
.PHONY: fmt
fmt:
@echo Running go fmt on query service ...
@$(GOFMT) -e -s -l -w $(QUERY_SERVICE_DIRECTORY)
.PHONY: install-ci
install-ci: install-tools
.PHONY: test-ci
test-ci: lint

View File

@ -23,7 +23,7 @@ const (
defaultOperationsTable string = "signoz_operations" defaultOperationsTable string = "signoz_operations"
defaultIndexTable string = "signoz_index_v2" defaultIndexTable string = "signoz_index_v2"
defaultErrorTable string = "signoz_error_index_v2" defaultErrorTable string = "signoz_error_index_v2"
defaulDurationTable string = "durationSortMV" defaultDurationTable string = "durationSortMV"
defaultSpansTable string = "signoz_spans" defaultSpansTable string = "signoz_spans"
defaultWriteBatchDelay time.Duration = 5 * time.Second defaultWriteBatchDelay time.Duration = 5 * time.Second
defaultWriteBatchSize int = 10000 defaultWriteBatchSize int = 10000
@ -58,12 +58,15 @@ type namespaceConfig struct {
Connector Connector Connector Connector
} }
// Connecto defines how to connect to the database // Connector defines how to connect to the database
type Connector func(cfg *namespaceConfig) (clickhouse.Conn, error) type Connector func(cfg *namespaceConfig) (clickhouse.Conn, error)
func defaultConnector(cfg *namespaceConfig) (clickhouse.Conn, error) { func defaultConnector(cfg *namespaceConfig) (clickhouse.Conn, error) {
ctx := context.Background() ctx := context.Background()
dsnURL, err := url.Parse(cfg.Datasource) dsnURL, err := url.Parse(cfg.Datasource)
if err != nil {
return nil, err
}
options := &clickhouse.Options{ options := &clickhouse.Options{
Addr: []string{dsnURL.Host}, Addr: []string{dsnURL.Host},
} }
@ -109,7 +112,7 @@ func NewOptions(datasource string, primaryNamespace string, otherNamespaces ...s
OperationsTable: defaultOperationsTable, OperationsTable: defaultOperationsTable,
IndexTable: defaultIndexTable, IndexTable: defaultIndexTable,
ErrorTable: defaultErrorTable, ErrorTable: defaultErrorTable,
DurationTable: defaulDurationTable, DurationTable: defaultDurationTable,
SpansTable: defaultSpansTable, SpansTable: defaultSpansTable,
WriteBatchDelay: defaultWriteBatchDelay, WriteBatchDelay: defaultWriteBatchDelay,
WriteBatchSize: defaultWriteBatchSize, WriteBatchSize: defaultWriteBatchSize,

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@ import (
// This time the global variable is unexported. // This time the global variable is unexported.
var db *sqlx.DB var db *sqlx.DB
// InitDB sets up setting up the connection pool global variable. // InitDB sets up the connection pool global variable.
func InitDB(dataSourceName string) (*sqlx.DB, error) { func InitDB(dataSourceName string) (*sqlx.DB, error) {
var err error var err error
@ -26,7 +26,7 @@ func InitDB(dataSourceName string) (*sqlx.DB, error) {
return nil, err return nil, err
} }
table_schema := `CREATE TABLE IF NOT EXISTS dashboards ( tableSchema := `CREATE TABLE IF NOT EXISTS dashboards (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
uuid TEXT NOT NULL UNIQUE, uuid TEXT NOT NULL UNIQUE,
created_at datetime NOT NULL, created_at datetime NOT NULL,
@ -34,24 +34,24 @@ func InitDB(dataSourceName string) (*sqlx.DB, error) {
data TEXT NOT NULL data TEXT NOT NULL
);` );`
_, err = db.Exec(table_schema) _, err = db.Exec(tableSchema)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error in creating dashboard table: %s", err.Error()) return nil, fmt.Errorf("error in creating dashboard table: %s", err.Error())
} }
table_schema = `CREATE TABLE IF NOT EXISTS rules ( tableSchema = `CREATE TABLE IF NOT EXISTS rules (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
updated_at datetime NOT NULL, updated_at datetime NOT NULL,
deleted INTEGER DEFAULT 0, deleted INTEGER DEFAULT 0,
data TEXT NOT NULL data TEXT NOT NULL
);` );`
_, err = db.Exec(table_schema) _, err = db.Exec(tableSchema)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error in creating rules table: %s", err.Error()) return nil, fmt.Errorf("error in creating rules table: %s", err.Error())
} }
table_schema = `CREATE TABLE IF NOT EXISTS notification_channels ( tableSchema = `CREATE TABLE IF NOT EXISTS notification_channels (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
created_at datetime NOT NULL, created_at datetime NOT NULL,
updated_at datetime NOT NULL, updated_at datetime NOT NULL,
@ -61,12 +61,12 @@ func InitDB(dataSourceName string) (*sqlx.DB, error) {
data TEXT NOT NULL data TEXT NOT NULL
);` );`
_, err = db.Exec(table_schema) _, err = db.Exec(tableSchema)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error in creating notification_channles table: %s", err.Error()) return nil, fmt.Errorf("error in creating notification_channles table: %s", err.Error())
} }
table_schema = `CREATE TABLE IF NOT EXISTS ttl_status ( tableSchema = `CREATE TABLE IF NOT EXISTS ttl_status (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
transaction_id TEXT NOT NULL, transaction_id TEXT NOT NULL,
created_at datetime NOT NULL, created_at datetime NOT NULL,
@ -77,9 +77,9 @@ func InitDB(dataSourceName string) (*sqlx.DB, error) {
status TEXT NOT NULL status TEXT NOT NULL
);` );`
_, err = db.Exec(table_schema) _, err = db.Exec(tableSchema)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error in creating ttl_status table: %s", err.Error()) return nil, fmt.Errorf("error in creating ttl_status table: %s", err.Error())
} }
return db, nil return db, nil
@ -128,17 +128,17 @@ func CreateDashboard(data map[string]interface{}) (*Dashboard, *model.ApiError)
dash.UpdateSlug() dash.UpdateSlug()
dash.Uuid = uuid.New().String() dash.Uuid = uuid.New().String()
map_data, err := json.Marshal(dash.Data) mapData, err := json.Marshal(dash.Data)
if err != nil { if err != nil {
zap.S().Errorf("Error in marshalling data field in dashboard: ", dash, err) zap.S().Error("Error in marshalling data field in dashboard: ", dash, err)
return nil, &model.ApiError{Typ: model.ErrorExec, Err: err} return nil, &model.ApiError{Typ: model.ErrorExec, Err: err}
} }
// db.Prepare("Insert into dashboards where") // db.Prepare("Insert into dashboards where")
result, err := db.Exec("INSERT INTO dashboards (uuid, created_at, updated_at, data) VALUES ($1, $2, $3, $4)", dash.Uuid, dash.CreatedAt, dash.UpdatedAt, map_data) result, err := db.Exec("INSERT INTO dashboards (uuid, created_at, updated_at, data) VALUES ($1, $2, $3, $4)", dash.Uuid, dash.CreatedAt, dash.UpdatedAt, mapData)
if err != nil { if err != nil {
zap.S().Errorf("Error in inserting dashboard data: ", dash, err) zap.S().Error("Error in inserting dashboard data: ", dash, err)
return nil, &model.ApiError{Typ: model.ErrorExec, Err: err} return nil, &model.ApiError{Typ: model.ErrorExec, Err: err}
} }
lastInsertId, err := result.LastInsertId() lastInsertId, err := result.LastInsertId()
@ -153,7 +153,7 @@ func CreateDashboard(data map[string]interface{}) (*Dashboard, *model.ApiError)
func GetDashboards() ([]Dashboard, *model.ApiError) { func GetDashboards() ([]Dashboard, *model.ApiError) {
dashboards := []Dashboard{} var dashboards []Dashboard
query := fmt.Sprintf("SELECT * FROM dashboards;") query := fmt.Sprintf("SELECT * FROM dashboards;")
err := db.Select(&dashboards, query) err := db.Select(&dashboards, query)
@ -200,9 +200,9 @@ func GetDashboard(uuid string) (*Dashboard, *model.ApiError) {
func UpdateDashboard(uuid string, data map[string]interface{}) (*Dashboard, *model.ApiError) { func UpdateDashboard(uuid string, data map[string]interface{}) (*Dashboard, *model.ApiError) {
map_data, err := json.Marshal(data) mapData, err := json.Marshal(data)
if err != nil { if err != nil {
zap.S().Errorf("Error in marshalling data field in dashboard: ", data, err) zap.S().Error("Error in marshalling data field in dashboard: ", data, err)
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err} return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
} }
@ -215,10 +215,10 @@ func UpdateDashboard(uuid string, data map[string]interface{}) (*Dashboard, *mod
dashboard.Data = data dashboard.Data = data
// db.Prepare("Insert into dashboards where") // db.Prepare("Insert into dashboards where")
_, err = db.Exec("UPDATE dashboards SET updated_at=$1, data=$2 WHERE uuid=$3 ", dashboard.UpdatedAt, map_data, dashboard.Uuid) _, err = db.Exec("UPDATE dashboards SET updated_at=$1, data=$2 WHERE uuid=$3 ", dashboard.UpdatedAt, mapData, dashboard.Uuid)
if err != nil { if err != nil {
zap.S().Errorf("Error in inserting dashboard data: ", data, err) zap.S().Error("Error in inserting dashboard data: ", data, err)
return nil, &model.ApiError{Typ: model.ErrorExec, Err: err} return nil, &model.ApiError{Typ: model.ErrorExec, Err: err}
} }
@ -249,7 +249,7 @@ func IsPostDataSane(data *map[string]interface{}) error {
func SlugifyTitle(title string) string { func SlugifyTitle(title string) string {
s := slug.Make(strings.ToLower(title)) s := slug.Make(strings.ToLower(title))
if s == "" { if s == "" {
// If the dashboard name is only characters outside of the // If the dashboard name is only characters outside the
// sluggable characters, the slug creation will return an // sluggable characters, the slug creation will return an
// empty string which will mess up URLs. This failsafe picks // empty string which will mess up URLs. This failsafe picks
// that up and creates the slug as a base64 identifier instead. // that up and creates the slug as a base64 identifier instead.

View File

@ -210,7 +210,7 @@ func ViewAccess(f func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
if !(auth.IsViewer(user) || auth.IsEditor(user) || auth.IsAdmin(user)) { if !(auth.IsViewer(user) || auth.IsEditor(user) || auth.IsAdmin(user)) {
respondError(w, &model.ApiError{ respondError(w, &model.ApiError{
Typ: model.ErrorForbidden, Typ: model.ErrorForbidden,
Err: errors.New("API is accessible to viewers/editors/admins."), Err: errors.New("API is accessible to viewers/editors/admins"),
}, nil) }, nil)
return return
} }
@ -231,7 +231,7 @@ func EditAccess(f func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
if !(auth.IsEditor(user) || auth.IsAdmin(user)) { if !(auth.IsEditor(user) || auth.IsAdmin(user)) {
respondError(w, &model.ApiError{ respondError(w, &model.ApiError{
Typ: model.ErrorForbidden, Typ: model.ErrorForbidden,
Err: errors.New("API is accessible to editors/admins."), Err: errors.New("API is accessible to editors/admins"),
}, nil) }, nil)
return return
} }
@ -253,7 +253,7 @@ func SelfAccess(f func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
if !(auth.IsSelfAccessRequest(user, id) || auth.IsAdmin(user)) { if !(auth.IsSelfAccessRequest(user, id) || auth.IsAdmin(user)) {
respondError(w, &model.ApiError{ respondError(w, &model.ApiError{
Typ: model.ErrorForbidden, Typ: model.ErrorForbidden,
Err: errors.New("API is accessible for self access or to the admins."), Err: errors.New("API is accessible for self access or to the admins"),
}, nil) }, nil)
return return
} }
@ -455,13 +455,13 @@ func (aH *APIHandler) queryRangeMetricsV2(w http.ResponseWriter, r *http.Request
} }
// prometheus instant query needs same timestamp // prometheus instant query needs same timestamp
if metricsQueryRangeParams.CompositeMetricQuery.PanelType == model.QUERY_VALUE && if metricsQueryRangeParams.CompositeMetricQuery.PanelType == model.QueryValue &&
metricsQueryRangeParams.CompositeMetricQuery.QueryType == model.PROM { metricsQueryRangeParams.CompositeMetricQuery.QueryType == model.Prom {
metricsQueryRangeParams.Start = metricsQueryRangeParams.End metricsQueryRangeParams.Start = metricsQueryRangeParams.End
} }
// round up the end to neaerest multiple // round down the end to the nearest multiple
if metricsQueryRangeParams.CompositeMetricQuery.QueryType == model.QUERY_BUILDER { if metricsQueryRangeParams.CompositeMetricQuery.QueryType == model.QueryBuilder {
end := (metricsQueryRangeParams.End) / 1000 end := (metricsQueryRangeParams.End) / 1000
step := metricsQueryRangeParams.Step step := metricsQueryRangeParams.Step
metricsQueryRangeParams.End = (end / step * step) * 1000 metricsQueryRangeParams.End = (end / step * step) * 1000
@ -571,15 +571,15 @@ func (aH *APIHandler) queryRangeMetricsV2(w http.ResponseWriter, r *http.Request
var seriesList []*model.Series var seriesList []*model.Series
var err error var err error
switch metricsQueryRangeParams.CompositeMetricQuery.QueryType { switch metricsQueryRangeParams.CompositeMetricQuery.QueryType {
case model.QUERY_BUILDER: case model.QueryBuilder:
runQueries := metrics.PrepareBuilderMetricQueries(metricsQueryRangeParams, constants.SIGNOZ_TIMESERIES_TABLENAME) runQueries := metrics.PrepareBuilderMetricQueries(metricsQueryRangeParams, constants.SignozTimeSeriesTableName)
if runQueries.Err != nil { if runQueries.Err != nil {
respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: runQueries.Err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: runQueries.Err}, nil)
return return
} }
seriesList, err = execClickHouseQueries(runQueries.Queries) seriesList, err = execClickHouseQueries(runQueries.Queries)
case model.CLICKHOUSE: case model.ClickHouse:
queries := make(map[string]string) queries := make(map[string]string)
for name, chQuery := range metricsQueryRangeParams.CompositeMetricQuery.ClickHouseQueries { for name, chQuery := range metricsQueryRangeParams.CompositeMetricQuery.ClickHouseQueries {
if chQuery.Disabled { if chQuery.Disabled {
@ -588,7 +588,7 @@ func (aH *APIHandler) queryRangeMetricsV2(w http.ResponseWriter, r *http.Request
queries[name] = chQuery.Query queries[name] = chQuery.Query
} }
seriesList, err = execClickHouseQueries(queries) seriesList, err = execClickHouseQueries(queries)
case model.PROM: case model.Prom:
seriesList, err = execPromQueries(metricsQueryRangeParams) seriesList, err = execPromQueries(metricsQueryRangeParams)
default: default:
err = fmt.Errorf("invalid query type") err = fmt.Errorf("invalid query type")
@ -601,10 +601,10 @@ func (aH *APIHandler) queryRangeMetricsV2(w http.ResponseWriter, r *http.Request
respondError(w, apiErrObj, nil) respondError(w, apiErrObj, nil)
return return
} }
if metricsQueryRangeParams.CompositeMetricQuery.PanelType == model.QUERY_VALUE && if metricsQueryRangeParams.CompositeMetricQuery.PanelType == model.QueryValue &&
len(seriesList) > 1 && len(seriesList) > 1 &&
(metricsQueryRangeParams.CompositeMetricQuery.QueryType == model.QUERY_BUILDER || (metricsQueryRangeParams.CompositeMetricQuery.QueryType == model.QueryBuilder ||
metricsQueryRangeParams.CompositeMetricQuery.QueryType == model.CLICKHOUSE) { metricsQueryRangeParams.CompositeMetricQuery.QueryType == model.ClickHouse) {
respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("invalid: query resulted in more than one series for value type")}, nil) respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("invalid: query resulted in more than one series for value type")}, nil)
return return
} }
@ -667,7 +667,7 @@ func (aH *APIHandler) getDashboards(w http.ResponseWriter, r *http.Request) {
inter = Intersection(inter, tags2Dash[tag]) inter = Intersection(inter, tags2Dash[tag])
} }
filteredDashboards := []dashboards.Dashboard{} var filteredDashboards []dashboards.Dashboard
for _, val := range inter { for _, val := range inter {
dash := (allDashboards)[val] dash := (allDashboards)[val]
filteredDashboards = append(filteredDashboards, dash) filteredDashboards = append(filteredDashboards, dash)
@ -827,14 +827,14 @@ func (aH *APIHandler) testChannel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close() defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
zap.S().Errorf("Error in getting req body of testChannel API\n", err) zap.S().Error("Error in getting req body of testChannel API\n", err)
respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return return
} }
receiver := &am.Receiver{} receiver := &am.Receiver{}
if err := json.Unmarshal(body, receiver); err != nil { // Parse []byte to go struct pointer if err := json.Unmarshal(body, receiver); err != nil { // Parse []byte to go struct pointer
zap.S().Errorf("Error in parsing req body of testChannel API\n", err) zap.S().Error("Error in parsing req body of testChannel API\n", err)
respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return return
} }
@ -855,14 +855,14 @@ func (aH *APIHandler) editChannel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close() defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
zap.S().Errorf("Error in getting req body of editChannel API\n", err) zap.S().Error("Error in getting req body of editChannel API\n", err)
respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return return
} }
receiver := &am.Receiver{} receiver := &am.Receiver{}
if err := json.Unmarshal(body, receiver); err != nil { // Parse []byte to go struct pointer if err := json.Unmarshal(body, receiver); err != nil { // Parse []byte to go struct pointer
zap.S().Errorf("Error in parsing req body of editChannel API\n", err) zap.S().Error("Error in parsing req body of editChannel API\n", err)
respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return return
} }
@ -883,14 +883,14 @@ func (aH *APIHandler) createChannel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close() defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
zap.S().Errorf("Error in getting req body of createChannel API\n", err) zap.S().Error("Error in getting req body of createChannel API\n", err)
respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return return
} }
receiver := &am.Receiver{} receiver := &am.Receiver{}
if err := json.Unmarshal(body, receiver); err != nil { // Parse []byte to go struct pointer if err := json.Unmarshal(body, receiver); err != nil { // Parse []byte to go struct pointer
zap.S().Errorf("Error in parsing req body of createChannel API\n", err) zap.S().Error("Error in parsing req body of createChannel API\n", err)
respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: err}, nil)
return return
} }
@ -968,20 +968,20 @@ func (aH *APIHandler) queryRangeMetrics(w http.ResponseWriter, r *http.Request)
if res.Err != nil { if res.Err != nil {
switch res.Err.(type) { switch res.Err.(type) {
case promql.ErrQueryCanceled: case promql.ErrQueryCanceled:
respondError(w, &model.ApiError{model.ErrorCanceled, res.Err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorCanceled, Err: res.Err}, nil)
case promql.ErrQueryTimeout: case promql.ErrQueryTimeout:
respondError(w, &model.ApiError{model.ErrorTimeout, res.Err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorTimeout, Err: res.Err}, nil)
} }
respondError(w, &model.ApiError{model.ErrorExec, res.Err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorExec, Err: res.Err}, nil)
} }
response_data := &model.QueryData{ responseData := &model.QueryData{
ResultType: res.Value.Type(), ResultType: res.Value.Type(),
Result: res.Value, Result: res.Value,
Stats: qs, Stats: qs,
} }
aH.respond(w, response_data) aH.respond(w, responseData)
} }
@ -1022,20 +1022,20 @@ func (aH *APIHandler) queryMetrics(w http.ResponseWriter, r *http.Request) {
if res.Err != nil { if res.Err != nil {
switch res.Err.(type) { switch res.Err.(type) {
case promql.ErrQueryCanceled: case promql.ErrQueryCanceled:
respondError(w, &model.ApiError{model.ErrorCanceled, res.Err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorCanceled, Err: res.Err}, nil)
case promql.ErrQueryTimeout: case promql.ErrQueryTimeout:
respondError(w, &model.ApiError{model.ErrorTimeout, res.Err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorTimeout, Err: res.Err}, nil)
} }
respondError(w, &model.ApiError{model.ErrorExec, res.Err}, nil) respondError(w, &model.ApiError{Typ: model.ErrorExec, Err: res.Err}, nil)
} }
response_data := &model.QueryData{ responseData := &model.QueryData{
ResultType: res.Value.Type(), ResultType: res.Value.Type(),
Result: res.Value, Result: res.Value,
Stats: qs, Stats: qs,
} }
aH.respond(w, response_data) aH.respond(w, responseData)
} }
@ -1065,7 +1065,7 @@ func (aH *APIHandler) submitFeedback(w http.ResponseWriter, r *http.Request) {
"email": email, "email": email,
"message": message, "message": message,
} }
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_INPRODUCT_FEEDBACK, data) telemetry.GetInstance().SendEvent(telemetry.EventInproductFeedback, data)
} }
@ -1134,7 +1134,7 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) {
"number": len(*result), "number": len(*result),
} }
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_NUMBER_OF_SERVICES, data) telemetry.GetInstance().SendEvent(telemetry.EventNumberOfServices, data)
aH.writeJSON(w, r, result) aH.writeJSON(w, r, result)
} }
@ -1378,8 +1378,8 @@ func (aH *APIHandler) getDisks(w http.ResponseWriter, r *http.Request) {
} }
func (aH *APIHandler) getVersion(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) getVersion(w http.ResponseWriter, r *http.Request) {
version := version.GetVersion() v := version.GetVersion()
aH.writeJSON(w, r, map[string]string{"version": version}) aH.writeJSON(w, r, map[string]string{"version": v})
} }
// inviteUser is used to invite a user. It is used by an admin api. // inviteUser is used to invite a user. It is used by an admin api.
@ -1411,7 +1411,7 @@ func (aH *APIHandler) getInvite(w http.ResponseWriter, r *http.Request) {
aH.writeJSON(w, r, resp) aH.writeJSON(w, r, resp)
} }
// revokeInvite is used to revoke an invite. // revokeInvite is used to revoke an invitation.
func (aH *APIHandler) revokeInvite(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) revokeInvite(w http.ResponseWriter, r *http.Request) {
email := mux.Vars(r)["email"] email := mux.Vars(r)["email"]
@ -1529,7 +1529,7 @@ func (aH *APIHandler) getUser(w http.ResponseWriter, r *http.Request) {
if user == nil { if user == nil {
respondError(w, &model.ApiError{ respondError(w, &model.ApiError{
Typ: model.ErrorInternal, Typ: model.ErrorInternal,
Err: errors.New("User not found"), Err: errors.New("user not found"),
}, nil) }, nil)
return return
} }
@ -1540,7 +1540,7 @@ func (aH *APIHandler) getUser(w http.ResponseWriter, r *http.Request) {
} }
// editUser only changes the user's Name and ProfilePictureURL. It is intentionally designed // editUser only changes the user's Name and ProfilePictureURL. It is intentionally designed
// to not support update of orgId, Password, createdAt for the sucurity reasons. // to not support update of orgId, Password, createdAt for the security reasons.
func (aH *APIHandler) editUser(w http.ResponseWriter, r *http.Request) { func (aH *APIHandler) editUser(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"] id := mux.Vars(r)["id"]
@ -1596,7 +1596,7 @@ func (aH *APIHandler) deleteUser(w http.ResponseWriter, r *http.Request) {
if user == nil { if user == nil {
respondError(w, &model.ApiError{ respondError(w, &model.ApiError{
Typ: model.ErrorNotFound, Typ: model.ErrorNotFound,
Err: errors.New("User not found"), Err: errors.New("user not found"),
}, nil) }, nil)
return return
} }
@ -1638,7 +1638,7 @@ func (aH *APIHandler) getRole(w http.ResponseWriter, r *http.Request) {
if user == nil { if user == nil {
respondError(w, &model.ApiError{ respondError(w, &model.ApiError{
Typ: model.ErrorNotFound, Typ: model.ErrorNotFound,
Err: errors.New("No user found"), Err: errors.New("no user found"),
}, nil) }, nil)
return return
} }
@ -1678,8 +1678,8 @@ func (aH *APIHandler) editRole(w http.ResponseWriter, r *http.Request) {
} }
// Make sure that the request is not demoting the last admin user. // Make sure that the request is not demoting the last admin user.
if user.GroupId == auth.AuthCacheObj.AdminGroupId { if user.GroupId == auth.CacheObj.AdminGroupId {
adminUsers, apiErr := dao.DB().GetUsersByGroup(ctx, auth.AuthCacheObj.AdminGroupId) adminUsers, apiErr := dao.DB().GetUsersByGroup(ctx, auth.CacheObj.AdminGroupId)
if apiErr != nil { if apiErr != nil {
respondError(w, apiErr, "Failed to fetch adminUsers") respondError(w, apiErr, "Failed to fetch adminUsers")
return return
@ -1687,7 +1687,7 @@ func (aH *APIHandler) editRole(w http.ResponseWriter, r *http.Request) {
if len(adminUsers) == 1 { if len(adminUsers) == 1 {
respondError(w, &model.ApiError{ respondError(w, &model.ApiError{
Err: errors.New("Cannot demote the last admin"), Err: errors.New("cannot demote the last admin"),
Typ: model.ErrorInternal}, nil) Typ: model.ErrorInternal}, nil)
return return
} }
@ -1739,7 +1739,7 @@ func (aH *APIHandler) editOrg(w http.ResponseWriter, r *http.Request) {
"organizationName": req.Name, "organizationName": req.Name,
} }
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_ORG_SETTINGS, data) telemetry.GetInstance().SendEvent(telemetry.EventOrgSettings, data)
aH.writeJSON(w, r, map[string]string{"data": "org updated successfully"}) aH.writeJSON(w, r, map[string]string{"data": "org updated successfully"})
} }

View File

@ -28,14 +28,14 @@ var AggregateOperatorToPercentile = map[model.AggregateOperator]float64{
} }
var AggregateOperatorToSQLFunc = map[model.AggregateOperator]string{ var AggregateOperatorToSQLFunc = map[model.AggregateOperator]string{
model.AVG: "avg", model.Avg: "avg",
model.MAX: "max", model.Max: "max",
model.MIN: "min", model.Min: "min",
model.SUM: "sum", model.Sum: "sum",
model.RATE_SUM: "sum", model.RateSum: "sum",
model.RATE_AVG: "avg", model.RateAvg: "avg",
model.RATE_MAX: "max", model.RateMax: "max",
model.RATE_MIN: "min", model.RateMin: "min",
} }
var SupportedFunctions = []string{"exp", "log", "ln", "exp2", "log2", "exp10", "log10", "sqrt", "cbrt", "erf", "erfc", "lgamma", "tgamma", "sin", "cos", "tan", "asin", "acos", "atan", "degrees", "radians"} var SupportedFunctions = []string{"exp", "log", "ln", "exp2", "log2", "exp10", "log10", "sqrt", "cbrt", "erf", "erfc", "lgamma", "tgamma", "sin", "cos", "tan", "asin", "acos", "atan", "degrees", "radians"}
@ -128,7 +128,7 @@ func BuildMetricsTimeSeriesFilterQuery(fs *model.FilterSet, groupTags []string,
queryString := strings.Join(conditions, " AND ") queryString := strings.Join(conditions, " AND ")
var selectLabels string var selectLabels string
if aggregateOperator == model.NOOP || aggregateOperator == model.RATE { if aggregateOperator == model.NoOp || aggregateOperator == model.Rate {
selectLabels = "labels," selectLabels = "labels,"
} else { } else {
for _, tag := range groupTags { for _, tag := range groupTags {
@ -136,14 +136,14 @@ func BuildMetricsTimeSeriesFilterQuery(fs *model.FilterSet, groupTags []string,
} }
} }
filterSubQuery := fmt.Sprintf("SELECT %s fingerprint FROM %s.%s WHERE %s", selectLabels, constants.SIGNOZ_METRIC_DBNAME, constants.SIGNOZ_TIMESERIES_TABLENAME, queryString) filterSubQuery := fmt.Sprintf("SELECT %s fingerprint FROM %s.%s WHERE %s", selectLabels, constants.SignozMetricDbname, constants.SignozTimeSeriesTableName, queryString)
return filterSubQuery, nil return filterSubQuery, nil
} }
func BuildMetricQuery(qp *model.QueryRangeParamsV2, mq *model.MetricQuery, tableName string) (string, error) { func BuildMetricQuery(qp *model.QueryRangeParamsV2, mq *model.MetricQuery, tableName string) (string, error) {
if qp.CompositeMetricQuery.PanelType == model.QUERY_VALUE && len(mq.GroupingTags) != 0 { if qp.CompositeMetricQuery.PanelType == model.QueryValue && len(mq.GroupingTags) != 0 {
return "", fmt.Errorf("reduce operator cannot be applied for the query") return "", fmt.Errorf("reduce operator cannot be applied for the query")
} }
@ -159,7 +159,7 @@ func BuildMetricQuery(qp *model.QueryRangeParamsV2, mq *model.MetricQuery, table
"SELECT %s" + "SELECT %s" +
" toStartOfInterval(toDateTime(intDiv(timestamp_ms, 1000)), INTERVAL %d SECOND) as ts," + " toStartOfInterval(toDateTime(intDiv(timestamp_ms, 1000)), INTERVAL %d SECOND) as ts," +
" %s as value" + " %s as value" +
" FROM " + constants.SIGNOZ_METRIC_DBNAME + "." + constants.SIGNOZ_SAMPLES_TABLENAME + " FROM " + constants.SignozMetricDbname + "." + constants.SignozSamplesTableName +
" INNER JOIN" + " INNER JOIN" +
" (%s) as filtered_time_series" + " (%s) as filtered_time_series" +
" USING fingerprint" + " USING fingerprint" +
@ -171,7 +171,7 @@ func BuildMetricQuery(qp *model.QueryRangeParamsV2, mq *model.MetricQuery, table
groupTags := groupSelect(mq.GroupingTags...) groupTags := groupSelect(mq.GroupingTags...)
switch mq.AggregateOperator { switch mq.AggregateOperator {
case model.RATE: case model.Rate:
// Calculate rate of change of metric for each unique time series // Calculate rate of change of metric for each unique time series
groupBy = "fingerprint, ts" groupBy = "fingerprint, ts"
groupTags = "fingerprint," groupTags = "fingerprint,"
@ -183,7 +183,7 @@ func BuildMetricQuery(qp *model.QueryRangeParamsV2, mq *model.MetricQuery, table
query = fmt.Sprintf(query, "labels as fullLabels,", subQuery) query = fmt.Sprintf(query, "labels as fullLabels,", subQuery)
return query, nil return query, nil
case model.SUM_RATE: case model.SumRate:
rateGroupBy := "fingerprint, " + groupBy rateGroupBy := "fingerprint, " + groupBy
rateGroupTags := "fingerprint, " + groupTags rateGroupTags := "fingerprint, " + groupTags
op := "max(value)" op := "max(value)"
@ -194,7 +194,7 @@ func BuildMetricQuery(qp *model.QueryRangeParamsV2, mq *model.MetricQuery, table
query = fmt.Sprintf(query, groupTags, subQuery) query = fmt.Sprintf(query, groupTags, subQuery)
query = fmt.Sprintf(`SELECT %s ts, sum(value) as value FROM (%s) GROUP BY %s ORDER BY %s ts`, groupTags, query, groupBy, groupTags) query = fmt.Sprintf(`SELECT %s ts, sum(value) as value FROM (%s) GROUP BY %s ORDER BY %s ts`, groupTags, query, groupBy, groupTags)
return query, nil return query, nil
case model.RATE_SUM, model.RATE_MAX, model.RATE_AVG, model.RATE_MIN: case model.RateSum, model.RateMax, model.RateAvg, model.RateMin:
op := fmt.Sprintf("%s(value)", AggregateOperatorToSQLFunc[mq.AggregateOperator]) op := fmt.Sprintf("%s(value)", AggregateOperatorToSQLFunc[mq.AggregateOperator])
subQuery := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags) subQuery := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags)
query := `SELECT %s ts, runningDifference(value)/runningDifference(ts) as value FROM(%s) OFFSET 1` query := `SELECT %s ts, runningDifference(value)/runningDifference(ts) as value FROM(%s) OFFSET 1`
@ -204,24 +204,24 @@ func BuildMetricQuery(qp *model.QueryRangeParamsV2, mq *model.MetricQuery, table
op := fmt.Sprintf("quantile(%v)(value)", AggregateOperatorToPercentile[mq.AggregateOperator]) op := fmt.Sprintf("quantile(%v)(value)", AggregateOperatorToPercentile[mq.AggregateOperator])
query := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags) query := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags)
return query, nil return query, nil
case model.AVG, model.SUM, model.MIN, model.MAX: case model.Avg, model.Sum, model.Min, model.Max:
op := fmt.Sprintf("%s(value)", AggregateOperatorToSQLFunc[mq.AggregateOperator]) op := fmt.Sprintf("%s(value)", AggregateOperatorToSQLFunc[mq.AggregateOperator])
query := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags) query := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags)
return query, nil return query, nil
case model.COUNT: case model.Count:
op := "toFloat64(count(*))" op := "toFloat64(count(*))"
query := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags) query := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags)
return query, nil return query, nil
case model.COUNT_DISTINCT: case model.CountDistinct:
op := "toFloat64(count(distinct(value)))" op := "toFloat64(count(distinct(value)))"
query := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags) query := fmt.Sprintf(queryTmpl, groupTags, qp.Step, op, filterSubQuery, groupBy, groupTags)
return query, nil return query, nil
case model.NOOP: case model.NoOp:
queryTmpl := queryTmpl :=
"SELECT fingerprint, labels as fullLabels," + "SELECT fingerprint, labels as fullLabels," +
" toStartOfInterval(toDateTime(intDiv(timestamp_ms, 1000)), INTERVAL %d SECOND) as ts," + " toStartOfInterval(toDateTime(intDiv(timestamp_ms, 1000)), INTERVAL %d SECOND) as ts," +
" any(value) as value" + " any(value) as value" +
" FROM " + constants.SIGNOZ_METRIC_DBNAME + "." + constants.SIGNOZ_SAMPLES_TABLENAME + " FROM " + constants.SignozMetricDbname + "." + constants.SignozSamplesTableName +
" INNER JOIN" + " INNER JOIN" +
" (%s) as filtered_time_series" + " (%s) as filtered_time_series" +
" USING fingerprint" + " USING fingerprint" +
@ -275,24 +275,24 @@ func reduceQuery(query string, reduceTo model.ReduceToOperator, aggregateOperato
var groupBy string var groupBy string
// NOOP and RATE can possibly return multiple time series and reduce should be applied // NOOP and RATE can possibly return multiple time series and reduce should be applied
// for each uniques series. When the final result contains more than one series we throw // for each uniques series. When the final result contains more than one series we throw
// an error post DB fetching. Otherwise just return the single data. This is not known until queried so the // an error post DB fetching. Otherwise, just return the single data. This is not known until queried so the
// the query is prepared accordingly. // query is prepared accordingly.
if aggregateOperator == model.NOOP || aggregateOperator == model.RATE { if aggregateOperator == model.NoOp || aggregateOperator == model.Rate {
selectLabels = ", any(fullLabels) as fullLabels" selectLabels = ", any(fullLabels) as fullLabels"
groupBy = "GROUP BY fingerprint" groupBy = "GROUP BY fingerprint"
} }
// the timestamp picked is not relevant here since the final value used is show the single // the timestamp picked is not relevant here since the final value used is show the single
// chart with just the query value. For the quer // chart with just the query value.
switch reduceTo { switch reduceTo {
case model.RLAST: case model.RLast:
query = fmt.Sprintf("SELECT anyLast(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy) query = fmt.Sprintf("SELECT anyLast(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy)
case model.RSUM: case model.RSum:
query = fmt.Sprintf("SELECT sum(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy) query = fmt.Sprintf("SELECT sum(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy)
case model.RAVG: case model.RAvg:
query = fmt.Sprintf("SELECT avg(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy) query = fmt.Sprintf("SELECT avg(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy)
case model.RMAX: case model.RMax:
query = fmt.Sprintf("SELECT max(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy) query = fmt.Sprintf("SELECT max(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy)
case model.RMIN: case model.RMin:
query = fmt.Sprintf("SELECT min(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy) query = fmt.Sprintf("SELECT min(value) as value, any(ts) as ts %s FROM (%s) %s", selectLabels, query, groupBy)
default: default:
return "", fmt.Errorf("unsupported reduce operator") return "", fmt.Errorf("unsupported reduce operator")
@ -317,7 +317,7 @@ func varToQuery(qp *model.QueryRangeParamsV2, tableName string) (map[string]stri
if err != nil { if err != nil {
errs = append(errs, err) errs = append(errs, err)
} else { } else {
if qp.CompositeMetricQuery.PanelType == model.QUERY_VALUE { if qp.CompositeMetricQuery.PanelType == model.QueryValue {
query, err = reduceQuery(query, mq.ReduceTo, mq.AggregateOperator) query, err = reduceQuery(query, mq.ReduceTo, mq.AggregateOperator)
if err != nil { if err != nil {
errs = append(errs, err) errs = append(errs, err)

View File

@ -18,7 +18,7 @@ func TestBuildQuery(t *testing.T) {
"a": { "a": {
QueryName: "a", QueryName: "a",
MetricName: "name", MetricName: "name",
AggregateOperator: model.RATE_MAX, AggregateOperator: model.RateMax,
Expression: "a", Expression: "a",
}, },
}, },
@ -46,7 +46,7 @@ func TestBuildQueryWithFilters(t *testing.T) {
{Key: "a", Value: "b", Operator: "neq"}, {Key: "a", Value: "b", Operator: "neq"},
{Key: "code", Value: "ERROR_*", Operator: "nmatch"}, {Key: "code", Value: "ERROR_*", Operator: "nmatch"},
}}, }},
AggregateOperator: model.RATE_MAX, AggregateOperator: model.RateMax,
Expression: "a", Expression: "a",
}, },
}, },
@ -75,13 +75,13 @@ func TestBuildQueryWithMultipleQueries(t *testing.T) {
TagFilters: &model.FilterSet{Operator: "AND", Items: []model.FilterItem{ TagFilters: &model.FilterSet{Operator: "AND", Items: []model.FilterItem{
{Key: "in", Value: []interface{}{"a", "b", "c"}, Operator: "in"}, {Key: "in", Value: []interface{}{"a", "b", "c"}, Operator: "in"},
}}, }},
AggregateOperator: model.RATE_AVG, AggregateOperator: model.RateAvg,
Expression: "a", Expression: "a",
}, },
"b": { "b": {
QueryName: "b", QueryName: "b",
MetricName: "name2", MetricName: "name2",
AggregateOperator: model.RATE_MAX, AggregateOperator: model.RateMax,
Expression: "b", Expression: "b",
}, },
}, },
@ -108,12 +108,12 @@ func TestBuildQueryWithMultipleQueriesAndFormula(t *testing.T) {
TagFilters: &model.FilterSet{Operator: "AND", Items: []model.FilterItem{ TagFilters: &model.FilterSet{Operator: "AND", Items: []model.FilterItem{
{Key: "in", Value: []interface{}{"a", "b", "c"}, Operator: "in"}, {Key: "in", Value: []interface{}{"a", "b", "c"}, Operator: "in"},
}}, }},
AggregateOperator: model.RATE_MAX, AggregateOperator: model.RateMax,
Expression: "a", Expression: "a",
}, },
"b": { "b": {
MetricName: "name2", MetricName: "name2",
AggregateOperator: model.RATE_AVG, AggregateOperator: model.RateAvg,
Expression: "b", Expression: "b",
}, },
"c": { "c": {

View File

@ -597,7 +597,7 @@ func parseTTLParams(r *http.Request) (*model.TTLParams, error) {
// Validate the TTL duration. // Validate the TTL duration.
durationParsed, err := time.ParseDuration(delDuration) durationParsed, err := time.ParseDuration(delDuration)
if err != nil || durationParsed.Seconds() <= 0 { if err != nil || durationParsed.Seconds() <= 0 {
return nil, fmt.Errorf("Not a valid TTL duration %v", delDuration) return nil, fmt.Errorf("not a valid TTL duration %v", delDuration)
} }
var toColdParsed time.Duration var toColdParsed time.Duration
@ -606,10 +606,10 @@ func parseTTLParams(r *http.Request) (*model.TTLParams, error) {
if len(coldStorage) > 0 { if len(coldStorage) > 0 {
toColdParsed, err = time.ParseDuration(toColdDuration) toColdParsed, err = time.ParseDuration(toColdDuration)
if err != nil || toColdParsed.Seconds() <= 0 { if err != nil || toColdParsed.Seconds() <= 0 {
return nil, fmt.Errorf("Not a valid toCold TTL duration %v", toColdDuration) return nil, fmt.Errorf("not a valid toCold TTL duration %v", toColdDuration)
} }
if toColdParsed.Seconds() != 0 && toColdParsed.Seconds() >= durationParsed.Seconds() { if toColdParsed.Seconds() != 0 && toColdParsed.Seconds() >= durationParsed.Seconds() {
return nil, fmt.Errorf("Delete TTL should be greater than cold storage move TTL.") return nil, fmt.Errorf("delete TTL should be greater than cold storage move TTL")
} }
} }

View File

@ -11,13 +11,13 @@ import (
func validateQueryRangeParamsV2(qp *model.QueryRangeParamsV2) error { func validateQueryRangeParamsV2(qp *model.QueryRangeParamsV2) error {
var errs []error var errs []error
if !(qp.DataSource >= model.METRICS && qp.DataSource <= model.LOGS) { if !(qp.DataSource >= model.Metrics && qp.DataSource <= model.Logs) {
errs = append(errs, fmt.Errorf("unsupported data source")) errs = append(errs, fmt.Errorf("unsupported data source"))
} }
if !(qp.CompositeMetricQuery.QueryType >= model.QUERY_BUILDER && qp.CompositeMetricQuery.QueryType <= model.PROM) { if !(qp.CompositeMetricQuery.QueryType >= model.QueryBuilder && qp.CompositeMetricQuery.QueryType <= model.Prom) {
errs = append(errs, fmt.Errorf("unsupported query type")) errs = append(errs, fmt.Errorf("unsupported query type"))
} }
if !(qp.CompositeMetricQuery.PanelType >= model.TIME_SERIES && qp.CompositeMetricQuery.PanelType <= model.QUERY_VALUE) { if !(qp.CompositeMetricQuery.PanelType >= model.TimeSeries && qp.CompositeMetricQuery.PanelType <= model.QueryValue) {
errs = append(errs, fmt.Errorf("unsupported panel type")) errs = append(errs, fmt.Errorf("unsupported panel type"))
} }
if len(errs) != 0 { if len(errs) != 0 {

View File

@ -22,7 +22,7 @@ func TestParseFilterSingleFilter(t *testing.T) {
}`) }`)
req, _ := http.NewRequest("POST", "", bytes.NewReader(postBody)) req, _ := http.NewRequest("POST", "", bytes.NewReader(postBody))
res, _ := parseFilterSet(req) res, _ := parseFilterSet(req)
query, _ := metrics.BuildMetricsTimeSeriesFilterQuery(res, []string{}, "table", model.NOOP) query, _ := metrics.BuildMetricsTimeSeriesFilterQuery(res, []string{}, "table", model.NoOp)
So(query, ShouldContainSubstring, "signoz_metrics.time_series_v2 WHERE metric_name = 'table' AND labels_object.namespace = 'a'") So(query, ShouldContainSubstring, "signoz_metrics.time_series_v2 WHERE metric_name = 'table' AND labels_object.namespace = 'a'")
}) })
} }
@ -38,7 +38,7 @@ func TestParseFilterMultipleFilter(t *testing.T) {
}`) }`)
req, _ := http.NewRequest("POST", "", bytes.NewReader(postBody)) req, _ := http.NewRequest("POST", "", bytes.NewReader(postBody))
res, _ := parseFilterSet(req) res, _ := parseFilterSet(req)
query, _ := metrics.BuildMetricsTimeSeriesFilterQuery(res, []string{}, "table", model.NOOP) query, _ := metrics.BuildMetricsTimeSeriesFilterQuery(res, []string{}, "table", model.NoOp)
So(query, should.ContainSubstring, "labels_object.host IN ['host-1','host-2']") So(query, should.ContainSubstring, "labels_object.host IN ['host-1','host-2']")
So(query, should.ContainSubstring, "labels_object.namespace = 'a'") So(query, should.ContainSubstring, "labels_object.namespace = 'a'")
}) })
@ -54,7 +54,7 @@ func TestParseFilterNotSupportedOp(t *testing.T) {
}`) }`)
req, _ := http.NewRequest("POST", "", bytes.NewReader(postBody)) req, _ := http.NewRequest("POST", "", bytes.NewReader(postBody))
res, _ := parseFilterSet(req) res, _ := parseFilterSet(req)
_, err := metrics.BuildMetricsTimeSeriesFilterQuery(res, []string{}, "table", model.NOOP) _, err := metrics.BuildMetricsTimeSeriesFilterQuery(res, []string{}, "table", model.NoOp)
So(err, should.BeError, "unsupported operation") So(err, should.BeError, "unsupported operation")
}) })
} }

View File

@ -55,10 +55,10 @@ func (s Server) HealthCheckStatus() chan healthcheck.Status {
// NewServer creates and initializes Server // NewServer creates and initializes Server
func NewServer(serverOptions *ServerOptions) (*Server, error) { func NewServer(serverOptions *ServerOptions) (*Server, error) {
if err := dao.InitDao("sqlite", constants.RELATIONAL_DATASOURCE_PATH); err != nil { if err := dao.InitDao("sqlite", constants.RelationalDatasourcePath); err != nil {
return nil, err return nil, err
} }
localDB, err := dashboards.InitDB(constants.RELATIONAL_DATASOURCE_PATH) localDB, err := dashboards.InitDB(constants.RelationalDatasourcePath)
if err != nil { if err != nil {
return nil, err return nil, err
@ -70,11 +70,11 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
storage := os.Getenv("STORAGE") storage := os.Getenv("STORAGE")
if storage == "clickhouse" { if storage == "clickhouse" {
zap.S().Info("Using ClickHouse as datastore ...") zap.S().Info("Using ClickHouse as datastore ...")
clickhouseReader := clickhouseReader.NewReader(localDB) chReader := clickhouseReader.NewReader(localDB)
go clickhouseReader.Start() go chReader.Start()
reader = clickhouseReader reader = chReader
} else { } else {
return nil, fmt.Errorf("Storage type: %s is not supported in query service", storage) return nil, fmt.Errorf("storage type: %s is not supported in query service", storage)
} }
telemetry.GetInstance().SetReader(reader) telemetry.GetInstance().SetReader(reader)
@ -211,7 +211,7 @@ func (s *Server) analyticsMiddleware(next http.Handler) http.Handler {
data := map[string]interface{}{"path": path, "statusCode": lrw.statusCode} data := map[string]interface{}{"path": path, "statusCode": lrw.statusCode}
if _, ok := telemetry.IgnoredPaths()[path]; !ok { if _, ok := telemetry.IgnoredPaths()[path]; !ok {
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data) telemetry.GetInstance().SendEvent(telemetry.EventPath, data)
} }
}) })

View File

@ -21,9 +21,10 @@ const (
) )
var ( var (
ErrorInvalidCreds = fmt.Errorf("Invalid credentials") ErrorInvalidCreds = fmt.Errorf("invalid credentials")
) )
// Invite sends the invitation for users
// The root user should be able to invite people to create account on SigNoz cluster. // The root user should be able to invite people to create account on SigNoz cluster.
func Invite(ctx context.Context, req *model.InviteRequest) (*model.InviteResponse, error) { func Invite(ctx context.Context, req *model.InviteRequest) (*model.InviteResponse, error) {
zap.S().Debugf("Got an invite request for email: %s\n", req.Email) zap.S().Debugf("Got an invite request for email: %s\n", req.Email)

View File

@ -17,13 +17,13 @@ type Group struct {
GroupName string GroupName string
} }
type AuthCache struct { type Cache struct {
AdminGroupId string AdminGroupId string
EditorGroupId string EditorGroupId string
ViewerGroupId string ViewerGroupId string
} }
var AuthCacheObj AuthCache var CacheObj Cache
// InitAuthCache reads the DB and initialize the auth cache. // InitAuthCache reads the DB and initialize the auth cache.
func InitAuthCache(ctx context.Context) error { func InitAuthCache(ctx context.Context) error {
@ -37,13 +37,13 @@ func InitAuthCache(ctx context.Context) error {
return nil return nil
} }
if err := setGroupId(constants.AdminGroup, &AuthCacheObj.AdminGroupId); err != nil { if err := setGroupId(constants.AdminGroup, &CacheObj.AdminGroupId); err != nil {
return err return err
} }
if err := setGroupId(constants.EditorGroup, &AuthCacheObj.EditorGroupId); err != nil { if err := setGroupId(constants.EditorGroup, &CacheObj.EditorGroupId); err != nil {
return err return err
} }
if err := setGroupId(constants.ViewerGroup, &AuthCacheObj.ViewerGroupId); err != nil { if err := setGroupId(constants.ViewerGroup, &CacheObj.ViewerGroupId); err != nil {
return err return err
} }
@ -65,9 +65,9 @@ func GetUserFromRequest(r *http.Request) (*model.UserPayload, error) {
func IsSelfAccessRequest(user *model.UserPayload, id string) bool { return user.Id == id } func IsSelfAccessRequest(user *model.UserPayload, id string) bool { return user.Id == id }
func IsViewer(user *model.UserPayload) bool { return user.GroupId == AuthCacheObj.ViewerGroupId } func IsViewer(user *model.UserPayload) bool { return user.GroupId == CacheObj.ViewerGroupId }
func IsEditor(user *model.UserPayload) bool { return user.GroupId == AuthCacheObj.EditorGroupId } func IsEditor(user *model.UserPayload) bool { return user.GroupId == CacheObj.EditorGroupId }
func IsAdmin(user *model.UserPayload) bool { return user.GroupId == AuthCacheObj.AdminGroupId } func IsAdmin(user *model.UserPayload) bool { return user.GroupId == CacheObj.AdminGroupId }
func ValidatePassword(password string) error { func ValidatePassword(password string) error {
if len(password) < minimumPasswordLength { if len(password) < minimumPasswordLength {

View File

@ -33,7 +33,6 @@ func isValidRole(role string) bool {
default: default:
return false return false
} }
return false
} }
func validateInviteRequest(req *model.InviteRequest) error { func validateInviteRequest(req *model.InviteRequest) error {

View File

@ -11,7 +11,7 @@ const (
DebugHttpPort = "0.0.0.0:6060" // Address to serve http (pprof) DebugHttpPort = "0.0.0.0:6060" // Address to serve http (pprof)
) )
var DEFAULT_TELEMETRY_ANONYMOUS = false var DefaultTelemetryAnonymous = false
func IsTelemetryEnabled() bool { func IsTelemetryEnabled() bool {
isTelemetryEnabledStr := os.Getenv("TELEMETRY_ENABLED") isTelemetryEnabledStr := os.Getenv("TELEMETRY_ENABLED")
@ -32,10 +32,10 @@ func GetAlertManagerApiPrefix() string {
return "http://alertmanager:9093/api/" return "http://alertmanager:9093/api/"
} }
// Alert manager channel subpath // AmChannelApiPath is a channel subpath for Alert manager
var AmChannelApiPath = GetOrDefaultEnv("ALERTMANAGER_API_CHANNEL_PATH", "v1/routes") var AmChannelApiPath = GetOrDefaultEnv("ALERTMANAGER_API_CHANNEL_PATH", "v1/routes")
var RELATIONAL_DATASOURCE_PATH = GetOrDefaultEnv("SIGNOZ_LOCAL_DB_PATH", "/var/lib/signoz/signoz.db") var RelationalDatasourcePath = GetOrDefaultEnv("SIGNOZ_LOCAL_DB_PATH", "/var/lib/signoz/signoz.db")
const ( const (
ServiceName = "serviceName" ServiceName = "serviceName"
@ -67,9 +67,9 @@ const (
FirstSeen = "firstSeen" FirstSeen = "firstSeen"
) )
const ( const (
SIGNOZ_METRIC_DBNAME = "signoz_metrics" SignozMetricDbname = "signoz_metrics"
SIGNOZ_SAMPLES_TABLENAME = "samples_v2" SignozSamplesTableName = "samples_v2"
SIGNOZ_TIMESERIES_TABLENAME = "time_series_v2" SignozTimeSeriesTableName = "time_series_v2"
) )
func GetOrDefaultEnv(key string, fallback string) string { func GetOrDefaultEnv(key string, fallback string) string {

View File

@ -26,7 +26,7 @@ func InitDB(dataSourceName string) (*ModelDaoSqlite, error) {
} }
db.SetMaxOpenConns(10) db.SetMaxOpenConns(10)
table_schema := ` tableSchema := `
PRAGMA foreign_keys = ON; PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS invites ( CREATE TABLE IF NOT EXISTS invites (
@ -70,9 +70,9 @@ func InitDB(dataSourceName string) (*ModelDaoSqlite, error) {
); );
` `
_, err = db.Exec(table_schema) _, err = db.Exec(tableSchema)
if err != nil { if err != nil {
return nil, fmt.Errorf("Error in creating tables: %v", err.Error()) return nil, fmt.Errorf("error in creating tables: %v", err.Error())
} }
mds := &ModelDaoSqlite{db: db} mds := &ModelDaoSqlite{db: db}
@ -96,7 +96,7 @@ func InitDB(dataSourceName string) (*ModelDaoSqlite, error) {
func (mds *ModelDaoSqlite) initializeOrgPreferences(ctx context.Context) error { func (mds *ModelDaoSqlite) initializeOrgPreferences(ctx context.Context) error {
// set anonymous setting as default in case of any failures to fetch UserPreference in below section // set anonymous setting as default in case of any failures to fetch UserPreference in below section
telemetry.GetInstance().SetTelemetryAnonymous(constants.DEFAULT_TELEMETRY_ANONYMOUS) telemetry.GetInstance().SetTelemetryAnonymous(constants.DefaultTelemetryAnonymous)
orgs, apiError := mds.GetOrgs(ctx) orgs, apiError := mds.GetOrgs(ctx)
if apiError != nil { if apiError != nil {

View File

@ -35,7 +35,7 @@ func (mds *ModelDaoSqlite) DeleteInvitation(ctx context.Context, email string) *
func (mds *ModelDaoSqlite) GetInviteFromEmail(ctx context.Context, email string, func (mds *ModelDaoSqlite) GetInviteFromEmail(ctx context.Context, email string,
) (*model.InvitationObject, *model.ApiError) { ) (*model.InvitationObject, *model.ApiError) {
invites := []model.InvitationObject{} var invites []model.InvitationObject
err := mds.db.Select(&invites, err := mds.db.Select(&invites,
`SELECT * FROM invites WHERE email=?;`, email) `SELECT * FROM invites WHERE email=?;`, email)
@ -57,7 +57,7 @@ func (mds *ModelDaoSqlite) GetInviteFromEmail(ctx context.Context, email string,
func (mds *ModelDaoSqlite) GetInviteFromToken(ctx context.Context, token string, func (mds *ModelDaoSqlite) GetInviteFromToken(ctx context.Context, token string,
) (*model.InvitationObject, *model.ApiError) { ) (*model.InvitationObject, *model.ApiError) {
invites := []model.InvitationObject{} var invites []model.InvitationObject
err := mds.db.Select(&invites, err := mds.db.Select(&invites,
`SELECT * FROM invites WHERE token=?;`, token) `SELECT * FROM invites WHERE token=?;`, token)
@ -77,7 +77,7 @@ func (mds *ModelDaoSqlite) GetInviteFromToken(ctx context.Context, token string,
func (mds *ModelDaoSqlite) GetInvites(ctx context.Context, func (mds *ModelDaoSqlite) GetInvites(ctx context.Context,
) ([]model.InvitationObject, *model.ApiError) { ) ([]model.InvitationObject, *model.ApiError) {
invites := []model.InvitationObject{} var invites []model.InvitationObject
err := mds.db.Select(&invites, "SELECT * FROM invites") err := mds.db.Select(&invites, "SELECT * FROM invites")
if err != nil { if err != nil {
return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err} return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err}
@ -103,7 +103,7 @@ func (mds *ModelDaoSqlite) CreateOrg(ctx context.Context,
func (mds *ModelDaoSqlite) GetOrg(ctx context.Context, func (mds *ModelDaoSqlite) GetOrg(ctx context.Context,
id string) (*model.Organization, *model.ApiError) { id string) (*model.Organization, *model.ApiError) {
orgs := []model.Organization{} var orgs []model.Organization
err := mds.db.Select(&orgs, `SELECT * FROM organizations WHERE id=?;`, id) err := mds.db.Select(&orgs, `SELECT * FROM organizations WHERE id=?;`, id)
if err != nil { if err != nil {
@ -125,7 +125,7 @@ func (mds *ModelDaoSqlite) GetOrg(ctx context.Context,
func (mds *ModelDaoSqlite) GetOrgByName(ctx context.Context, func (mds *ModelDaoSqlite) GetOrgByName(ctx context.Context,
name string) (*model.Organization, *model.ApiError) { name string) (*model.Organization, *model.ApiError) {
orgs := []model.Organization{} var orgs []model.Organization
if err := mds.db.Select(&orgs, `SELECT * FROM organizations WHERE name=?;`, name); err != nil { if err := mds.db.Select(&orgs, `SELECT * FROM organizations WHERE name=?;`, name); err != nil {
return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err} return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err}
@ -144,7 +144,7 @@ func (mds *ModelDaoSqlite) GetOrgByName(ctx context.Context,
} }
func (mds *ModelDaoSqlite) GetOrgs(ctx context.Context) ([]model.Organization, *model.ApiError) { func (mds *ModelDaoSqlite) GetOrgs(ctx context.Context) ([]model.Organization, *model.ApiError) {
orgs := []model.Organization{} var orgs []model.Organization
err := mds.db.Select(&orgs, `SELECT * FROM organizations`) err := mds.db.Select(&orgs, `SELECT * FROM organizations`)
if err != nil { if err != nil {
@ -194,7 +194,7 @@ func (mds *ModelDaoSqlite) CreateUser(ctx context.Context,
"email": user.Email, "email": user.Email,
} }
telemetry.GetInstance().IdentifyUser(user) telemetry.GetInstance().IdentifyUser(user)
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_USER, data) telemetry.GetInstance().SendEvent(telemetry.EventUser, data)
return user, nil return user, nil
} }
@ -254,7 +254,7 @@ func (mds *ModelDaoSqlite) DeleteUser(ctx context.Context, id string) *model.Api
func (mds *ModelDaoSqlite) GetUser(ctx context.Context, func (mds *ModelDaoSqlite) GetUser(ctx context.Context,
id string) (*model.UserPayload, *model.ApiError) { id string) (*model.UserPayload, *model.ApiError) {
users := []model.UserPayload{} var users []model.UserPayload
query := `select query := `select
u.id, u.id,
u.name, u.name,
@ -291,7 +291,7 @@ func (mds *ModelDaoSqlite) GetUser(ctx context.Context,
func (mds *ModelDaoSqlite) GetUserByEmail(ctx context.Context, func (mds *ModelDaoSqlite) GetUserByEmail(ctx context.Context,
email string) (*model.UserPayload, *model.ApiError) { email string) (*model.UserPayload, *model.ApiError) {
users := []model.UserPayload{} var users []model.UserPayload
query := `select query := `select
u.id, u.id,
u.name, u.name,
@ -326,7 +326,7 @@ func (mds *ModelDaoSqlite) GetUserByEmail(ctx context.Context,
} }
func (mds *ModelDaoSqlite) GetUsers(ctx context.Context) ([]model.UserPayload, *model.ApiError) { func (mds *ModelDaoSqlite) GetUsers(ctx context.Context) ([]model.UserPayload, *model.ApiError) {
users := []model.UserPayload{} var users []model.UserPayload
query := `select query := `select
u.id, u.id,
@ -355,7 +355,7 @@ func (mds *ModelDaoSqlite) GetUsers(ctx context.Context) ([]model.UserPayload, *
func (mds *ModelDaoSqlite) GetUsersByOrg(ctx context.Context, func (mds *ModelDaoSqlite) GetUsersByOrg(ctx context.Context,
orgId string) ([]model.UserPayload, *model.ApiError) { orgId string) ([]model.UserPayload, *model.ApiError) {
users := []model.UserPayload{} var users []model.UserPayload
query := `select query := `select
u.id, u.id,
u.name, u.name,
@ -382,7 +382,7 @@ func (mds *ModelDaoSqlite) GetUsersByOrg(ctx context.Context,
func (mds *ModelDaoSqlite) GetUsersByGroup(ctx context.Context, func (mds *ModelDaoSqlite) GetUsersByGroup(ctx context.Context,
groupId string) ([]model.UserPayload, *model.ApiError) { groupId string) ([]model.UserPayload, *model.ApiError) {
users := []model.UserPayload{} var users []model.UserPayload
query := `select query := `select
u.id, u.id,
u.name, u.name,
@ -430,7 +430,7 @@ func (mds *ModelDaoSqlite) DeleteGroup(ctx context.Context, id string) *model.Ap
func (mds *ModelDaoSqlite) GetGroup(ctx context.Context, func (mds *ModelDaoSqlite) GetGroup(ctx context.Context,
id string) (*model.Group, *model.ApiError) { id string) (*model.Group, *model.ApiError) {
groups := []model.Group{} var groups []model.Group
if err := mds.db.Select(&groups, `SELECT id, name FROM groups WHERE id=?`, id); err != nil { if err := mds.db.Select(&groups, `SELECT id, name FROM groups WHERE id=?`, id); err != nil {
return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err} return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err}
} }
@ -451,7 +451,7 @@ func (mds *ModelDaoSqlite) GetGroup(ctx context.Context,
func (mds *ModelDaoSqlite) GetGroupByName(ctx context.Context, func (mds *ModelDaoSqlite) GetGroupByName(ctx context.Context,
name string) (*model.Group, *model.ApiError) { name string) (*model.Group, *model.ApiError) {
groups := []model.Group{} var groups []model.Group
if err := mds.db.Select(&groups, `SELECT id, name FROM groups WHERE name=?`, name); err != nil { if err := mds.db.Select(&groups, `SELECT id, name FROM groups WHERE name=?`, name); err != nil {
return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err} return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err}
} }
@ -472,7 +472,7 @@ func (mds *ModelDaoSqlite) GetGroupByName(ctx context.Context,
func (mds *ModelDaoSqlite) GetGroups(ctx context.Context) ([]model.Group, *model.ApiError) { func (mds *ModelDaoSqlite) GetGroups(ctx context.Context) ([]model.Group, *model.ApiError) {
groups := []model.Group{} var groups []model.Group
if err := mds.db.Select(&groups, "SELECT * FROM groups"); err != nil { if err := mds.db.Select(&groups, "SELECT * FROM groups"); err != nil {
return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err} return nil, &model.ApiError{Typ: model.ErrorInternal, Err: err}
} }
@ -502,7 +502,7 @@ func (mds *ModelDaoSqlite) DeleteResetPasswordEntry(ctx context.Context,
func (mds *ModelDaoSqlite) GetResetPasswordEntry(ctx context.Context, func (mds *ModelDaoSqlite) GetResetPasswordEntry(ctx context.Context,
token string) (*model.ResetPasswordEntry, *model.ApiError) { token string) (*model.ResetPasswordEntry, *model.ApiError) {
entries := []model.ResetPasswordEntry{} var entries []model.ResetPasswordEntry
q := `SELECT user_id,token FROM reset_password_request WHERE token=?;` q := `SELECT user_id,token FROM reset_password_request WHERE token=?;`
if err := mds.db.Select(&entries, q, token); err != nil { if err := mds.db.Select(&entries, q, token); err != nil {

View File

@ -40,7 +40,7 @@ func prepareAmChannelApiURL() string {
basePath := constants.GetAlertManagerApiPrefix() basePath := constants.GetAlertManagerApiPrefix()
AmChannelApiPath := constants.AmChannelApiPath AmChannelApiPath := constants.AmChannelApiPath
if len(AmChannelApiPath) > 0 && rune(AmChannelApiPath[0]) == rune('/') { if len(AmChannelApiPath) > 0 && rune(AmChannelApiPath[0]) == '/' {
AmChannelApiPath = AmChannelApiPath[1:] AmChannelApiPath = AmChannelApiPath[1:]
} }
@ -109,7 +109,7 @@ func (m *manager) DeleteRoute(name string) *model.ApiError {
req, err := http.NewRequest(http.MethodDelete, amURL, bytes.NewBuffer(requestData)) req, err := http.NewRequest(http.MethodDelete, amURL, bytes.NewBuffer(requestData))
if err != nil { if err != nil {
zap.S().Errorf("Error in creating new delete request to alertmanager/v1/receivers\n", err) zap.S().Error("Error in creating new delete request to alertmanager/v1/receivers\n", err)
return &model.ApiError{Typ: model.ErrorInternal, Err: err} return &model.ApiError{Typ: model.ErrorInternal, Err: err}
} }
@ -119,7 +119,7 @@ func (m *manager) DeleteRoute(name string) *model.ApiError {
response, err := client.Do(req) response, err := client.Do(req)
if err != nil { if err != nil {
zap.S().Errorf(fmt.Sprintf("Error in getting response of API call to alertmanager(DELETE %s)\n", amURL), err) zap.S().Error("Error in getting response of API call to alertmanager(DELETE %s)\n", amURL, err)
return &model.ApiError{Typ: model.ErrorInternal, Err: err} return &model.ApiError{Typ: model.ErrorInternal, Err: err}
} }

View File

@ -47,10 +47,8 @@ type Reader interface {
GetErrorFromGroupID(ctx context.Context, params *model.GetErrorParams) (*model.ErrorWithSpan, *model.ApiError) GetErrorFromGroupID(ctx context.Context, params *model.GetErrorParams) (*model.ErrorWithSpan, *model.ApiError)
GetNextPrevErrorIDs(ctx context.Context, params *model.GetErrorParams) (*model.NextPrevErrorIDs, *model.ApiError) GetNextPrevErrorIDs(ctx context.Context, params *model.GetErrorParams) (*model.NextPrevErrorIDs, *model.ApiError)
// Search Interfaces
SearchTraces(ctx context.Context, traceID string) (*[]model.SearchSpansResult, error) SearchTraces(ctx context.Context, traceID string) (*[]model.SearchSpansResult, error)
// Setter Interfaces
SetTTL(ctx context.Context, ttlParams *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError) SetTTL(ctx context.Context, ttlParams *model.TTLParams) (*model.SetTTLResponseItem, *model.ApiError)
GetMetricAutocompleteMetricNames(ctx context.Context, matchText string, limit int) (*[]string, *model.ApiError) GetMetricAutocompleteMetricNames(ctx context.Context, matchText string, limit int) (*[]string, *model.ApiError)

View File

@ -33,20 +33,20 @@ type ReduceToOperator int
const ( const (
_ ReduceToOperator = iota _ ReduceToOperator = iota
RLAST RLast
RSUM RSum
RAVG RAvg
RMAX RMax
RMIN RMin
) )
type QueryType int type QueryType int
const ( const (
_ QueryType = iota _ QueryType = iota
QUERY_BUILDER QueryBuilder
CLICKHOUSE ClickHouse
PROM Prom
) )
type PromQuery struct { type PromQuery struct {
@ -64,8 +64,8 @@ type PanelType int
const ( const (
_ PanelType = iota _ PanelType = iota
TIME_SERIES TimeSeries
QUERY_VALUE QueryValue
) )
type CompositeMetricQuery struct { type CompositeMetricQuery struct {
@ -80,13 +80,13 @@ type AggregateOperator int
const ( const (
_ AggregateOperator = iota _ AggregateOperator = iota
NOOP NoOp
COUNT Count
COUNT_DISTINCT CountDistinct
SUM Sum
AVG Avg
MAX Max
MIN Min
P05 P05
P10 P10
P20 P20
@ -96,25 +96,25 @@ const (
P90 P90
P95 P95
P99 P99
RATE Rate
SUM_RATE SumRate
// leave blank space for possily {AVG, X}_RATE // leave blank space for possibly {AVG, X}_RATE
_ _
_ _
_ _
RATE_SUM RateSum
RATE_AVG RateAvg
RATE_MAX RateMax
RATE_MIN RateMin
) )
type DataSource int type DataSource int
const ( const (
_ DataSource = iota _ DataSource = iota
METRICS Metrics
TRACES Traces
LOGS Logs
) )
type QueryRangeParamsV2 struct { type QueryRangeParamsV2 struct {

View File

@ -73,7 +73,7 @@ type AlertDiscovery struct {
Alerts []*AlertingRuleResponse `json:"rules"` Alerts []*AlertingRuleResponse `json:"rules"`
} }
// Alert has info for an alert. // AlertingRuleResponse has info for an alert.
type AlertingRuleResponse struct { type AlertingRuleResponse struct {
Labels labels.Labels `json:"labels"` Labels labels.Labels `json:"labels"`
Annotations labels.Labels `json:"annotations"` Annotations labels.Labels `json:"annotations"`
@ -137,7 +137,7 @@ type GetFilterSpansResponse struct {
TotalSpans uint64 `json:"totalSpans"` TotalSpans uint64 `json:"totalSpans"`
} }
type SearchSpanDBReponseItem struct { type SearchSpanDBResponseItem struct {
Timestamp time.Time `ch:"timestamp"` Timestamp time.Time `ch:"timestamp"`
TraceID string `ch:"traceID"` TraceID string `ch:"traceID"`
Model string `ch:"model"` Model string `ch:"model"`
@ -150,7 +150,7 @@ type Event struct {
IsError bool `json:"isError,omitempty"` IsError bool `json:"isError,omitempty"`
} }
type SearchSpanReponseItem struct { type SearchSpanResponseItem struct {
TimeUnixNano uint64 `json:"timestamp"` TimeUnixNano uint64 `json:"timestamp"`
SpanID string `json:"spanID"` SpanID string `json:"spanID"`
TraceID string `json:"traceID"` TraceID string `json:"traceID"`
@ -177,13 +177,13 @@ func (ref *OtelSpanRef) toString() string {
return retString return retString
} }
func (item *SearchSpanReponseItem) GetValues() []interface{} { func (item *SearchSpanResponseItem) GetValues() []interface{} {
references := []OtelSpanRef{} var references []OtelSpanRef
jsonbody, _ := json.Marshal(item.References) jsonBody, _ := json.Marshal(item.References)
json.Unmarshal(jsonbody, &references) json.Unmarshal(jsonBody, &references)
referencesStringArray := []string{} var referencesStringArray []string
for _, item := range references { for _, item := range references {
referencesStringArray = append(referencesStringArray, item.toString()) referencesStringArray = append(referencesStringArray, item.toString())
} }

View File

@ -16,18 +16,18 @@ import (
) )
const ( const (
TELEMETRY_EVENT_PATH = "API Call" EventPath = "API Call"
TELEMETRY_EVENT_USER = "User" EventUser = "User"
TELEMETRY_EVENT_INPRODUCT_FEEDBACK = "InProduct Feeback Submitted" EventInproductFeedback = "InProduct Feedback Submitted"
TELEMETRY_EVENT_NUMBER_OF_SERVICES = "Number of Services" EventNumberOfServices = "Number of Services"
TELEMETRY_EVENT_HEART_BEAT = "Heart Beat" EventHeartBeat = "Heart Beat"
TELEMETRY_EVENT_ORG_SETTINGS = "Org Settings" EventOrgSettings = "Org Settings"
) )
const api_key = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz" const writeKey = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz"
const IP_NOT_FOUND_PLACEHOLDER = "NA" const IpNotFoundPlaceholder = "NA"
const HEART_BEAT_DURATION = 6 * time.Hour const HeartBeatDuration = 6 * time.Hour
// const HEART_BEAT_DURATION = 10 * time.Second // const HEART_BEAT_DURATION = 10 * time.Second
@ -45,15 +45,15 @@ type Telemetry struct {
func createTelemetry() { func createTelemetry() {
telemetry = &Telemetry{ telemetry = &Telemetry{
operator: analytics.New(api_key), operator: analytics.New(writeKey),
ipAddress: getOutboundIP(), ipAddress: getOutboundIP(),
} }
data := map[string]interface{}{} data := map[string]interface{}{}
telemetry.SetTelemetryEnabled(constants.IsTelemetryEnabled()) telemetry.SetTelemetryEnabled(constants.IsTelemetryEnabled())
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data) telemetry.SendEvent(EventHeartBeat, data)
ticker := time.NewTicker(HEART_BEAT_DURATION) ticker := time.NewTicker(HeartBeatDuration)
go func() { go func() {
for { for {
select { select {
@ -71,7 +71,7 @@ func createTelemetry() {
for key, value := range tsInfo { for key, value := range tsInfo {
data[key] = value data[key] = value
} }
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data) telemetry.SendEvent(EventHeartBeat, data)
} }
} }
}() }()
@ -81,7 +81,7 @@ func createTelemetry() {
// Get preferred outbound ip of this machine // Get preferred outbound ip of this machine
func getOutboundIP() string { func getOutboundIP() string {
ip := []byte(IP_NOT_FOUND_PLACEHOLDER) ip := []byte(IpNotFoundPlaceholder)
resp, err := http.Get("https://api.ipify.org?format=text") resp, err := http.Get("https://api.ipify.org?format=text")
if err != nil { if err != nil {
@ -112,7 +112,7 @@ func (a *Telemetry) IdentifyUser(user *model.User) {
} }
func (a *Telemetry) checkEvents(event string) bool { func (a *Telemetry) checkEvents(event string) bool {
sendEvent := true sendEvent := true
if event == TELEMETRY_EVENT_USER && a.isTelemetryAnonymous() { if event == EventUser && a.isTelemetryAnonymous() {
sendEvent = false sendEvent = false
} }
return sendEvent return sendEvent
@ -139,7 +139,7 @@ func (a *Telemetry) SendEvent(event string, data map[string]interface{}) {
} }
userId := a.ipAddress userId := a.ipAddress
if a.isTelemetryAnonymous() || userId == IP_NOT_FOUND_PLACEHOLDER { if a.isTelemetryAnonymous() || userId == IpNotFoundPlaceholder {
userId = a.GetDistinctId() userId = a.GetDistinctId()
} }

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os"
"testing" "testing"
"time" "time"
@ -27,6 +28,9 @@ func setTTL(table, coldStorage, toColdTTL, deleteTTL string, jwtToken string) ([
} }
var bearer = "Bearer " + jwtToken var bearer = "Bearer " + jwtToken
req, err := http.NewRequest("POST", endpoint+"/api/v1/settings/ttl?"+params, nil) req, err := http.NewRequest("POST", endpoint+"/api/v1/settings/ttl?"+params, nil)
if err != nil {
return nil, err
}
req.Header.Add("Authorization", bearer) req.Header.Add("Authorization", bearer)
resp, err := client.Do(req) resp, err := client.Do(req)
@ -128,6 +132,9 @@ func getTTL(t *testing.T, table string, jwtToken string) *model.GetTTLResponseIt
var bearer = "Bearer " + jwtToken var bearer = "Bearer " + jwtToken
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil {
t.Fatal(err)
}
req.Header.Add("Authorization", bearer) req.Header.Add("Authorization", bearer)
resp, err := client.Do(req) resp, err := client.Do(req)
@ -214,5 +221,5 @@ func TestMain(m *testing.M) {
} }
defer stopCluster() defer stopCluster()
m.Run() os.Exit(m.Run())
} }