src/vs/platform/log/common/log.ts

926 LOC · 570 covered · 356 uncovered · 108 ranges · 10775 concepts · 15 introducers · 5601 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

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 related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filesrc/vs/base/common/observableInternal/observables/observableValue.ts · 129 LOCobservables/observableVa…src/vs/base/common/observableInternal/reactions/autorun.ts · 294 LOCreactions/autorun.tssrc/vs/platform/agentHost/common/otlp/otlpLogEmitter.ts · 485 LOCotlp/otlpLogEmitter.tssrc/vs/platform/agentHost/node/agentHostTelemetryService.ts · 267 LOCnode/agentHostTelemetryS…src/vs/platform/log/common/logService.ts · 57 LOCcommon/logService.tssrc/vs/platform/telemetry/common/commonProperties.ts · 108 LOCcommon/commonProperties.…src/vs/platform/telemetry/common/telemetryService.ts · 366 LOCcommon/telemetryService.…src/vs/platform/telemetry/common/telemetryUtils.ts · 478 LOCcommon/telemetryUtils.tssrc/vs/platform/terminal/common/requestStore.ts · 73 LOCcommon/requestStore.tssrc/vs/platform/webContentExtractor/common/webContentExtractor.ts · 63 LOCcommon/webContentExtract…src/vs/workbench/contrib/mcp/common/mcpDevMode.ts · 213 LOCcommon/mcpDevMode.tssrc/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.ts · 316 LOCcommon/mcpResourceFilesy…src/vs/workbench/contrib/mcp/common/mcpServer.ts · 1539 LOCcommon/mcpServer.tssrc/vs/workbench/contrib/mcp/common/mcpServerConnection.ts · 195 LOCcommon/mcpServerConnecti…src/vs/workbench/contrib/mcp/common/mcpService.ts · 297 LOCcommon/mcpService.tssrc/vs/workbench/contrib/mcp/test/common/mcpRegistryTypes.ts · 247 LOCcommon/mcpRegistryTypes.…mcpResourceFilesystem.ts ×4 · 8 introduced LOCmcpResourceFilesystem.ts…mcpServer.ts ×23 · 552 introduced LOCmcpServer.ts ×23mcpServerConnection.ts ×1 · 4 introduced LOCmcpServerConnection.ts ×…mcpServerConnection.ts ×3 · 17 introduced LOCmcpServerConnection.ts ×…mcpServerRequestHandler.ts ×2 · 9 introduced LOCmcpServerRequestHandler.…mcpTypes.ts ×1 · 1 introduced LOCmcpTypes.ts ×1mcpServerConnection.ts ×1 · 7 introduced LOCmcpServerConnection.ts ×…1dsAppender.ts ×11 · 106 introduced LOC1dsAppender.ts ×11utils.ts ×1 · 2 introduced LOCutils.ts ×1pluginMarketplaceService.test|title=PluginMarketplaceService parses GitHub shorthand marketplace|occurrence=1, pluginMarketplaceService.test|title=PluginMarketplaceService parses GitHub shorthand marketplace with ref suffix|occurrence=1 · 0 introduced LOCpluginMarketplaceService…telemetryUtils.ts ×1 · 2 introduced LOCtelemetryUtils.ts ×1telemetryService.ts ×9 · 113 introduced LOCtelemetryService.ts ×9instantiationServiceMock.ts ×2 · 4 introduced LOCinstantiationServiceMock…log.ts ×5 · 36 introduced LOClog.ts ×5debugger.ts ×5 · 89 introduced LOCdebugger.ts ×5networkDiagnosticsService.ts ×11 · 83 introduced LOCnetworkDiagnosticsServic…derived.ts ×1 · 9 introduced LOCderived.ts ×1tunnelProxy.ts ×20 · 329 introduced LOCtunnelProxy.ts ×20requestStore.ts ×2 · 8 introduced LOCrequestStore.ts ×2chatStreamStats.ts ×6 · 73 introduced LOCchatStreamStats.ts ×6requestStore.ts ×1 · 2 introduced LOCrequestStore.ts ×1logService.ts ×10 · 63 introduced LOClogService.ts ×10instantiationService.ts ×1 · 2 introduced LOCinstantiationService.ts …telemetryLogAppender.test|title=TelemetryLogAdapter Log Telemetry if log level is trace|occurrence=1 · 0 introduced LOCtelemetryLogAppender.tes…telemetryUtils.ts ×8 · 50 introduced LOCtelemetryUtils.ts ×8log.ts ×1 · 2 introduced LOClog.ts ×1log.ts ×2 · 4 introduced LOClog.ts ×2log.ts ×3 · 11 introduced LOClog.ts ×3outboundForwarder.ts ×4 · 15 introduced LOCoutboundForwarder.ts ×4requestStore.ts ×4 · 52 introduced LOCrequestStore.ts ×4workspaces.ts ×6 · 46 introduced LOCworkspaces.ts ×6workspaces.ts ×2 · 22 introduced LOCworkspaces.ts ×2outboundForwarder.ts ×19 · 155 introduced LOCoutboundForwarder.ts ×19chatStreamStats.ts ×6 · 62 introduced LOCchatStreamStats.ts ×6environment.ts ×1 · 165 introduced LOCenvironment.ts ×1otlpLogEmitter.ts ×5 · 9 introduced LOCotlpLogEmitter.ts ×5otlpLogEmitter.ts ×7 · 51 introduced LOCotlpLogEmitter.ts ×7log.ts ×3 · 5 introduced LOClog.ts ×3log.ts ×1 · 3 introduced LOClog.ts ×1log.ts ×3 · 5 introduced LOClog.ts ×3sshRemoteAgentHostHelpers.ts ×1 · 2 introduced LOCsshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.ts ×1 · 4 introduced LOCsshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.ts ×1 · 2 introduced LOCsshRemoteAgentHostHelper…localOtlpReceiver.ts ×6 · 100 introduced LOClocalOtlpReceiver.ts ×6log.ts ×1 · 2 introduced LOClog.ts ×1agentHostRestrictedTelemetry.ts ×2 · 18 introduced LOCagentHostRestrictedTelem…log.ts ×1 · 1 introduced LOClog.ts ×1log.ts ×72 · 446 introduced LOClog.ts ×72otlpLogEmitter.test|title=OtlpLogEmitter logger level gates which records reach the OTLP emitter|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/common/otlpLogEmitter.test|title=OtlpLogEmitter logger level gates which records reach the OTLP emitter|occurrence=1otlpLogEmitter.test|titl…agentHostRequestService.test|title=NetworkDiagnosticsService includes nested proxy response errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=NetworkDiagnosticsService includes nested proxy response errors|occurrence=1agentHostRequestService.…agentHostTelemetryService.test|title=AgentHostTelemetryService logging-only builds do not create restricted network senders|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostTelemetryService.test|title=AgentHostTelemetryService logging-only builds do not create restricted network senders|occurrence=1agentHostTelemetryServic…agentHostTelemetryService.test|title=AgentHostTelemetryService uses the built-in Copilot manifest version for internal telemetry|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostTelemetryService.test|title=AgentHostTelemetryService uses the built-in Copilot manifest version for internal telemetry|occurrence=1agentHostTelemetryServic…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers buildAgentHostBaseCommand includes --cli-data-dir before the agent host subcommand|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers buildAgentHostBaseCommand includes --cli-data-dir before the agent host subcommand|occurrence=1sshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers redactToken preserves text without tokens|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers redactToken preserves text without tokens|occurrence=1sshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers redactToken redacts multiple tokens|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers redactToken redacts multiple tokens|occurrence=1sshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers redactToken redacts token in WebSocket URL|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers redactToken redacts token in WebSocket URL|occurrence=1sshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers redactToken redacts token with following whitespace|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers redactToken redacts token with following whitespace|occurrence=1sshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers shellEscape escapes embedded single quotes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers shellEscape escapes embedded single quotes|occurrence=1sshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers shellEscape handles empty string|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers shellEscape handles empty string|occurrence=1sshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers shellEscape passes through special chars safely wrapped|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers shellEscape passes through special chars safely wrapped|occurrence=1sshRemoteAgentHostHelper…sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers shellEscape wraps simple string in single quotes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/sshRemoteAgentHostHelpers.test|title=SSH Remote Agent Host Helpers shellEscape wraps simple string in single quotes|occurrence=1sshRemoteAgentHostHelper…otel - localOtlpHttpReceiver binds to 127.0.0.1 on an ephemeral port|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/otel/test/node/otlp/localOtlpReceiver.test|title=platform/otel - localOtlpHttpReceiver binds to 127.0.0.1 on an ephemeral port|occurrence=1otel - localOtlpHttpRece…otel - outboundForwarder ConsoleForwarder logs one info per span|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/otel/test/node/otlp/outboundForwarder.test|title=platform/otel - outboundForwarder ConsoleForwarder logs one info per span|occurrence=1otel - outboundForwarder…telemetryLogAppender.test|title=TelemetryLogAdapter Do not Log Telemetry if log level is not trace|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/telemetry/test/common/telemetryLogAppender.test|title=TelemetryLogAdapter Do not Log Telemetry if log level is not trace|occurrence=1telemetryLogAppender.tes…telemetryLogAppender.test|title=TelemetryLogAdapter Log Telemetry if log level is trace|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/telemetry/test/common/telemetryLogAppender.test|title=TelemetryLogAdapter Log Telemetry if log level is trace|occurrence=1telemetryLogAppender.tes…requestStore.test|title=RequestStore should reject the promise when the request times out|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/terminal/test/common/requestStore.test|title=RequestStore should reject the promise when the request times out|occurrence=1requestStore.test|title=…requestStore.test|title=RequestStore should resolve requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/terminal/test/common/requestStore.test|title=RequestStore should resolve requests|occurrence=1requestStore.test|title=…tunnelProxy.test|title=TunnelProxy dispose shuts down the server|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/tunnel/test/node/tunnelProxy.test|title=TunnelProxy dispose shuts down the server|occurrence=1tunnelProxy.test|title=T…tunnelProxy.test|title=TunnelProxy returns 400 for malformed URL|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/tunnel/test/node/tunnelProxy.test|title=TunnelProxy returns 400 for malformed URL|occurrence=1tunnelProxy.test|title=T…tunnelProxy.test|title=TunnelProxy server uses TLS|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/tunnel/test/node/tunnelProxy.test|title=TunnelProxy server uses TLS|occurrence=1tunnelProxy.test|title=T…tunnelProxy.test|title=TunnelProxy start returns a valid ITunnelProxyInfo|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/tunnel/test/node/tunnelProxy.test|title=TunnelProxy start returns a valid ITunnelProxyInfo|occurrence=1tunnelProxy.test|title=T…workspacesHistoryStorage.test|title=History Storage open 1_55|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/workspaces/test/node/workspacesHistoryStorage.test|title=History Storage open 1_55|occurrence=1workspacesHistoryStorage…workspacesHistoryStorage.test|title=History Storage toStoreData drops label if it matches path|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/workspaces/test/node/workspacesHistoryStorage.test|title=History Storage toStoreData drops label if it matches path|occurrence=1workspacesHistoryStorage…chatStreamStats.test|title=ChatStreamStatsTracker large initial chunk uses higher bootstrap minimum|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/model/chatStreamStats.test|title=ChatStreamStatsTracker large initial chunk uses higher bootstrap minimum|occurrence=1chatStreamStats.test|tit…chatStreamStats.test|title=ChatStreamStatsTracker records first markdown time but keeps bootstrap active|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/model/chatStreamStats.test|title=ChatStreamStatsTracker records first markdown time but keeps bootstrap active|occurrence=1chatStreamStats.test|tit…pluginMarketplaceService.test|title=PluginMarketplaceService parses GitHub shorthand marketplace with ref suffix|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/plugins/pluginMarketplaceService.test|title=PluginMarketplaceService parses GitHub shorthand marketplace with ref suffix|occurrence=1pluginMarketplaceService…pluginMarketplaceService.test|title=PluginMarketplaceService parses GitHub shorthand marketplace|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/plugins/pluginMarketplaceService.test|title=PluginMarketplaceService parses GitHub shorthand marketplace|occurrence=1pluginMarketplaceService…debugger.test|title=Debug - Debugger getSchemaAttributes logs malformed properties and ignores them|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/debug/test/node/debugger.test|title=Debug - Debugger getSchemaAttributes logs malformed properties and ignores them|occurrence=1debugger.test|title=Debu…mcpResourceFilesystem.test|title=Workbench - MCP - ResourceFilesystem throws error for write operations|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/mcp/test/common/mcpResourceFilesystem.test|title=Workbench - MCP - ResourceFilesystem throws error for write operations|occurrence=1mcpResourceFilesystem.te…mcpServerConnection.test|title=Workbench - MCP - ServerConnection should handle errors during start|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/mcp/test/common/mcpServerConnection.test|title=Workbench - MCP - ServerConnection should handle errors during start|occurrence=1mcpServerConnection.test…mcpServerConnection.test|title=Workbench - MCP - ServerConnection should handle transport errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/mcp/test/common/mcpServerConnection.test|title=Workbench - MCP - ServerConnection should handle transport errors|occurrence=1mcpServerConnection.test…mcpServerConnection.test|title=Workbench - MCP - ServerConnection should log transport messages|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/mcp/test/common/mcpServerConnection.test|title=Workbench - MCP - ServerConnection should log transport messages|occurrence=1mcpServerConnection.test…mcpServerRequestHandler.test|title=Workbench - MCP - ServerRequestHandler callTool forwards _meta.traceparent to the JSON-RPC payload (MCP SEP-414)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/mcp/test/common/mcpServerRequestHandler.test|title=Workbench - MCP - ServerRequestHandler callTool forwards _meta.traceparent to the JSON-RPC payload (MCP SEP-414)|occurrence=1mcpServerRequestHandler.…Focused file · src/vs/platform/log/common/log.ts · 926 LOCcommon/log.ts

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- log.ts ×72
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import * as nls from '../../../nls.js';
7 > import { toErrorMessage } from '../../../base/common/errorMessage.js';
8 > import { Emitter, Event } from '../../../base/common/event.js';
9 > import { hash } from '../../../base/common/hash.js';
10 > import { Disposable, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
11 > import { ResourceMap } from '../../../base/common/map.js';
12 > import { isWindows } from '../../../base/common/platform.js';
13 > import { joinPath } from '../../../base/common/resources.js';
14 > import { Mutable, isNumber, isString } from '../../../base/common/types.js';
15 > import { URI } from '../../../base/common/uri.js';
16 > import { ILocalizedString } from '../../action/common/action.js';
17 > import { RawContextKey } from '../../contextkey/common/contextkey.js';
18 > import { IEnvironmentService } from '../../environment/common/environment.js';
19 > import { createDecorator } from '../../instantiation/common/instantiation.js';
20 >
21 > export const ILogService = createDecorator<ILogService>('logService');
22 > export const ILoggerService = createDecorator<ILoggerService>('loggerService');
23 >
24 function now(): string {
25 return new Date().toISOString();
26 }
28 > export function isLogLevel(thing: unknown): thing is LogLevel {
29 return isNumber(thing);
30 }
32 > export enum LogLevel {
33 > Off,
34 > Trace,
35 > Debug,
36 > Info,
37 > Warning,
38 > Error
39 > }
40 >
41 > export const DEFAULT_LOG_LEVEL: LogLevel = LogLevel.Info;
42 >
43 > export interface ILogger extends IDisposable {
44 > readonly onDidChangeLogLevel: Event<LogLevel>;
45 > getLevel(): LogLevel;
46 > setLevel(level: LogLevel): void;
47 >
48 > trace(message: string, ...args: unknown[]): void;
49 > debug(message: string, ...args: unknown[]): void;
50 > info(message: string, ...args: unknown[]): void;
51 > warn(message: string, ...args: unknown[]): void;
52 > error(message: string | Error, ...args: unknown[]): void;
53 >
54 > /**
55 > * An operation to flush the contents. Can be synchronous.
56 > */
57 > flush(): void;
58 > }
59 >
60 > export function canLog(loggerLevel: LogLevel, messageLevel: LogLevel): boolean {
61 > return loggerLevel !== LogLevel.Off && loggerLevel <= messageLevel; log.ts ×1
62 > }
64 > export function log(logger: ILogger, level: LogLevel, message: string): void {
65 > switch (level) { mcpServerConnection.ts ×3
66 > case LogLevel.Trace: logger.trace(message); break;
67 > case LogLevel.Debug: logger.debug(message); break;
68 > case LogLevel.Info: logger.info(message); break;
69 > case LogLevel.Warning: logger.warn(message); break;
70 > case LogLevel.Error: logger.error(message); break;
71 > case LogLevel.Off: /* do nothing */ break;
72 > default: throw new Error(`Invalid log level ${level}`);
73 > }
74 > }
76 > type ConsoleMethod = 'debug' | 'error' | 'info' | 'log' | 'warn';
77 > type ConsoleMethodFn = (...args: unknown[]) => void;
78 >
79 > /**
80 > * Flag to enable forwarding of console.* calls to the log service in development.
81 > * This is intended for the use of agents to quickly instrument the code with console.logs
82 > * which will end up in the log service's file outputs.
83 > */
84 > export const isDevConsoleLogForwardingEnabled = false
85 > // || Boolean("true") // done "weirdly" so that a lint warning prevents you from pushing this
86 > ;
87 >
88 > let isConsoleForwarding = false;
89 > let isLogServiceConsoleEcho = false;
90 >
91 function getConsoleMethod(method: ConsoleMethod): ConsoleMethodFn {
92 switch (method) {
93 case 'debug': return console.debug;
94 case 'error': return console.error;
95 case 'info': return console.info;
96 case 'log': return console.log;
97 case 'warn': return console.warn;
98 }
99 }
100 > log.ts ×72
101 function setConsoleMethod(method: ConsoleMethod, fn: ConsoleMethodFn): void {
102 switch (method) {
103 case 'debug': console.debug = fn; break;
104 case 'error': console.error = fn; break;
105 case 'info': console.info = fn; break;
106 case 'log': console.log = fn; break;
107 case 'warn': console.warn = fn; break;
108 }
109 }
110 > log.ts ×72
111 function logToConsole(method: ConsoleMethod, ...args: unknown[]): void {
112 if (isConsoleForwarding) {
113 return;
114 }
115 isLogServiceConsoleEcho = true;
116 try {
117 getConsoleMethod(method).apply(console, args);
118 } finally {
119 isLogServiceConsoleEcho = false;
120 }
121 }
122 > log.ts ×72
123 > export function registerDevConsoleLogForwarder(logService: ILogService): IDisposable {
124 const originalConsoleMethods: Record<ConsoleMethod, ConsoleMethodFn> = {
125 debug: console.debug,
126 error: console.error,
127 info: console.info,
128 log: console.log,
129 warn: console.warn
130 };
131
132 const forward = (method: ConsoleMethod, level: LogLevel, args: unknown[]): void => {
133 if (!isLogServiceConsoleEcho) {
134 isConsoleForwarding = true;
135 try {
136 log(logService, level, format(args));
137 } catch {
138 // Best-effort development logging must not break normal console semantics.
139 } finally {
140 isConsoleForwarding = false;
141 }
142 }
143
144 originalConsoleMethods[method].apply(console, args);
145 };
146
147 const wrappers: Record<ConsoleMethod, ConsoleMethodFn> = {
148 debug: (...args: unknown[]) => forward('debug', LogLevel.Debug, args),
149 error: (...args: unknown[]) => forward('error', LogLevel.Error, args),
150 info: (...args: unknown[]) => forward('info', LogLevel.Info, args),
151 log: (...args: unknown[]) => forward('log', LogLevel.Info, args),
152 warn: (...args: unknown[]) => forward('warn', LogLevel.Warning, args)
153 };
154
155 setConsoleMethod('debug', wrappers.debug);
156 setConsoleMethod('error', wrappers.error);
157 setConsoleMethod('info', wrappers.info);
158 setConsoleMethod('log', wrappers.log);
159 setConsoleMethod('warn', wrappers.warn);
160
161 return toDisposable(() => {
162 if (console.debug === wrappers.debug) {
163 console.debug = originalConsoleMethods.debug;
164 }
165 if (console.error === wrappers.error) {
166 console.error = originalConsoleMethods.error;
167 }
168 if (console.info === wrappers.info) {
169 console.info = originalConsoleMethods.info;
170 }
171 if (console.log === wrappers.log) {
172 console.log = originalConsoleMethods.log;
173 }
174 if (console.warn === wrappers.warn) {
175 console.warn = originalConsoleMethods.warn;
176 }
177 });
178 }
179 > log.ts ×72
180 > export function format(args: any, verbose: boolean = false): string {
181 > let result = ''; otlpLogEmitter.ts ×7
182 >
183 > for (let i = 0; i < args.length; i++) {
184 > let a = args[i];
185 >
186 > if (a instanceof Error) {
187 a = toErrorMessage(a, verbose);
188 }
190 > if (typeof a === 'object') {
191 try {
192 a = JSON.stringify(a);
193 } catch (e) { }
194 }
196 > result += (i > 0 ? ' ' : '') + a;
197 > }
198 >
199 > return result;
200 > }
201 > log.ts ×72
202 > export type LoggerGroup = {
203 > readonly id: string;
204 > readonly name: string;
205 > };
206 >
207 > export interface ILogService extends ILogger {
208 > readonly _serviceBrand: undefined;
209 > }
210 >
211 > export interface ILoggerOptions {
212 >
213 > /**
214 > * Id of the logger.
215 > */
216 > id?: string;
217 >
218 > /**
219 > * Name of the logger.
220 > */
221 > name?: string;
222 >
223 > /**
224 > * Do not create rotating files if max size exceeds.
225 > */
226 > donotRotate?: boolean;
227 >
228 > /**
229 > * Do not use formatters.
230 > */
231 > donotUseFormatters?: boolean;
232 >
233 > /**
234 > * When to log. Set to `always` to log always.
235 > */
236 > logLevel?: 'always' | LogLevel;
237 >
238 > /**
239 > * Whether the log should be hidden from the user.
240 > */
241 > hidden?: boolean;
242 >
243 > /**
244 > * Condition which must be true to show this logger
245 > */
246 > when?: string;
247 >
248 > /**
249 > * Id of the extension that created this logger.
250 > */
251 > extensionId?: string;
252 >
253 > /**
254 > * Group of the logger.
255 > */
256 > group?: LoggerGroup;
257 > }
258 >
259 > export interface ILoggerResource {
260 > readonly resource: URI;
261 > readonly id: string;
262 > readonly name?: string;
263 > readonly logLevel?: LogLevel;
264 > readonly hidden?: boolean;
265 > readonly when?: string;
266 > readonly extensionId?: string;
267 > readonly group?: LoggerGroup;
268 > }
269 >
270 > export type DidChangeLoggersEvent = {
271 > readonly added: Iterable<ILoggerResource>;
272 > readonly removed: Iterable<ILoggerResource>;
273 > };
274 >
275 > export interface ILoggerService {
276 >
277 > readonly _serviceBrand: undefined;
278 >
279 > /**
280 > * Creates a logger for the given resource, or gets one if it already exists.
281 > *
282 > * This will also register the logger with the logger service.
283 > */
284 > createLogger(resource: URI, options?: ILoggerOptions): ILogger;
285 >
286 > /**
287 > * Creates a logger with the given id in the logs folder, or gets one if it already exists.
288 > *
289 > * This will also register the logger with the logger service.
290 > */
291 > createLogger(id: string, options?: Omit<ILoggerOptions, 'id'>): ILogger;
292 >
293 > /**
294 > * Gets an existing logger, if any.
295 > */
296 > getLogger(resourceOrId: URI | string): ILogger | undefined;
297 >
298 > /**
299 > * An event which fires when the log level of a logger has changed
300 > */
301 > readonly onDidChangeLogLevel: Event<LogLevel | [URI, LogLevel]>;
302 >
303 > /**
304 > * Set default log level.
305 > */
306 > setLogLevel(level: LogLevel): void;
307 >
308 > /**
309 > * Set log level for a logger.
310 > */
311 > setLogLevel(resource: URI, level: LogLevel): void;
312 >
313 > /**
314 > * Get log level for a logger or the default log level.
315 > */
316 > getLogLevel(resource?: URI): LogLevel;
317 >
318 > /**
319 > * An event which fires when the visibility of a logger has changed
320 > */
321 > readonly onDidChangeVisibility: Event<[URI, boolean]>;
322 >
323 > /**
324 > * Set the visibility of a logger.
325 > */
326 > setVisibility(resourceOrId: URI | string, visible: boolean): void;
327 >
328 > /**
329 > * An event which fires when the logger resources are changed
330 > */
331 > readonly onDidChangeLoggers: Event<DidChangeLoggersEvent>;
332 >
333 > /**
334 > * Register a logger with the logger service.
335 > *
336 > * Note that this will not create a logger, but only register it.
337 > *
338 > * Use `createLogger` to create a logger and register it.
339 > *
340 > * Use it when you want to register a logger that is not created by the logger service.
341 > */
342 > registerLogger(resource: ILoggerResource): void;
343 >
344 > /**
345 > * Deregister the logger for the given resource.
346 > */
347 > deregisterLogger(idOrResource: URI | string): void;
348 >
349 > /**
350 > * Get all registered loggers
351 > */
352 > getRegisteredLoggers(): Iterable<ILoggerResource>;
353 >
354 > /**
355 > * Get the registered logger for the given resource.
356 > */
357 > getRegisteredLogger(resource: URI): ILoggerResource | undefined;
358 > }
359 >
360 > export abstract class AbstractLogger extends Disposable implements ILogger {
361 > log.ts ×3
362 > private level: LogLevel = DEFAULT_LOG_LEVEL;
363 > private readonly _onDidChangeLogLevel: Emitter<LogLevel> = this._register(new Emitter<LogLevel>());
364 > get onDidChangeLogLevel(): Event<LogLevel> { return this._onDidChangeLogLevel.event; } log.ts ×72
365 >
366 > setLevel(level: LogLevel): void {
367 > if (this.level !== level) { log.ts ×3
368 > this.level = level; log.ts ×1
369 > this._onDidChangeLogLevel.fire(this.level);
370 > }
371 > } log.ts ×3
372 > log.ts ×72
373 > getLevel(): LogLevel {
374 > return this.level; logService.ts ×10
375 > }
376 > log.ts ×72
377 > protected checkLogLevel(level: LogLevel): boolean {
378 > return canLog(this.level, level); log.ts ×3
379 > }
380 > log.ts ×72
381 > protected canLog(level: LogLevel): boolean {
382 > if (this._store.isDisposed) { log.ts ×3
383 return false;
384 }
385 > return this.checkLogLevel(level); log.ts ×3
386 > }
387 > log.ts ×72
388 > abstract trace(message: string, ...args: unknown[]): void;
389 > abstract debug(message: string, ...args: unknown[]): void;
390 > abstract info(message: string, ...args: unknown[]): void;
391 > abstract warn(message: string, ...args: unknown[]): void;
392 > abstract error(message: string | Error, ...args: unknown[]): void;
393 > abstract flush(): void;
394 > }
395 >
396 > export abstract class AbstractMessageLogger extends AbstractLogger implements ILogger {
397 >
398 > constructor(private readonly logAlways?: boolean) {
399 > super(); otlpLogEmitter.ts ×7
400 > }
401 > log.ts ×72
402 > protected override checkLogLevel(level: LogLevel): boolean {
403 > return this.logAlways || super.checkLogLevel(level); otlpLogEmitter.ts ×7
404 > }
405 > log.ts ×72
406 > trace(message: string, ...args: unknown[]): void {
407 if (this.canLog(LogLevel.Trace)) {
408 this.log(LogLevel.Trace, format([message, ...args], true));
409 }
410 }
411 > log.ts ×72
412 > debug(message: string, ...args: unknown[]): void {
413 if (this.canLog(LogLevel.Debug)) {
414 this.log(LogLevel.Debug, format([message, ...args]));
415 }
416 }
417 > log.ts ×72
418 > info(message: string, ...args: unknown[]): void {
419 if (this.canLog(LogLevel.Info)) {
420 this.log(LogLevel.Info, format([message, ...args]));
421 }
422 }
423 > log.ts ×72
424 > warn(message: string, ...args: unknown[]): void {
425 if (this.canLog(LogLevel.Warning)) {
426 this.log(LogLevel.Warning, format([message, ...args]));
427 }
428 }
429 > log.ts ×72
430 > error(message: string | Error, ...args: unknown[]): void {
431 if (this.canLog(LogLevel.Error)) {
432 if (message instanceof Error) {
433 const array = Array.prototype.slice.call(arguments);
434 array[0] = message.stack;
435 this.log(LogLevel.Error, format(array));
436 } else {
437 this.log(LogLevel.Error, format([message, ...args]));
438 }
439 }
440 }
441 > log.ts ×72
442 > flush(): void { }
443 >
444 > protected abstract log(level: LogLevel, message: string): void;
445 > }
446 >
447 >
448 > export class ConsoleMainLogger extends AbstractLogger implements ILogger {
449 >
450 > private useColors: boolean;
451 >
452 > constructor(logLevel: LogLevel = DEFAULT_LOG_LEVEL) {
453 super();
454 this.setLevel(logLevel);
455 this.useColors = !isWindows;
456 }
457 > log.ts ×72
458 > trace(message: string, ...args: unknown[]): void {
459 if (this.canLog(LogLevel.Trace)) {
460 if (this.useColors) {
461 logToConsole('log', `\x1b[90m[main ${now()}]\x1b[0m`, message, ...args);
462 } else {
463 logToConsole('log', `[main ${now()}]`, message, ...args);
464 }
465 }
466 }
467 > log.ts ×72
468 > debug(message: string, ...args: unknown[]): void {
469 if (this.canLog(LogLevel.Debug)) {
470 if (this.useColors) {
471 logToConsole('log', `\x1b[90m[main ${now()}]\x1b[0m`, message, ...args);
472 } else {
473 logToConsole('log', `[main ${now()}]`, message, ...args);
474 }
475 }
476 }
477 > log.ts ×72
478 > info(message: string, ...args: unknown[]): void {
479 if (this.canLog(LogLevel.Info)) {
480 if (this.useColors) {
481 logToConsole('log', `\x1b[90m[main ${now()}]\x1b[0m`, message, ...args);
482 } else {
483 logToConsole('log', `[main ${now()}]`, message, ...args);
484 }
485 }
486 }
487 > log.ts ×72
488 > warn(message: string | Error, ...args: unknown[]): void {
489 if (this.canLog(LogLevel.Warning)) {
490 if (this.useColors) {
491 logToConsole('warn', `\x1b[93m[main ${now()}]\x1b[0m`, message, ...args);
492 } else {
493 logToConsole('warn', `[main ${now()}]`, message, ...args);
494 }
495 }
496 }
497 > log.ts ×72
498 > error(message: string, ...args: unknown[]): void {
499 if (this.canLog(LogLevel.Error)) {
500 if (this.useColors) {
501 logToConsole('error', `\x1b[91m[main ${now()}]\x1b[0m`, message, ...args);
502 } else {
503 logToConsole('error', `[main ${now()}]`, message, ...args);
504 }
505 }
506 }
507 > log.ts ×72
508 > flush(): void {
509 // noop
510 }
511 > log.ts ×72
512 > }
513 >
514 > export class ConsoleLogger extends AbstractLogger implements ILogger {
515 >
516 > constructor(logLevel: LogLevel = DEFAULT_LOG_LEVEL, private readonly useColors: boolean = true) {
517 > super(); logService.ts ×10
518 > this.setLevel(logLevel);
519 > }
520 > log.ts ×72
521 > trace(message: string, ...args: unknown[]): void {
522 if (this.canLog(LogLevel.Trace)) {
523 if (this.useColors) {
524 logToConsole('log', '%cTRACE', 'color: #888', message, ...args);
525 } else {
526 logToConsole('log', message, ...args);
527 }
528 }
529 }
530 > log.ts ×72
531 > debug(message: string, ...args: unknown[]): void {
532 if (this.canLog(LogLevel.Debug)) {
533 if (this.useColors) {
534 logToConsole('log', '%cDEBUG', 'background: #eee; color: #888', message, ...args);
535 } else {
536 logToConsole('log', message, ...args);
537 }
538 }
539 }
540 > log.ts ×72
541 > info(message: string, ...args: unknown[]): void {
542 if (this.canLog(LogLevel.Info)) {
543 if (this.useColors) {
544 logToConsole('log', '%c INFO', 'color: #33f', message, ...args);
545 } else {
546 logToConsole('log', message, ...args);
547 }
548 }
549 }
550 > log.ts ×72
551 > warn(message: string | Error, ...args: unknown[]): void {
552 if (this.canLog(LogLevel.Warning)) {
553 if (this.useColors) {
554 logToConsole('warn', '%c WARN', 'color: #993', message, ...args);
555 } else {
556 logToConsole('log', message, ...args);
557 }
558 }
559 }
560 > log.ts ×72
561 > error(message: string, ...args: unknown[]): void {
562 if (this.canLog(LogLevel.Error)) {
563 if (this.useColors) {
564 logToConsole('error', '%c ERR', 'color: #f33', message, ...args);
565 } else {
566 logToConsole('error', message, ...args);
567 }
568 }
569 }
570 > log.ts ×72
571 >
572 > flush(): void {
573 // noop
574 }
575 > } log.ts ×72
576 >
577 > export class AdapterLogger extends AbstractLogger implements ILogger {
578 >
579 > constructor(private readonly adapter: { log: (logLevel: LogLevel, args: any[]) => void }, logLevel: LogLevel = DEFAULT_LOG_LEVEL) {
580 super();
581 this.setLevel(logLevel);
582 }
583 > log.ts ×72
584 > trace(message: string, ...args: unknown[]): void {
585 if (this.canLog(LogLevel.Trace)) {
586 this.adapter.log(LogLevel.Trace, [this.extractMessage(message), ...args]);
587 }
588 }
589 > log.ts ×72
590 > debug(message: string, ...args: unknown[]): void {
591 if (this.canLog(LogLevel.Debug)) {
592 this.adapter.log(LogLevel.Debug, [this.extractMessage(message), ...args]);
593 }
594 }
595 > log.ts ×72
596 > info(message: string, ...args: unknown[]): void {
597 if (this.canLog(LogLevel.Info)) {
598 this.adapter.log(LogLevel.Info, [this.extractMessage(message), ...args]);
599 }
600 }
601 > log.ts ×72
602 > warn(message: string | Error, ...args: unknown[]): void {
603 if (this.canLog(LogLevel.Warning)) {
604 this.adapter.log(LogLevel.Warning, [this.extractMessage(message), ...args]);
605 }
606 }
607 > log.ts ×72
608 > error(message: string | Error, ...args: unknown[]): void {
609 if (this.canLog(LogLevel.Error)) {
610 this.adapter.log(LogLevel.Error, [this.extractMessage(message), ...args]);
611 }
612 }
613 > log.ts ×72
614 > private extractMessage(msg: string | Error): string {
615 if (typeof msg === 'string') {
616 return msg;
617 }
618
619 return toErrorMessage(msg, this.canLog(LogLevel.Trace));
620 }
621 > log.ts ×72
622 > flush(): void {
623 // noop
624 }
625 > } log.ts ×72
626 >
627 > export class MultiplexLogger extends AbstractLogger implements ILogger {
628 >
629 > constructor(private readonly loggers: ReadonlyArray<ILogger>) {
630 > super(); logService.ts ×10
631 > if (loggers.length) {
632 > this.setLevel(loggers[0].getLevel());
633 > }
634 > }
635 > log.ts ×72
636 > override setLevel(level: LogLevel): void {
637 > for (const logger of this.loggers) { logService.ts ×10
638 > logger.setLevel(level);
639 > }
640 > super.setLevel(level);
641 > }
642 > log.ts ×72
643 > trace(message: string, ...args: unknown[]): void {
644 for (const logger of this.loggers) {
645 logger.trace(message, ...args);
646 }
647 }
648 > log.ts ×72
649 > debug(message: string, ...args: unknown[]): void {
650 for (const logger of this.loggers) {
651 logger.debug(message, ...args);
652 }
653 }
654 > log.ts ×72
655 > info(message: string, ...args: unknown[]): void {
656 for (const logger of this.loggers) {
657 logger.info(message, ...args);
658 }
659 }
660 > log.ts ×72
661 > warn(message: string, ...args: unknown[]): void {
662 for (const logger of this.loggers) {
663 logger.warn(message, ...args);
664 }
665 }
666 > log.ts ×72
667 > error(message: string | Error, ...args: unknown[]): void {
668 for (const logger of this.loggers) {
669 logger.error(message, ...args);
670 }
671 }
672 > log.ts ×72
673 > flush(): void {
674 for (const logger of this.loggers) {
675 logger.flush();
676 }
677 }
678 > log.ts ×72
679 > override dispose(): void {
680 for (const logger of this.loggers) {
681 logger.dispose();
682 }
683 super.dispose();
684 }
685 > } log.ts ×72
686 >
687 > type LoggerEntry = { logger: ILogger | undefined; info: Mutable<ILoggerResource> };
688 >
689 > export abstract class AbstractLoggerService extends Disposable implements ILoggerService {
690 >
691 > declare readonly _serviceBrand: undefined;
692 >
693 > private readonly _loggers = new ResourceMap<LoggerEntry>();
694 >
695 > private _onDidChangeLoggers = this._register(new Emitter<{ added: ILoggerResource[]; removed: ILoggerResource[] }>);
696 > readonly onDidChangeLoggers = this._onDidChangeLoggers.event;
697 >
698 > private _onDidChangeLogLevel = this._register(new Emitter<LogLevel | [URI, LogLevel]>);
699 > readonly onDidChangeLogLevel = this._onDidChangeLogLevel.event;
700 >
701 > private _onDidChangeVisibility = this._register(new Emitter<[URI, boolean]>);
702 > readonly onDidChangeVisibility = this._onDidChangeVisibility.event;
703 >
704 > constructor(
705 > protected logLevel: LogLevel, log.ts ×3
706 > private readonly logsHome: URI,
707 > loggerResources?: Iterable<ILoggerResource>,
708 > ) {
709 > super();
710 > if (loggerResources) {
711 for (const loggerResource of loggerResources) {
712 this._loggers.set(loggerResource.resource, { logger: undefined, info: loggerResource });
713 }
714 }
715 > } log.ts ×3
716 > log.ts ×72
717 > private getLoggerEntry(resourceOrId: URI | string): LoggerEntry | undefined {
718 > if (isString(resourceOrId)) { telemetryService.ts ×9
719 > return [...this._loggers.values()].find(logger => logger.info.id === resourceOrId);
720 > }
721 return this._loggers.get(resourceOrId);
723 > log.ts ×72
724 > getLogger(resourceOrId: URI | string): ILogger | undefined {
725 > return this.getLoggerEntry(resourceOrId)?.logger; telemetryService.ts ×9
726 > }
727 > log.ts ×72
728 > createLogger(idOrResource: URI | string, options?: ILoggerOptions): ILogger {
729 > const resource = this.toResource(idOrResource); log.ts ×5
730 > const id = isString(idOrResource) ? idOrResource : (options?.id ?? hash(resource.toString()).toString(16));
731 > let logger = this._loggers.get(resource)?.logger;
732 > const logLevel = options?.logLevel === 'always' ? LogLevel.Trace : options?.logLevel;
733 > if (!logger) {
734 > logger = this.doCreateLogger(resource, logLevel ?? this.getLogLevel(resource) ?? this.logLevel, { ...options, id });
735 > }
736 > const loggerEntry: LoggerEntry = {
737 > logger,
738 > info: {
739 > resource,
740 > id,
741 > logLevel,
742 > name: options?.name,
743 > hidden: options?.hidden,
744 > group: options?.group,
745 > extensionId: options?.extensionId,
746 > when: options?.when
747 > }
748 > };
749 > this.registerLogger(loggerEntry.info);
750 > // TODO: @sandy081 Remove this once registerLogger can take ILogger
751 > this._loggers.set(resource, loggerEntry);
752 > return logger;
753 > }
754 > log.ts ×72
755 > protected toResource(idOrResource: string | URI): URI {
756 > return isString(idOrResource) ? joinPath(this.logsHome, `${idOrResource.replace(/[\\/:\*\?"<>\|]/g, '')}.log`) : idOrResource; log.ts ×5
757 > }
758 > log.ts ×72
759 > setLogLevel(logLevel: LogLevel): void;
760 > setLogLevel(resource: URI, logLevel: LogLevel): void;
761 > setLogLevel(arg1: any, arg2?: any): void {
762 if (URI.isUri(arg1)) {
763 const resource = arg1;
764 const logLevel = arg2;
765 const logger = this._loggers.get(resource);
766 if (logger && logLevel !== logger.info.logLevel) {
767 logger.info.logLevel = logLevel === this.logLevel ? undefined : logLevel;
768 logger.logger?.setLevel(logLevel);
769 this._loggers.set(logger.info.resource, logger);
770 this._onDidChangeLogLevel.fire([resource, logLevel]);
771 }
772 } else {
773 this.logLevel = arg1;
774 for (const [resource, logger] of this._loggers.entries()) {
775 if (this._loggers.get(resource)?.info.logLevel === undefined) {
776 logger.logger?.setLevel(this.logLevel);
777 }
778 }
779 this._onDidChangeLogLevel.fire(this.logLevel);
780 }
781 }
782 > log.ts ×72
783 > setVisibility(resourceOrId: URI | string, visibility: boolean): void {
784 const logger = this.getLoggerEntry(resourceOrId);
785 if (logger && visibility !== !logger.info.hidden) {
786 logger.info.hidden = !visibility;
787 this._loggers.set(logger.info.resource, logger);
788 this._onDidChangeVisibility.fire([logger.info.resource, visibility]);
789 }
790 }
791 > log.ts ×72
792 > getLogLevel(resource?: URI): LogLevel {
793 > let logLevel; log.ts ×2
794 > if (resource) {
795 > logLevel = this._loggers.get(resource)?.info.logLevel; log.ts ×5
796 > }
797 > return logLevel ?? this.logLevel; log.ts ×2
798 > }
799 > log.ts ×72
800 > registerLogger(resource: ILoggerResource): void {
801 > const existing = this._loggers.get(resource.resource); log.ts ×5
802 > if (existing) {
803 if (existing.info.hidden !== resource.hidden) {
804 this.setVisibility(resource.resource, !resource.hidden);
805 }
806 > } else { log.ts ×5
807 > this._loggers.set(resource.resource, { info: resource, logger: undefined });
808 > this._onDidChangeLoggers.fire({ added: [resource], removed: [] });
809 > }
810 > }
811 > log.ts ×72
812 > deregisterLogger(idOrResource: URI | string): void {
813 > const resource = this.toResource(idOrResource); mcpServer.ts ×23
814 > const existing = this._loggers.get(resource);
815 > if (existing) {
816 if (existing.logger) {
817 existing.logger.dispose();
818 }
819 this._loggers.delete(resource);
820 this._onDidChangeLoggers.fire({ added: [], removed: [existing.info] });
821 }
823 > log.ts ×72
824 > *getRegisteredLoggers(): Iterable<ILoggerResource> {
825 for (const entry of this._loggers.values()) {
826 yield entry.info;
827 }
828 }
829 > log.ts ×72
830 > getRegisteredLogger(resource: URI): ILoggerResource | undefined {
831 return this._loggers.get(resource)?.info;
832 }
833 > log.ts ×72
834 > override dispose(): void {
835 > this._loggers.forEach(logger => logger.logger?.dispose()); log.ts ×3
836 > this._loggers.clear();
837 > super.dispose();
838 > }
839 > log.ts ×72
840 > protected abstract doCreateLogger(resource: URI, logLevel: LogLevel, options?: ILoggerOptions): ILogger;
841 > }
842 >
843 > export class NullLogger implements ILogger {
844 > readonly onDidChangeLogLevel: Event<LogLevel> = new Emitter<LogLevel>().event; log.ts ×1
845 > setLevel(level: LogLevel): void { } log.ts ×72
846 > getLevel(): LogLevel { return LogLevel.Info; }
847 > trace(message: string, ...args: unknown[]): void { }
848 > debug(message: string, ...args: unknown[]): void { }
849 > info(message: string, ...args: unknown[]): void { }
850 > warn(message: string, ...args: unknown[]): void { }
851 > error(message: string | Error, ...args: unknown[]): void { }
852 > critical(message: string | Error, ...args: unknown[]): void { }
853 > dispose(): void { }
854 > flush(): void { }
855 > }
856 >
857 > export class NullLogService extends NullLogger implements ILogService {
858 > declare readonly _serviceBrand: undefined;
859 > }
860 >
861 > export class NullLoggerService extends AbstractLoggerService {
862 > constructor() {
863 > super(LogLevel.Off, URI.parse('log:///log')); log.ts ×1
864 > }
865 > protected override doCreateLogger(resource: URI, logLevel: LogLevel, options?: ILoggerOptions): ILogger { log.ts ×72
866 > return new NullLogger(); telemetryService.ts ×9
867 > }
868 > } log.ts ×72
869 >
870 > export function getLogLevel(environmentService: IEnvironmentService): LogLevel {
871 if (environmentService.verbose) {
872 return LogLevel.Trace;
873 }
874 if (typeof environmentService.logLevel === 'string') {
875 const logLevel = parseLogLevel(environmentService.logLevel.toLowerCase());
876 if (logLevel !== undefined) {
877 return logLevel;
878 }
879 }
880 return DEFAULT_LOG_LEVEL;
881 }
882 > log.ts ×72
883 > export function LogLevelToString(logLevel: LogLevel): string {
884 > switch (logLevel) {
885 > case LogLevel.Trace: return 'trace';
886 > case LogLevel.Debug: return 'debug';
887 > case LogLevel.Info: return 'info';
888 > case LogLevel.Warning: return 'warn';
889 > case LogLevel.Error: return 'error';
890 > case LogLevel.Off: return 'off';
891 > }
892 > }
893 >
894 > export function LogLevelToLocalizedString(logLevel: LogLevel): ILocalizedString {
895 switch (logLevel) {
896 case LogLevel.Trace: return { original: 'Trace', value: nls.localize('trace', "Trace") };
897 case LogLevel.Debug: return { original: 'Debug', value: nls.localize('debug', "Debug") };
898 case LogLevel.Info: return { original: 'Info', value: nls.localize('info', "Info") };
899 case LogLevel.Warning: return { original: 'Warning', value: nls.localize('warn', "Warning") };
900 case LogLevel.Error: return { original: 'Error', value: nls.localize('error', "Error") };
901 case LogLevel.Off: return { original: 'Off', value: nls.localize('off', "Off") };
902 }
903 }
904 > log.ts ×72
905 > export function parseLogLevel(logLevel: string): LogLevel | undefined {
906 switch (logLevel) {
907 case 'trace':
908 return LogLevel.Trace;
909 case 'debug':
910 return LogLevel.Debug;
911 case 'info':
912 return LogLevel.Info;
913 case 'warn':
914 return LogLevel.Warning;
915 case 'error':
916 return LogLevel.Error;
917 case 'critical':
918 return LogLevel.Error;
919 case 'off':
920 return LogLevel.Off;
921 }
922 return undefined;
923 }
924 > log.ts ×72
925 > // Contexts
926 > export const CONTEXT_LOG_LEVEL = new RawContextKey<string>('logLevel', LogLevelToString(LogLevel.Info));