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; } } } } }
public ValueTask HandleAsync(IActivityMonitor m, IMulticastLogEntry logEvent) => ValueTask.CompletedTask;
/// <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; }
/// <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; }
/// <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); }
/// <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)); }
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; }
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; } } } } }
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); }
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); }
public ValueTask HandleAsync(IActivityMonitor m, IMulticastLogEntry logEvent) { LogEvents.Add(logEvent); return(ValueTask.CompletedTask); }
ValueTask IGrandOutputHandler.HandleAsync(IActivityMonitor m, IMulticastLogEntry logEvent) { _builder.Append(_formatter.FormatEntryString(logEvent)); _config.FromSink(_builder, false); return(ValueTask.CompletedTask); }
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); }
/// <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)); }
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 ); }
/// <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; }
public AlertEntry(IMulticastLogEntry multicastLogEntry, string appName) { MulticastLogEntry = multicastLogEntry; AppName = appName; }