Skip to content

Commit

Permalink
Add qryn to destinations (#41)
Browse files Browse the repository at this point in the history
This PR implements a dedicated [qryn](https://qryn.dev) Odigos
destination based off the original Grafana destination.

Opening draft PR for peer-review and testing


![image](https://user-images.githubusercontent.com/1423657/206232336-82b33805-e167-4023-a969-1281b1175b0a.png)
  • Loading branch information
lmangani committed Dec 17, 2022
1 parent 0c52819 commit 6bd800f
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 1 deletion.
2 changes: 2 additions & 0 deletions DESTINATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
| Loki | | ||
| Jaeger || | |
| SigNoz ||||
| qryn ||||


**Many more destinations are coming soon.**

Expand Down
135 changes: 135 additions & 0 deletions autoscaler/controllers/gateway/config/qryn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package config

import (
"fmt"
odigosv1 "github.com/keyval-dev/odigos/api/odigos/v1alpha1"
commonconf "github.com/keyval-dev/odigos/autoscaler/controllers/common"
"github.com/keyval-dev/odigos/common"
"sigs.k8s.io/controller-runtime/pkg/log"
"strings"
)

const (
qrynUrl = "QRYN_URL"
qrynUser = "QRYN_USER"
qrynToken = "QRYN_TOKEN"
)

type Qryn struct{}

func (g *Qryn) DestType() common.DestinationType {
return common.QrynDestinationType
}

func (g *Qryn) ModifyConfig(dest *odigosv1.Destination, currentConfig *commonconf.Config) {
if isMetricsEnabled(dest) && g.isQrynVarsExists(dest) {
url := dest.Spec.Data[qrynUrl]
if !strings.HasSuffix(url, "/api/prom/remote/write") {
url = fmt.Sprintf("%s/api/prom/remote/write", url)
}
rwExporterName := "prometheusremotewrite/qryn"
if g.isQrynAuthExists(dest) {
url = strings.TrimPrefix(dest.Spec.Data[qrynUrl], "https://")
user := dest.Spec.Data[qrynUser]
currentConfig.Exporters[rwExporterName] = commonconf.GenericMap{
"endpoint": fmt.Sprintf("https://%s:%s@%s", user, "${QRYN_TOKEN}", url),
}
} else {
currentConfig.Exporters[rwExporterName] = commonconf.GenericMap{
"endpoint": fmt.Sprintf("%s", url),
}
}
currentConfig.Service.Pipelines["metrics/qryn"] = commonconf.Pipeline{
Receivers: []string{"otlp"},
Processors: []string{"batch"},
Exporters: []string{rwExporterName},
}
}

if isTracingEnabled(dest) && g.isQrynVarsExists(dest) {
url := dest.Spec.Data[qrynUrl]
if g.isQrynAuthExists(dest) {
url = strings.TrimPrefix(dest.Spec.Data[qrynUrl], "https://")
user := dest.Spec.Data[qrynUser]
currentConfig.Exporters["otlp/qryn"] = commonconf.GenericMap{
"endpoint": fmt.Sprintf("https://%s:%s@%s", user, "${QRYN_TOKEN}", url),
}
} else {
currentConfig.Exporters["otlp/qryn"] = commonconf.GenericMap{
"endpoint": fmt.Sprintf("%s", url),
}
}

currentConfig.Service.Pipelines["traces/qryn"] = commonconf.Pipeline{
Receivers: []string{"otlp"},
Processors: []string{"batch"},
Exporters: []string{"otlp/qryn"},
}
}

if isLoggingEnabled(dest) && g.isQrynVarsExists(dest) {
url := dest.Spec.Data[qrynUrl]
if !strings.HasSuffix(url, "/loki/api/v1/push") {
url = fmt.Sprintf("%s/loki/api/v1/push", url)
}
lokiExporterName := "loki/qryn"
if g.isQrynAuthExists(dest) {
url = strings.TrimPrefix(dest.Spec.Data[qrynUrl], "https://")
user := dest.Spec.Data[qrynUser]
currentConfig.Exporters[lokiExporterName] = commonconf.GenericMap{
"endpoint": fmt.Sprintf("https://%s:%s@%s", user, "${QRYN_TOKEN}", url),
"labels": commonconf.GenericMap{
"attributes": commonconf.GenericMap{
"k8s.container.name": "k8s_container_name",
"k8s.pod.name": "k8s_pod_name",
"k8s.namespace.name": "k8s_namespace_name",
},
},
}
} else {
currentConfig.Exporters[lokiExporterName] = commonconf.GenericMap{
"endpoint": fmt.Sprintf("%s", url),
"labels": commonconf.GenericMap{
"attributes": commonconf.GenericMap{
"k8s.container.name": "k8s_container_name",
"k8s.pod.name": "k8s_pod_name",
"k8s.namespace.name": "k8s_namespace_name",
},
},
}
}

currentConfig.Service.Pipelines["logs/qryn"] = commonconf.Pipeline{
Receivers: []string{"otlp"},
Processors: []string{"batch"},
Exporters: []string{lokiExporterName},
}
}
}


func (g *Qryn) isQrynVarsExists(dest *odigosv1.Destination) bool {
_, exists := dest.Spec.Data[qrynUrl]
if !exists {
log.Log.V(0).Info("Qryn API URL not specified, gateway will not be configured")
return false
}

return true
}

func (g *Qryn) isQrynAuthExists(dest *odigosv1.Destination) bool {
_, exists := dest.Spec.Data[qrynToken]
if !exists {
log.Log.V(0).Info("Qryn API Token not specified, gateway auth will not be configured")
return false
}

_, exists = dest.Spec.Data[qrynUser]
if !exists {
log.Log.V(0).Info("Qryn API Auth user not specified, gateway auth will not be configured")
return false
}

return true
}
2 changes: 1 addition & 1 deletion autoscaler/controllers/gateway/config/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

var availableConfigers = []Configer{&Honeycomb{}, &Grafana{}, &Datadog{}, &NewRelic{}, &Logzio{}, &Prometheus{}, &Tempo{}, &Loki{},
&Jaeger{}, &GenericOTLP{}, &Signoz{}}
&Jaeger{}, &GenericOTLP{}, &Signoz{}, &Qryn{}}

type Configer interface {
DestType() common.DestinationType
Expand Down
1 change: 1 addition & 0 deletions common/dests.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ const (
JaegerDestinationType DestinationType = "jaeger"
GenericOTLPDestinationType DestinationType = "otlp"
SignozDestinationType DestinationType = "signoz"
QrynDestinationType DestinationType = "qryn"
)
Loading

0 comments on commit 6bd800f

Please sign in to comment.