mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-31 00:10:04 +08:00
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:
@@ -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,
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user