void Run()
        {
            try
            {
                int streamVersion = _reader.ReadInt32();
                if (_interProcess)
                {
                    _server.DisposeLocalCopyOfClientHandle();
                }
                for (; ;)
                {
                    var e = LogEntry.Read(_reader, streamVersion, out bool badEndOfStream);
                    if (e == null || badEndOfStream)
                    {
                        _endFlag = badEndOfStream ? LogReceiverEndStatus.MissingEndMarker : LogReceiverEndStatus.Normal;
                        break;
                    }
                    switch (e.LogType)
                    {
                    case LogEntryType.Line:
                    {
                        if (_monitor.ShouldLogLine(e.LogLevel, e.Tags, out var finalTags))
                        {
                            var d = new ActivityMonitorLogData(e.LogLevel | LogLevel.IsFiltered, finalTags, e.Text, CKException.CreateFrom(e.Exception), e.FileName, e.LineNumber);
                            d.SetExplicitLogTime(e.LogTime);
                            _monitor.UnfilteredLog(ref d);
                        }
                        break;
                    }

                    case LogEntryType.OpenGroup:
                    {
                        ActivityMonitorLogData d;
                        if (_monitor.ShouldLogLine(e.LogLevel, e.Tags, out var finalTags))
                        {
                            d = new ActivityMonitorLogData(e.LogLevel | LogLevel.IsFiltered, finalTags, e.Text, CKException.CreateFrom(e.Exception), e.FileName, e.LineNumber);
                            d.SetExplicitLogTime(e.LogTime);
                        }
                        else
                        {
                            d = default;
                        }
                        _monitor.UnfilteredOpenGroup(ref d);
                    }

                    break;

                    case LogEntryType.CloseGroup:
                        _monitor.CloseGroup(e.Conclusions, e.LogTime);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                _endFlag = LogReceiverEndStatus.Error;
                _monitor.UnfilteredLog(LogLevel.Fatal, null, "While receiving pipe logs.", ex);
            }
        }
Exemplo n.º 2
0
            /// <summary>
            /// Creates a token for a dependent activity that will use the current monitor's topic.
            /// By default, a line with <see cref="ActivityMonitor.Tags.CreateDependentActivity"/> is logged that describes the
            /// creation of the token.
            /// If <paramref name="delayedLaunch"/> is true, the actual launch of the dependent activity must be signaled thanks to <see cref="Launch(ActivityMonitor.DependentToken)"/>
            /// (otherwise there will be no way to bind the two activities).
            /// </summary>
            /// <param name="delayedLaunch">True to use <see cref="Launch(ActivityMonitor.DependentToken)"/> later to indicate the actual launch of the dependent activity.</param>
            /// <returns>A dependent token.</returns>
            public ActivityMonitor.DependentToken CreateToken(bool delayedLaunch = false)
            {
                string msg;
                var    t = ActivityMonitor.DependentToken.CreateWithMonitorTopic(_monitor, delayedLaunch, out msg);

                if (delayedLaunch)
                {
                    t.DelayedLaunchMessage = msg;
                }
                else
                {
                    _monitor.UnfilteredLog(ActivityMonitor.Tags.CreateDependentActivity, LogLevel.Info, msg, t.CreationDate, null, _fileName, _lineNumber);
                }
                return(t);
            }
Exemplo n.º 3
0
 public static void SendLine(this IActivityMonitor @this, LogLevel level, string text, Exception ex, [CallerFilePath] string fileName = null, [CallerLineNumber] int lineNumber = 0)
 {
     if (@this.ShouldLogLine(level, fileName, lineNumber))
     {
         @this.UnfilteredLog(null, level | LogLevel.IsFiltered, text, @this.NextLogTime(), ex, fileName, lineNumber);
     }
 }
Exemplo n.º 4
0
        void IActivityMonitorClient.OnUnfilteredLog(ActivityMonitorLogData data)
        {
            // If the level is above the actual target filter, we always send the message.
            // If the level is lower: if the log has not been filtered (UnfilteredLog has been called and not an extension method) we must
            // send it to honor the "Unfiltered" contract, but if _applyTargetFilterToUnfilteredLogs is true, we avoid sending it.
            var level = data.Level;

            if (((level & LogLevel.IsFiltered) == 0 && !_applyTargetFilterToUnfilteredLogs) || (int)GetActualTargetFilter().Line <= (int)(level & LogLevel.Mask))
            {
                _targetMonitor.UnfilteredLog(data);
            }
        }
Exemplo n.º 5
0
            /// <summary>
            /// Replays this monitor's content into another monitor.
            /// </summary>
            /// <param name="replay">The target monitor. Can not be null.</param>
            /// <param name="monitor">Optional monitor (nothing is logged when null).</param>
            public void Replay(IActivityMonitor replay, IActivityMonitor?monitor = null)
            {
                using (monitor?.OpenInfo($"Replaying activity from '{MonitorId}'."))
                {
                    int nbMissing = 0;
                    int nbTotal   = 0;
                    using (var page = ReadFirstPage(1024))
                    {
                        foreach (ParentedLogEntry e in page.Entries)
                        {
                            ++nbTotal;
                            LogLevel level = e.Entry.LogLevel;
                            if (e.IsMissing)
                            {
                                ++nbMissing;
                                level = LogLevel.Trace;
                            }
                            switch (e.Entry.LogType)
                            {
                            case LogEntryType.Line:
                                var d = new ActivityMonitorLogData(level, e.Entry.Tags, e.Entry.Text, CKException.CreateFrom(e.Entry.Exception), e.Entry.FileName, e.Entry.LineNumber);
                                d.SetExplicitLogTime(e.Entry.LogTime);
                                replay.UnfilteredLog(ref d);
                                break;

                            case LogEntryType.OpenGroup:
                                d = new ActivityMonitorLogData(level, e.Entry.Tags, e.Entry.Text, CKException.CreateFrom(e.Entry.Exception), e.Entry.FileName, e.Entry.LineNumber);
                                d.SetExplicitLogTime(e.Entry.LogTime);
                                replay.UnfilteredOpenGroup(ref d);
                                break;

                            case LogEntryType.CloseGroup:
                                replay.CloseGroup(e.Entry.Conclusions, e.Entry.LogTime);
                                break;
                            }
                        }
                        page.ForwardPage();
                    }
                    monitor?.CloseGroup($"Replayed {nbTotal} entries ({nbMissing} missing).");
                }
            }
            /// <summary>
            /// Replays this monitor's content into another monitor.
            /// </summary>
            /// <param name="replay">The target monitor. Can not be null.</param>
            /// <param name="m">Optional monitor (nothing is logged when null).</param>
            public void Replay(IActivityMonitor replay, IActivityMonitor m = null)
            {
                using (m != null ? m.OpenGroup(LogLevel.Info, string.Format("Replaying activity from '{0}'.", MonitorId), null) : null)
                {
                    int nbMissing = 0;
                    int nbTotal   = 0;
                    using (var page = ReadFirstPage(1024))
                    {
                        foreach (ParentedLogEntry e in page.Entries)
                        {
                            ++nbTotal;
                            LogLevel level = e.Entry.LogLevel;
                            if (e.IsMissing)
                            {
                                ++nbMissing;
                                level = LogLevel.Trace;
                            }
                            switch (e.Entry.LogType)
                            {
                            case LogEntryType.Line:
                                replay.UnfilteredLog(e.Entry.Tags, level, e.Entry.Text, e.Entry.LogTime, CKException.CreateFrom(e.Entry.Exception), e.Entry.FileName, e.Entry.LineNumber);
                                break;

                            case LogEntryType.OpenGroup:
                                replay.UnfilteredOpenGroup(e.Entry.Tags, level, null, e.Entry.Text, e.Entry.LogTime, CKException.CreateFrom(e.Entry.Exception), e.Entry.FileName, e.Entry.LineNumber);
                                break;

                            case LogEntryType.CloseGroup:
                                replay.CloseGroup(e.Entry.LogTime, e.Entry.Conclusions);
                                break;
                            }
                        }
                        page.ForwardPage();
                    }
                    if (m != null)
                    {
                        m.CloseGroup(String.Format("Replayed {0} entries ({1} missing).", nbTotal, nbMissing));
                    }
                }
            }
Exemplo n.º 7
0
        bool DumpGitFolders(IActivityMonitor m, IEnumerable <GitFolder> gitFolders)
        {
            bool      isLogFilterDefault = false;
            LogFilter final = m.ActualFilter;

            if (final == LogFilter.Undefined)
            {
                final = ActivityMonitor.DefaultFilter;
                isLogFilterDefault = true;
            }
            var msg = $"Monitor filters: User:'******' => Final:'{final}'{(isLogFilterDefault ? "(AppDomain's default)" : "")}.";

            m.UnfilteredLog(ActivityMonitor.Tags.Empty, LogLevel.Info, msg, m.NextLogTime(), null);

            int  gitFoldersCount    = 0;
            bool hasPluginInitError = false;
            var  dirty = new List <string>();

            foreach (var git in gitFolders)
            {
                ++gitFoldersCount;
                string commitAhead = git.Head.AheadOriginCommitCount != null ? $"{git.Head.AheadOriginCommitCount} commits ahead origin" : "Untracked";
                using (m.OpenInfo($"{git.SubPath} - branch: {git.CurrentBranchName} ({commitAhead})."))
                {
                    string pluginInfo;
                    if (!git.EnsureCurrentBranchPlugins(m))
                    {
                        hasPluginInitError = true;
                        pluginInfo         = "Plugin initialization error.";
                    }
                    else
                    {
                        pluginInfo = $"({git.PluginManager.BranchPlugins[git.CurrentBranchName].Count} plugins)";
                    }

                    if (git.CheckCleanCommit(m))
                    {
                        m.CloseGroup("Up-to-date. " + pluginInfo);
                    }
                    else
                    {
                        dirty.Add(git.SubPath);
                        m.CloseGroup("Dirty. " + pluginInfo);
                    }
                }
            }
            if (gitFoldersCount == 0)
            {
                m.Error("No git folder found.");
            }
            else
            {
                m.CloseGroup($"{dirty.Count} dirty (out of {gitFoldersCount}).");
                if (dirty.Count > 0)
                {
                    m.Info($"Dirty: {dirty.Concatenate()}");
                }
                var byActiveBranch = gitFolders.GroupBy(g => g.CurrentBranchName);
                if (byActiveBranch.Count() > 1)
                {
                    using (m.OpenWarn($"{byActiveBranch.Count()} different branches:"))
                    {
                        foreach (var b in byActiveBranch)
                        {
                            using (m.OpenWarn($"Branch '{b.Key}':"))
                            {
                                m.Warn(b.Select(g => g.SubPath.Path).Concatenate());
                            }
                        }
                    }
                }
                else
                {
                    m.Info($"All {gitFoldersCount} git folders are on '{byActiveBranch.First().Key}' branch.");
                }

                if (hasPluginInitError)
                {
                    m.Error("At least one git folder is unable to initialize its plugins.");
                }
            }
            return(!hasPluginInitError);
        }
 /// <summary>
 /// Logs a text regardless of <see cref="IActivityMonitor.ActualFilter">ActualFilter</see> level.
 /// </summary>
 /// <param name="this">This <see cref="IActivityMonitor"/>.</param>
 /// <param name="tags">
 /// Tags (from <see cref="ActivityMonitor.Tags"/>) to associate to the log.
 /// These tags will be union-ed with the current <see cref="IActivityMonitor.AutoTags">AutoTags</see>.
 /// </param>
 /// <param name="level">Log level. Must not be <see cref="LogLevel.None"/>.</param>
 /// <param name="text">Text to log. Must not be null or empty.</param>
 /// <param name="logTime">
 /// Time-stamp of the log entry.
 /// You can use <see cref="DateTimeStamp.UtcNow"/> or <see cref="ActivityMonitorExtension.NextLogTime">IActivityMonitor.NextLogTime()</see> extension method.
 /// </param>
 /// <param name="ex">Optional exception associated to the log. When not null, a Group is automatically created.</param>
 /// <param name="fileName">The source code file name from which the log is emitted.</param>
 /// <param name="lineNumber">The line number in the source from which the log is emitted.</param>
 /// <remarks>
 /// The <paramref name="text"/> can not be null or empty.
 /// <para>
 /// Each call to log is considered as a unit of text: depending on the rendering engine, a line or a
 /// paragraph separator (or any appropriate separator) should be appended between each text if
 /// the <paramref name="level"/> is the same as the previous one.
 /// </para>
 /// <para>If needed, the special text <see cref="ActivityMonitor.ParkLevel"/> ("PARK-LEVEL") can be used as a convention
 /// to break the current <see cref="LogLevel"/> and resets it: the next log, even with the same LogLevel, should be
 /// treated as if a different LogLevel is used.
 /// </para>
 /// </remarks>
 static public void UnfilteredLog(this IActivityMonitor @this, CKTrait tags, LogLevel level, string text, DateTimeStamp logTime, Exception ex, [CallerFilePath] string fileName = null, [CallerLineNumber] int lineNumber = 0)
 {
     @this.UnfilteredLog(new ActivityMonitorLogData(level, ex, tags, text, logTime, fileName, lineNumber));
 }
 internal void InitializeAndSend(Exception exception, CKTrait tags, string text)
 {
     Debug.Assert(!IsRejected);
     Initialize(text, exception, tags, _monitor.NextLogTime());
     _monitor.UnfilteredLog(this);
 }
Exemplo n.º 10
0
 static void DefaultOnRequestError(HttpContext ctx, IActivityMonitor m, Exception ex)
 {
     m.UnfilteredLog(null, LogLevel.Fatal, ex.Message, m.NextLogTime(), ex);
     ctx.Response.StatusCode = StatusCodes.Status500InternalServerError;
 }