-
Notifications
You must be signed in to change notification settings - Fork 119
logging #3007
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
logging #3007
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -546,6 +546,10 @@ export async function dispatchExecution(params: { | |
| // Wrap agent execution in a single promise protected by waitUntil | ||
| // The trigger.message_received span is created inside executeAgentAsync | ||
| const dispatchedAt = Date.now(); | ||
| logger.info( | ||
| { tenantId, projectId, agentId, triggerId, invocationId, conversationId, dispatchedAt }, | ||
| 'Trigger execution dispatched and starting execution' | ||
| ); | ||
|
Comment on lines
+549
to
+552
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Low: Duplicate of the log 5 lines above. Line 541–543 already logs |
||
| const executionPromise = executeAgentAsync({ | ||
| tenantId, | ||
| projectId, | ||
|
|
@@ -653,7 +657,10 @@ export async function executeAgentAsync( | |
| forwardedHeaders, | ||
| invocationType = 'trigger', | ||
| } = params; | ||
|
|
||
| logger.info( | ||
| { tenantId, projectId, agentId, triggerId, invocationId }, | ||
| 'executeAgentAsync: starting' | ||
|
Comment on lines
+660
to
+662
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Low: Redundant entry-point log. |
||
| ); | ||
| let userMessage: string; | ||
| let messageParts: Part[]; | ||
|
|
||
|
|
@@ -695,14 +702,16 @@ export async function executeAgentAsync( | |
| } | ||
|
|
||
| // Load project FIRST to get agent name | ||
| const loadProjectStart = Date.now(); | ||
| const project = await withRef(manageDbPool, resolvedRef, async (db) => { | ||
| return await getFullProjectWithRelationIds(db)({ | ||
| scopes: { tenantId, projectId }, | ||
| }); | ||
| }); | ||
| const loadProjectMs = Date.now() - loadProjectStart; | ||
|
|
||
| logger.info( | ||
| { tenantId, projectId, agentId, triggerId, invocationId, hasProject: !!project }, | ||
| { tenantId, projectId, agentId, triggerId, invocationId, hasProject: !!project, loadProjectMs }, | ||
| 'executeAgentAsync: project loaded' | ||
| ); | ||
|
|
||
|
|
@@ -884,6 +893,7 @@ export async function executeAgentAsync( | |
|
|
||
| try { | ||
| // Create conversation and set active agent | ||
| const convStart = Date.now(); | ||
| await createOrGetConversation(runDbClient)({ | ||
| id: conversationId, | ||
| tenantId, | ||
|
|
@@ -900,6 +910,12 @@ export async function executeAgentAsync( | |
| agentId, | ||
| ref: resolvedRef, | ||
| }); | ||
| const convMs = Date.now() - convStart; | ||
|
|
||
| logger.info( | ||
| { invocationId, conversationId, convMs }, | ||
| 'executeAgentAsync: conversation created' | ||
| ); | ||
|
|
||
| if (messages && messages.length > 0) { | ||
| for (const msg of messages) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -70,7 +70,12 @@ export const branchScopedDbMiddleware = async (c: Context, next: Next) => { | |||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Get a dedicated connection from the pool | ||||||||||||||||||||||||||||||||||
| const mwStartTime = Date.now(); | ||||||||||||||||||||||||||||||||||
| const connection: PoolClient = await pool.connect(); | ||||||||||||||||||||||||||||||||||
| const connectMs = Date.now() - mwStartTime; | ||||||||||||||||||||||||||||||||||
| if (connectMs > 5_000) { | ||||||||||||||||||||||||||||||||||
| logger.info({ ref: resolvedRef.name, connectMs }, 'Slow pool.connect in branchScopedDb'); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| let tempBranch: string | null = null; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||
|
|
@@ -79,7 +84,12 @@ export const branchScopedDbMiddleware = async (c: Context, next: Next) => { | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (resolvedRef.type === 'branch') { | ||||||||||||||||||||||||||||||||||
| logger.debug({ branch: resolvedRef.name }, 'Checking out branch'); | ||||||||||||||||||||||||||||||||||
| const checkoutStart = Date.now(); | ||||||||||||||||||||||||||||||||||
| await checkoutBranch(requestDb)({ branchName: resolvedRef.name, autoCommitPending: true }); | ||||||||||||||||||||||||||||||||||
| const checkoutMs = Date.now() - checkoutStart; | ||||||||||||||||||||||||||||||||||
| if (checkoutMs > 5_000) { | ||||||||||||||||||||||||||||||||||
| logger.info({ ref: resolvedRef.name, checkoutMs }, 'Slow checkoutBranch in branchScopedDb'); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||
| // For tags/commits, create temporary branch (needed for reads) | ||||||||||||||||||||||||||||||||||
| tempBranch = `temp_${resolvedRef.type}_${resolvedRef.hash}_${generateId()}`; | ||||||||||||||||||||||||||||||||||
|
|
@@ -139,15 +149,31 @@ export const branchScopedDbMiddleware = async (c: Context, next: Next) => { | |||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } finally { | ||||||||||||||||||||||||||||||||||
| // Always cleanup: checkout main and release connection | ||||||||||||||||||||||||||||||||||
| const cleanupStart = Date.now(); | ||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||
| await connection.query(`SELECT DOLT_CHECKOUT('main')`); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if (tempBranch) { | ||||||||||||||||||||||||||||||||||
| await connection.query(`SELECT DOLT_BRANCH('-D', $1)`, [tempBranch]); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } catch (cleanupError) { | ||||||||||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| ref: resolvedRef.name, | ||||||||||||||||||||||||||||||||||
| cleanupMs: Date.now() - cleanupStart, | ||||||||||||||||||||||||||||||||||
| error: cleanupError instanceof Error ? cleanupError.message : String(cleanupError), | ||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||
| 'branchScopedDb cleanup failed' | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+160
to
+167
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Medium: Same duplicate-log pattern as
Suggested change
|
||||||||||||||||||||||||||||||||||
| logger.error({ error: cleanupError }, 'Error during connection cleanup'); | ||||||||||||||||||||||||||||||||||
| } finally { | ||||||||||||||||||||||||||||||||||
| const totalMs = Date.now() - mwStartTime; | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+165
to
+170
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Minor: Same duplicate logging pattern as ref-scope.ts Issue: Lines 166-169 log at INFO, then line 170 logs the same error at ERROR level. Fix: Keep only the ERROR log, include
Suggested change
|
||||||||||||||||||||||||||||||||||
| if (totalMs > 5_000) { | ||||||||||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||||||||||
| { ref: resolvedRef.name, totalMs, connectMs }, | ||||||||||||||||||||||||||||||||||
| 'Slow branchScopedDb middleware total duration' | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| connection.release(); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -229,8 +229,20 @@ async function resolveProjectRef( | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| let refResult: Awaited<ReturnType<ReturnType<typeof resolveRef>>> = null; | ||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||
| const resolveStart = Date.now(); | ||||||||||||||||||||||||||
| refResult = await resolveRef(db)(projectMain); | ||||||||||||||||||||||||||
| const resolveMs = Date.now() - resolveStart; | ||||||||||||||||||||||||||
| if (resolveMs > 5_000) { | ||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||
| { projectMain, resolveMs, found: !!refResult }, | ||||||||||||||||||||||||||
| 'Slow resolveRef in ref middleware' | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||
| { projectMain, error: error instanceof Error ? error.message : String(error) }, | ||||||||||||||||||||||||||
| 'resolveRef threw in ref middleware' | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| logger.warn({ error, projectMain }, 'Failed to resolve project main branch'); | ||||||||||||||||||||||||||
|
Comment on lines
+242
to
246
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Medium: Duplicate log — this
Suggested change
|
||||||||||||||||||||||||||
| refResult = null; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
241
to
248
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 MAJOR: Duplicate logging — error logged at both INFO and WARN levels Issue: Lines 242-245 log at INFO level, then line 246 logs the same error at WARN level. This creates redundant log entries for the same event. Why: The established codebase pattern (per api-logging-guidelines) is to use WARN for recoverable issues, not to double-log at multiple levels. This adds noise and makes log analysis harder. Fix: Remove the INFO log and keep only the WARN log:
Suggested change
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -25,6 +25,8 @@ export const getTenantScopedRef = (tenantId: string, ref: string): string => { | |||||||||||||||||
| export const resolveRef = | ||||||||||||||||||
| (db: AgentsManageDatabaseClient) => | ||||||||||||||||||
| async (ref: string): Promise<ResolvedRef | null> => { | ||||||||||||||||||
| const startTime = Date.now(); | ||||||||||||||||||
|
|
||||||||||||||||||
| if (isValidCommitHash(ref)) { | ||||||||||||||||||
| return { | ||||||||||||||||||
| type: 'commit', | ||||||||||||||||||
|
|
@@ -43,8 +45,25 @@ export const resolveRef = | |||||||||||||||||
| }; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| const branchQueryStart = Date.now(); | ||||||||||||||||||
| const branches = await doltListBranches(db)(); | ||||||||||||||||||
| const branchQueryMs = Date.now() - branchQueryStart; | ||||||||||||||||||
| const branch = branches.find((b) => b.name === ref); | ||||||||||||||||||
|
|
||||||||||||||||||
| if (!branch) { | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 MAJOR: Unconditional INFO log on expected code path creates noise Issue: Why: Per api-logging-guidelines, INFO is for "important business events, NOT routine operations". Branch-not-found is a normal return path — the caller handles Fix: Downgrade to DEBUG level, or let the caller log at INFO when resolution ultimately fails:
Suggested change
|
||||||||||||||||||
| const totalMs = Date.now() - startTime; | ||||||||||||||||||
| logger.info( | ||||||||||||||||||
| { | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 CRITICAL: Logging all branch names exposes tenant/project identifiers Issue: Branch names follow the pattern Why: This creates:
Fix: Remove
Suggested change
Refs: |
||||||||||||||||||
| ref, | ||||||||||||||||||
| branchCount: branches.length, | ||||||||||||||||||
| branchQueryMs, | ||||||||||||||||||
| totalMs, | ||||||||||||||||||
| branchNames: branches.map((b) => b.name), | ||||||||||||||||||
| }, | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. High: Drop
Suggested change
|
||||||||||||||||||
| 'resolveRef: branch not found in dolt_branches result' | ||||||||||||||||||
| ); | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+53
to
+65
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Medium: Log level should be |
||||||||||||||||||
|
|
||||||||||||||||||
| if (branch) { | ||||||||||||||||||
| return { | ||||||||||||||||||
| type: 'branch', | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -147,15 +147,29 @@ export async function withRef<T>( | |||||||||||||||||||||||||||||
| 'Acquiring connection for ref scope' | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const connectStart = Date.now(); | ||||||||||||||||||||||||||||||
| const connection: PoolClient = await pool.connect(); | ||||||||||||||||||||||||||||||
| const connectMs = Date.now() - connectStart; | ||||||||||||||||||||||||||||||
| if (connectMs > 5_000) { | ||||||||||||||||||||||||||||||
| logger.info({ ref: resolvedRef.name, connectMs, connectionId }, 'Slow pool.connect in withRef'); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| let tempBranch: string | null = null; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||
| const db = drizzle(connection, { schema }) as unknown as AgentsManageDatabaseClient; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (resolvedRef.type === 'branch') { | ||||||||||||||||||||||||||||||
| logger.debug({ branch: resolvedRef.name, connectionId }, 'Checking out branch'); | ||||||||||||||||||||||||||||||
| const checkoutStart = Date.now(); | ||||||||||||||||||||||||||||||
| await checkoutBranch(db)({ branchName: resolvedRef.name, syncSchema: false }); | ||||||||||||||||||||||||||||||
| const checkoutMs = Date.now() - checkoutStart; | ||||||||||||||||||||||||||||||
| if (checkoutMs > 5_000) { | ||||||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||||||
| { ref: resolvedRef.name, checkoutMs, connectionId }, | ||||||||||||||||||||||||||||||
| 'Slow checkoutBranch in withRef' | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||
| // For tags/commits, create temporary branch from the hash | ||||||||||||||||||||||||||||||
| // Include timestamp for easier cleanup of orphaned branches | ||||||||||||||||||||||||||||||
|
|
@@ -237,6 +251,7 @@ export async function withRef<T>( | |||||||||||||||||||||||||||||
| throw error; | ||||||||||||||||||||||||||||||
| } finally { | ||||||||||||||||||||||||||||||
| // Cleanup: checkout main, delete temp branch, release connection | ||||||||||||||||||||||||||||||
| const cleanupStart = Date.now(); | ||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||
| await connection.query(`SELECT DOLT_CHECKOUT('main')`); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -245,14 +260,30 @@ export async function withRef<T>( | |||||||||||||||||||||||||||||
| await connection.query(`SELECT DOLT_BRANCH('-D', $1)`, [tempBranch]); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } catch (cleanupError) { | ||||||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| ref: resolvedRef.name, | ||||||||||||||||||||||||||||||
| connectionId, | ||||||||||||||||||||||||||||||
| cleanupMs: Date.now() - cleanupStart, | ||||||||||||||||||||||||||||||
| error: cleanupError instanceof Error ? cleanupError.message : String(cleanupError), | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| 'withRef cleanup failed' | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
|
Comment on lines
+263
to
+271
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Medium: Duplicate log — same cleanup failure is logged twice. This new
Suggested change
|
||||||||||||||||||||||||||||||
| logger.error( | ||||||||||||||||||||||||||||||
| { error: cleanupError, tempBranch, connectionId }, | ||||||||||||||||||||||||||||||
|
Comment on lines
+265
to
273
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Minor: Duplicate logging — cleanup failure logged at both INFO and ERROR levels Issue: Lines 266-269 log at INFO level, then lines 270-273 log the same error at ERROR level. The same pattern appears in Why: Cleanup failures are unexpected errors warranting ERROR level, not INFO. Double-logging the same event at different levels creates noise. Fix: Keep only the ERROR log:
Suggested change
|
||||||||||||||||||||||||||||||
| 'Error during ref scope cleanup' | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } finally { | ||||||||||||||||||||||||||||||
| const totalMs = Date.now() - startTime; | ||||||||||||||||||||||||||||||
| if (totalMs > 5_000) { | ||||||||||||||||||||||||||||||
| logger.info( | ||||||||||||||||||||||||||||||
| { ref: resolvedRef.name, totalMs, connectMs, connectionId }, | ||||||||||||||||||||||||||||||
| 'Slow withRef total duration' | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| connection.release(); | ||||||||||||||||||||||||||||||
| logger.debug( | ||||||||||||||||||||||||||||||
| { ref: resolvedRef.name, duration: Date.now() - startTime, connectionId }, | ||||||||||||||||||||||||||||||
| { ref: resolvedRef.name, duration: totalMs, connectionId }, | ||||||||||||||||||||||||||||||
| 'Connection released' | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optionally, you can just always log the time in case 5 seconds doesn't capture what you are looking for