Merge pull request #1357 from SigNoz/release/v0.9.2

Release/v0.9.2
This commit is contained in:
Ankit Nayan 2022-07-04 22:30:46 +05:30 committed by GitHub
commit be814afeea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 178 additions and 33 deletions

View File

@ -32,7 +32,6 @@ SigNoz helps developers monitor applications and troubleshoot problems in their
👉 Run aggregates on trace data to get business relevant metrics
![screenzy-1644432902955](https://user-images.githubusercontent.com/504541/153270713-1b2156e6-ec03-42de-975b-3c02b8ec1836.png)
<br />
![screenzy-1644432986784](https://user-images.githubusercontent.com/504541/153270725-0efb73b3-06ed-4207-bf13-9b7e2e17c4b8.png)
@ -88,8 +87,7 @@ You can find the complete list of languages here - https://opentelemetry.io/docs
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/Philosophy.svg" width="50px" />
## Getting Started
### Deploy using Docker
Please follow the steps listed [here](https://signoz.io/docs/deployment/docker/) to install using docker
@ -102,7 +100,6 @@ The [troubleshooting instructions](https://signoz.io/docs/deployment/troubleshoo
### Deploy in Kubernetes using Helm
Please follow the steps listed [here](https://signoz.io/docs/deployment/helm_chart) to install using helm charts
<br /><br />
@ -112,7 +109,7 @@ Please follow the steps listed [here](https://signoz.io/docs/deployment/helm_cha
### SigNoz vs Prometheus
Prometheus is good if you want to do just metrics. But if you want to have a seamless experience between metrics and traces, then current experience of stitching together Prometheus & Jaeger is not great.
Prometheus is good if you want to do just metrics. But if you want to have a seamless experience between metrics and traces, then current experience of stitching together Prometheus & Jaeger is not great.
Our goal is to provide an integrated UI between metrics & traces - similar to what SaaS vendors like Datadog provides - and give advanced filtering and aggregation over traces, something which Jaeger currently lack.
@ -133,11 +130,28 @@ Moreover, SigNoz has few more advanced features wrt Jaeger:
## Contributing
We ❤️ contributions big or small. Please read [CONTRIBUTING.md](CONTRIBUTING.md) to get started with making contributions to SigNoz.
We ❤️ contributions big or small. Please read [CONTRIBUTING.md](CONTRIBUTING.md) to get started with making contributions to SigNoz.
Not sure how to get started? Just ping us on `#contributing` in our [slack community](https://signoz.io/slack)
### Project maintainers
#### Backend
- [Ankit Nayan](https://github.com/ankitnayan)
- [Nityananda Gohain](https://github.com/nityanandagohain)
- [Srikanth Chekuri](https://github.com/srikanthccv)
- [Vishal Sharma](https://github.com/makeavish)
#### Frontend
- [Palash Gupta](https://github.com/palashgdev)
- [Pranshu Chittora](https://github.com/pranshuchittora)
#### DevOps
- [Prashant Shahi](https://github.com/prashant-shahi)
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/DevelopingLocally.svg" width="50px" />
@ -156,11 +170,8 @@ Join the [slack community](https://signoz.io/slack) to know more about distribut
If you have any ideas, questions, or any feedback, please share on our [Github Discussions](https://github.com/SigNoz/signoz/discussions)
As always, thanks to our amazing contributors!
As always, thanks to our amazing contributors!
<a href="https://github.com/signoz/signoz/graphs/contributors">
<img src="https://contrib.rocks/image?repo=signoz/signoz" />
</a>

View File

@ -40,7 +40,7 @@ services:
condition: on-failure
query-service:
image: signoz/query-service:0.9.1
image: signoz/query-service:0.9.2
command: ["-config=/root/config/prometheus.yml"]
# ports:
# - "6060:6060" # pprof port
@ -68,7 +68,7 @@ services:
- clickhouse
frontend:
image: signoz/frontend:0.9.1
image: signoz/frontend:0.9.2
deploy:
restart_policy:
condition: on-failure

View File

@ -39,7 +39,7 @@ services:
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
query-service:
image: signoz/query-service:0.9.1
image: signoz/query-service:0.9.2
container_name: query-service
command: ["-config=/root/config/prometheus.yml"]
# ports:
@ -66,7 +66,7 @@ services:
condition: service_healthy
frontend:
image: signoz/frontend:0.9.1
image: signoz/frontend:0.9.2
container_name: frontend
restart: on-failure
depends_on:

View File

@ -1 +0,0 @@
module.exports = { extends: ['@commitlint/config-conventional'] };

View File

@ -0,0 +1 @@
export default { extends: ['@commitlint/config-conventional'] };

View File

@ -102,6 +102,11 @@ export const AxiosAlertManagerInstance = axios.create({
export const ApiV2Instance = axios.create({
baseURL: `${ENVIRONMENT.baseURL}${apiV2}`,
});
ApiV2Instance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,
);
ApiV2Instance.interceptors.request.use(interceptorsRequestResponse);
AxiosAlertManagerInstance.interceptors.response.use(
interceptorsResponse,

View File

@ -15,7 +15,11 @@ import ROUTES from 'constants/routes';
import history from 'lib/history';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import { generatePath } from 'react-router-dom';
import { Dispatch } from 'redux';
import AppActions from 'types/actions';
import { FLUSH_DASHBOARD } from 'types/actions/dashboard';
import { DashboardData } from 'types/api/dashboard/getAll';
import { EditorContainer, FooterContainer } from './styles';
@ -30,6 +34,8 @@ function ImportJSON({
const [isCreateDashboardError, setIsCreateDashboardError] = useState<boolean>(
false,
);
const dispatch = useDispatch<Dispatch<AppActions>>();
const [dashboardCreating, setDashboardCreating] = useState<boolean>(false);
const [editorValue, setEditorValue] = useState<string>('');
@ -86,6 +92,9 @@ function ImportJSON({
});
if (response.statusCode === 200) {
dispatch({
type: FLUSH_DASHBOARD,
});
setTimeout(() => {
history.push(
generatePath(ROUTES.DASHBOARD, {

View File

@ -5,6 +5,7 @@ import AppRoutes from 'AppRoutes';
import React from 'react';
import ReactDOM from 'react-dom';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import { Provider } from 'react-redux';
import reportWebVitals from 'reportWebVitals';
import store from 'store';
@ -28,6 +29,9 @@ ReactDOM.render(
<AppRoutes />
</React.StrictMode>
</Provider>
{process.env.NODE_ENV === 'development' && (
<ReactQueryDevtools initialIsOpen />
)}
</QueryClientProvider>,
document.querySelector('#root'),
);

View File

@ -143,17 +143,23 @@ export async function GetMetricQueryRange({
`API responded with ${response.statusCode} - ${response.error}`,
);
}
if (response.payload?.data?.result) {
response.payload.data.result = response.payload.data.result.map(
(queryData) => {
const newQueryData = queryData;
newQueryData.legend = legendMap[queryData.queryName];
newQueryData.legend = legendMap[queryData.queryName]; // Adds the legend if it is already defined by the user.
// If metric names is an empty object
if (isEmpty(queryData.metric)) {
newQueryData.metric[queryData.queryName] = queryData.queryName;
newQueryData.legend = queryData.queryName;
// If metrics list is empty && the user haven't defined a legend then add the legend equal to the name of the query.
if (!newQueryData.legend) {
newQueryData.legend = queryData.queryName;
}
// If name of the query and the legend if inserted is same then add the same to the metrics object.
if (queryData.queryName === newQueryData.legend) {
newQueryData.metric[queryData.queryName] = queryData.queryName;
}
}
return queryData;
return newQueryData;
},
);
}

View File

@ -32,8 +32,8 @@
"./conf/default.conf",
"./public",
"./tests",
"playwright.config.ts",
"./commitlint.config.js",
"./playwright.config.ts",
"./commitlint.config.ts",
"./webpack.config.js",
"./webpack.config.prod.js",
"./jest.setup.ts"

View File

@ -2906,3 +2906,77 @@ func (r *ClickHouseReader) GetMetricResult(ctx context.Context, query string) ([
}
return seriesList, nil
}
func (r *ClickHouseReader) GetTotalSpans(ctx context.Context) (uint64, error) {
var totalSpans uint64
queryStr := fmt.Sprintf("SELECT count() from %s.%s;", signozTraceDBName, signozTraceTableName)
r.db.QueryRow(ctx, queryStr).Scan(&totalSpans)
return totalSpans, nil
}
func (r *ClickHouseReader) GetSpansInLastHeartBeatInterval(ctx context.Context) (uint64, error) {
var spansInLastHeartBeatInterval uint64
queryStr := fmt.Sprintf("SELECT count() from %s.%s where timestamp > toUnixTimestamp(now()-toIntervalMinute(%d));", signozTraceDBName, signozSpansTable, 30)
r.db.QueryRow(ctx, queryStr).Scan(&spansInLastHeartBeatInterval)
return spansInLastHeartBeatInterval, nil
}
// func sum(array []tsByMetricName) uint64 {
// var result uint64
// result = 0
// for _, v := range array {
// result += v.count
// }
// return result
// }
func (r *ClickHouseReader) GetTimeSeriesInfo(ctx context.Context) (map[string]interface{}, error) {
queryStr := fmt.Sprintf("SELECT count() as count from %s.%s group by metric_name order by count desc;", signozMetricDBName, signozTSTableName)
// r.db.Select(ctx, &tsByMetricName, queryStr)
rows, _ := r.db.Query(ctx, queryStr)
var totalTS uint64
totalTS = 0
var maxTS uint64
maxTS = 0
count := 0
for rows.Next() {
var value uint64
rows.Scan(&value)
totalTS += value
if count == 0 {
maxTS = value
}
count += 1
}
timeSeriesData := map[string]interface{}{}
timeSeriesData["totalTS"] = totalTS
timeSeriesData["maxTS"] = maxTS
return timeSeriesData, nil
}
func (r *ClickHouseReader) GetSamplesInfoInLastHeartBeatInterval(ctx context.Context) (uint64, error) {
var totalSamples uint64
queryStr := fmt.Sprintf("select count() from %s.%s where timestamp_ms > toUnixTimestamp(now()-toIntervalMinute(%d))*1000;", signozMetricDBName, signozSampleTableName, 30)
r.db.QueryRow(ctx, queryStr).Scan(&totalSamples)
return totalSamples, nil
}

View File

@ -22,6 +22,7 @@ import (
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/dao"
am "go.signoz.io/query-service/integrations/alertManager"
"go.signoz.io/query-service/interfaces"
"go.signoz.io/query-service/model"
"go.signoz.io/query-service/telemetry"
"go.signoz.io/query-service/version"
@ -46,14 +47,14 @@ type APIHandler struct {
// queryParser queryParser
basePath string
apiPrefix string
reader *Reader
reader *interfaces.Reader
relationalDB dao.ModelDao
alertManager am.Manager
ready func(http.HandlerFunc) http.HandlerFunc
}
// NewAPIHandler returns an APIHandler
func NewAPIHandler(reader *Reader, relationalDB dao.ModelDao) (*APIHandler, error) {
func NewAPIHandler(reader *interfaces.Reader, relationalDB dao.ModelDao) (*APIHandler, error) {
alertManager := am.New("")
aH := &APIHandler{

View File

@ -19,6 +19,7 @@ import (
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/dao"
"go.signoz.io/query-service/healthcheck"
"go.signoz.io/query-service/interfaces"
"go.signoz.io/query-service/telemetry"
"go.signoz.io/query-service/utils"
"go.uber.org/zap"
@ -65,7 +66,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
localDB.SetMaxOpenConns(10)
var reader Reader
var reader interfaces.Reader
storage := os.Getenv("STORAGE")
if storage == "clickhouse" {
zap.S().Info("Using ClickHouse as datastore ...")
@ -76,6 +77,8 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
return nil, fmt.Errorf("Storage type: %s is not supported in query service", storage)
}
telemetry.GetInstance().SetReader(reader)
apiHandler, err := NewAPIHandler(&reader, dao.DB())
if err != nil {
return nil, err

View File

@ -140,4 +140,4 @@ require (
k8s.io/client-go v8.0.0+incompatible // indirect
)
replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.9.72
replace github.com/prometheus/prometheus => github.com/SigNoz/prometheus v1.9.73

View File

@ -57,8 +57,8 @@ github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/SigNoz/govaluate v0.0.0-20220522085550-d19c08c206cb h1:bneLSKPf9YUSFmafKx32bynV6QrzViL/s+ZDvQxH1E4=
github.com/SigNoz/govaluate v0.0.0-20220522085550-d19c08c206cb/go.mod h1:JznGDNg9x1cujDKa22RaQOimOvvEfy3nxzDGd8XDgmA=
github.com/SigNoz/prometheus v1.9.72 h1:0p4ZN/NUb5jChB3blqpKKmANCAMWLp7N5L9YyyV7SQs=
github.com/SigNoz/prometheus v1.9.72/go.mod h1:Y4J9tGDmacMC+EcOTp+EIAn2C1sN+9kE+idyVKadiVM=
github.com/SigNoz/prometheus v1.9.73 h1:f6PjQrJGoCot9iJp/tWoKwgy0HTIqicYave4K3fT9ro=
github.com/SigNoz/prometheus v1.9.73/go.mod h1:Y4J9tGDmacMC+EcOTp+EIAn2C1sN+9kE+idyVKadiVM=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=

View File

@ -1,4 +1,4 @@
package app
package interfaces
import (
"context"
@ -54,4 +54,9 @@ type Reader interface {
GetMetricAutocompleteTagKey(ctx context.Context, params *model.MetricAutocompleteTagParams) (*[]string, *model.ApiError)
GetMetricAutocompleteTagValue(ctx context.Context, params *model.MetricAutocompleteTagParams) (*[]string, *model.ApiError)
GetMetricResult(ctx context.Context, query string) ([]*model.Series, error)
GetTotalSpans(ctx context.Context) (uint64, error)
GetSpansInLastHeartBeatInterval(ctx context.Context) (uint64, error)
GetTimeSeriesInfo(ctx context.Context) (map[string]interface{}, error)
GetSamplesInfoInLastHeartBeatInterval(ctx context.Context) (uint64, error)
}

View File

@ -2,8 +2,11 @@ package telemetry
func IgnoredPaths() map[string]struct{} {
ignoredPaths := map[string]struct{}{
"/api/v1/tags": {},
"/api/v1/version": {},
"/api/v1/tags": {},
"/api/v1/version": {},
"/api/v1/query_range": {},
"/api/v2/metrics/query_range": {},
"/api/v1/services/list": {},
}
return ignoredPaths

View File

@ -1,6 +1,7 @@
package telemetry
import (
"context"
"io/ioutil"
"net/http"
"os"
@ -8,6 +9,7 @@ import (
"time"
"go.signoz.io/query-service/constants"
"go.signoz.io/query-service/interfaces"
"go.signoz.io/query-service/model"
"go.signoz.io/query-service/version"
"gopkg.in/segmentio/analytics-go.v3"
@ -25,6 +27,10 @@ const (
const api_key = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz"
const IP_NOT_FOUND_PLACEHOLDER = "NA"
const HEART_BEAT_DURATION = 6 * time.Hour
// const HEART_BEAT_DURATION = 10 * time.Second
var telemetry *Telemetry
var once sync.Once
@ -34,6 +40,7 @@ type Telemetry struct {
isEnabled bool
isAnonymous bool
distinctId string
reader interfaces.Reader
}
func createTelemetry() {
@ -46,11 +53,24 @@ func createTelemetry() {
telemetry.SetTelemetryEnabled(constants.IsTelemetryEnabled())
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data)
ticker := time.NewTicker(6 * time.Hour)
ticker := time.NewTicker(HEART_BEAT_DURATION)
go func() {
for {
select {
case <-ticker.C:
totalSpans, _ := telemetry.reader.GetTotalSpans(context.Background())
spansInLastHeartBeatInterval, _ := telemetry.reader.GetSpansInLastHeartBeatInterval(context.Background())
getSamplesInfoInLastHeartBeatInterval, _ := telemetry.reader.GetSamplesInfoInLastHeartBeatInterval(context.Background())
tsInfo, _ := telemetry.reader.GetTimeSeriesInfo(context.Background())
data := map[string]interface{}{
"totalSpans": totalSpans,
"spansInLastHeartBeatInterval": spansInLastHeartBeatInterval,
"getSamplesInfoInLastHeartBeatInterval": getSamplesInfoInLastHeartBeatInterval,
}
for key, value := range tsInfo {
data[key] = value
}
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data)
}
}
@ -153,6 +173,10 @@ func (a *Telemetry) SetTelemetryEnabled(value bool) {
a.isEnabled = value
}
func (a *Telemetry) SetReader(reader interfaces.Reader) {
a.reader = reader
}
func GetInstance() *Telemetry {
once.Do(func() {