diff --git a/common/config/last9.go b/common/config/last9.go
new file mode 100644
index 000000000..938d4d4b4
--- /dev/null
+++ b/common/config/last9.go
@@ -0,0 +1,60 @@
+package config
+
+import (
+ "errors"
+
+ "github.com/odigos-io/odigos/common"
+)
+
+const (
+ l9OtlpEndpointKey = "LAST9_OTLP_ENDPOINT"
+ l9OtlpAuthHeaderKey = "LAST9_OTLP_BASIC_AUTH_HEADER"
+)
+
+type Last9 struct{}
+
+func (m *Last9) DestType() common.DestinationType {
+ // DestinationType defined in common/dests.go
+ return common.Last9DestinationType
+}
+
+func (m *Last9) ModifyConfig(dest ExporterConfigurer, currentConfig *Config) error {
+ config := dest.GetConfig()
+ l9OtlpEndpoint, exists := config[l9OtlpEndpointKey]
+ if !exists {
+ return errors.New("Last9 OpenTelemetry Endpoint key(\"LAST9_OTLP_ENDPOINT\") not specified, Last9 will not be configured")
+ }
+
+ // to make sure that the exporter name is unique, we'll ask a ID from destination
+ exporterName := "otlp/last9-" + dest.GetID()
+ currentConfig.Exporters[exporterName] = GenericMap{
+ "endpoint": l9OtlpEndpoint,
+ "headers": GenericMap{
+ "Authorization": "${LAST9_OTLP_BASIC_AUTH_HEADER}",
+ },
+ }
+
+ // Modify the config here
+ if isTracingEnabled(dest) {
+ tracesPipelineName := "traces/last9-" + dest.GetID()
+ currentConfig.Service.Pipelines[tracesPipelineName] = Pipeline{
+ Exporters: []string{exporterName},
+ }
+ }
+
+ if isMetricsEnabled(dest) {
+ metricsPipelineName := "metrics/last9-" + dest.GetID()
+ currentConfig.Service.Pipelines[metricsPipelineName] = Pipeline{
+ Exporters: []string{exporterName},
+ }
+ }
+
+ if isLoggingEnabled(dest) {
+ logsPipelineName := "logs/last9-" + dest.GetID()
+ currentConfig.Service.Pipelines[logsPipelineName] = Pipeline{
+ Exporters: []string{exporterName},
+ }
+ }
+
+ return nil
+}
diff --git a/common/config/root.go b/common/config/root.go
index b619cda4e..643cd55ec 100644
--- a/common/config/root.go
+++ b/common/config/root.go
@@ -16,7 +16,7 @@ const (
var availableConfigers = []Configer{
&Middleware{}, &Honeycomb{}, &GrafanaCloudPrometheus{}, &GrafanaCloudTempo{},
- &GrafanaCloudLoki{}, &Datadog{}, &NewRelic{}, &Logzio{}, &Prometheus{},
+ &GrafanaCloudLoki{}, &Datadog{}, &NewRelic{}, &Logzio{}, &Last9{}, &Prometheus{},
&Tempo{}, &Loki{}, &Jaeger{}, &GenericOTLP{}, &OTLPHttp{}, &Elasticsearch{}, &Quickwit{}, &Signoz{}, &Qryn{},
&OpsVerse{}, &Splunk{}, &Lightstep{}, &GoogleCloud{}, &GoogleCloudStorage{}, &Sentry{}, &AzureBlobStorage{},
&AWSS3{}, &Dynatrace{}, &Chronosphere{}, &ElasticAPM{}, &Axiom{}, &SumoLogic{}, &Coralogix{}, &Clickhouse{},
diff --git a/common/dests.go b/common/dests.go
index 014bc09de..5c2f1dad5 100644
--- a/common/dests.go
+++ b/common/dests.go
@@ -23,6 +23,7 @@ const (
GrafanaCloudTempoDestinationType DestinationType = "grafanacloudtempo"
HoneycombDestinationType DestinationType = "honeycomb"
JaegerDestinationType DestinationType = "jaeger"
+ Last9DestinationType DestinationType = "last9"
LightstepDestinationType DestinationType = "lightstep"
LogzioDestinationType DestinationType = "logzio"
LokiDestinationType DestinationType = "loki"
diff --git a/destinations/data/last9.yaml b/destinations/data/last9.yaml
new file mode 100644
index 000000000..a345a4b0c
--- /dev/null
+++ b/destinations/data/last9.yaml
@@ -0,0 +1,31 @@
+apiVersion: internal.odigos.io/v1beta1
+kind: Destination
+metadata:
+ type: last9
+ displayName: Last9
+ category: managed
+spec:
+ image: last9.svg
+ signals:
+ traces:
+ supported: true
+ metrics:
+ supported: true
+ logs:
+ supported: true
+ fields:
+ - name: LAST9_OTLP_ENDPOINT
+ displayName: Last9 OpenTelemetry Endpoint
+ componentType: input
+ componentProps:
+ type: text
+ required: true
+ tooltip: 'Last9 OpenTelemetry Endpoint. Can be found at https://app.last9.io/integrations?category=all&integration=OpenTelemetry'
+ - name: LAST9_OTLP_BASIC_AUTH_HEADER
+ displayName: Basic Auth Header
+ componentType: input
+ secret: true
+ componentProps:
+ type: password
+ required: true
+ placeholder: "Basic ..."
diff --git a/destinations/logos/last9.svg b/destinations/logos/last9.svg
new file mode 100644
index 000000000..fd6c2b639
--- /dev/null
+++ b/destinations/logos/last9.svg
@@ -0,0 +1 @@
+
diff --git a/docs/backends/last9.mdx b/docs/backends/last9.mdx
new file mode 100644
index 000000000..9f26d42a8
--- /dev/null
+++ b/docs/backends/last9.mdx
@@ -0,0 +1,72 @@
+---
+title: "Last9"
+---
+
+## Obtaining Last9 OpenTelemetry Endpoint and Basic Auth Header
+
+[Click here](https://app.last9.io/integrations?category=all&integration=OpenTelemetry) to visit the Last9 OpenTelemetry integration page.
+
+
+
+
+
+## Configuring Last9 Backend
+
+- **Endpoint** - Last9 OpenTelemetry Endpoint obtained in above step.
+- **Authorization Header**: Last9 OpenTelemetry Basic Auth Header obtained in above step.
+
+## Adding a Destination to Odigos
+
+Odigos makes it simple to add and configure destinations, allowing you to select the specific signals [traces/logs/metrics] that you want to send to each destination. There are two primary methods for configuring destinations in Odigos:
+
+1. **Using the UI**
+ To add a destination via the UI, follow these steps:
+ - Use the Odigos CLI to access the UI: [Odigos UI](https://docs.odigos.io/cli/odigos_ui)
+ ```bash
+ odigos ui
+ ```
+- In the left sidebar, navigate to the `Destination` page.
+
+- Click `Add New Destination`
+
+- Select `Last9` and follow the on-screen instructions.
+
+
+
+2. **Using kubernetes manifests**
+
+Save the YAML below to a file (e.g., `destination.yaml`) and apply it using `kubectl`:
+
+```bash
+kubectl apply -f destination.yaml
+```
+
+
+```yaml
+apiVersion: odigos.io/v1alpha1
+kind: Destination
+metadata:
+ name: last9-example
+ namespace: odigos-system
+spec:
+ data:
+ LAST9_OTLP_ENDPOINT:
+ destinationName: last9
+ secretRef:
+ name: last9-secret
+ signals:
+ - TRACES
+ - METRICS
+ - LOGS
+ type: last9
+
+---
+apiVersion: v1
+data:
+ LAST9_OTLP_BASIC_AUTH_HEADER:
+kind: Secret
+metadata:
+ name: last9-secret
+ namespace: odigos-system
+type: Opaque
+```
diff --git a/docs/images/last9.png b/docs/images/last9.png
new file mode 100644
index 000000000..000f04cf1
Binary files /dev/null and b/docs/images/last9.png differ
diff --git a/docs/mint.json b/docs/mint.json
index b00e7b5b3..32718b0c8 100644
--- a/docs/mint.json
+++ b/docs/mint.json
@@ -125,7 +125,7 @@
"instrumentations/java/java",
"instrumentations/java/ebpf"
]
- }
+ }
]
},
{
@@ -218,6 +218,7 @@
"backends/honeycomb",
"backends/jaeger",
"backends/lightstep",
+ "backends/last9",
"backends/logzio",
"backends/loki",
"backends/newrelic",