예제 #1
0
 internal void Register( RawLogFileMonitorOccurence fileOccurrence, bool newOccurrence, long streamOffset, IMulticastLogEntry log )
 {
     lock( _files )
     {
         Debug.Assert( newOccurrence == !_files.Contains( fileOccurrence ) ); 
         if( newOccurrence ) _files.Add( fileOccurrence );
         if( _firstEntryTime > log.LogTime )
         {
             _firstEntryTime = log.LogTime;
             _firstDepth = log.GroupDepth;
         }
         if( _lastEntryTime < log.LogTime )
         {
             _lastEntryTime = log.LogTime;
             _lastDepth = log.GroupDepth;
         }
         if( !log.Tags.IsEmpty )
         {
             if( _tags == null )
             {
                 _tags = new Dictionary<CKTrait, int>();
                 foreach( var t in log.Tags.AtomicTraits ) _tags.Add( t, 1 );
             }
             else
             {
                 foreach( var t in log.Tags.AtomicTraits )
                 {
                     int count;
                     _tags.TryGetValue( t, out count );
                     _tags[t] = count + 1;
                 }
             }
         }
     }
 }
예제 #2
0
 public ValueTask HandleAsync(IActivityMonitor m, IMulticastLogEntry logEvent) => ValueTask.CompletedTask;
예제 #3
0
        /// <summary>
        /// Writes a log entry (that can actually be a <see cref="IMulticastLogEntry"/>).
        /// </summary>
        /// <param name="e">The log entry.</param>
        public void Write(IMulticastLogEntry e)
        {
            Debug.Assert(DateTimeStamp.MaxValue.ToString().Length == 32,
                         "DateTimeStamp FileNameUniqueTimeUtcFormat and the uniquifier: max => 32 characters long.");
            Debug.Assert(Guid.NewGuid().ToString().Length == 36,
                         "Guid => 18 characters long.");

            BeforeWrite();
            _builder.Append(' ', _nameLen + 32);
            _builder.Append("| ", e.Text != null ? e.GroupDepth : e.GroupDepth - 1);
            string prefix = _builder.ToString();

            _builder.Clear();
            // MonitorId (if needed) on one line.
            if (_currentMonitorId == e.MonitorId)
            {
                _builder.Append(' ', _nameLen + 1);
            }
            else
            {
                _currentMonitorId = e.MonitorId;
                if (!_monitorNames.TryGetValue(_currentMonitorId, out _currentMonitorName))
                {
                    _currentMonitorName = _monitorNames.Count.ToString("X" + _nameLen);
                    int len = _currentMonitorName.Length;
                    if (_nameLen < len)
                    {
                        prefix   = " " + prefix;
                        _nameLen = len;
                    }
                    _monitorNames.Add(_currentMonitorId, _currentMonitorName);
                    _builder.Append(_currentMonitorName)
                    .Append("~~~~")
                    .Append(' ', 28)
                    .Append("~~ Monitor: ")
                    .AppendLine(_currentMonitorId.ToString());
                    _builder.Append(' ', _nameLen + 1);
                }
                else
                {
                    _builder.Append(_currentMonitorName).Append('~');
                    _builder.Append(' ', _nameLen - _currentMonitorName.Length);
                }
            }
            // Log time prefixes the first line only.
            TimeSpan delta = e.LogTime.TimeUtc - _lastLogTime;

            if (delta >= TimeSpan.FromMinutes(1))
            {
                string logTime = e.LogTime.TimeUtc.ToString(FileUtil.FileNameUniqueTimeUtcFormat);
                _builder.Append(' ');
                _builder.Append(logTime);
                _builder.Append(' ');
                _lastLogTime = e.LogTime.TimeUtc;
            }
            else
            {
                _builder.Append(' ', 17);
                _builder.Append('+');
                _builder.Append(delta.ToString(@"ss\.fffffff"));
                _builder.Append(' ');
            }

            // Level is one char.
            char level;

            switch (e.LogLevel & LogLevel.Mask)
            {
            case LogLevel.Trace: level = ' '; break;

            case LogLevel.Info: level = 'i'; break;

            case LogLevel.Warn: level = 'W'; break;

            case LogLevel.Error: level = 'E'; break;

            default: level = 'F'; break;
            }
            _builder.Append(level);
            _builder.Append(' ');
            _builder.Append("| ", e.Text != null ? e.GroupDepth : e.GroupDepth - 1);

            if (e.Text != null)
            {
                if (e.LogType == LogEntryType.OpenGroup)
                {
                    _builder.Append("> ");
                }
                prefix += "  ";
                _builder.AppendMultiLine(prefix, e.Text, false).AppendLine();
                if (e.Exception != null)
                {
                    e.Exception.ToStringBuilder(_builder, prefix);
                }
            }
            else
            {
                Debug.Assert(e.Conclusions != null);
                _builder.Append("< ");
                if (e.Conclusions.Count > 0)
                {
                    _builder.Append(" | ").Append(e.Conclusions.Count).Append(" conclusion");
                    if (e.Conclusions.Count > 1)
                    {
                        _builder.Append('s');
                    }
                    _builder.Append(':').AppendLine();
                    prefix += "   | ";
                    foreach (var c in e.Conclusions)
                    {
                        _builder.AppendMultiLine(prefix, c.Text, true).AppendLine();
                    }
                }
                else
                {
                    _builder.AppendLine();
                }
            }
            _writer.Write(_builder.ToString());
            AfterWrite();
            _builder.Clear();
        }
 /// <summary>
 /// Initializes a new <see cref="MulticastLogEntryWithOffset"/>.
 /// </summary>
 /// <param name="e">The entry.</param>
 /// <param name="o">The offset.</param>
 public MulticastLogEntryWithOffset(IMulticastLogEntry e, long o)
 {
     Entry  = e;
     Offset = o;
 }
예제 #5
0
 /// <summary>
 /// Initializes a new <see cref="GrandOutputEventInfo"/>.
 /// </summary>
 /// <param name="e">Log entry.</param>
 /// <param name="topic">Current topic.</param>
 public GrandOutputEventInfo( IMulticastLogEntry e, string topic )
 {
     Entry = e;
     Topic = topic;
 }
예제 #6
0
 /// <summary>
 /// Writes a log entry.
 /// </summary>
 /// <param name="monitor">The monitor to use.</param>
 /// <param name="logEvent">The log entry.</param>
 public ValueTask HandleAsync(IActivityMonitor monitor, IMulticastLogEntry logEvent)
 {
     _file.Write(logEvent);
     return(ValueTask.CompletedTask);
 }
예제 #7
0
 /// <summary>
 /// Index the log document after creating it
 /// </summary>
 /// <param name="log">The log to index</param>
 /// <param name="appName"></param>
 public void IndexLog(IMulticastLogEntry log, string appName)
 {
     WriteDocument(GetDocument(log, appName));
 }
예제 #8
0
 LiveIndexedMonitor RegisterOneLog( RawLogFileMonitorOccurence fileOccurrence, bool newOccurrence, long streamOffset, IMulticastLogEntry log )
 {
     Debug.Assert( fileOccurrence.MonitorId == log.MonitorId );
     Debug.Assert( !newOccurrence || (fileOccurrence.FirstEntryTime == log.LogTime && fileOccurrence.LastEntryTime == log.LogTime ) );
     LiveIndexedMonitor m = _monitors.GetOrAdd( log.MonitorId, id => new LiveIndexedMonitor( id, this ) );
     m.Register( fileOccurrence, newOccurrence, streamOffset, log );
     return m;
 }
예제 #9
0
 internal void Register(RawLogFileMonitorOccurence fileOccurrence, bool newOccurrence, long streamOffset, IMulticastLogEntry log)
 {
     lock ( _files )
     {
         Debug.Assert(newOccurrence == !_files.Contains(fileOccurrence));
         if (newOccurrence)
         {
             _files.Add(fileOccurrence);
         }
         if (_firstEntryTime > log.LogTime)
         {
             _firstEntryTime = log.LogTime;
             _firstDepth     = log.GroupDepth;
         }
         if (_lastEntryTime < log.LogTime)
         {
             _lastEntryTime = log.LogTime;
             _lastDepth     = log.GroupDepth;
         }
         if (!log.Tags.IsEmpty)
         {
             if (_tags == null)
             {
                 _tags = new Dictionary <CKTrait, int>();
                 foreach (var t in log.Tags.AtomicTraits)
                 {
                     _tags.Add(t, 1);
                 }
             }
             else
             {
                 foreach (var t in log.Tags.AtomicTraits)
                 {
                     int count;
                     _tags.TryGetValue(t, out count);
                     _tags[t] = count + 1;
                 }
             }
         }
     }
 }
예제 #10
0
        LiveIndexedMonitor RegisterOneLog(RawLogFileMonitorOccurence fileOccurrence, bool newOccurrence, long streamOffset, IMulticastLogEntry log)
        {
            Debug.Assert(fileOccurrence.MonitorId == log.MonitorId);
            Debug.Assert(!newOccurrence || (fileOccurrence.FirstEntryTime == log.LogTime && fileOccurrence.LastEntryTime == log.LogTime));
            LiveIndexedMonitor m = _monitors.GetOrAdd(log.MonitorId, id => new LiveIndexedMonitor(id, this));

            m.Register(fileOccurrence, newOccurrence, streamOffset, log);
            return(m);
        }
예제 #11
0
            void UpdateMonitor(MultiLogReader reader, long streamOffset, Dictionary <Guid, RawLogFileMonitorOccurence> monitorOccurrence, List <RawLogFileMonitorOccurence> monitorOccurenceList, IMulticastLogEntry log)
            {
                bool newOccurrence = false;
                RawLogFileMonitorOccurence occ;

                if (!monitorOccurrence.TryGetValue(log.MonitorId, out occ))
                {
                    occ = new RawLogFileMonitorOccurence(this, log.MonitorId, streamOffset);
                    monitorOccurrence.Add(log.MonitorId, occ);
                    monitorOccurenceList.Add(occ);
                    newOccurrence = true;
                }
                if (occ.FirstEntryTime > log.LogTime)
                {
                    occ.FirstEntryTime = log.LogTime;
                }
                if (occ.LastEntryTime < log.LogTime)
                {
                    occ.LastEntryTime = log.LogTime;
                }
                occ.LastOffset = streamOffset;
                reader.RegisterOneLog(occ, newOccurrence, streamOffset, log);
            }
예제 #12
0
 public ValueTask HandleAsync(IActivityMonitor m, IMulticastLogEntry logEvent)
 {
     LogEvents.Add(logEvent);
     return(ValueTask.CompletedTask);
 }
예제 #13
0
 ValueTask IGrandOutputHandler.HandleAsync(IActivityMonitor m, IMulticastLogEntry logEvent)
 {
     _builder.Append(_formatter.FormatEntryString(logEvent));
     _config.FromSink(_builder, false);
     return(ValueTask.CompletedTask);
 }
예제 #14
0
        private Document GetDocument(IMulticastLogEntry log, string appName)
        {
            var document = new Document();

            foreach (var propertyInfo in log.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                var logValue = log.GetType().GetProperty(propertyInfo.Name)?.GetValue(log);
                if (logValue == null)
                {
                    continue;
                }

                switch (propertyInfo.PropertyType.Name)
                {
                case LogField.DATE_TIME_STAMP:
                    document.Add(new TextField
                                 (
                                     propertyInfo.Name,
                                     DateTools.DateToString((logValue as DateTimeStamp? ?? new DateTimeStamp(new DateTime(1, 1, 1))).TimeUtc, DateTools.Resolution.MILLISECOND),
                                     Field.Store.YES
                                 ));
                    break;

                case "List`1":     // Matches: IReadOnlyList<ActivityLogGroupConclusion>
                    var stringBuilder = new StringBuilder();
                    foreach (var conclusion in log.Conclusions)
                    {
                        stringBuilder.Append(conclusion.Text + "\n");
                    }
                    document.Add(new TextField
                                 (
                                     propertyInfo.Name,
                                     stringBuilder.ToString(),
                                     Field.Store.YES
                                 ));
                    break;

                case LogField.CK_EXCEPTION_DATA:
                    document.Add(new TextField(
                                     "Exception",
                                     GetDocument(logValue as CKExceptionData).Get("IndexDTS"),
                                     Field.Store.YES
                                     ));
                    break;

                case LogField.CK_TRAIT:     // TODO: Add foreach on every field contained in the stringfield. Need to split on pipes.
                    document.Add(new StringField(
                                     propertyInfo.Name,
                                     logValue.ToString(),
                                     Field.Store.YES
                                     ));
                    break;

                default:
                    document.Add(new TextField(propertyInfo.Name, logValue.ToString(), Field.Store.YES));
                    break;
                }
            }

            document.Add(new TextField(LogField.INDEX_DTS, CreateIndexDts().ToString(), Field.Store.YES));
            document.Add(new TextField(LogField.APP_NAME, appName, Field.Store.YES));

            return(document);
        }
예제 #15
0
        /// <summary>
        /// Format the <paramref name="logEntry"/>
        /// </summary>
        /// <param name="logEntry"></param>
        /// <returns>A possible first entry - for monitor numbering - and the entry itself.</returns>
        public (FormattedEntry Before, FormattedEntry Entry) FormatEntry(IMulticastLogEntry logEntry)
        {
            FormattedEntry before        = default;
            string         formattedDate = GetFormattedDate(logEntry);

            char   logLevel          = logEntry.LogLevel.ToChar();
            string indentationPrefix = ActivityMonitorTextHelperClient.GetMultilinePrefixWithDepth(logEntry.Text != null ? logEntry.GroupDepth : logEntry.GroupDepth - 1);

            if (!_monitorNames.TryGetValue(logEntry.MonitorId, out string?monitorId))
            {
                string _monitorResetLog = "";
                if (_monitorNames.Count - 1 == _maxMonitorCount)
                {
                    ClearMonitorNames();
                    _monitorResetLog = $" Monitor reset count {_maxMonitorCount}.";
                }
                monitorId = B64ConvertInt(_monitorNames.Count);
                _monitorNames.Add(logEntry.MonitorId, monitorId);
                Debug.Assert(LogLevel.Info.ToChar() == 'i');
                before = new FormattedEntry('i',
                                            indentationPrefix,
                                            monitorId,
                                            formattedDate,
                                            $" [] Monitor: ~{logEntry.MonitorId}. {_monitorResetLog}");
            }
            string multiLinePrefix = _blankSpacePrefix + indentationPrefix;

            if (logEntry.Text != null)
            {
                Debug.Assert(logEntry.LogType != LogEntryType.CloseGroup);
                if (logEntry.LogType == LogEntryType.OpenGroup)
                {
                    _builder.Append("> ");
                }
                _builder.Append(" [").Append(logEntry.Tags).Append("] ");
                multiLinePrefix += "   ";
                _builder.AppendMultiLine(multiLinePrefix, logEntry.Text, false);
                if (logEntry.Exception != null)
                {
                    _builder.AppendLine();
                    logEntry.Exception.ToStringBuilder(_builder, multiLinePrefix, false);
                }
            }
            else
            {
                Debug.Assert(logEntry.Conclusions != null);
                _builder.Append("< ");
                if (logEntry.Conclusions.Count > 0)
                {
                    if (logEntry.Conclusions.Count == 1)
                    {
                        _builder.AppendMultiLine(multiLinePrefix + ' ', logEntry.Conclusions.Single().Text, false);
                    }
                    else
                    {
                        _builder.Append(logEntry.Conclusions.Count).Append(" conclusion");
                        if (logEntry.Conclusions.Count > 1)
                        {
                            _builder.Append('s');
                        }
                        _builder.Append(':').AppendLine();
                        multiLinePrefix += ' ';
                        bool first = true;
                        foreach (var c in logEntry.Conclusions)
                        {
                            if (!first)
                            {
                                _builder.AppendLine();
                            }
                            first = false;
                            _builder.AppendMultiLine(multiLinePrefix + ' ', c.Text, true);
                        }
                    }
                }
            }
            string outputLine = _builder.ToString();

            _builder.Clear();
            return(before, new FormattedEntry(logLevel,
                                              indentationPrefix,
                                              monitorId,
                                              formattedDate,
                                              outputLine));
        }
예제 #16
0
 void UpdateMonitor( MultiLogReader reader, long streamOffset, Dictionary<Guid, RawLogFileMonitorOccurence> monitorOccurrence, List<RawLogFileMonitorOccurence> monitorOccurenceList, IMulticastLogEntry log )
 {
     bool newOccurrence = false;
     RawLogFileMonitorOccurence occ;
     if( !monitorOccurrence.TryGetValue( log.MonitorId, out occ ) )
     {
         occ = new RawLogFileMonitorOccurence( this, log.MonitorId, streamOffset );
         monitorOccurrence.Add( log.MonitorId, occ );
         monitorOccurenceList.Add( occ );
         newOccurrence = true;
     }
     if( occ.FirstEntryTime > log.LogTime ) occ.FirstEntryTime = log.LogTime;
     if( occ.LastEntryTime < log.LogTime ) occ.LastEntryTime = log.LogTime;
     occ.LastOffset = streamOffset;
     reader.RegisterOneLog( occ, newOccurrence, streamOffset, log );
 }
예제 #17
0
        /// <summary>
        /// Writes a log entry (that can actually be a <see cref="IMulticastLogEntry"/>).
        /// </summary>
        /// <param name="e">The log entry.</param>
        public void Write( IMulticastLogEntry e )
        {
            Debug.Assert( DateTimeStamp.MaxValue.ToString().Length == 32,
                "DateTimeStamp FileNameUniqueTimeUtcFormat and the uniquifier: max => 32 characters long." );
            Debug.Assert( Guid.NewGuid().ToString().Length == 36,
                "Guid => 18 characters long." );

            BeforeWrite();
            _builder.Append( ' ', _nameLen + 32 );
            _builder.Append( "| ", e.Text != null ? e.GroupDepth : e.GroupDepth - 1 );
            string prefix = _builder.ToString();
            _builder.Clear();
            // MonitorId (if needed) on one line.
            if( _currentMonitorId == e.MonitorId )
            {
                _builder.Append( ' ', _nameLen + 1 );
            }
            else
            {
                _currentMonitorId = e.MonitorId;
                if( !_monitorNames.TryGetValue( _currentMonitorId, out _currentMonitorName ) )
                {
                    _currentMonitorName = _monitorNames.Count.ToString( "X" + _nameLen );
                    int len = _currentMonitorName.Length;
                    if( _nameLen < len )
                    {
                        prefix = " " + prefix;
                        _nameLen = len;
                    }
                    _monitorNames.Add( _currentMonitorId, _currentMonitorName );
                    _builder.Append( _currentMonitorName )
                            .Append( "~~~~" )
                            .Append( ' ', 28 )
                            .Append( "~~ Monitor: " )
                            .AppendLine( _currentMonitorId.ToString() );
                    _builder.Append( ' ', _nameLen + 1 );
                }
                else
                {
                    _builder.Append( _currentMonitorName ).Append( '~' );
                    _builder.Append( ' ', _nameLen - _currentMonitorName.Length );
                }
            }
            // Log time prefixes the first line only.
            TimeSpan delta = e.LogTime.TimeUtc - _lastLogTime;
            if( delta >= TimeSpan.FromMinutes(1) )
            {
                string logTime = e.LogTime.TimeUtc.ToString( FileUtil.FileNameUniqueTimeUtcFormat );
                _builder.Append( ' ' );
                _builder.Append( logTime );
                _builder.Append( ' ' );
                _lastLogTime = e.LogTime.TimeUtc;
            }
            else
            {
                _builder.Append( ' ', 17 );
                _builder.Append( '+' );
                _builder.Append( delta.ToString( @"ss\.fffffff" ) );
                _builder.Append( ' ' );
            }

            // Level is one char.
            char level;
            switch( e.LogLevel & LogLevel.Mask )
            {
                case LogLevel.Trace: level = ' '; break;
                case LogLevel.Info: level = 'i'; break;
                case LogLevel.Warn: level = 'W'; break;
                case LogLevel.Error: level = 'E'; break;
                default: level = 'F'; break;
            }
            _builder.Append( level );
            _builder.Append( ' ' );
            _builder.Append( "| ", e.Text != null ? e.GroupDepth : e.GroupDepth - 1 );

            if( e.Text != null )
            {
                if( e.LogType == LogEntryType.OpenGroup ) _builder.Append( "> " );
                prefix += "  ";
                _builder.AppendMultiLine( prefix, e.Text, false ).AppendLine();
                if( e.Exception != null )
                {
                    e.Exception.ToStringBuilder( _builder, prefix );
                }
            }
            else 
            {
                Debug.Assert( e.Conclusions != null );
                _builder.Append( "< " );
                if( e.Conclusions.Count > 0 )
                {
                    _builder.Append( " | " ).Append( e.Conclusions.Count ).Append( " conclusion" );
                    if( e.Conclusions.Count > 1 ) _builder.Append( 's' );
                    _builder.Append( ':' ).AppendLine();
                    prefix += "   | ";
                    foreach( var c in e.Conclusions )
                    {
                        _builder.AppendMultiLine( prefix, c.Text, true ).AppendLine();
                    }
                }
                else 
                {
                    _builder.AppendLine();
                }
            }
            _writer.Write( _builder.ToString() );
            AfterWrite();
            _builder.Clear();
        }
 /// <summary>
 /// Initializes a new <see cref="MulticastLogEntryWithOffset"/>.
 /// </summary>
 /// <param name="e">The entry.</param>
 /// <param name="o">The offset.</param>
 public MulticastLogEntryWithOffset( IMulticastLogEntry e, long o )
 {
     Entry = e;
     Offset = o;
 }
예제 #19
0
 public AlertEntry(IMulticastLogEntry multicastLogEntry, string appName)
 {
     MulticastLogEntry = multicastLogEntry;
     AppName           = appName;
 }