@genkit-ai/core
Version:
Genkit AI framework core libraries.
1 lines • 11.3 kB
Source Map (JSON)
{"version":3,"sources":["../../src/tracing/instrumentation.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Span as ApiSpan,\n Link,\n SpanStatusCode,\n trace,\n} from '@opentelemetry/api';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { performance } from 'node:perf_hooks';\nimport { PathMetadata, SpanMetadata, TraceMetadata } from './types.js';\n\nexport const spanMetadataAls = new AsyncLocalStorage<SpanMetadata>();\nexport const traceMetadataAls = new AsyncLocalStorage<TraceMetadata>();\n\nexport const ATTR_PREFIX = 'genkit';\nexport const SPAN_TYPE_ATTR = ATTR_PREFIX + ':type';\nconst TRACER_NAME = 'genkit-tracer';\nconst TRACER_VERSION = 'v1';\n\n/**\n *\n */\nexport async function newTrace<T>(\n opts: {\n name: string;\n labels?: Record<string, string>;\n links?: Link[];\n },\n fn: (metadata: SpanMetadata, rootSpan: ApiSpan) => Promise<T>\n) {\n // This is the root node only if we haven't previously started a trace.\n const isRoot = traceMetadataAls.getStore() ? false : true;\n const traceMetadata = traceMetadataAls.getStore() || {\n paths: new Set<PathMetadata>(),\n timestamp: performance.now(),\n };\n if (opts.labels && opts.labels[SPAN_TYPE_ATTR] === 'flow') {\n traceMetadata.flowName = opts.name;\n }\n return await traceMetadataAls.run(traceMetadata, () =>\n runInNewSpan(\n {\n metadata: {\n name: opts.name,\n isRoot,\n },\n labels: opts.labels,\n links: opts.links,\n },\n async (metadata, otSpan) => {\n return await fn(metadata, otSpan);\n }\n )\n );\n}\n\n/**\n *\n */\nexport async function runInNewSpan<T>(\n opts: {\n metadata: SpanMetadata;\n labels?: Record<string, string>;\n links?: Link[];\n },\n fn: (metadata: SpanMetadata, otSpan: ApiSpan, isRoot: boolean) => Promise<T>\n): Promise<T> {\n const tracer = trace.getTracer(TRACER_NAME, TRACER_VERSION);\n const parentStep = spanMetadataAls.getStore();\n const isInRoot = parentStep?.isRoot === true;\n return await tracer.startActiveSpan(\n opts.metadata.name,\n { links: opts.links, root: opts.metadata.isRoot },\n async (otSpan) => {\n if (opts.labels) otSpan.setAttributes(opts.labels);\n try {\n opts.metadata.path = buildPath(\n opts.metadata.name,\n parentStep?.path || '',\n opts.labels\n );\n\n const output = await spanMetadataAls.run(opts.metadata, () =>\n fn(opts.metadata, otSpan, isInRoot)\n );\n if (opts.metadata.state !== 'error') {\n opts.metadata.state = 'success';\n }\n\n recordPath(opts.metadata);\n return output;\n } catch (e) {\n recordPath(opts.metadata, e);\n opts.metadata.state = 'error';\n otSpan.setStatus({\n code: SpanStatusCode.ERROR,\n message: getErrorMessage(e),\n });\n if (e instanceof Error) {\n otSpan.recordException(e);\n }\n throw e;\n } finally {\n otSpan.setAttributes(metadataToAttributes(opts.metadata));\n otSpan.end();\n }\n }\n );\n}\n\nfunction getErrorMessage(e: any): string {\n if (e instanceof Error) {\n return e.message;\n }\n return `${e}`;\n}\n\nfunction metadataToAttributes(metadata: SpanMetadata): Record<string, string> {\n const out = {} as Record<string, string>;\n Object.keys(metadata).forEach((key) => {\n if (\n key === 'metadata' &&\n typeof metadata[key] === 'object' &&\n metadata.metadata\n ) {\n Object.entries(metadata.metadata).forEach(([metaKey, value]) => {\n out[ATTR_PREFIX + ':metadata:' + metaKey] = value;\n });\n } else if (key === 'input' || typeof metadata[key] === 'object') {\n out[ATTR_PREFIX + ':' + key] = JSON.stringify(metadata[key]);\n } else {\n out[ATTR_PREFIX + ':' + key] = metadata[key];\n }\n });\n return out;\n}\n\n/**\n * Sets provided attribute value in the current span.\n */\nexport function setCustomMetadataAttribute(key: string, value: string) {\n const currentStep = getCurrentSpan();\n if (!currentStep) {\n return;\n }\n if (!currentStep.metadata) {\n currentStep.metadata = {};\n }\n currentStep.metadata[key] = value;\n}\n\n/**\n * Sets provided attribute values in the current span.\n */\nexport function setCustomMetadataAttributes(values: Record<string, string>) {\n const currentStep = getCurrentSpan();\n if (!currentStep) {\n return;\n }\n if (!currentStep.metadata) {\n currentStep.metadata = {};\n }\n for (const [key, value] of Object.entries(values)) {\n currentStep.metadata[key] = value;\n }\n}\n\n/** Converts a fully annotated path to a friendly display version for logs */\nexport function toDisplayPath(path: string): string {\n const pathPartRegex = /\\{([^\\,}]+),[^\\}]+\\}/g;\n return Array.from(path.matchAll(pathPartRegex), (m) => m[1]).join(' > ');\n}\n\nfunction getCurrentSpan(): SpanMetadata {\n const step = spanMetadataAls.getStore();\n if (!step) {\n throw new Error('running outside step context');\n }\n return step;\n}\n\nfunction buildPath(\n name: string,\n parentPath: string,\n labels?: Record<string, string>\n) {\n const stepType =\n labels && labels['genkit:type'] ? `,t:${labels['genkit:type']}` : '';\n return parentPath + `/{${name}${stepType}}`;\n}\n\nfunction recordPath(spanMeta: SpanMetadata, err?: any) {\n const path = spanMeta.path || '';\n const decoratedPath = decoratePathWithSubtype(spanMeta);\n // Only add the path if a child has not already been added. In the event that\n // an error is rethrown, we don't want to add each step in the unwind.\n const paths = Array.from(\n traceMetadataAls.getStore()?.paths || new Set<PathMetadata>()\n );\n const status = err ? 'failure' : 'success';\n if (!paths.some((p) => p.path.startsWith(path) && p.status === status)) {\n const now = performance.now();\n const start = traceMetadataAls.getStore()?.timestamp || now;\n traceMetadataAls.getStore()?.paths?.add({\n path: decoratedPath,\n error: err?.name,\n latency: now - start,\n status,\n });\n }\n spanMeta.path = decoratedPath;\n}\n\nfunction decoratePathWithSubtype(metadata: SpanMetadata): string {\n if (!metadata.path) {\n return '';\n }\n\n const pathComponents = metadata.path.split('}/{');\n\n if (pathComponents.length == 1) {\n return metadata.path;\n }\n\n const stepSubtype =\n metadata.metadata && metadata.metadata['subtype']\n ? `,s:${metadata.metadata['subtype']}`\n : '';\n const root = `${pathComponents.slice(0, -1).join('}/{')}}/`;\n const decoratedStep = `{${pathComponents.at(-1)?.slice(0, -1)}${stepSubtype}}`;\n return root + decoratedStep;\n}\n"],"mappings":"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","names":[]}