Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Binlogs Redacting] API and support for external redaction functionality #9219

Closed
wants to merge 9 commits into from
Closed
172 changes: 171 additions & 1 deletion src/Build/CompatibilitySuppressions.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</Suppressions>
<!-- Start of suppressions needed for adjustments of added binlog reader API -->
JanKrivanek marked this conversation as resolved.
Show resolved Hide resolved
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BinaryLogReplayEventSource.add_NotificationsSourceCreated(System.Action{Microsoft.Build.Logging.IBuildEventArgsReaderNotifications})</Target>
<Left>lib/net472/Microsoft.Build.dll</Left>
<Right>lib/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BinaryLogReplayEventSource.remove_NotificationsSourceCreated(System.Action{Microsoft.Build.Logging.IBuildEventArgsReaderNotifications})</Target>
<Left>lib/net472/Microsoft.Build.dll</Left>
<Right>lib/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BuildEventArgsReader.add_StringEncountered(System.Action)</Target>
<Left>lib/net472/Microsoft.Build.dll</Left>
<Right>lib/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BuildEventArgsReader.remove_StringEncountered(System.Action)</Target>
<Left>lib/net472/Microsoft.Build.dll</Left>
<Right>lib/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.IBuildEventStringsReader.add_StringEncountered(System.Action)</Target>
<Left>lib/net472/Microsoft.Build.dll</Left>
<Right>lib/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.IBuildEventStringsReader.remove_StringEncountered(System.Action)</Target>
<Left>lib/net472/Microsoft.Build.dll</Left>
<Right>lib/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BinaryLogReplayEventSource.add_NotificationsSourceCreated(System.Action{Microsoft.Build.Logging.IBuildEventArgsReaderNotifications})</Target>
<Left>lib/net8.0/Microsoft.Build.dll</Left>
<Right>lib/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BinaryLogReplayEventSource.remove_NotificationsSourceCreated(System.Action{Microsoft.Build.Logging.IBuildEventArgsReaderNotifications})</Target>
<Left>lib/net8.0/Microsoft.Build.dll</Left>
<Right>lib/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BuildEventArgsReader.add_StringEncountered(System.Action)</Target>
<Left>lib/net8.0/Microsoft.Build.dll</Left>
<Right>lib/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BuildEventArgsReader.remove_StringEncountered(System.Action)</Target>
<Left>lib/net8.0/Microsoft.Build.dll</Left>
<Right>lib/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.IBuildEventStringsReader.add_StringEncountered(System.Action)</Target>
<Left>lib/net8.0/Microsoft.Build.dll</Left>
<Right>lib/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.IBuildEventStringsReader.remove_StringEncountered(System.Action)</Target>
<Left>lib/net8.0/Microsoft.Build.dll</Left>
<Right>lib/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BinaryLogReplayEventSource.add_NotificationsSourceCreated(System.Action{Microsoft.Build.Logging.IBuildEventArgsReaderNotifications})</Target>
<Left>ref/net472/Microsoft.Build.dll</Left>
<Right>ref/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BinaryLogReplayEventSource.remove_NotificationsSourceCreated(System.Action{Microsoft.Build.Logging.IBuildEventArgsReaderNotifications})</Target>
<Left>ref/net472/Microsoft.Build.dll</Left>
<Right>ref/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BuildEventArgsReader.add_StringEncountered(System.Action)</Target>
<Left>ref/net472/Microsoft.Build.dll</Left>
<Right>ref/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BuildEventArgsReader.remove_StringEncountered(System.Action)</Target>
<Left>ref/net472/Microsoft.Build.dll</Left>
<Right>ref/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.IBuildEventStringsReader.add_StringEncountered(System.Action)</Target>
<Left>ref/net472/Microsoft.Build.dll</Left>
<Right>ref/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.IBuildEventStringsReader.remove_StringEncountered(System.Action)</Target>
<Left>ref/net472/Microsoft.Build.dll</Left>
<Right>ref/net472/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BinaryLogReplayEventSource.add_NotificationsSourceCreated(System.Action{Microsoft.Build.Logging.IBuildEventArgsReaderNotifications})</Target>
<Left>ref/net8.0/Microsoft.Build.dll</Left>
<Right>ref/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BinaryLogReplayEventSource.remove_NotificationsSourceCreated(System.Action{Microsoft.Build.Logging.IBuildEventArgsReaderNotifications})</Target>
<Left>ref/net8.0/Microsoft.Build.dll</Left>
<Right>ref/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BuildEventArgsReader.add_StringEncountered(System.Action)</Target>
<Left>ref/net8.0/Microsoft.Build.dll</Left>
<Right>ref/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.BuildEventArgsReader.remove_StringEncountered(System.Action)</Target>
<Left>ref/net8.0/Microsoft.Build.dll</Left>
<Right>ref/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.IBuildEventStringsReader.add_StringEncountered(System.Action)</Target>
<Left>ref/net8.0/Microsoft.Build.dll</Left>
<Right>ref/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Build.Logging.IBuildEventStringsReader.remove_StringEncountered(System.Action)</Target>
<Left>ref/net8.0/Microsoft.Build.dll</Left>
<Right>ref/net8.0/Microsoft.Build.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<!-- End of suppressions needed for adjustments of added binlog reader API -->
</Suppressions>
2 changes: 1 addition & 1 deletion src/Build/Logging/BinaryLogger/BinaryLogRecordKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal enum BinaryLogRecordKind
ProjectEvaluationStarted,
ProjectEvaluationFinished,
ProjectImported,
ProjectImportArchive,
ProjectImportArchive = 17,
JanKrivanek marked this conversation as resolved.
Show resolved Hide resolved
TargetSkipped,
PropertyReassignment,
UninitializedPropertyRead,
Expand Down
85 changes: 65 additions & 20 deletions src/Build/Logging/BinaryLogger/BinaryLogReplayEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.Build.Logging
/// by implementing IEventSource and raising corresponding events.
/// </summary>
/// <remarks>The class is public so that we can call it from MSBuild.exe when replaying a log file.</remarks>
public sealed class BinaryLogReplayEventSource : EventArgsDispatcher
public sealed class BinaryLogReplayEventSource : EventArgsDispatcher, IEmbeddedContentSource
{
/// Touches the <see cref="ItemGroupLoggingHelper"/> static constructor
/// to ensure it initializes <see cref="TaskParameterEventArgs.MessageGetter"/>
Expand All @@ -26,11 +26,6 @@ static BinaryLogReplayEventSource()
_ = ItemGroupLoggingHelper.ItemGroupIncludeLogMessagePrefix;
}

/// <summary>
/// Raised once <see cref="BuildEventArgsReader"/> is created during replaying
/// </summary>
public event Action<IBuildEventArgsReaderNotifications>? NotificationsSourceCreated;

/// <summary>
/// Read the provided binary log file and raise corresponding events for each BuildEventArgs
/// </summary>
Expand Down Expand Up @@ -68,41 +63,91 @@ public static BinaryReader OpenReader(string sourceFilePath)
}
}

/// <summary>
/// Creates a <see cref="BuildEventArgsReader"/> for the provided binary reader over binary log file.
/// Caller is responsible for disposing the returned reader.
/// </summary>
/// <param name="binaryReader"></param>
/// <param name="closeInput">Indicates whether the passed BinaryReader should be closed on disposing.</param>
/// <returns>BuildEventArgsReader over the given binlog file binary reader.</returns>
public static BuildEventArgsReader OpenBuildEventsReader(BinaryReader binaryReader, bool closeInput)
{
int fileFormatVersion = binaryReader.ReadInt32();

// the log file is written using a newer version of file format
// that we don't know how to read
if (fileFormatVersion > BinaryLogger.FileFormatVersion)
{
var text = ResourceUtilities.FormatResourceStringStripCodeAndKeyword("UnsupportedLogFileFormat", fileFormatVersion, BinaryLogger.FileFormatVersion);
throw new NotSupportedException(text);
}

return new BuildEventArgsReader(binaryReader, fileFormatVersion) { CloseInput = closeInput };
}

/// <summary>
/// Creates a <see cref="BinaryReader"/> for the provided binary log file.
/// Performs decompression and buffering in the optimal way.
/// Caller is responsible for disposing the returned reader.
/// </summary>
/// <param name="sourceFilePath"></param>
/// <returns>BinaryReader of the given binlog file.</returns>
public static BuildEventArgsReader OpenBuildEventsReader(string sourceFilePath)
=> OpenBuildEventsReader(OpenReader(sourceFilePath), true);

/// <summary>
/// Read the provided binary log file and raise corresponding events for each BuildEventArgs
/// </summary>
/// <param name="sourceFilePath">The full file path of the binary log file</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> indicating the replay should stop as soon as possible.</param>
public void Replay(string sourceFilePath, CancellationToken cancellationToken)
{
using var binaryReader = OpenReader(sourceFilePath);
Replay(binaryReader, cancellationToken);
using var eventsReader = OpenBuildEventsReader(sourceFilePath);
Replay(eventsReader, cancellationToken);
}

/// <summary>
/// Read the provided binary log file and raise corresponding events for each BuildEventArgs
/// </summary>
/// <param name="binaryReader">The binary log content binary reader - caller is responsible for disposing.</param>
/// <param name="closeInput">Indicates whether the passed BinaryReader should be closed on disposing.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> indicating the replay should stop as soon as possible.</param>
public void Replay(BinaryReader binaryReader, CancellationToken cancellationToken)
public void Replay(BinaryReader binaryReader, bool closeInput, CancellationToken cancellationToken)
{
int fileFormatVersion = binaryReader.ReadInt32();

// the log file is written using a newer version of file format
// that we don't know how to read
if (fileFormatVersion > BinaryLogger.FileFormatVersion)
{
var text = ResourceUtilities.FormatResourceStringStripCodeAndKeyword("UnsupportedLogFileFormat", fileFormatVersion, BinaryLogger.FileFormatVersion);
throw new NotSupportedException(text);
}
using var reader = OpenBuildEventsReader(binaryReader, closeInput);
Replay(reader, cancellationToken);
}

using var reader = new BuildEventArgsReader(binaryReader, fileFormatVersion);
NotificationsSourceCreated?.Invoke(reader);
/// <summary>
/// Read the provided binary log file and raise corresponding events for each BuildEventArgs
/// </summary>
/// <param name="reader">The build events reader - caller is responsible for disposing.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> indicating the replay should stop as soon as possible.</param>
public void Replay(BuildEventArgsReader reader, CancellationToken cancellationToken)
{
_fileFormatVersionRead?.Invoke(reader.FileFormatVersion);
reader.EmbeddedContentRead += _embeddedContentRead;

while (!cancellationToken.IsCancellationRequested && reader.Read() is { } instance)
{
Dispatch(instance);
}
}

private Action<int>? _fileFormatVersionRead;
event Action<int> ILogVersionInfo.FileFormatVersionRead
{
add => _fileFormatVersionRead += value;
remove => _fileFormatVersionRead -= value;
}
private Action<EmbeddedContentEventArgs>? _embeddedContentRead;
/// <inheritdoc cref="IEmbeddedContentSource.EmbeddedContentRead"/>
event Action<EmbeddedContentEventArgs>? IEmbeddedContentSource.EmbeddedContentRead
{
// Explicitly implemented event has to declare explicit add/remove accessors
// https://stackoverflow.com/a/2268472/2308106
add => _embeddedContentRead += value;
remove => _embeddedContentRead -= value;
}
}
}
Loading
Loading