public static void Constructor___Valid___Works()
        {
            // Arrange
            var configurations = new LogWriterConfigBase[] { ShareSerializationTestLogic.FileConfig, ShareSerializationTestLogic.EventLogConfig, ShareSerializationTestLogic.ConsoleConfig }.ToList();

            // Act
            var actual = new LogWritingSettings(configurations);

            // Assert
            actual.Should().NotBeNull();
            actual.Configs.Should().BeEquivalentTo(configurations);
        }
        public static void Constructor___Null_configuration___Empty_set()
        {
            // Arrange
            LogWriterConfigBase[] configurations = null;

            // Act
            var actual = new LogWritingSettings(configurations);

            // Assert
            actual.Should().NotBeNull();
            actual.Configs.Should().NotBeNull();
            actual.Configs.Should().BeEmpty();
        }
        /// <summary>
        /// Runs common setup logic to prepare for and <see cref="Naos.Configuration" />, also will launch the debugger if the debug flag is provided.
        /// </summary>
        /// <param name="debug">A value indicating whether or not to launch the debugger.</param>
        /// <param name="environment">Optional environment name that will set the <see cref="Naos.Configuration" /> precedence instead of the default which is reading the App.Config value.</param>
        /// <param name="logWritingSettings">Optional <see cref="LogWritingSettings" /> to use instead of the default found in <see cref="Naos.Configuration" />.</param>
        /// <param name="configuredAndManagedLogProcessors">Optional set of pre-configured and externally managed <see cref="LogWriterBase" /> to use.</param>
        /// <param name="announcer">Optional announcer; DEFAULT is null which will go to <see cref="Console.WriteLine(string)" />.<see cref="Console.WriteLine(string)" />.</param>
        protected static void CommonSetup(bool debug, string environment = null, LogWritingSettings logWritingSettings = null, IReadOnlyCollection <LogWriterBase> configuredAndManagedLogProcessors = null, Action <string> announcer = null)
        {
            var launchTime     = DateTime.UtcNow;
            var localAnnouncer = BuildPrefixingAnnouncer(announcer);

            localAnnouncer(Invariant($"Launched at {launchTime.ToLocalTime().TimeOfDay} on {launchTime.ToLocalTime().Date} (Local) | {launchTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)}Z (UTC)."));
            localAnnouncer(Invariant($"> Common Setup"));

            /*---------------------------------------------------------------------------*
            * Useful for launching the debugger from the command line and making sure   *
            * it is connected to the instance of the IDE you want to use.               *
            *---------------------------------------------------------------------------*/
            if (debug)
            {
                localAnnouncer(Invariant($"Debugger was set to be launched (debug=true option provide).{Environment.NewLine}{DefaultAnnouncementPadding}{DefaultAnnouncementPadding}- If the VisualStudio debugger menu is not shown check your 'Just-In-Time debugger' settings.{Environment.NewLine}{DefaultAnnouncementPadding}{DefaultAnnouncementPadding}- Go to (Visual Studio Menu Bar)->Tools->Options{Environment.NewLine}{DefaultAnnouncementPadding}{DefaultAnnouncementPadding}- then (Options Left Pane Navigation)->Debugging->Just-In-Time{Environment.NewLine}{DefaultAnnouncementPadding}{DefaultAnnouncementPadding}- then (Just-In-Time Debugging Settings on right pane)->Make sure the 'Managed' check box is checked."));
                Debugger.Launch();
            }

            /*---------------------------------------------------------------------------*
            * Setup deserialization logic for any use of Naos.Configuration reading      *
            * config files from the '.config' directory with 'environment' sub folders  *
            * the chain of responsibility is set in the App.config file using the       *
            * 'Naos.Configuration.Settings.Precedence' setting.  You can override the    *
            * way this is used by specifying a different directory for the config or     *
            * providing additional precedence values using                               *
            * ResetConfigureSerializationAndSetValues.                                  *
            *---------------------------------------------------------------------------*/
            if (!string.IsNullOrWhiteSpace(environment))
            {
                localAnnouncer(Invariant($"Set Config Precedence to: '{environment}'."));
                Config.SetPrecedence(environment, Config.CommonPrecedence);
            }

            /*---------------------------------------------------------------------------*
            * Initialize logging; this sets up Its.Log which is what gets used through- *
            * out the code.  All logging will also get sent through it.  This  can be   *
            * swapped out to send all Its.Log messages to another logging framework if  *
            * there is already one in place.                                            *
            *---------------------------------------------------------------------------*/
            var localLogProcessorSettings = logWritingSettings ?? Config.Get <LogWritingSettings>(new SerializerRepresentation(SerializationKind.Json, typeof(LoggingJsonSerializationConfiguration).ToRepresentation()));

            if (localLogProcessorSettings == null)
            {
                localAnnouncer(Invariant($"{DefaultAnnouncementPadding}- No LogProcessorSettings provided or found in config; using Null Object substitute."));
                localLogProcessorSettings = new LogWritingSettings();
            }

            LogWriting.Instance.Setup(localLogProcessorSettings, localAnnouncer, configuredAndManagedLogProcessors, errorCodeKeys: new[] { "__OBC_ErrorCode__" });
            localAnnouncer(Invariant($"< Common Setup"));
        }
Beispiel #4
0
        /// <summary>
        /// Runs common setup logic to prepare for and <see cref="Naos.Configuration" />, also will launch the debugger if the debug flag is provided.
        /// </summary>
        /// <param name="debug">A value indicating whether or not to launch the debugger.</param>
        /// <param name="environment">Optional environment name that will set the <see cref="Naos.Configuration" /> precedence instead of the default which is reading the App.Config value.</param>
        /// <param name="logWritingSettings">Optional <see cref="LogWritingSettings" /> to use instead of the default found in <see cref="Naos.Configuration" />.</param>
        /// <param name="configuredAndManagedLogProcessors">Optional set of pre-configured and externally managed <see cref="LogWriterBase" /> to use.</param>
        /// <param name="announcer">Optional announcer; DEFAULT is null which will go to <see cref="Console.WriteLine(string)" />.<see cref="Console.WriteLine(string)" />.</param>
        protected static void CommonSetup(bool debug, string environment = null, LogWritingSettings logWritingSettings = null, IReadOnlyCollection <LogWriterBase> configuredAndManagedLogProcessors = null, Action <string> announcer = null)
        {
            var localAnnouncer = announcer ?? Console.WriteLine;

            /*---------------------------------------------------------------------------*
            * Useful for launching the debugger from the command line and making sure   *
            * it is connected to the instance of the IDE you want to use.               *
            *---------------------------------------------------------------------------*/
            if (debug)
            {
                Debugger.Launch();
            }

            /*---------------------------------------------------------------------------*
            * Setup deserialization logic for any use of Naos.Configuration reading      *
            * config files from the '.config' directory with 'environment' sub folders  *
            * the chain of responsibility is set in the App.config file using the       *
            * 'Naos.Configuration.Settings.Precedence' setting.  You can override the    *
            * way this is used by specifying a different diretory for the config or     *
            * providing additonal precedence values using                               *
            * ResetConfigureSerializationAndSetValues.                                  *
            *---------------------------------------------------------------------------*/
            if (!string.IsNullOrWhiteSpace(environment))
            {
                Config.SetPrecedence(environment, Config.CommonPrecedence);
            }

            /*---------------------------------------------------------------------------*
            * Initialize logging; this sets up Its.Log which is what gets used through- *
            * out the code.  All logging will also get sent through it.  This  can be   *
            * swapped out to send all Its.Log messages to another logging framework if  *
            * there is already one in place.                                            *
            *---------------------------------------------------------------------------*/
            var localLogProcessorSettings = logWritingSettings ?? Config.Get <LogWritingSettings>(typeof(LoggingJsonConfiguration));

            if (localLogProcessorSettings == null)
            {
                localAnnouncer("No LogProcessorSettings provided or found in config; using Null Object susbstitue.");
                localLogProcessorSettings = new LogWritingSettings();
            }

            LogWriting.Instance.Setup(localLogProcessorSettings, localAnnouncer, configuredAndManagedLogProcessors, errorCodeKeys: new[] { "__OBC_ErrorCode__" });
        }
        public static void Example(
            [Aliases("")][Description("Launches the debugger.")][DefaultValue(false)] bool debug,
            [Aliases("")][Description("Sets the Naos.Configuration precedence to use specific settings.")][DefaultValue(null)] string environment,
            [Required][Aliases("")][Description("Example of a directory that needs to be checked for files to process.")] string filePathToProcess)
        {
            /*---------------------------------------------------------------------------*
            * Normally this would just be done from the Naos.Configuration file but the  *
            * we're overriding to only use the Console for demonstration purposes.      *
            *---------------------------------------------------------------------------*/
            var logProcessorSettingsOverride = new LogWritingSettings(new[]
            {
                new ConsoleLogConfig(
                    new Dictionary <LogItemKind, IReadOnlyCollection <string> >(),  // all
                    new Dictionary <LogItemKind, IReadOnlyCollection <string> > {
                    { LogItemKind.Exception, null }
                },                                                               // all Exceptions
                    new Dictionary <LogItemKind, IReadOnlyCollection <string> >  // Strings and Objects from ItsLogEntryPosted
                {
                    { LogItemKind.String, new[] { LogItemOrigin.ItsLogEntryPosted.ToString() } },
                    { LogItemKind.Object, new[] { LogItemOrigin.ItsLogEntryPosted.ToString() } },
                }),
            });

            /*---------------------------------------------------------------------------*
            * Any method should run this logic to debug, setup config & logging, etc.   *
            *---------------------------------------------------------------------------*/
            CommonSetup(debug, environment, logProcessorSettingsOverride);

            /*---------------------------------------------------------------------------*
            * Any method should run this logic to write telemetry info to the log.      *
            *---------------------------------------------------------------------------*/
            // WriteStandardTelemetry(); // removing this for now because it's not being collected well enough

            /*---------------------------------------------------------------------------*
            * This is not necessary but often very useful to print out the arguments.   *
            *---------------------------------------------------------------------------*/
            PrintArguments(new { filePathToProcess, environment });

            Its.Log.Instrumentation.Log.Write(() => Invariant($"Processed files at: {filePathToProcess}"));
        }
Beispiel #6
0
        private static InMemoryLogWriter BuildAndConfigureMemoryLogWriter()
        {
            lock (MemoryLogWriterSync)
            {
                if (memoryLogWriter == null)
                {
                    var memoryLogConfig =
                        new InMemoryLogConfig(new Dictionary <LogItemKind, IReadOnlyCollection <string> >());
                    memoryLogWriter = new InMemoryLogWriter(memoryLogConfig);
                    var settings = new LogWritingSettings();
                    LogWriting.Instance.Setup(
                        settings,
                        configuredAndManagedLogWriters: new[] { memoryLogWriter },
                        errorCodeKeys: new[] { ErrorCodeConstants.ExceptionDataKeyForErrorCode },
                        multipleCallsToSetupStrategy: MultipleCallsToSetupStrategy.Overwrite);
                }
                else
                {
                    memoryLogWriter.PurgeAllLoggedItems();
                }

                return(memoryLogWriter);
            }
        }
        public void Test_NaosLogWrite_Versus_ItsLogWrite()
        {
            // Arrange
            var memoryLogConfig =
                new InMemoryLogConfig(new Dictionary <LogItemKind, IReadOnlyCollection <string> >());
            var memoryLogWriter = new InMemoryLogWriter(memoryLogConfig);
            var settings        = new LogWritingSettings();

            LogWriting.Instance.Setup(
                settings,
                configuredAndManagedLogWriters: new[] { memoryLogWriter },
                errorCodeKeys: new[] { ErrorCodeConstants.ExceptionDataKeyForErrorCode },
                multipleCallsToSetupStrategy: MultipleCallsToSetupStrategy.Overwrite);

            var itsLogStopwatch  = new Stopwatch();
            var naosLogStopwatch = new Stopwatch();
            var testSubjects     = Enumerable.Range(0, 100).Select(_ => Invariant($"{Guid.NewGuid().ToString()}{_}")).ToList();

            // Act
            itsLogStopwatch.Start();
            foreach (var testSubject in testSubjects)
            {
                Its.Log.Instrumentation.Log.Write(() => testSubject);
                using (var logger = Its.Log.Instrumentation.Log.Enter(() => testSubject))
                {
                    logger.Trace(() => testSubject);
                }
            }

            while (memoryLogWriter.LoggedItems.Count < testSubjects.Count * 4)
            {
                Thread.Sleep(100);
            }

            itsLogStopwatch.Stop();
            this.testOutputHelper.WriteLine("Its Log Took: " + itsLogStopwatch.Elapsed);

            memoryLogWriter.PurgeAllLoggedItems();
            naosLogStopwatch.Start();
            foreach (var testSubject in testSubjects)
            {
                Naos.Logging.Domain.Log.Write(() => testSubject);
                using (var logger = Naos.Logging.Domain.Log.With(() => testSubject))
                {
                    logger.Write(() => testSubject);
                }
            }

            while (memoryLogWriter.LoggedItems.Count < testSubjects.Count * 4)
            {
                Thread.Sleep(100);
            }

            naosLogStopwatch.Stop();
            this.testOutputHelper.WriteLine("Naos Log Took: " + naosLogStopwatch.Elapsed);

            naosLogStopwatch.Elapsed.Should().BeLessThan(itsLogStopwatch.Elapsed);

            foreach (var logItem in memoryLogWriter.LoggedItems)
            {
                var message = LogWriterBase.BuildLogMessageFromLogItem(logItem, LogItemPropertiesToIncludeInLogMessage.Default, memoryLogWriter.BuildSerializer());
                this.testOutputHelper.WriteLine(message);
            }
        }
Beispiel #8
0
        public void Setup(
            LogWritingSettings logWritingSettings,
            Action <string> announcer = null,
            IReadOnlyCollection <LogWriterBase> configuredAndManagedLogWriters = null,
            MultipleCallsToSetupStrategy multipleCallsToSetupStrategy          = MultipleCallsToSetupStrategy.Throw,
            IReadOnlyCollection <string> errorCodeKeys = null)
        {
            if (logWritingSettings == null)
            {
                throw new ArgumentNullException(nameof(logWritingSettings));
            }

            if (multipleCallsToSetupStrategy == MultipleCallsToSetupStrategy.Invalid)
            {
                throw new ArgumentException(Invariant($"{nameof(multipleCallsToSetupStrategy)} == {nameof(MultipleCallsToSetupStrategy.Invalid)}"));
            }

            this.errorCodeKeysField = errorCodeKeys;
            var localAnnouncer = announcer ?? NullAnnouncement;

            lock (this.sync)
            {
                if (this.hasBeenSetup)
                {
                    switch (multipleCallsToSetupStrategy)
                    {
                    case MultipleCallsToSetupStrategy.Throw:
                        throw new ArgumentException(Invariant($"{nameof(LogWriting)}.{nameof(LogWriting.Setup)} was called a second time with {nameof(multipleCallsToSetupStrategy)} - {multipleCallsToSetupStrategy}."));

                    case MultipleCallsToSetupStrategy.Ignore:
                        return;

                    case MultipleCallsToSetupStrategy.Overwrite:
                        break;

                    default:
                        throw new NotSupportedException(Invariant($"{nameof(LogWriting)}.{nameof(LogWriting.Setup)} was called with unspported {nameof(multipleCallsToSetupStrategy)} - {multipleCallsToSetupStrategy}."));
                    }
                }

                this.hasBeenSetup = true;

                var logWriters = new List <LogWriterBase>(configuredAndManagedLogWriters ?? new LogWriterBase[0]);
                if (logWriters.Any())
                {
                    localAnnouncer(Invariant($"Used pre-configured loggers: {string.Join(",", logWriters)}"));
                }

                foreach (var config in logWritingSettings.Configs)
                {
                    LogWriterBase logWriter;
                    switch (config)
                    {
                    case FileLogConfig fileLogConfig:
                        logWriter = new FileLogWriter(fileLogConfig);
                        break;

                    case TimeSlicedFilesLogConfig timeSlicedFilesLogConfig:
                        logWriter = new TimeSlicedFilesLogWriter(timeSlicedFilesLogConfig);
                        break;

                    case EventLogConfig eventLogConfig:
                        logWriter = new EventLogWriter(eventLogConfig);
                        break;

                    case ConsoleLogConfig consoleLogConfig:
                        logWriter = new ConsoleLogWriter(consoleLogConfig);
                        break;

                    default:
                        throw new NotSupportedException(Invariant($"Unsupported implementation of {nameof(LogWriterConfigBase)} - {config.GetType().ToStringReadable()}, try providing a pre-configured implementation of {nameof(LogWriterBase)} until the config type is supported."));
                    }

                    logWriters.Add(logWriter);
                    localAnnouncer(Invariant($"Wired up {logWriter}."));
                }

                this.activeLogWriters = logWriters;

                this.WireUpAppDomainUnhandledExceptionToActiveLogWriters(localAnnouncer);
                this.WireUpItsLogInternalErrorsToActiveLogWriters(localAnnouncer);
                this.WireUpItsLogEntryPostedToActiveLogWriters(localAnnouncer);
                this.WireUpNaosLoggerToActiveLogWriters(localAnnouncer);
            }
        }