ahpJsonlLogger.ts ×15

Frontier kind: Code frontier

unlabeled · c_ab01b713a811

5 tests · 12996 LOC · 46 files · introduces 0 tests · 103 LOC · 3 files

Introduces — evidence that enters the hierarchy at this concept

Code
17 ranges103 lines · 3 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
2255 ranges12996 lines · 46 files · Browse complete extent
All tests (intent)
5 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

3 files ranked by introduced lines: 103 introduced LOC across 17 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/common/ahpJsonlLogger.ts 95 introduced LOC · 15 ranges

Open complete file

69
70 constructor(
71 > private readonly _options: IAhpJsonlLoggerOptions, ahpJsonlLogger.ts
72 > @IFileService private readonly _fileService: IFileService,
73 > @ILogService private readonly _logService: ILogService,
74 > ) {
75 > super();
76 > this._directory = joinPath(this._options.logsHome, AHP_LOG_DIR);
77 > // Truncate connectionId to avoid filesystem filename length limits (e.g. 255 on ext4/APFS)
78 > const safeConnectionId = sanitizeFilePart(this._options.connectionId).slice(0, 64);
79 > this._baseName = `ahp-${toFileTimestamp(new Date())}-${safeConnectionId}.jsonl`;
80 > this._maxFileSizeBytes = this._options.maxFileSizeBytes ?? DEFAULT_MAX_FILE_SIZE_BYTES;
81 > this._maxFiles = this._options.maxFiles ?? DEFAULT_MAX_FILES;
82 > this._currentFile = joinPath(this._directory, this._baseName);
83 > }
84
85 get resource(): URI {
86 > return this._currentFile; ahpJsonlLogger.ts
87 > }
88
89 log(message: object, dir: AhpLogDirection, byteLength?: number): void {
90 > const meta: IAhpLogMeta = { ahpJsonlLogger.ts
91 > ts: new Date().toISOString(),
92 > dir,
93 > connectionId: this._options.connectionId,
94 > transport: this._options.transport,
95 > ...(typeof byteLength === 'number' ? { byteLength } : {}),
96 > };
97 > const entry = { ...message, _ahpLog: meta };
98 > // Fast path: serialize once. The vast majority of messages are small, so
99 > // we only pay a single stringify and use its length to decide whether the
100 > // rare oversized-message path below is needed.
101 > let body = stringifyAhpLogEntry(entry);
102 > if (body.length > MAX_LOG_LINE_LENGTH) {
103 // Slow path (rare): a single message carried very large payloads. Walk
104 // the object via a replacer that elides long string values, keeping the
107 body = stringifyAhpLogEntryTruncated(entry, MAX_LOGGED_STRING_LENGTH);
108 }
109 > const line = `${body}\n`; ahpJsonlLogger.ts
110 > this._pending.push(VSBuffer.fromString(line));
111 > this._scheduleDrain();
112 > }
113
114 async flush(): Promise<void> {
115 > // Pending entries always have a drain scheduled (see _scheduleDrain), so ahpJsonlLogger.ts
116 > // awaiting the queue is sufficient to flush everything submitted before
117 > // this call.
118 > await this._queue;
119 > }
120
121 private _scheduleDrain(): void {
122 > if (this._drainScheduled) { ahpJsonlLogger.ts
123 > return;
124 > }
125 > this._drainScheduled = true;
126 > this._queue = this._queue.then(() => this._drainPending()).catch(error => {
127 this._logService.error('[AHPLog] Failed to write transport log', error);
128 > }); ahpJsonlLogger.ts
129 > }
130
131 private async _drainPending(): Promise<void> {
132 > // Clear the scheduled flag before snapshotting _pending so that any log() ahpJsonlLogger.ts
133 > // calls happening during the awaits below will schedule a fresh drain.
134 > this._drainScheduled = false;
135 > if (this._pending.length === 0) {
136 return;
137 }
138 > const buffers = this._pending; ahpJsonlLogger.ts
139 > this._pending = [];
140 >
141 > // Create folder once and memoize to avoid repeated filesystem calls
142 > if (!this._folderCreated) {
143 > this._folderCreated = this._fileService.createFolder(this._directory);
144 > }
145 > await this._folderCreated;
146 > if (this._currentSize === 0) {
147 > this._currentSize = await this._getFileSize(this._currentFile);
148 > }
149 >
150 > // Coalesce buffers into chunks, respecting both file-rotation size and the
151 > // per-write batch cap. Rotation is checked per-entry to preserve the
152 > // invariant that we don't exceed maxFileSizeBytes once a file has data.
153 > let chunk: VSBuffer[] = [];
154 > let chunkSize = 0;
155 > const flushChunk = async () => {
156 > if (chunk.length === 0) {
157 return;
158 }
159 > const combined = chunk.length === 1 ? chunk[0] : VSBuffer.concat(chunk, chunkSize); ahpJsonlLogger.ts
160 > await this._fileService.writeFile(this._currentFile, combined, { append: true });
161 > this._currentSize += combined.byteLength;
162 > chunk = [];
163 > chunkSize = 0;
164 > };
165 >
166 > for (const buffer of buffers) {
167 > const totalInFile = this._currentSize + chunkSize;
168 > if (totalInFile > 0 && totalInFile + buffer.byteLength > this._maxFileSizeBytes) {
169 await flushChunk();
170 await this._rotate();
171 > } else if (chunkSize > 0 && chunkSize + buffer.byteLength > MAX_BATCH_BYTES) { ahpJsonlLogger.ts
172 // Same file but the batch is getting too large; flush early to
173 // avoid creating an oversized concatenated VSBuffer.
174 await flushChunk();
175 }
176 > chunk.push(buffer); ahpJsonlLogger.ts
177 > chunkSize += buffer.byteLength;
178 > }
179 > await flushChunk();
180 > }
181
182 private async _rotate(): Promise<void> {
201
202 private async _getFileSize(resource: URI): Promise<number> {
203 > try { ahpJsonlLogger.ts
204 > return (await this._fileService.resolve(resource)).size ?? 0;
205 > } catch {
206 > return 0;
207 > }
208 > }
209 }
210
253 }
254
255 > function toFileTimestamp(date: Date): string { ahpJsonlLogger.ts
256 > return date.toISOString().replace(/[:.]/g, '-');
257 > }
258
259 > function sanitizeFilePart(value: string): string { ahpJsonlLogger.ts
260 > return value.replace(/[\\/:\*\?"<>\|\s]+/g, '-').replace(/^-+|-+$/g, '') || 'connection';
261 > }
src/vs/platform/files/common/inMemoryFilesystemProvider.ts 6 introduced LOC · 1 range

Open complete file

132
133 if (opts.append) {
134 > entry.size += content.byteLength; inMemoryFilesystemProvider.ts
135 > const oldData = entry.data ?? new Uint8Array(0);
136 > const newData = new Uint8Array(oldData.byteLength + content.byteLength);
137 > newData.set(oldData, 0);
138 > newData.set(content, oldData.byteLength);
139 > entry.data = newData;
140 } else {
141 entry.size = content.byteLength;
src/vs/platform/files/common/files.ts 2 introduced LOC · 1 range

Open complete file

716
717 export function hasFileAppendCapability(provider: IFileSystemProvider): boolean {
718 > return !!(provider.capabilities & FileSystemProviderCapabilities.FileAppend); files.ts
719 > }
720
721 export interface IFileSystemProviderWithFileFolderCopyCapability extends IFileSystemProvider {