Example #1
0
        /// <summary>
        ///     This method allows CASaaS to replace the host's logger for our own logger.
        /// </summary>
        /// <remarks>
        ///     Since we don't perform any kind of stats aggregation on our side (i.e. statsd, MDM, etc), we rely on
        ///     the host to do it. This is done through <see cref="MetricsAdapter"/>.
        ///
        ///     The situation with respect to shutdown is a little bit odd: we create a custom target, which holds some
        ///     managed resources that need to be released (because this release ensures any remaining logs will be
        ///     sent to Kusto).
        ///     NLog will make sure to dispose those resources when we shut it down, but we may actually return the
        ///     host's logger, in which case we don't consider that we own it, because clean up may happen on whatever
        ///     code is actually using us, so we don't want to dispose in that case.
        /// </remarks>
        public static (ILogger Logger, IDisposable DisposableToken) CreateReplacementLogger(LoggerFactoryArguments arguments)
        {
            var logger = arguments.Logger;

            var loggingSettings = arguments.LoggingSettings;

            if (string.IsNullOrEmpty(loggingSettings?.NLogConfigurationPath))
            {
                return(logger, null);
            }

            // This context is associated to the host's logger. In this way, we can make sure that if we have any
            // issues with our logging, we can always go and read the host's logs to figure out what's going on.
            var context          = new Context(logger);
            var operationContext = new OperationContext(context);

            Tracer.Info(context, $"Replacing cache logger for NLog-based implementation using configuration file at `{loggingSettings.NLogConfigurationPath}`");

            try
            {
                var nLogAdapter = CreateNLogAdapter(operationContext, arguments);
                context = new Context(nLogAdapter);
                if (arguments.Logger is IOperationLogger operationLogger)
                {
                    // NOTE(jubayard): the MetricsAdapter doesn't own the loggers, and hence won't dispose them. This
                    // means we don't change the disposableToken.
                    Tracer.Debug(context, "Creating MetricsAdapter with an existing 'operationLogger'.");
                    var wrapper = new MetricsAdapter(nLogAdapter, operationLogger);
                    return(wrapper, nLogAdapter);
                }
                // The current implementation now supports the mdm metrics as well.
                if (!string.IsNullOrEmpty(arguments.LoggingSettings.MdmAccountName))
                {
                    Tracer.Debug(context, "Creating MetricsLogger with an in-proc MdmOperationLogger.");
                    operationLogger = MdmOperationLogger.Create(context, arguments.LoggingSettings.MdmAccountName, GetDefaultDimensions(arguments));
                    var wrapper = new MetricsAdapter(nLogAdapter, operationLogger);
                    return(wrapper, nLogAdapter);
                }
                return(nLogAdapter, nLogAdapter);
            }
            catch (Exception e)
            {
                Tracer.Error(context, $"Failed to instantiate NLog-based logger with error: {e}");
                return(logger, null);
            }
        }
Example #2
0
        /// <summary>
        ///     This method allows CASaaS to replace the host's logger for our own logger.
        /// </summary>
        /// <remarks>
        ///     Since we don't perform any kind of stats aggregation on our side (i.e. statsd, MDM, etc), we rely on
        ///     the host to do it. This is done through <see cref="MetricsAdapter"/>.
        ///
        ///     The situation with respect to shutdown is a little bit odd: we create a custom target, which holds some
        ///     managed resources that need to be released (because this release ensures any remaining logs will be
        ///     sent to Kusto).
        ///     NLog will make sure to dispose those resources when we shut it down, but we may actually return the
        ///     host's logger, in which case we don't consider that we own it, because clean up may happen on whatever
        ///     code is actually using us, so we don't want to dispose in that case.
        /// </remarks>
        public static (ILogger Logger, IDisposable DisposableToken) CreateReplacementLogger(LoggerFactoryArguments arguments)
        {
            Contract.RequiresNotNull(arguments.TelemetryFieldsProvider);

            var logger = arguments.Logger;

            var loggingSettings = arguments.LoggingSettings;

            if (string.IsNullOrEmpty(loggingSettings?.NLogConfigurationPath))
            {
                return(logger, null);
            }

            // This context is associated to the host's logger. In this way, we can make sure that if we have any
            // issues with our logging, we can always go and read the host's logs to figure out what's going on.
            var context          = new Context(logger);
            var operationContext = new OperationContext(context);

            context.Info($"Replacing cache logger for NLog-based implementation using configuration file at `{loggingSettings.NLogConfigurationPath}`");

            try
            {
                var nLogAdapter = CreateNLogAdapter(operationContext, arguments);
                if (arguments.Logger is IOperationLogger operationLogger)
                {
                    // NOTE(jubayard): the MetricsAdapter doesn't own the loggers, and hence won't dispose them. This
                    // means we don't change the disposableToken.
                    var wrapper = new MetricsAdapter(nLogAdapter, operationLogger);
                    return(wrapper, nLogAdapter);
                }

                return(nLogAdapter, nLogAdapter);
            }
            catch (Exception e)
            {
                context.Error($"Failed to instantiate NLog-based logger with error: {e}");
                return(logger, null);
            }
        }