Пример #1
0
        /// <summary>
        /// Create a logger using the configured sinks, enrichers and minimum level.
        /// </summary>
        /// <returns>The logger.</returns>
        /// <remarks>To free resources held by sinks ahead of program shutdown,
        /// the returned logger may be cast to <see cref="IDisposable"/> and
        /// disposed.</remarks>
        public Logger CreateLogger()
        {
            if (_loggerCreated)
            {
                throw new InvalidOperationException("CreateLogger() was previously called and can only be called once.");
            }
            _loggerCreated = true;

            Action dispose = () =>
            {
                foreach (var disposable in _logEventSinks.OfType <IDisposable>())
                {
                    disposable.Dispose();
                }
            };

            ILogEventSink sink = new SafeAggregateSink(_logEventSinks);

            if (_filters.Any())
            {
                sink = new FilteringSink(sink, _filters);
            }

            var converter = new PropertyValueConverter(_maximumDestructuringDepth, _additionalScalarTypes, _additionalDestructuringPolicies);
            var processor = new MessageTemplateProcessor(converter);

            ILogEventEnricher enricher;

            switch (_enrichers.Count)
            {
            case 0:
                // Should be a rare case, so no problem making that extra interface dispatch.
                enricher = new EmptyEnricher();
                break;

            case 1:
                enricher = _enrichers[0];
                break;

            default:
                enricher = new SafeAggregateEnricher(_enrichers);
                break;
            }

            LevelOverrideMap overrideMap = null;

            if (_overrides.Count != 0)
            {
                overrideMap = new LevelOverrideMap(_overrides, _minimumLevel, _levelSwitch);
            }

            return(_levelSwitch == null ?
                   new Logger(processor, _minimumLevel, sink, enricher, dispose, overrideMap) :
                   new Logger(processor, _levelSwitch, sink, enricher, dispose, overrideMap));
        }
Пример #2
0
        /// <summary>
        /// Initializes a subscription tracking service based on the supplied
        /// <paramref name="configuration"/>
        /// </summary>
        /// <param name="configuration">The subscription tracking configuration</param>
        /// <returns>Returns a task whose result is the initialized subscription tracking service</returns>
        public async Task <IDiagnosticEventSink> InitDiagnosticEventSink(IConfiguration configuration)
        {
            var name         = configuration?["name"];
            var providerName = configuration?["provider"];

            if (string.IsNullOrWhiteSpace(providerName))
            {
                var message = "Provider not specified for diagnostic event sink '" + name + "'";
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationError)
                {
                    Detail = message
                }.Build());

                throw new ConfigurationErrorsException(message);
            }

            var provider = GetProvider(providerName);

            if (provider == null)
            {
                var message = "Unknown provider '" + providerName + "' specified for diagnostic event sink '" + name + "'";
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationError)
                {
                    Detail = message
                }.Build());

                throw new ConfigurationErrorsException(message);
            }

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = "Initializing diagnostic event sink '" + name + "'"
            }.Build());

            var minLevel = configuration.GetValue("minLevel", DiagnosticEventLevel.Debug);
            var maxLevel = configuration.GetValue("minLevel", DiagnosticEventLevel.Error);
            var sink     = await provider.CreateDiagnosticEventSink(configuration);

            var filterSpec = new DiagnosticEventLevelSpecification(minLevel, maxLevel);
            var filterSink = new FilteringSink(sink, filterSpec);

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = "Diagnostic event sink '" + name + "' initialized"
            }.Build());

            return(filterSink);
        }
Пример #3
0
        /// <summary>
        /// Initializes a subscription tracking service based on the supplied
        /// <paramref name="configuration"/>
        /// </summary>
        /// <param name="configuration">The subscription tracking configuration</param>
        /// <returns>Returns a task whose result is the initialized subscription tracking service</returns>
        public async Task <IDiagnosticEventSink> InitDiagnosticEventSink(DiagnosticEventSinkElement configuration)
        {
            var myConfig = configuration ?? new DiagnosticEventSinkElement();

            if (string.IsNullOrWhiteSpace(myConfig.Provider))
            {
                var message = "Provider not specified for diagnostic event sink '" + myConfig.Name + "'";
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationError)
                {
                    Detail = message
                }.Build());

                throw new ConfigurationErrorsException(message);
            }

            var provider = GetProvider(myConfig.Provider);

            if (provider == null)
            {
                var message = "Unknown provider '" + myConfig.Provider + "' specified for diagnostic event sink '" + myConfig.Name + "'";
                await _diagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.ConfigurationError)
                {
                    Detail = message
                }.Build());

                throw new ConfigurationErrorsException(message);
            }

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = "Initializing diagnostic event sink '" + myConfig.Name + "'"
            }.Build());

            var sink = await provider.CreateDiagnosticEventSink(myConfig);

            var filterSpec = new DiagnosticEventLevelSpecification(myConfig.MinLevel, myConfig.MaxLevel);
            var filterSink = new FilteringSink(sink, filterSpec);

            await _diagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.ComponentInitialization)
            {
                Detail = "Diagnostic event sink '" + myConfig.Name + "' initialized"
            }.Build());

            return(filterSink);
        }
Пример #4
0
 protected async Task WhenFilteringAsync()
 {
     var filter = new FilteringSink(Inner.Object, Specification);
     await filter.ConsumeAsync(Event);
 }
Пример #5
0
        protected void WhenFiltering()
        {
            var filter = new FilteringSink(Inner.Object, Specification);

            filter.Consume(Event);
        }
Пример #6
0
        /// <summary>
        /// Create a logger using the configured sinks, enrichers and minimum level.
        /// </summary>
        /// <returns>The logger.</returns>
        /// <remarks>To free resources held by sinks ahead of program shutdown,
        /// the returned logger may be cast to <see cref="IDisposable"/> and
        /// disposed.</remarks>
        public Logger CreateLogger()
        {
            if (_loggerCreated)
                throw new InvalidOperationException("CreateLogger() was previously called and can only be called once.");
            _loggerCreated = true;

            Action dispose = () =>
            {
                foreach (var disposable in _logEventSinks.OfType<IDisposable>())
                    disposable.Dispose();
            };

            ILogEventSink sink = new SafeAggregateSink(_logEventSinks);

            var auditing = _auditSinks.Any();
            if (auditing)
                sink = new AggregateSink(new[] { sink }.Concat(_auditSinks));

            if (_filters.Any())
            {
                // A throwing filter could drop an auditable event, so exceptions in filters must be propagated
                // if auditing is used.
                sink = new FilteringSink(sink, _filters, auditing);
            }

            var converter = new PropertyValueConverter(_maximumDestructuringDepth, _additionalScalarTypes, _additionalDestructuringPolicies, auditing);
            var processor = new MessageTemplateProcessor(converter);

            ILogEventEnricher enricher;
            switch (_enrichers.Count)
            {
                case 0:
                    // Should be a rare case, so no problem making that extra interface dispatch.
                    enricher = new EmptyEnricher();
                    break;
                case 1:
                    enricher = _enrichers[0];
                    break;
                default:
                    enricher = new SafeAggregateEnricher(_enrichers);
                    break;
            }

            LevelOverrideMap overrideMap = null;
            if (_overrides.Count != 0)
            {
                overrideMap = new LevelOverrideMap(_overrides, _minimumLevel, _levelSwitch);
            }

            return _levelSwitch == null ?
                new Logger(processor, _minimumLevel, sink, enricher, dispose, overrideMap) :
                new Logger(processor, _levelSwitch, sink, enricher, dispose, overrideMap);
        }
        /// <summary>
        /// Create a logger using the configured sinks, enrichers and minimum level.
        /// </summary>
        /// <returns>The logger.</returns>
        /// <remarks>To free resources held by sinks ahead of program shutdown,
        /// the returned logger may be cast to <see cref="IDisposable"/> and
        /// disposed.</remarks>
        /// <exception cref="InvalidOperationException">When the logger is already created</exception>
        public Logger CreateLogger()
        {
            if (_loggerCreated)
            {
                throw new InvalidOperationException("CreateLogger() was previously called and can only be called once.");
            }

            _loggerCreated = true;

            ILogEventSink sink = new SafeAggregateSink(_logEventSinks);

            var auditing = _auditSinks.Any();

            if (auditing)
            {
                sink = new AggregateSink(new[] { sink }.Concat(_auditSinks));
            }

            if (_filters.Any())
            {
                // A throwing filter could drop an auditable event, so exceptions in filters must be propagated
                // if auditing is used.
                sink = new FilteringSink(sink, _filters, auditing);
            }

            var converter = new PropertyValueConverter(
                _maximumDestructuringDepth,
                _maximumStringLength,
                _maximumCollectionCount,
                _additionalScalarTypes,
                _additionalDestructuringPolicies,
                auditing);
            var processor = new MessageTemplateProcessor(converter);

            ILogEventEnricher enricher;

            switch (_enrichers.Count)
            {
            case 0:
                // Should be a rare case, so no problem making that extra interface dispatch.
                enricher = new EmptyEnricher();
                break;

            case 1:
                enricher = _enrichers[0];
                break;

            default:
                // Enrichment failures are not considered blocking for auditing purposes.
                enricher = new SafeAggregateEnricher(_enrichers);
                break;
            }

            LevelOverrideMap overrideMap = null;

            if (_overrides.Count != 0)
            {
                overrideMap = new LevelOverrideMap(_overrides, _minimumLevel, _levelSwitch);
            }

            var disposableSinks = _logEventSinks.Concat(_auditSinks).OfType <IDisposable>().ToArray();

            void Dispose()
            {
                foreach (var disposable in disposableSinks)
                {
                    disposable.Dispose();
                }
            }

            return(_levelSwitch == null ?
                   new Logger(processor, _minimumLevel, sink, enricher, Dispose, overrideMap) :
                   new Logger(processor, _levelSwitch, sink, enricher, Dispose, overrideMap));
        }