Пример #1
0
        /// <summary>
        /// Initializes the log message.
        /// </summary>
        /// <param name="timestamp">Time the message was written to the log.</param>
        /// <param name="highPrecisionTimestamp">
        /// Timestamp for relative time measurements with high precision
        /// (the actual precision depends on the <see cref="System.Diagnostics.Stopwatch"/> class).
        /// </param>
        /// <param name="lostMessageCount">
        /// Gets or sets the number of preceding messages that have been lost before this message
        /// (useful when dealing with message streams).
        /// </param>
        /// <param name="logWriterName">Name of the log writer that was used to emit the message.</param>
        /// <param name="logLevelName">Name of the log level that is associated with the message.</param>
        /// <param name="tags">Tags that are associated with the message.</param>
        /// <param name="applicationName">
        /// Name of the application emitting the log message
        /// (can differ from the process name, if the application is using an interpreter (the actual process)).
        /// </param>
        /// <param name="processName">Name of the process emitting the log message.</param>
        /// <param name="processId">Id of the process emitting the log message.</param>
        /// <param name="text">The actual text the log message is about.</param>
        /// <returns>The initialized log message.</returns>
        /// <exception cref="InvalidOperationException">The log message has not been prepared for asynchronous initialization.</exception>
        /// <exception cref="InvalidOperationException">The log message is already initialized.</exception>
        LogMessage ILogMessageInitializer.Initialize(
            DateTimeOffset timestamp,
            long highPrecisionTimestamp,
            int lostMessageCount,
            string logWriterName,
            string logLevelName,
            TagSet tags,
            string applicationName,
            string processName,
            int processId,
            string text)
        {
            lock (Sync)
            {
                if (!IsAsyncInitPending)
                {
                    throw new InvalidOperationException("The log message is not prepared for asynchronous initialization.");
                }

                if (IsInitializedInternal)
                {
                    throw new InvalidOperationException("The log message is already initialized.");
                }

                mTimestamp = timestamp;
                mHighPrecisionTimestamp = highPrecisionTimestamp;
                mLostMessageCount       = lostMessageCount;
                mLogWriterName          = logWriterName;
                mLogLevelName           = logLevelName;
                mTags            = tags;
                mApplicationName = applicationName;
                mProcessName     = processName;
                mProcessId       = processId;
                mText            = text;

                IsAsyncInitPending    = false;
                IsInitializedInternal = true;
            }

            OnPropertyChanged(null);

            return(this);
        }
Пример #2
0
        /// <summary>
        /// Initializes the log message.
        /// </summary>
        /// <param name="id">Id uniquely identifying the message in the log file.</param>
        /// <param name="timestamp">Time the message was written to the log.</param>
        /// <param name="highPrecisionTimestamp">
        /// Timestamp for relative time measurements with high precision
        /// (the actual precision depends on the <see cref="System.Diagnostics.Stopwatch"/> class).
        /// </param>
        /// <param name="lostMessageCount">
        /// Gets or sets the number of preceding messages that have been lost before this message
        /// (useful when dealing with message streams).
        /// </param>
        /// <param name="logWriterName">Name of the log writer that was used to emit the message.</param>
        /// <param name="logLevelName">Name of the log level that is associated with the message.</param>
        /// <param name="tags">Tags that are associated with the message.</param>
        /// <param name="applicationName">
        /// Name of the application emitting the log message
        /// (can differ from the process name, if the application is using an interpreter (the actual process)).
        /// </param>
        /// <param name="processName">Name of the process emitting the log message.</param>
        /// <param name="processId">Id of the process emitting the log message.</param>
        /// <param name="text">The actual text the log message is about.</param>
        /// <returns>The initialized log message.</returns>
        /// <exception cref="InvalidOperationException">The log message has not been prepared for asynchronous initialization.</exception>
        /// <exception cref="InvalidOperationException">The log message is already initialized.</exception>
        LogFileMessage IFileLogMessageInitializer.Initialize(
            long id,
            DateTimeOffset timestamp,
            long highPrecisionTimestamp,
            int lostMessageCount,
            string logWriterName,
            string logLevelName,
            TagSet tags,
            string applicationName,
            string processName,
            int processId,
            string text)
        {
            lock (Sync)
            {
                // disable raising the PropertyChanged event
                PropertyChangedSuspensionCounter++;

                // set specific message fields
                mId = id;

                // set command message fields
                ((ILogMessageInitializer)this).Initialize(
                    timestamp,
                    highPrecisionTimestamp,
                    lostMessageCount,
                    logWriterName,
                    logLevelName,
                    tags,
                    applicationName,
                    processName,
                    processId,
                    text);

                // enable raising the PropertyChanged event
                PropertyChangedSuspensionCounter--;
            }

            OnPropertyChanged(null);

            return(this);
        }
Пример #3
0
        /// <summary>
        /// Initializes the log message atomically.
        /// The <see cref="PropertyChanged"/> event is only fired once.
        /// </summary>
        /// <param name="timestamp">Time the message was written to the log.</param>
        /// <param name="highPrecisionTimestamp">
        /// Timestamp for relative time measurements with high precision
        /// (the actual precision depends on the <see cref="System.Diagnostics.Stopwatch"/> class).
        /// </param>
        /// <param name="lostMessageCount">
        /// Gets or sets the number of preceding messages that have been lost before this message
        /// (useful when dealing with message streams).
        /// </param>
        /// <param name="logWriterName">Name of the log writer that was used to emit the message.</param>
        /// <param name="logLevelName">Name of the log level that is associated with the message.</param>
        /// <param name="tags">Tags that are associated with the message.</param>
        /// <param name="applicationName">
        /// Name of the application emitting the log message
        /// (can differ from the process name, if the application is using an interpreter (the actual process)).
        /// </param>
        /// <param name="processName">Name of the process emitting the log message.</param>
        /// <param name="processId">Id of the process emitting the log message.</param>
        /// <param name="text">The actual text the log message is about.</param>
        /// <returns>The log message itself.</returns>
        /// <exception cref="NotSupportedException">The log message is read-only.</exception>
        /// <exception cref="InvalidOperationException">Initializing manually is not allowed as an asynchronous initialization is pending.</exception>
        public LogMessage InitWith(
            DateTimeOffset timestamp,
            long highPrecisionTimestamp,
            int lostMessageCount,
            string logWriterName,
            string logLevelName,
            TagSet tags,
            string applicationName,
            string processName,
            int processId,
            string text)
        {
            lock (Sync)
            {
                if (IsReadOnlyInternal)
                {
                    throw new NotSupportedException("The log message is read-only.");
                }

                if (IsAsyncInitPending)
                {
                    throw new InvalidOperationException("Initializing manually is not allowed as an asynchronous initialization is pending.");
                }

                mTimestamp = timestamp;
                mHighPrecisionTimestamp = highPrecisionTimestamp;
                mLostMessageCount       = lostMessageCount;
                mLogWriterName          = logWriterName;
                mLogLevelName           = logLevelName;
                mTags            = tags;
                mApplicationName = applicationName;
                mProcessName     = processName;
                mProcessId       = processId;
                mText            = text;

                IsInitializedInternal = true;
            }

            OnPropertyChanged(null);

            return(this);
        }
Пример #4
0
        /// <summary>
        /// Gets a deterministic set of random log messages.
        /// </summary>
        /// <param name="count">Number of log messages to generate.</param>
        /// <param name="randomNumberGeneratorSeed">
        /// Seed for the random number generator
        /// (0 is usually used to generate default log message sets, use some other value to generate a different set).
        /// </param>
        /// <param name="maxDifferentWritersCount">Maximum number of different log writer names.</param>
        /// <param name="maxDifferentLevelsCount">Maximum number of different log level names.</param>
        /// <param name="maxDifferentApplicationsCount">Maximum number of different application names.</param>
        /// <param name="maxDifferentProcessIdsCount">Maximum number of different process ids.</param>
        /// <returns>The requested log message set.</returns>
        public static TMessage[] GetTestMessages <TMessage>(
            int count,
            int randomNumberGeneratorSeed     = 0,
            int maxDifferentWritersCount      = 50,
            int maxDifferentLevelsCount       = 50,
            int maxDifferentApplicationsCount = 3,
            int maxDifferentProcessIdsCount   = 10000) where TMessage : class, ILogMessage, new()
        {
            var messages = new List <TMessage>();

            var  random                 = new Random(randomNumberGeneratorSeed);
            var  utcTimestamp           = DateTime.Parse("2020-01-01T01:02:03");
            long highPrecisionTimestamp = 0;

            // init list of tags to select from
            var allTags = new List <string>();

            for (int i = 0; i < 50; i++)
            {
                allTags.Add($"Tag{i}");
            }

            for (long i = 0; i < count; i++)
            {
                var timezoneOffset = TimeSpan.FromHours(random.Next(-14, 14));
                int processId      = random.Next(1, maxDifferentProcessIdsCount);

                // build tag set to associate with a message (up to 3 tags per message)
                // (the first and the last message must contain at least one tag for filter tests)
                int tagCount = random.Next(i == 0 || i == count - 1 ? 1 : 0, 3);
                var tags     = new TagSet();
                for (int j = 0; j < tagCount; j++)
                {
                    tags += allTags[random.Next(0, allTags.Count - 1)];
                }

                var message = new TMessage
                {
                    Timestamp = new DateTimeOffset(utcTimestamp + timezoneOffset, timezoneOffset),
                    HighPrecisionTimestamp = highPrecisionTimestamp,
                    LostMessageCount       = random.Next(0, 1),
                    LogWriterName          = $"Log Writer {random.Next(1, maxDifferentWritersCount)}",
                    LogLevelName           = $"Log Level {random.Next(1, maxDifferentLevelsCount)}",
                    Tags            = tags,
                    ApplicationName = $"Application {random.Next(1, maxDifferentApplicationsCount)}",
                    ProcessName     = $"Process {processId}",
                    ProcessId       = processId,
                    Text            = $"[{i + 1:D6}/{count:D6}] Log message # Generated Text: {i / 10:D6}/{'a' + i % 10}"          // lower-case letter in text only
                };

                // move the timestamps up to 1 day into the future
                var timeSkip = TimeSpan.FromMilliseconds(random.Next(1, 24 * 60 * 60 * 1000));
                utcTimestamp           += timeSkip;
                highPrecisionTimestamp += timeSkip.Ticks * 10;                 // the high precision timestamp is in nanoseconds, ticks are in 100ps

                messages.Add(message);
            }

            // the first an the last message should have different field values to allow the tests to match properly
            if (count > 0)
            {
                var firstMessage = messages[0];
                firstMessage.LogWriterName   = "log writer of first message";
                firstMessage.LogLevelName    = "log level of first message";
                firstMessage.ApplicationName = "application name of first message";
                firstMessage.ProcessName     = "process name of first message";
                firstMessage.ProcessId       = int.MinValue;
                firstMessage.Tags            = new TagSet("tag-of-first-message");
                // firstMessage.Text is just fine

                var lastMessage = messages[count - 1];
                lastMessage.LogWriterName   = "log writer of last message";
                lastMessage.LogLevelName    = "log level of last message";
                lastMessage.ApplicationName = "application name of last message";
                lastMessage.ProcessName     = "process name of last message";
                lastMessage.ProcessId       = int.MaxValue;
                lastMessage.Tags            = new TagSet("tag-of-last-message");
                // lastMessage.Text is just fine
            }

            return(messages.ToArray());
        }
        public void OperatorInequality(bool expected, TagSet left, TagSet right)
        {
            bool isEqual = left != right;

            Assert.Equal(expected, isEqual);
        }