Agent Debug: Add configurable max session log size setting for debug file logging (#4890)

* Add configurable max session log size setting for debug file logging

* update
This commit is contained in:
Vijay Upadya
2026-03-31 18:46:59 -07:00
committed by GitHub
parent adb8b86965
commit 021a997e60
4 changed files with 35 additions and 8 deletions

View File

@@ -4650,6 +4650,17 @@
"onExp"
]
},
"github.copilot.chat.agentDebugLog.fileLogging.maxSessionLogSizeMB": {
"type": "number",
"default": 100,
"minimum": 1,
"markdownDescription": "%github.copilot.config.chat.agentDebugLog.fileLogging.maxSessionLogSizeMB%",
"tags": [
"advanced",
"experimental",
"onExp"
]
},
"github.copilot.chat.otel.enabled": {
"type": "boolean",
"default": false,

View File

@@ -379,6 +379,7 @@
"github.copilot.config.chat.agentDebugLog.fileLogging.enabled": "Enable writing chat debug events to JSONL files on disk for diagnostics. When disabled, the built-in `troubleshoot` skill is also disabled. Requires window reload to take effect.",
"github.copilot.config.chat.agentDebugLog.fileLogging.flushIntervalMs": "How often (in milliseconds) buffered debug log entries are flushed to disk. Lower values provide more up-to-date logs at the cost of more frequent disk writes.",
"github.copilot.config.chat.agentDebugLog.fileLogging.maxRetainedSessionLogs": "Maximum number of chat debug session log directories to retain on disk. Each chat session produces one directory. Older session logs are automatically deleted when this limit is exceeded.",
"github.copilot.config.chat.agentDebugLog.fileLogging.maxSessionLogSizeMB": "Maximum size in megabytes for a single chat debug session log file. When the log exceeds this size, older entries are truncated to retain the most recent data. Defaults to 100 MB.",
"github.copilot.config.inlineEdits.diagnosticsContextProvider.enabled": "Enable diagnostics context provider for next edit suggestions.",
"github.copilot.config.inlineEdits.chatSessionContextProvider.enabled": "Enable chat session context provider for next edit suggestions.",
"github.copilot.config.codesearch.agent.enabled": "Enable code search capabilities in agent mode.",

View File

@@ -25,8 +25,8 @@ const DEFAULT_FLUSH_INTERVAL_MS = 4_000;
const MIN_FLUSH_INTERVAL_MS = 2_000;
const MAX_ATTR_VALUE_LENGTH = 5_000;
const MAX_PENDING_CORE_EVENTS = 100;
const MAX_SESSION_LOG_BYTES = 100 * 1024 * 1024; // 100MB
const TRUNCATION_RETAIN_BYTES = 60 * 1024 * 1024; // 60 MB
const DEFAULT_MAX_SESSION_LOG_MB = 100;
const TRUNCATION_RETAIN_RATIO = 0.6; // retain 60% of max on truncation
const MAX_SPAN_SESSION_INDEX = 10_000;
@@ -87,6 +87,7 @@ export class ChatDebugFileLoggerService extends Disposable implements IChatDebug
private _debugLogsDirUri: URI | undefined;
private _autoFlushTimer: ReturnType<typeof setInterval> | undefined;
private _autoFlushIntervalMs: number;
private _maxSessionLogBytes: number;
private _totalBytesWritten = 0;
private _totalSessionCount = 0;
@@ -111,17 +112,22 @@ export class ChatDebugFileLoggerService extends Disposable implements IChatDebug
*/
this._telemetryService.sendMSFTTelemetryEvent('chatDebugFileLogger.disabled');
this._autoFlushIntervalMs = DEFAULT_FLUSH_INTERVAL_MS;
this._maxSessionLogBytes = DEFAULT_MAX_SESSION_LOG_MB * 1024 * 1024;
return;
}
this._autoFlushIntervalMs = Math.max(MIN_FLUSH_INTERVAL_MS, this._configurationService.getConfig(ConfigKey.Advanced.ChatDebugFileLoggingFlushInterval) ?? DEFAULT_FLUSH_INTERVAL_MS);
this._maxSessionLogBytes = this._resolveMaxSessionLogBytes();
// React to flush interval changes at runtime
// React to changes at runtime
this._register(this._configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(ConfigKey.Advanced.ChatDebugFileLoggingFlushInterval.fullyQualifiedId)) {
this._autoFlushIntervalMs = Math.max(MIN_FLUSH_INTERVAL_MS, this._configurationService.getConfig(ConfigKey.Advanced.ChatDebugFileLoggingFlushInterval) ?? DEFAULT_FLUSH_INTERVAL_MS);
this._restartFlushTimer();
}
if (e.affectsConfiguration(ConfigKey.Advanced.ChatDebugFileLoggingMaxSessionLogSizeMB.fullyQualifiedId)) {
this._maxSessionLogBytes = this._resolveMaxSessionLogBytes();
}
}));
// Subscribe to OTel span completions
@@ -142,6 +148,12 @@ export class ChatDebugFileLoggerService extends Disposable implements IChatDebug
}
}
private _resolveMaxSessionLogBytes(): number {
const raw = this._configurationService.getExperimentBasedConfig(ConfigKey.Advanced.ChatDebugFileLoggingMaxSessionLogSizeMB, this._experimentationService);
const mb = typeof raw === 'number' && Number.isFinite(raw) ? raw : DEFAULT_MAX_SESSION_LOG_MB;
return Math.max(1, Math.floor(mb)) * 1024 * 1024;
}
override dispose(): void {
if (this._autoFlushTimer) {
clearInterval(this._autoFlushTimer);
@@ -764,7 +776,7 @@ export class ChatDebugFileLoggerService extends Disposable implements IChatDebug
}
await fs.promises.appendFile(session.uri.fsPath, content, 'utf-8');
session.bytesWritten += Buffer.byteLength(content, 'utf-8');
if (session.bytesWritten > MAX_SESSION_LOG_BYTES) {
if (session.bytesWritten > this._maxSessionLogBytes) {
await this._truncateLogFile(session);
}
} catch (err) {
@@ -773,18 +785,20 @@ export class ChatDebugFileLoggerService extends Disposable implements IChatDebug
}
/**
* Truncate a log file to retain the newest ~80MB using a streaming
* approach via a temp file to avoid loading the entire tail into memory.
* Truncate a log file to retain the newest portion (TRUNCATION_RETAIN_RATIO
* of the configured max size) using a streaming approach via a temp file
* to avoid loading the entire tail into memory.
*/
private async _truncateLogFile(session: IActiveLogSession): Promise<void> {
try {
const filePath = session.uri.fsPath;
const stat = await fs.promises.stat(filePath);
if (stat.size <= MAX_SESSION_LOG_BYTES) {
if (stat.size <= this._maxSessionLogBytes) {
return;
}
const skipBytes = stat.size - TRUNCATION_RETAIN_BYTES;
const retainBytes = Math.floor(this._maxSessionLogBytes * TRUNCATION_RETAIN_RATIO);
const skipBytes = stat.size - retainBytes;
const fd = await fs.promises.open(filePath, 'r');
try {
// Read a small probe around the cut point to find the next newline

View File

@@ -692,6 +692,7 @@ export namespace ConfigKey {
export const ChatDebugFileLogging = defineAndMigrateExpSetting<boolean>('chat.chatDebug.fileLogging.enabled', 'chat.agentDebugLog.fileLogging.enabled', false);
export const ChatDebugFileLoggingFlushInterval = defineAndMigrateSetting<number>('chat.chatDebug.fileLogging.flushIntervalMs', 'chat.agentDebugLog.fileLogging.flushIntervalMs', 4000);
export const ChatDebugFileLoggingMaxRetainedSessionLogs = defineSetting<number>('chat.agentDebugLog.fileLogging.maxRetainedSessionLogs', ConfigType.ExperimentBased, 50);
export const ChatDebugFileLoggingMaxSessionLogSizeMB = defineSetting<number>('chat.agentDebugLog.fileLogging.maxSessionLogSizeMB', ConfigType.ExperimentBased, 100);
// OTel settings
export const OTelEnabled = defineSetting<boolean>('chat.otel.enabled', ConfigType.Simple, false);