@genkit-ai/google-cloud
Version:
Genkit AI framework plugin for Google Cloud Platform including Firestore trace/state store and deployment helpers for Cloud Functions for Firebase.
167 lines • 4.77 kB
JavaScript
import { ValueType } from "@opentelemetry/api";
import { hrTimeDuration, hrTimeToMilliseconds } from "@opentelemetry/core";
import { GENKIT_VERSION } from "genkit";
import { logger } from "genkit/logging";
import { toDisplayPath } from "genkit/tracing";
import {
MetricCounter,
MetricHistogram,
internalMetricNamespaceWrap
} from "../metrics.js";
import {
createCommonLogAttributes,
extractErrorMessage,
extractErrorName,
extractErrorStack,
truncatePath
} from "../utils.js";
class PathsTelemetry {
/**
* Wraps the declared metrics in a Genkit-specific, internal namespace.
*/
_N = internalMetricNamespaceWrap.bind(null, "feature");
pathCounter = new MetricCounter(this._N("path/requests"), {
description: "Tracks unique flow paths per flow.",
valueType: ValueType.INT
});
pathLatencies = new MetricHistogram(this._N("path/latency"), {
description: "Latencies per flow path.",
ValueType: ValueType.DOUBLE,
unit: "ms"
});
tick(span, paths, logInputAndOutput, projectId) {
const attributes = span.attributes;
const name = attributes["genkit:name"];
const path = attributes["genkit:path"];
const sessionId = attributes["genkit:sessionId"];
const threadName = attributes["genkit:threadName"];
const latencyMs = hrTimeToMilliseconds(
hrTimeDuration(span.startTime, span.endTime)
);
const state = attributes["genkit:state"];
if (state === "success") {
this.writePathSuccess(
span,
paths,
name,
path,
latencyMs,
projectId,
sessionId,
threadName
);
return;
}
if (state === "error") {
const errorName = extractErrorName(span.events) || "<unknown>";
const errorMessage = extractErrorMessage(span.events) || "<unknown>";
const errorStack = extractErrorStack(span.events) || "";
this.writePathFailure(
span,
paths,
name,
path,
latencyMs,
errorName,
projectId,
sessionId,
threadName
);
this.recordError(
span,
path,
errorName,
errorMessage,
errorStack,
projectId,
sessionId,
threadName
);
return;
}
logger.warn(`Unknown state; ${state}`);
}
recordError(span, path, errorName, errorMessage, errorStack, projectId, sessionId, threadName) {
const displayPath = truncatePath(toDisplayPath(path));
logger.logStructuredError(`Error[${displayPath}, ${errorName}]`, {
...createCommonLogAttributes(span, projectId),
path: displayPath,
qualifiedPath: path,
name: errorName,
message: errorMessage,
stack: errorStack,
source: "ts",
sourceVersion: GENKIT_VERSION,
sessionId,
threadName
});
}
writePathSuccess(span, paths, featureName, path, latencyMs, projectId, sessionId, threadName) {
this.writePathMetrics(
span,
path,
paths,
featureName,
latencyMs,
void 0,
projectId,
sessionId,
threadName
);
}
writePathFailure(span, paths, featureName, path, latencyMs, errorName, projectId, sessionId, threadName) {
this.writePathMetrics(
span,
path,
paths,
featureName,
latencyMs,
errorName,
projectId,
sessionId,
threadName
);
}
/** Writes all path-level metrics stored in the current flow execution. */
writePathMetrics(span, rootPath, paths, featureName, latencyMs, err, projectId, sessionId, threadName) {
const flowPaths = Array.from(paths).filter(
(meta) => meta.path.includes(featureName)
);
if (flowPaths) {
logger.logStructured(`Paths[${featureName}]`, {
...createCommonLogAttributes(span, projectId),
flowName: featureName,
sessionId,
threadName,
paths: flowPaths.map((p) => truncatePath(toDisplayPath(p.path)))
});
flowPaths.forEach((p) => this.writePathMetric(featureName, p));
if (err && !flowPaths.some((p) => p.status === "failure")) {
this.writePathMetric(featureName, {
status: "failure",
path: rootPath,
error: err,
latency: latencyMs
});
}
}
}
/** Writes metrics for a single PathMetadata */
writePathMetric(featureName, meta) {
const pathDimensions = {
featureName,
status: meta.status,
error: meta.error,
path: meta.path,
source: "ts",
sourceVersion: GENKIT_VERSION
};
this.pathCounter.add(1, pathDimensions);
this.pathLatencies.record(meta.latency, pathDimensions);
}
}
const pathsTelemetry = new PathsTelemetry();
export {
pathsTelemetry
};
//# sourceMappingURL=path.mjs.map