static void ReadMulticastFooter(int streamVersion, CKBinaryReader r, StreamLogType t, out string gId, out string mId, out int depth, out LogEntryType prevType, out DateTimeStamp prevTime) { if (streamVersion == 9) { gId = r.ReadString(); mId = r.ReadString(); depth = r.ReadNonNegativeSmallInt32(); Throw.CheckData(mId == GrandOutput.ExternalLogMonitorUniqueId || Base64UrlHelper.IsBase64UrlCharacters(mId)); } else { gId = GrandOutput.UnknownGrandOutputId; Debug.Assert(Guid.Empty.ToByteArray().Length == 16); mId = streamVersion < 8 ? new Guid(r.ReadBytes(16)).ToString() : r.ReadString(); depth = streamVersion < 6 ? r.ReadInt32() : r.ReadNonNegativeSmallInt32(); if (streamVersion >= 8) { Throw.CheckData(mId == GrandOutput.ExternalLogMonitorUniqueId || Base64UrlHelper.IsBase64UrlCharacters(mId)); } } Throw.CheckData(gId == GrandOutput.UnknownGrandOutputId || Base64UrlHelper.IsBase64UrlCharacters(gId)); Throw.CheckData(depth >= 0); prevType = LogEntryType.None; prevTime = DateTimeStamp.Unknown; if ((t & StreamLogType.IsPreviousKnown) != 0) { prevTime = new DateTimeStamp(DateTime.FromBinary(r.ReadInt64()), (t & StreamLogType.IsPreviousKnownHasUniquifier) != 0 ? r.ReadByte() : (Byte)0); prevType = (LogEntryType)r.ReadByte(); } }
static ILogEntry ReadGroupClosed(int streamVersion, CKBinaryReader r, StreamLogType t, LogLevel logLevel) { DateTimeStamp time = new DateTimeStamp(DateTime.FromBinary(r.ReadInt64()), (t & StreamLogType.HasUniquifier) != 0 ? r.ReadByte() : (Byte)0); ActivityLogGroupConclusion[] conclusions = Util.Array.Empty <ActivityLogGroupConclusion>(); if ((t & StreamLogType.HasConclusions) != 0) { int conclusionsCount = streamVersion < 6 ? r.ReadInt32() : r.ReadNonNegativeSmallInt32(); conclusions = new ActivityLogGroupConclusion[conclusionsCount]; for (int i = 0; i < conclusionsCount; i++) { CKTrait cTags = ActivityMonitor.Tags.Register(r.ReadString()); string cText = r.ReadString(); conclusions[i] = new ActivityLogGroupConclusion(cText, cTags); } } if ((t & StreamLogType.IsMultiCast) == 0) { return(new LECloseGroup(time, logLevel, conclusions)); } Guid mId; int depth; LogEntryType prevType; DateTimeStamp prevTime; ReadMulticastFooter(streamVersion, r, t, out mId, out depth, out prevType, out prevTime); return(new LEMCCloseGroup(mId, depth, prevTime, prevType, time, logLevel, conclusions)); }
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); } }
public void basic_types_writing_and_reading() { using (var mem = new MemoryStream()) { var sShared = Guid.NewGuid().ToString(); using (var w = new CKBinaryWriter(mem, Encoding.UTF8, true)) { w.WriteNullableString(DefString); w.Write(DefInt32); w.Write(DefUInt32); w.Write(DefInt64); w.Write(DefUInt64); w.Write(DefInt16); w.Write(DefUInt16); w.Write(DefByte); w.Write(DefSByte); w.Write(DefDateTime); w.Write(DefTimeSpan); w.WriteSharedString(sShared); w.Write(DefDateTimeOffset); w.Write(DefGuid); w.Write(DefDouble); w.Write(DefSingle); w.Write(DefChar); w.Write(DefBoolean); w.WriteSharedString(sShared); } mem.Position = 0; using (var r = new CKBinaryReader(mem, Encoding.UTF8, true)) { r.ReadNullableString().Should().Be(DefString); r.ReadInt32().Should().Be(DefInt32); r.ReadUInt32().Should().Be(DefUInt32); r.ReadInt64().Should().Be(DefInt64); r.ReadUInt64().Should().Be(DefUInt64); r.ReadInt16().Should().Be(DefInt16); r.ReadUInt16().Should().Be(DefUInt16); r.ReadByte().Should().Be(DefByte); r.ReadSByte().Should().Be(DefSByte); r.ReadDateTime().Should().Be(DefDateTime); r.ReadTimeSpan().Should().Be(DefTimeSpan); r.ReadSharedString().Should().Be(sShared); r.ReadDateTimeOffset().Should().Be(DefDateTimeOffset); r.ReadGuid().Should().Be(DefGuid); r.ReadDouble().Should().Be(DefDouble); r.ReadSingle().Should().Be(DefSingle); r.ReadChar().Should().Be(DefChar); r.ReadBoolean().Should().Be(DefBoolean); r.ReadSharedString().Should().Be(sShared); } } }
static void ReadMulticastFooter(int streamVersion, CKBinaryReader r, StreamLogType t, out Guid mId, out int depth, out LogEntryType prevType, out DateTimeStamp prevTime) { Debug.Assert(Guid.Empty.ToByteArray().Length == 16); mId = new Guid(r.ReadBytes(16)); depth = streamVersion < 6 ? r.ReadInt32() : r.ReadNonNegativeSmallInt32(); if (depth < 0) { throw new InvalidDataException(); } prevType = LogEntryType.None; prevTime = DateTimeStamp.Unknown; if ((t & StreamLogType.IsPreviousKnown) != 0) { prevTime = new DateTimeStamp(DateTime.FromBinary(r.ReadInt64()), (t & StreamLogType.IsPreviousKnownHasUniquifier) != 0 ? r.ReadByte() : (Byte)0); prevType = (LogEntryType)r.ReadByte(); } }
/// <summary> /// Reads a <see cref="ILogEntry"/> from the binary reader that can be a <see cref="IMulticastLogEntry"/>. /// If the first read byte is 0, read stops and null is returned. /// The 0 byte is the "end marker" that <see cref="CKMonWriterClient.Close()"/> write, but this /// method can read non zero-terminated streams (it catches an EndOfStreamException when reading the first byte and handles it silently). /// This method can throw any type of exception except <see cref="EndOfStreamException"/> /// (like <see cref="InvalidDataException"/> for instance) that must be handled by the caller. /// </summary> /// <param name="r">The binary reader.</param> /// <param name="streamVersion">The version of the stream.</param> /// <param name="badEndOfFile">True whenever the end of file is the result of an <see cref="EndOfStreamException"/>.</param> /// <returns>The log entry or null if a zero byte (end marker) has been found.</returns> static public ILogEntry?Read(CKBinaryReader r, int streamVersion, out bool badEndOfFile) { Throw.CheckNotNullArgument(r); badEndOfFile = false; StreamLogType t = StreamLogType.EndOfStream; LogLevel logLevel = LogLevel.None; try { ReadLogTypeAndLevel(r, streamVersion, out t, out logLevel); } catch (EndOfStreamException) { badEndOfFile = true; // Silently ignores here reading beyond the stream: this // kindly handles the lack of terminating 0 byte. } if (t == StreamLogType.EndOfStream) { return(null); } if ((t & StreamLogType.TypeMask) == StreamLogType.TypeGroupClosed) { return(ReadGroupClosed(streamVersion, r, t, logLevel)); } DateTimeStamp time = new DateTimeStamp(DateTime.FromBinary(r.ReadInt64()), (t & StreamLogType.HasUniquifier) != 0 ? r.ReadByte() : (Byte)0); if (time.TimeUtc.Year < 2014 || time.TimeUtc.Year > 3000) { throw new InvalidDataException("Date year before 2014 or after 3000 are considered invalid."); } CKTrait tags = ActivityMonitor.Tags.Empty; string? fileName = null; int lineNumber = 0; CKExceptionData?ex = null; string? text = null; if ((t & StreamLogType.HasTags) != 0) { tags = ActivityMonitor.Tags.Register(r.ReadString()); } if ((t & StreamLogType.HasFileName) != 0) { fileName = r.ReadString(); lineNumber = streamVersion < 6 ? r.ReadInt32() : r.ReadNonNegativeSmallInt32(); if (lineNumber > 100 * 1000) { throw new InvalidDataException("LineNumber greater than 100K is considered invalid."); } } if ((t & StreamLogType.HasException) != 0) { ex = new CKExceptionData(r); if ((t & StreamLogType.IsTextTheExceptionMessage) != 0) { text = ex.Message; } } if (text == null) { text = r.ReadString((t & StreamLogType.IsLFOnly) == 0); } string gId; string mId; int depth; LogEntryType prevType; DateTimeStamp prevTime; if ((t & StreamLogType.TypeMask) == StreamLogType.TypeLine) { if ((t & StreamLogType.IsMultiCast) == 0) { return(new LELog(text, time, fileName, lineNumber, logLevel, tags, ex)); } ReadMulticastFooter(streamVersion, r, t, out gId, out mId, out depth, out prevType, out prevTime); return(new LEMCLog(gId, mId, depth, prevTime, prevType, text, time, fileName, lineNumber, logLevel, tags, ex)); } if ((t & StreamLogType.TypeMask) != StreamLogType.TypeOpenGroup) { throw new InvalidDataException(); } if ((t & StreamLogType.IsMultiCast) == 0) { return(new LEOpenGroup(text, time, fileName, lineNumber, logLevel, tags, ex)); } ReadMulticastFooter(streamVersion, r, t, out gId, out mId, out depth, out prevType, out prevTime); return(new LEMCOpenGroup(gId, mId, depth, prevTime, prevType, text, time, fileName, lineNumber, logLevel, tags, ex)); }