Skip to content

Commit

Permalink
Merge branch 'main' of github.com:keyval-dev/odigos
Browse files Browse the repository at this point in the history
  • Loading branch information
alonkeyval committed May 22, 2024
2 parents 9488eb0 + cf194fd commit 798ea80
Show file tree
Hide file tree
Showing 25 changed files with 618 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${{ secrets.RELEASE_BOT_TOKEN }}" \
https://api.github.com/repos/odigos-io/odigos-charts/dispatches \
-d '{"event_type": "create_release_pr", "client_payload": {"tag": "${{ steps.extract_tag.outputs.tag }}"}}'
-d '{"event_type": "create_release_pr", "client_payload": {"tag": "${{ steps.set_tag.outputs.tag }}"}}'

- uses: ko-build/setup-ko@v0.6
Expand Down
1 change: 1 addition & 0 deletions DESTINATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
| Splunk || | |
| Lightstep || | |
| Sentry || | |
| Causely ||| |

## Open Source

Expand Down
98 changes: 98 additions & 0 deletions common/config/causely.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package config

import (
"errors"
"fmt"
"github.com/odigos-io/odigos/common"
"net/url"
"strings"
)

const (
causelyUrl = "CAUSELY_URL"
)

type Causely struct{}

func (e *Causely) DestType() common.DestinationType {
return common.CauselyDestinationType
}

func validateCauselyUrlInput(rawUrl string) (string, error) {
urlWithScheme := strings.TrimSpace(rawUrl)

if !strings.Contains(rawUrl, "://") {
urlWithScheme = "http://" + rawUrl
}

parsedUrl, err := url.Parse(urlWithScheme)
if err != nil {
return "", err
}

// Causely does not support paths, so remove it
parsedUrl.Path = ""

// --- validate the protocol ---
// if scheme is https, convert to "http" (Causely does not currently support TLS export)
if parsedUrl.Scheme == "https" {
parsedUrl.Scheme = "http"
}
// at this point if scheme is not http, it is invalid
if parsedUrl.Scheme != "http" {
return "", fmt.Errorf("Causely endpoint scheme must be http, got %s", parsedUrl.Scheme)
}

// --- validate host ---
if parsedUrl.Hostname() == "" {
return "", fmt.Errorf("Causely endpoint host is required")
}

// --- validate port ---
// allow the user specified port, but fallback to Causely default port 4317 if none provided
if parsedUrl.Port() == "" {
parsedUrl.Host = parsedUrl.Hostname() + ":4317"
if err != nil {
return "", err
}
}

return parsedUrl.String(), nil
}

func (e *Causely) ModifyConfig(dest ExporterConfigurer, currentConfig *Config) error {
rawUrl, exists := dest.GetConfig()[causelyUrl]
if !exists {
return errors.New("Causely url not specified, gateway will not be configured for Causely")
}

validatedUrl, err := validateCauselyUrlInput(rawUrl)
if err != nil {
return errors.Join(err, errors.New("failed to parse Causely endpoint, gateway will not be configured for Causely"))
}

exporterName := "otlp/causely-" + dest.GetName()

currentConfig.Exporters[exporterName] = GenericMap{
"endpoint": validatedUrl,
"tls": GenericMap{
"insecure": true,
},
}

if isTracingEnabled(dest) {
tracesPipelineName := "traces/causely-" + dest.GetName()
currentConfig.Service.Pipelines[tracesPipelineName] = Pipeline{
Exporters: []string{exporterName},
}
}

if isMetricsEnabled(dest) {
logsPipelineName := "metrics/causely-" + dest.GetName()
currentConfig.Service.Pipelines[logsPipelineName] = Pipeline{
Exporters: []string{exporterName},
}
}

return nil
}
119 changes: 119 additions & 0 deletions common/config/causely_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package config

import (
"testing"
)

func TestCauselyUrlFromInput(t *testing.T) {
type args struct {
rawUrl string
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "valid url",
args: args{
rawUrl: "http://mediator.causely:4317",
},
want: "http://mediator.causely:4317",
wantErr: false,
},
{
name: "remove path from url",
args: args{
rawUrl: "http://mediator.causely:4317/",
},
want: "http://mediator.causely:4317",
wantErr: false,
},
{
name: "add http protocol if missing",
args: args{
rawUrl: "mediator.causely:4317",
},
want: "http://mediator.causely:4317",
wantErr: false,
},
{
name: "convert https protocol to http",
args: args{
rawUrl: "https://mediator.causely:4317",
},
want: "http://mediator.causely:4317",
wantErr: false,
},
{
name: "allow only http and https protocols",
args: args{
rawUrl: "ftp://mediator.causely:4317",
},
want: "",
wantErr: true,
},
{
name: "add default port if missing",
args: args{
rawUrl: "http://mediator.causely",
},
want: "http://mediator.causely:4317",
wantErr: false,
},
{
name: "allow non standard port",
args: args{
rawUrl: "http://mediator.causely:4567",
},
want: "http://mediator.causely:4567",
wantErr: false,
},
{
name: "remove whitespaces",
args: args{
rawUrl: " http://mediator.causely:4317 ",
},
want: "http://mediator.causely:4317",
wantErr: false,
},
{
name: "non numeric port",
args: args{
rawUrl: "http://mediator.causely:a4317/",
},
want: "",
wantErr: true,
},
{
name: "missing host",
args: args{
rawUrl: "http://:4317",
},
want: "",
wantErr: true,
},
{
name: "missing host and port",
args: args{
rawUrl: "http://",
},
want: "",
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := validateCauselyUrlInput(tt.args.rawUrl)
if (err != nil) != tt.wantErr {
t.Errorf("validateCauselyUrlInput() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("validateCauselyUrlInput() = %v, want %v", got, tt.want)
}
})
}
}
2 changes: 1 addition & 1 deletion common/config/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const (
var availableConfigers = []Configer{&Middleware{}, &Honeycomb{}, &GrafanaCloudPrometheus{}, &GrafanaCloudTempo{}, &GrafanaCloudLoki{}, &Datadog{}, &NewRelic{}, &Logzio{}, &Prometheus{},
&Tempo{}, &Loki{}, &Jaeger{}, &GenericOTLP{}, &OTLPHttp{}, &Elasticsearch{}, &Quickwit{}, &Signoz{}, &Qryn{},
&OpsVerse{}, &Splunk{}, &Lightstep{}, &GoogleCloud{}, &GoogleCloudStorage{}, &Sentry{}, &AzureBlobStorage{},
&AWSS3{}, &Dynatrace{}, &Chronosphere{}, &ElasticAPM{}, &Axiom{}, &SumoLogic{}, &Coralogix{}}
&AWSS3{}, &Dynatrace{}, &Chronosphere{}, &ElasticAPM{}, &Axiom{}, &SumoLogic{}, &Coralogix{}, &Causely{}}

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 @@ -35,4 +35,5 @@ const (
AxiomDestinationType DestinationType = "axiom"
SumoLogicDestinationType DestinationType = "sumologic"
CoralogixDestinationType DestinationType = "coralogix"
CauselyDestinationType DestinationType = "causely"
)
20 changes: 20 additions & 0 deletions destinations/data/causely.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: internal.odigos.io/v1beta1
kind: Destination
metadata:
type: causely
displayName: Causely
category: managed
spec:
image: causely.svg
signals:
traces:
supported: true
metrics:
supported: true
fields:
- name: CAUSELY_URL
displayName: Endpoint
componentType: input
componentProps:
type: text
required: true
81 changes: 81 additions & 0 deletions destinations/logos/causely.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions docs/backends/causely.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: "Causely"
---

## Configuring the Causely Backend

To complete adding a new Causely backend, input the following information into the Odigos UI

### Causely Destination Settings

To send Metrics/Traces to Causely, you need to configure the Causely URL in the Odigos UI.
This destination is for the Causely Mediator Service, so you will need to have a Causely instance running and accessible from the k8s cluster running odigos.

#### Endpoint

The endpoint URL is the combined `<protocol>://<hostname>:<port>` to access your Causely Mediator service.

- Protocol should be `http`; using `https` or omitting it will automatically be converted to `http`
- Hostname should typically follow the format: `mediator.<namespace>`
- `namespace` is the k8s namespace where the Causely Mediator service is deployed
- Default port is `4317`; if no port is specified, it will be appended automatically

Example: `http://mediator.causely:4317`
3 changes: 2 additions & 1 deletion docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@
"backends/signoz",
"backends/splunk",
"backends/sumologic",
"backends/tempo"
"backends/tempo",
"backends/causely"
]
},
{
Expand Down
1 change: 1 addition & 0 deletions docs/quickstart/next-steps.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ Select the relevant backend for your use case below to connect it to Odigos.
<Card title="SigNoz" href="/backends/signoz" />
<Card title="Splunk" href="/backends/splunk" />
<Card title="Tempo" href="/backends/tempo" />
<Card title="Causely" href="/backends/causely" />
</CardGroup>

0 comments on commit 798ea80

Please sign in to comment.