Skip to content

Commit

Permalink
fix(js): Marking root spans that have failed (#1615)
Browse files Browse the repository at this point in the history
  • Loading branch information
maxl0rd authored Jan 17, 2025
1 parent 3c31306 commit 3825822
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
22 changes: 20 additions & 2 deletions js/plugins/google-cloud/src/gcpOpenTelemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,26 @@ class AdjustingTraceExporter implements SpanExporter {
)
);

// Check if we have a failure in the root span that requires special handling
const rootSpan = spans.find((s) =>
Object.keys(s.attributes).includes('genkit:isRoot')
);
if (rootSpan) {
const rootSpanFailed =
(rootSpan.attributes['genkit:state'] as string) === 'error';
const anotherFailedSpan = spans.find(
(s) =>
!Object.keys(s.attributes).includes('genkit:isRoot') &&
s.attributes['genkit:state'] === 'error'
);
if (rootSpanFailed && !anotherFailedSpan) {
rootSpan.attributes['genkit:failedSpan'] =
rootSpan.attributes['genkit:name'];
rootSpan.attributes['genkit:failedPath'] =
rootSpan.attributes['genkit:path'];
}
}

return spans.map((span) => {
this.tickTelemetry(span, allLeafPaths);

Expand Down Expand Up @@ -389,8 +409,6 @@ class AdjustingTraceExporter implements SpanExporter {
};
}

// This is a workaround for GCP Trace to mark a span with a red
// exclamation mark indicating that it is an error.
private normalizeLabels(span: ReadableSpan): ReadableSpan {
const normalized = {} as Record<string, any>;
for (const [key, value] of Object.entries(span.attributes)) {
Expand Down
21 changes: 21 additions & 0 deletions js/plugins/google-cloud/tests/traces_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,27 @@ describe('GoogleCloudTracing', () => {
assert.equal(spans[1].attributes['genkit/rootState'], 'success');
});

it('marks the root feature failed when it is the failure', async () => {
const testFlow = createFlow(ai, 'failingFlow', async () => {
await ai.run('good step', async () => {});
throw new Error('oops!');
});
try {
await testFlow();
} catch (e) {}

const spans = await getExportedSpans();
assert.equal(spans.length, 2);
assert.equal(spans[1].name, 'failingFlow');
assert.equal(spans[1].attributes['genkit/failedSpan'], 'failingFlow');
assert.equal(
spans[1].attributes['genkit/failedPath'],
'/{failingFlow,t:flow}'
);
assert.equal(spans[1].attributes['genkit/isRoot'], true);
assert.equal(spans[1].attributes['genkit/rootState'], 'error');
});

it('adds the genkit/model label for model actions', async () => {
const echoModel = ai.defineModel(
{
Expand Down

0 comments on commit 3825822

Please sign in to comment.