diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IDiagnosticLogger.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IDiagnosticLogger.ts index 5b79e6d90..13e48bd3b 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IDiagnosticLogger.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IDiagnosticLogger.ts @@ -48,6 +48,14 @@ export interface IDiagnosticLogger { */ warnToConsole(message: string): void; + /** + * This will write an error to the console if possible. + * Provided by the default DiagnosticLogger instance, and internally the SDK will fall back to warnToConsole, however, + * direct callers MUST check for its existence on the logger as you can provide your own IDiagnosticLogger instance. + * @param message {string} - The error message + */ + errorToConsole?(message: string): void; + /** * Resets the internal message count */ diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/BaseCore.ts b/shared/AppInsightsCore/src/JavaScriptSDK/BaseCore.ts index 0643b0a00..3c2ea5033 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/BaseCore.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/BaseCore.ts @@ -23,6 +23,7 @@ import { ICookieMgr } from "../JavaScriptSDK.Interfaces/ICookieMgr"; import { createCookieMgr } from "./CookieMgr"; import { arrForEach, isNullOrUndefined, toISOString, getSetValue, setValue, throwError, isNotTruthy, isFunction } from "./HelperFuncs"; import { strExtensionConfig, strIKey } from "./Constants"; +import { DiagnosticLogger } from "./DiagnosticLogger"; const validationError = "Extensions must provide callback to initialize"; @@ -56,11 +57,8 @@ export class BaseCore implements IAppInsightsCore { dynamicProto(BaseCore, this, (_self) => { _self._extensions = new Array(); _channelController = new ChannelController(); - _self.logger = objCreateFn({ - throwInternal: (severity: LoggingSeverity, msgId: _InternalMessageId, msg: string, properties?: Object, isUserAct = false) => { }, - warnToConsole: (message: string) => { }, - resetInternalMessageCount: () => { } - }); + // Use a default logger so initialization errors are not dropped on the floor with full logging + _self.logger = new DiagnosticLogger({ loggingLevelConsole: LoggingSeverity.CRITICAL }); _eventQueue = []; _self.isInitialized = () => _isInitialized; @@ -74,7 +72,7 @@ export class BaseCore implements IAppInsightsCore { if (!config || isNullOrUndefined(config.instrumentationKey)) { throwError("Please provide instrumentation key"); } - + _notificationManager = notificationManager; // For backward compatibility only @@ -95,7 +93,7 @@ export class BaseCore implements IAppInsightsCore { if (logger) { _self.logger = logger; } - + // Concat all available extensions let allExtensions = []; allExtensions.push(...extensions, ...config.extensions); diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/DiagnosticLogger.ts b/shared/AppInsightsCore/src/JavaScriptSDK/DiagnosticLogger.ts index 3a9488779..3fa335ece 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/DiagnosticLogger.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/DiagnosticLogger.ts @@ -24,6 +24,8 @@ const AiUserActionablePrefix = "AI: "; */ const AIInternalMessagePrefix = "AITR_"; +const strErrorToConsole = "errorToConsole"; +const strWarnToConsole = "warnToConsole"; function _sanitizeDiagnosticText(text: string) { if (text) { @@ -33,6 +35,20 @@ function _sanitizeDiagnosticText(text: string) { return ""; } +function _logToConsole(func: string, message: string) { + let theConsole = getConsole(); + if (!!theConsole) { + let logFunc = "log"; + if (theConsole[func]) { + logFunc = "func"; + } + + if (isFunction(theConsole[logFunc])) { + theConsole[logFunc](message); + } + } +} + export class _InternalLogMessage{ public static dataType: string = "MessageData"; @@ -107,20 +123,23 @@ export class DiagnosticLogger implements IDiagnosticLogger { if (_self.enableDebugExceptions()) { throw message; } else { + // Get the logging function and fallback to warnToConsole of for some reason errorToConsole doesn't exist + let logFunc = severity === LoggingSeverity.CRITICAL ? strErrorToConsole : strWarnToConsole; + if (!isUndefined(message.message)) { const logLevel = _self.consoleLoggingLevel(); if (isUserAct) { // check if this message type was already logged to console for this page view and if so, don't log it again const messageKey: number = +message.messageId; - if (!_messageLogged[messageKey] && logLevel >= LoggingSeverity.WARNING) { - _self.warnToConsole(message.message); + if (!_messageLogged[messageKey] && logLevel >= severity) { + _self[logFunc](message.message); _messageLogged[messageKey] = true; } } else { - // don't log internal AI traces in the console, unless the verbose logging is enabled - if (logLevel >= LoggingSeverity.WARNING) { - _self.warnToConsole(message.message); + // Only log traces if the console Logging Level is >= the throwInternal severity level + if (logLevel >= severity) { + _self[logFunc](message.message); } } @@ -134,17 +153,15 @@ export class DiagnosticLogger implements IDiagnosticLogger { * @param message {string} - The warning message */ _self.warnToConsole = (message: string) => { - let theConsole = getConsole(); - if (!!theConsole) { - let logFunc = "log"; - if (theConsole.warn) { - logFunc = "warn"; - } + _logToConsole("warn", message); + } - if (isFunction(theConsole[logFunc])) { - theConsole[logFunc](message); - } - } + /** + * This will write an error to the console if possible + * @param message {string} - The error message + */ + _self.errorToConsole = (message: string) => { + _logToConsole("error", message); } /** @@ -261,6 +278,14 @@ export class DiagnosticLogger implements IDiagnosticLogger { // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging } + /** + * This will write an error to the console if possible + * @param message {string} - The warning message + */ + public errorToConsole(message: string) { + // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging + } + /** * Resets the internal message count */