Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add instrumentation feature flag #62

Merged
merged 3 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ USE_CHARACTER_STORAGE=false
# Logging
DEFAULT_LOG_LEVEL=warn
LOG_JSON_FORMAT=false # Print everything in logger as json; false by default
INSTRUMENTATION_ENABLED=false # Requires to define POSTGRES_URL

###############################
#### Client Configurations ####
Expand Down
53 changes: 34 additions & 19 deletions agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
type IDatabaseAdapter,
type IDatabaseCacheAdapter,
ModelProviderName,
type State,
defaultCharacter,
elizaLogger,
parseBooleanFromText,
Expand Down Expand Up @@ -52,7 +53,10 @@ import {
import Database from "better-sqlite3";
import yargs from "yargs";
import { z } from "zod";
import { getRuntimeInstrumentation } from "./runtime-instrumentation";
import {
type RuntimeInstrumentation,
getRuntimeInstrumentation,
} from "./runtime-instrumentation";

const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
const __dirname = path.dirname(__filename); // get the name of the directory
Expand Down Expand Up @@ -580,14 +584,17 @@ export async function createAgent(
fetch: logFetch,
});

// Set up automatic instrumentation for all agents
const runtimeInstrumentation = getRuntimeInstrumentation();
if (process.env.INSTRUMENTATION_ENABLED === "true") {
// Set up automatic instrumentation for all agents
const runtimeInstrumentation = getRuntimeInstrumentation();

// This will attach to evaluate and other methods to automatically instrument
runtimeInstrumentation.attachToRuntime(runtime);
elizaLogger.info(
`🔄 Instrumentation attached to runtime for agent ${runtime.agentId}`,
);
// This will attach to evaluate and other methods to automatically instrument
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
runtimeInstrumentation.attachToRuntime(runtime as any);
elizaLogger.info(
`🔄 Instrumentation attached to runtime for agent ${runtime.agentId}`,
);
}

return runtime;
}
Expand Down Expand Up @@ -664,11 +671,9 @@ async function startAgent(
};

// Call evaluate to trigger instrumentation
runtime
.evaluate(message, state as Record<string, unknown>)
.catch((err) => {
elizaLogger.error(`Error evaluating agent start: ${err.message}`);
});
runtime.evaluate(message, state as State).catch((err) => {
elizaLogger.error(`Error evaluating agent start: ${err.message}`);
});
} catch (error) {
elizaLogger.error(
`Error during agent start instrumentation: ${error.message}`,
Expand Down Expand Up @@ -750,9 +755,12 @@ const startAgents = async () => {
directClient.loadCharacterTryPath = loadCharacterTryPath;
directClient.jsonToCharacter = jsonToCharacter;

// Make sure Runtime Instrumentation is exposed to DirectClient
const runtimeInstrumentation = getRuntimeInstrumentation();
directClient.instrumentationAttached = false;
let runtimeInstrumentation: RuntimeInstrumentation;
if (process.env.INSTRUMENTATION_ENABLED === "true") {
// Make sure Runtime Instrumentation is exposed to DirectClient
runtimeInstrumentation = getRuntimeInstrumentation();
directClient.instrumentationAttached = false;
}

// Add a method to DirectClient to ensure instrumentation is set up properly
const originalRegisterAgent = directClient.registerAgent.bind(directClient);
Expand All @@ -761,14 +769,18 @@ const startAgents = async () => {
originalRegisterAgent(runtime);

// Ensure the runtime is instrumented
if (!directClient.instrumentationAttached) {
if (
process.env.INSTRUMENTATION_ENABLED === "true" &&
!directClient.instrumentationAttached
) {
try {
// Attach the instrumentation wrapper to all POST request handlers
// Apply to each route handler that processes messages
elizaLogger.info(
`🔌 Attaching instrumentation to DirectClient routes for agent ${runtime.agentId}`,
);
runtimeInstrumentation.attachToRuntime(runtime);
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
runtimeInstrumentation.attachToRuntime(runtime as any);
directClient.instrumentationAttached = true;
} catch (error) {
elizaLogger.error(
Expand Down Expand Up @@ -811,7 +823,10 @@ if (
}

// Initialize the runtime instrumentation at the module level
const runtimeInstrumentation = getRuntimeInstrumentation();
let runtimeInstrumentation: RuntimeInstrumentation;
if (process.env.INSTRUMENTATION_ENABLED === "true") {
runtimeInstrumentation = getRuntimeInstrumentation();
}

// Export the instrumentation for direct access if needed
export { runtimeInstrumentation };
8 changes: 7 additions & 1 deletion agent/src/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,10 @@ export class Instrumentation {
}
}

export const instrument = Instrumentation.getInstance();
let instrument: Instrumentation;

if (process.env.INSTRUMENTATION_ENABLED === "true") {
instrument = Instrumentation.getInstance();
}

export { instrument };
Loading