mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 01:55:57 +08:00
Merge branch 'develop' into 513-dashboard
This commit is contained in:
commit
58038c222f
33
README.md
33
README.md
@ -32,7 +32,6 @@ SigNoz helps developers monitor applications and troubleshoot problems in their
|
|||||||
|
|
||||||
👉 Run aggregates on trace data to get business relevant metrics
|
👉 Run aggregates on trace data to get business relevant metrics
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
<br />
|
<br />
|
||||||

|

|
||||||
@ -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" />
|
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/Philosophy.svg" width="50px" />
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
|
||||||
### Deploy using Docker
|
### Deploy using Docker
|
||||||
|
|
||||||
Please follow the steps listed [here](https://signoz.io/docs/deployment/docker/) to install 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
|
### Deploy in Kubernetes using Helm
|
||||||
|
|
||||||
Please follow the steps listed [here](https://signoz.io/docs/deployment/helm_chart) to install using helm charts
|
Please follow the steps listed [here](https://signoz.io/docs/deployment/helm_chart) to install using helm charts
|
||||||
|
|
||||||
|
|
||||||
<br /><br />
|
<br /><br />
|
||||||
|
|
||||||
@ -112,7 +109,7 @@ Please follow the steps listed [here](https://signoz.io/docs/deployment/helm_cha
|
|||||||
|
|
||||||
### SigNoz vs Prometheus
|
### 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.
|
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
|
## 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)
|
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 />
|
<br /><br />
|
||||||
|
|
||||||
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/DevelopingLocally.svg" width="50px" />
|
<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)
|
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">
|
<a href="https://github.com/signoz/signoz/graphs/contributors">
|
||||||
<img src="https://contrib.rocks/image?repo=signoz/signoz" />
|
<img src="https://contrib.rocks/image?repo=signoz/signoz" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
module.exports = { extends: ['@commitlint/config-conventional'] };
|
|
1
frontend/commitlint.config.ts
Normal file
1
frontend/commitlint.config.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default { extends: ['@commitlint/config-conventional'] };
|
@ -32,8 +32,8 @@
|
|||||||
"./conf/default.conf",
|
"./conf/default.conf",
|
||||||
"./public",
|
"./public",
|
||||||
"./tests",
|
"./tests",
|
||||||
"playwright.config.ts",
|
"./playwright.config.ts",
|
||||||
"./commitlint.config.js",
|
"./commitlint.config.ts",
|
||||||
"./webpack.config.js",
|
"./webpack.config.js",
|
||||||
"./webpack.config.prod.js",
|
"./webpack.config.prod.js",
|
||||||
"./jest.setup.ts"
|
"./jest.setup.ts"
|
||||||
|
@ -2906,3 +2906,77 @@ func (r *ClickHouseReader) GetMetricResult(ctx context.Context, query string) ([
|
|||||||
}
|
}
|
||||||
return seriesList, nil
|
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
|
||||||
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"go.signoz.io/query-service/constants"
|
"go.signoz.io/query-service/constants"
|
||||||
"go.signoz.io/query-service/dao"
|
"go.signoz.io/query-service/dao"
|
||||||
am "go.signoz.io/query-service/integrations/alertManager"
|
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/model"
|
||||||
"go.signoz.io/query-service/telemetry"
|
"go.signoz.io/query-service/telemetry"
|
||||||
"go.signoz.io/query-service/version"
|
"go.signoz.io/query-service/version"
|
||||||
@ -46,14 +47,14 @@ type APIHandler struct {
|
|||||||
// queryParser queryParser
|
// queryParser queryParser
|
||||||
basePath string
|
basePath string
|
||||||
apiPrefix string
|
apiPrefix string
|
||||||
reader *Reader
|
reader *interfaces.Reader
|
||||||
relationalDB dao.ModelDao
|
relationalDB dao.ModelDao
|
||||||
alertManager am.Manager
|
alertManager am.Manager
|
||||||
ready func(http.HandlerFunc) http.HandlerFunc
|
ready func(http.HandlerFunc) http.HandlerFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAPIHandler returns an APIHandler
|
// 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("")
|
alertManager := am.New("")
|
||||||
aH := &APIHandler{
|
aH := &APIHandler{
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"go.signoz.io/query-service/constants"
|
"go.signoz.io/query-service/constants"
|
||||||
"go.signoz.io/query-service/dao"
|
"go.signoz.io/query-service/dao"
|
||||||
"go.signoz.io/query-service/healthcheck"
|
"go.signoz.io/query-service/healthcheck"
|
||||||
|
"go.signoz.io/query-service/interfaces"
|
||||||
"go.signoz.io/query-service/telemetry"
|
"go.signoz.io/query-service/telemetry"
|
||||||
"go.signoz.io/query-service/utils"
|
"go.signoz.io/query-service/utils"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@ -65,7 +66,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
|
|
||||||
localDB.SetMaxOpenConns(10)
|
localDB.SetMaxOpenConns(10)
|
||||||
|
|
||||||
var reader Reader
|
var reader interfaces.Reader
|
||||||
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 ...")
|
||||||
@ -76,6 +77,8 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
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)
|
||||||
|
|
||||||
apiHandler, err := NewAPIHandler(&reader, dao.DB())
|
apiHandler, err := NewAPIHandler(&reader, dao.DB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -140,4 +140,4 @@ require (
|
|||||||
k8s.io/client-go v8.0.0+incompatible // indirect
|
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
|
||||||
|
@ -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/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 h1:bneLSKPf9YUSFmafKx32bynV6QrzViL/s+ZDvQxH1E4=
|
||||||
github.com/SigNoz/govaluate v0.0.0-20220522085550-d19c08c206cb/go.mod h1:JznGDNg9x1cujDKa22RaQOimOvvEfy3nxzDGd8XDgmA=
|
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.73 h1:f6PjQrJGoCot9iJp/tWoKwgy0HTIqicYave4K3fT9ro=
|
||||||
github.com/SigNoz/prometheus v1.9.72/go.mod h1:Y4J9tGDmacMC+EcOTp+EIAn2C1sN+9kE+idyVKadiVM=
|
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/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/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=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package app
|
package interfaces
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -54,4 +54,9 @@ type Reader interface {
|
|||||||
GetMetricAutocompleteTagKey(ctx context.Context, params *model.MetricAutocompleteTagParams) (*[]string, *model.ApiError)
|
GetMetricAutocompleteTagKey(ctx context.Context, params *model.MetricAutocompleteTagParams) (*[]string, *model.ApiError)
|
||||||
GetMetricAutocompleteTagValue(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)
|
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)
|
||||||
}
|
}
|
@ -2,8 +2,11 @@ package telemetry
|
|||||||
|
|
||||||
func IgnoredPaths() map[string]struct{} {
|
func IgnoredPaths() map[string]struct{} {
|
||||||
ignoredPaths := map[string]struct{}{
|
ignoredPaths := map[string]struct{}{
|
||||||
"/api/v1/tags": {},
|
"/api/v1/tags": {},
|
||||||
"/api/v1/version": {},
|
"/api/v1/version": {},
|
||||||
|
"/api/v1/query_range": {},
|
||||||
|
"/api/v2/metrics/query_range": {},
|
||||||
|
"/api/v1/services/list": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
return ignoredPaths
|
return ignoredPaths
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package telemetry
|
package telemetry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -8,6 +9,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.signoz.io/query-service/constants"
|
"go.signoz.io/query-service/constants"
|
||||||
|
"go.signoz.io/query-service/interfaces"
|
||||||
"go.signoz.io/query-service/model"
|
"go.signoz.io/query-service/model"
|
||||||
"go.signoz.io/query-service/version"
|
"go.signoz.io/query-service/version"
|
||||||
"gopkg.in/segmentio/analytics-go.v3"
|
"gopkg.in/segmentio/analytics-go.v3"
|
||||||
@ -25,6 +27,10 @@ const (
|
|||||||
const api_key = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz"
|
const api_key = "4Gmoa4ixJAUHx2BpJxsjwA1bEfnwEeRz"
|
||||||
const IP_NOT_FOUND_PLACEHOLDER = "NA"
|
const IP_NOT_FOUND_PLACEHOLDER = "NA"
|
||||||
|
|
||||||
|
const HEART_BEAT_DURATION = 6 * time.Hour
|
||||||
|
|
||||||
|
// const HEART_BEAT_DURATION = 10 * time.Second
|
||||||
|
|
||||||
var telemetry *Telemetry
|
var telemetry *Telemetry
|
||||||
var once sync.Once
|
var once sync.Once
|
||||||
|
|
||||||
@ -34,6 +40,7 @@ type Telemetry struct {
|
|||||||
isEnabled bool
|
isEnabled bool
|
||||||
isAnonymous bool
|
isAnonymous bool
|
||||||
distinctId string
|
distinctId string
|
||||||
|
reader interfaces.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTelemetry() {
|
func createTelemetry() {
|
||||||
@ -46,11 +53,24 @@ func createTelemetry() {
|
|||||||
|
|
||||||
telemetry.SetTelemetryEnabled(constants.IsTelemetryEnabled())
|
telemetry.SetTelemetryEnabled(constants.IsTelemetryEnabled())
|
||||||
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data)
|
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data)
|
||||||
ticker := time.NewTicker(6 * time.Hour)
|
ticker := time.NewTicker(HEART_BEAT_DURATION)
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
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)
|
telemetry.SendEvent(TELEMETRY_EVENT_HEART_BEAT, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,6 +173,10 @@ func (a *Telemetry) SetTelemetryEnabled(value bool) {
|
|||||||
a.isEnabled = value
|
a.isEnabled = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Telemetry) SetReader(reader interfaces.Reader) {
|
||||||
|
a.reader = reader
|
||||||
|
}
|
||||||
|
|
||||||
func GetInstance() *Telemetry {
|
func GetInstance() *Telemetry {
|
||||||
|
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user