Skip to content

Commit 46db367

Browse files
authored
Fix #8974 by supporting strings in configureLogging for SignalR JS client (#9252)
1 parent 01b0c88 commit 46db367

File tree

4 files changed

+241
-97
lines changed

4 files changed

+241
-97
lines changed

src/SignalR/clients/ts/signalr/src/HubConnectionBuilder.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,31 @@ import { JsonHubProtocol } from "./JsonHubProtocol";
1313
import { NullLogger } from "./Loggers";
1414
import { Arg, ConsoleLogger } from "./Utils";
1515

16+
// tslint:disable:object-literal-sort-keys
17+
const LogLevelNameMapping = {
18+
trace: LogLevel.Trace,
19+
debug: LogLevel.Debug,
20+
info: LogLevel.Information,
21+
information: LogLevel.Information,
22+
warn: LogLevel.Warning,
23+
warning: LogLevel.Warning,
24+
error: LogLevel.Error,
25+
critical: LogLevel.Critical,
26+
none: LogLevel.None,
27+
};
28+
29+
function parseLogLevel(name: string): LogLevel {
30+
// Case-insensitive matching via lower-casing
31+
// Yes, I know case-folding is a complicated problem in Unicode, but we only support
32+
// the ASCII strings defined in LogLevelNameMapping anyway, so it's fine -anurse.
33+
const mapping = LogLevelNameMapping[name.toLowerCase()];
34+
if (typeof mapping !== "undefined") {
35+
return mapping;
36+
} else {
37+
throw new Error(`Unknown log level: ${name}`);
38+
}
39+
}
40+
1641
/** A builder for configuring {@link @aspnet/signalr.HubConnection} instances. */
1742
export class HubConnectionBuilder {
1843
/** @internal */
@@ -44,15 +69,26 @@ export class HubConnectionBuilder {
4469

4570
/** Configures custom logging for the {@link @aspnet/signalr.HubConnection}.
4671
*
47-
* @param {LogLevel | ILogger} logging An object implementing the {@link @aspnet/signalr.ILogger} interface or {@link @aspnet/signalr.LogLevel}.
72+
* @param {string} logLevel A string representing a LogLevel setting a minimum level of messages to log.
73+
* See {@link https://docs.microsoft.com/en-us/aspnet/core/signalr/configuration#configure-logging|the documentation for client logging configuration} for more details.
74+
*/
75+
public configureLogging(logLevel: string): HubConnectionBuilder;
76+
77+
/** Configures custom logging for the {@link @aspnet/signalr.HubConnection}.
78+
*
79+
* @param {LogLevel | string | ILogger} logging A {@link @aspnet/signalr.LogLevel}, a string representing a LogLevel, or an object implementing the {@link @aspnet/signalr.ILogger} interface.
80+
* See {@link https://docs.microsoft.com/en-us/aspnet/core/signalr/configuration#configure-logging|the documentation for client logging configuration} for more details.
4881
* @returns The {@link @aspnet/signalr.HubConnectionBuilder} instance, for chaining.
4982
*/
50-
public configureLogging(logging: LogLevel | ILogger): HubConnectionBuilder;
51-
public configureLogging(logging: LogLevel | ILogger): HubConnectionBuilder {
83+
public configureLogging(logging: LogLevel | string | ILogger): HubConnectionBuilder;
84+
public configureLogging(logging: LogLevel | string | ILogger): HubConnectionBuilder {
5285
Arg.isRequired(logging, "logging");
5386

5487
if (isLogger(logging)) {
5588
this.logger = logging;
89+
} else if (typeof logging === "string") {
90+
const logLevel = parseLogLevel(logging);
91+
this.logger = new ConsoleLogger(logLevel);
5692
} else {
5793
this.logger = new ConsoleLogger(logging);
5894
}
@@ -92,7 +128,7 @@ export class HubConnectionBuilder {
92128
// Flow-typing knows where it's at. Since HttpTransportType is a number and IHttpConnectionOptions is guaranteed
93129
// to be an object, we know (as does TypeScript) this comparison is all we need to figure out which overload was called.
94130
if (typeof transportTypeOrOptions === "object") {
95-
this.httpConnectionOptions = {...this.httpConnectionOptions, ...transportTypeOrOptions};
131+
this.httpConnectionOptions = { ...this.httpConnectionOptions, ...transportTypeOrOptions };
96132
} else {
97133
this.httpConnectionOptions = {
98134
...this.httpConnectionOptions,

src/SignalR/clients/ts/signalr/src/Utils.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,26 +147,35 @@ export class SubjectSubscription<T> implements ISubscription<T> {
147147
export class ConsoleLogger implements ILogger {
148148
private readonly minimumLogLevel: LogLevel;
149149

150+
// Public for testing purposes.
151+
public outputConsole: {
152+
error(message: any): void,
153+
warn(message: any): void,
154+
info(message: any): void,
155+
log(message: any): void,
156+
};
157+
150158
constructor(minimumLogLevel: LogLevel) {
151159
this.minimumLogLevel = minimumLogLevel;
160+
this.outputConsole = console;
152161
}
153162

154163
public log(logLevel: LogLevel, message: string): void {
155164
if (logLevel >= this.minimumLogLevel) {
156165
switch (logLevel) {
157166
case LogLevel.Critical:
158167
case LogLevel.Error:
159-
console.error(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);
168+
this.outputConsole.error(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);
160169
break;
161170
case LogLevel.Warning:
162-
console.warn(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);
171+
this.outputConsole.warn(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);
163172
break;
164173
case LogLevel.Information:
165-
console.info(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);
174+
this.outputConsole.info(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);
166175
break;
167176
default:
168177
// console.debug only goes to attached debuggers in Node, so we use console.log for Trace and Debug
169-
console.log(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);
178+
this.outputConsole.log(`[${new Date().toISOString()}] ${LogLevel[logLevel]}: ${message}`);
170179
break;
171180
}
172181
}

0 commit comments

Comments
 (0)