Skip to content

Commit

Permalink
fix: make trace name configurable (#1896)
Browse files Browse the repository at this point in the history
[MASTRA-1822](https://linear.app/kepler-crm/issue/MASTRA-1822/fix-langfuse-exporter-not-functioning),
make trace name configurable to fix langfuse exporter. Langfuse client
is expecting trace name "ai", all other trace names are dropped.

in langfuse dashboard:

![image](https://github.com/user-attachments/assets/861f7bbe-1382-46dd-9a69-789ca6f1626e)
  • Loading branch information
YujohnNattrass authored Feb 13, 2025
1 parent bc1d50e commit 5ee67d3
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 125 deletions.
5 changes: 5 additions & 0 deletions .changeset/spicy-dolphins-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mastra/core': patch
---

make trace name configurable for telemetry exporter
4 changes: 4 additions & 0 deletions docs/public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7797,6 +7797,8 @@ LANGFUSE_SECRET_KEY=your_secret_key
LANGFUSE_BASEURL=https://cloud.langfuse.com # Optional - defaults to cloud.langfuse.com
```

**Important**: When configuring the telemetry export settings, the `traceName` parameter must be set to `"ai"` for the Langfuse integration to work properly.

## Implementation

Here's how to configure Mastra to use Langfuse:
Expand All @@ -7813,6 +7815,8 @@ export const mastra = new Mastra({
export: {
type: "custom",
exporter: new LangfuseExporter({
type: "custom",
traceName: "ai",
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
secretKey: process.env.LANGFUSE_SECRET_KEY,
baseUrl: process.env.LANGFUSE_BASEURL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ LANGFUSE_SECRET_KEY=your_secret_key
LANGFUSE_BASEURL=https://cloud.langfuse.com # Optional - defaults to cloud.langfuse.com
```

**Important**: When configuring the telemetry export settings, the `traceName` parameter must be set to `"ai"` for the Langfuse integration to work properly.

## Implementation

Here's how to configure Mastra to use Langfuse:
Expand All @@ -32,6 +34,7 @@ export const mastra = new Mastra({
enabled: true,
export: {
type: "custom",
traceName: "ai",
exporter: new LangfuseExporter({
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
secretKey: process.env.LANGFUSE_SECRET_KEY,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/mastra/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class Mastra<
Telemetry
*/
// if storage is a libsql instance, we need to default the telemetry exporter to OTLPStorageExporter
if (storage instanceof DefaultStorage) {
if (storage instanceof DefaultStorage && config?.telemetry?.export?.type !== 'custom') {
const newTelemetry = {
...(config?.telemetry || {}),
export: {
Expand Down
13 changes: 10 additions & 3 deletions packages/core/src/telemetry/telemetry.decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { trace, context, SpanStatusCode, SpanKind, propagation } from '@opentele
import { hasActiveTelemetry } from './utility';

// Decorator factory that takes optional spanName
export function withSpan(options: { spanName?: string; skipIfNoTelemetry?: boolean; spanKind?: SpanKind }): any {
export function withSpan(options: {
spanName?: string;
skipIfNoTelemetry?: boolean;
spanKind?: SpanKind;
tracerName?: string;
}): any {
return function (_target: any, propertyKey: string | symbol, descriptor?: PropertyDescriptor | number) {
if (!descriptor || typeof descriptor === 'number') return;

Expand All @@ -12,11 +17,11 @@ export function withSpan(options: { spanName?: string; skipIfNoTelemetry?: boole

descriptor.value = function (...args: any[]) {
// Skip if no telemetry is available and skipIfNoTelemetry is true
if (options?.skipIfNoTelemetry && !hasActiveTelemetry()) {
if (options?.skipIfNoTelemetry && !hasActiveTelemetry(options?.tracerName)) {
return originalMethod.apply(this, args);
}

const tracer = trace.getTracer('default-tracer');
const tracer = trace.getTracer(options?.tracerName ?? 'default-tracer');

// Determine span name and kind
let spanName: string;
Expand Down Expand Up @@ -113,6 +118,7 @@ export function InstrumentClass(options?: {
spanKind?: SpanKind;
excludeMethods?: string[];
methodFilter?: (methodName: string) => boolean;
tracerName?: string;
}) {
return function (target: any) {
const methods = Object.getOwnPropertyNames(target.prototype);
Expand All @@ -132,6 +138,7 @@ export function InstrumentClass(options?: {
spanName: options?.prefix ? `${options.prefix}.${method}` : method,
skipIfNoTelemetry: true,
spanKind: options?.spanKind || SpanKind.INTERNAL,
tracerName: options?.tracerName,
})(target, method, descriptor),
);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/telemetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export type OtelConfig = {
/** Whether telemetry is enabled. Defaults to true */
enabled?: boolean;

/** Name of the tracer to use. Defaults to 'mastra-tracer' */
tracerName?: string;

/** Sampling configuration to control trace data volume */
sampling?: SamplingStrategy;

Expand All @@ -53,6 +56,7 @@ export type OtelConfig = {
}
| {
type: 'custom';
tracerName?: string;
exporter: SpanExporter;
};
};
4 changes: 2 additions & 2 deletions packages/core/src/telemetry/utility.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { trace } from '@opentelemetry/api';

// Helper function to check if telemetry is active
export function hasActiveTelemetry(): boolean {
export function hasActiveTelemetry(tracerName: string = 'default-tracer'): boolean {
try {
return !!trace.getTracer('default-tracer');
return !!trace.getTracer(tracerName);
} catch {
return false;
}
Expand Down
Loading

0 comments on commit 5ee67d3

Please sign in to comment.