Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
BenElferink committed Dec 4, 2024
2 parents 880204f + aacf22e commit 167b9ee
Show file tree
Hide file tree
Showing 32 changed files with 331 additions and 293 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ For more details, see our [quickstart guide](https://docs.odigos.io/intro).

| Destination | Traces | Metrics | Logs |
|-------------------------|:------:|:-------:|:----:|
| AppDynamics || | |
| AppDynamics || | |
| Axiom || ||
| AWS S3 || ||
| Azure Blob Storage || ||
Expand Down
4 changes: 2 additions & 2 deletions destinations/data/appdynamics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ spec:
traces:
supported: true
metrics:
supported: false
supported: true
logs:
supported: false
supported: true
fields:
- name: APPDYNAMICS_APPLICATION_NAME
displayName: Application Name
Expand Down
2 changes: 1 addition & 1 deletion docs/backends-overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Odigos has destinations for many observability backends.

| Destination | Category | Traces | Metrics | Logs |
|-------------------------|------------------|:------:|:-------:|:----:|
| AppDynamics | Managed || | |
| AppDynamics | Managed || | |
| Axiom | Managed || ||
| AWS S3 | Managed || ||
| Azure Blob Storage | Managed || ||
Expand Down
2 changes: 2 additions & 0 deletions docs/backends/appdynamics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ spec:
name: appdynamics-secret
signals:
- TRACES
- METRICS
- LOGS
type: appdynamics

---
Expand Down
62 changes: 62 additions & 0 deletions docs/backends/axiom.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: 'Axiom'
---

## Configuring Axiom Backend

1. [Register](https://app.axiom.co/register)/[Login](https://app.axiom.co/login) to Axiom.
2. Navigate to the [Axiom Datasets](https://app.axiom.co/settings/datasets) page, create a dataset and copy it's name.
3. Navigate to the [Axiom API Tokens](https://app.axiom.co/settings/api-tokens) page, and generate a new API Token.

- **AXIOM_DATASET** - Axiom Dataset Name from above (step 2).
- **AXIOM_API_TOKEN** - Axiom API Token from above (step 3).

## 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**

- Use the [Odigos CLI](https://docs.odigos.io/cli/odigos_ui) to access the UI:

```bash
odigos ui
```


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: axiom-example
namespace: odigos-system
spec:
data:
AXIOM_DATASET: <Dataset>
destinationName: axiom
secretRef:
name: axiom-secret
signals:
- TRACES
- LOGS
type: axiom

---
apiVersion: v1
data:
AXIOM_API_TOKEN: <base64 Axiom API token>
kind: Secret
metadata:
name: axiom-secret
namespace: odigos-system
type: Opaque
```
1 change: 1 addition & 0 deletions docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
"pages": [
"backends/appdynamics",
"backends/s3",
"backends/axiom",
"backends/azureblob",
"backends/causely",
"backends/chronosphere",
Expand Down
58 changes: 0 additions & 58 deletions frontend/webapp/utils/functions/formatters.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export function cleanObjectEmptyStringsValues(obj: Record<string, any>): Record<string, any> {
const cleanArray = (arr: any[]): any[] =>
arr.filter((item) => {
if (typeof item === 'object' && item !== null) {
return item.key !== '' && item.value !== '';
}
return item !== '';
});

const cleanObject = (o: Record<string, any>): Record<string, any> =>
Object.fromEntries(
Object.entries(o)
.filter(([key, value]) => key !== '' && value !== '')
.map(([key, value]) => {
if (Array.isArray(value)) return [key, cleanArray(value)];
else if (typeof value === 'object' && value !== null) return [key, cleanObject(value)];
return [key, value];
}),
);

return Object.entries(obj).reduce((acc, [key, value]) => {
try {
const parsed = JSON.parse(value);
if (Array.isArray(parsed)) {
acc[key] = JSON.stringify(cleanArray(parsed));
} else if (typeof parsed === 'object' && parsed !== null) {
acc[key] = JSON.stringify(cleanObject(parsed));
} else {
acc[key] = value;
}
} catch (error) {
// Handle non-stringified objects or arrays directly
if (typeof value === 'object' && value !== null) {
if (Array.isArray(value)) acc[key] = JSON.stringify(cleanArray(value));
else acc[key] = JSON.stringify(cleanObject(value));
} else {
// In case JSON.parse fails, assume value is a plain string or non-object/array
acc[key] = value;
}
}
return acc;
}, {} as Record<string, any>);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { ExportedSignals } from '@/types';

export const extractMonitors = (exportedSignals: ExportedSignals) => {
const filtered = Object.keys(exportedSignals).filter((signal) => exportedSignals[signal] === true);

return filtered;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const formatBytes = (bytes?: number) => {
if (!bytes) return '0 KB/s';

const sizes = ['Bytes/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s'];
const i = Math.floor(Math.log(bytes) / Math.log(1024));
const value = bytes / Math.pow(1024, i);

return `${value.toFixed(i === 0 ? 0 : 1)} ${sizes[i]}`;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { OVERVIEW_ENTITY_TYPES, type WorkloadId } from '@/types';

export const getIdFromSseTarget = (target: string, type: OVERVIEW_ENTITY_TYPES) => {
switch (type) {
case OVERVIEW_ENTITY_TYPES.SOURCE: {
const id: WorkloadId = {
namespace: '',
name: '',
kind: '',
};

target.split('&').forEach((str) => {
const [key, value] = str.split('=');
id[key] = value;
});

return id;
}

default:
return target as string;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { OVERVIEW_ENTITY_TYPES, type WorkloadId } from '@/types';

export const getSseTargetFromId = (id: string | WorkloadId, type: OVERVIEW_ENTITY_TYPES) => {
switch (type) {
case OVERVIEW_ENTITY_TYPES.SOURCE: {
let target = '';

Object.entries(id as WorkloadId).forEach(([key, value]) => {
target += `${key}=${value}&`;
});

target.slice(0, -1);

return target;
}

default:
return id as string;
}
};
8 changes: 8 additions & 0 deletions frontend/webapp/utils/functions/formatters/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export * from './clean-object-empty-strings-values';
export * from './extract-monitors';
export * from './format-bytes';
export * from './get-id-from-sse-target';
export * from './get-sse-target-from-id';
export * from './parse-json-string-to-pretty-string';
export * from './safe-json-parse';
export * from './stringify-non-string-values';
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export const parseJsonStringToPrettyString = (value: string) => {
let str = '';

try {
const parsed = JSON.parse(value);

// Handle arrays
if (Array.isArray(parsed)) {
str = parsed
.map((item) => {
if (typeof item === 'object' && item !== null) return `${item.key}: ${item.value}`;
else return item;
})
.join(', ');
}

// Handle objects (non-array JSON objects)
else if (typeof parsed === 'object' && parsed !== null) {
str = Object.entries(parsed)
.map(([key, val]) => `${key}: ${val}`)
.join(', ');
}

// Should never reach this if it's a string (it will throw)
else {
str = value;
}
} catch (error) {
str = value;
}

return str;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export function safeJsonParse<T>(str: string | undefined, fallback: T): T {
if (!str) return fallback;
try {
const parsed = JSON.parse(str) as T;
return parsed;
} catch (e) {
console.error('Error parsing JSON string:', e);
return fallback;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function stringifyNonStringValues(obj: Record<string, any>): Record<string, string> {
return Object.entries(obj).reduce((acc, [key, value]) => {
// Check if the value is already a string
if (typeof value === 'string') {
acc[key] = value;
} else {
// If not, stringify the value
acc[key] = JSON.stringify(value);
}
return acc;
}, {} as Record<string, string>);
}
Loading

0 comments on commit 167b9ee

Please sign in to comment.