// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using EpicGames.Core;
using Microsoft.Extensions.Logging;
namespace EpicGames.Horde.Issues
{
///
/// Wraps a log event and allows it to be tagged by issue handlers
///
public class IssueEvent
{
///
/// Index of the line within this log
///
public int LineIndex { get; }
///
/// Severity of the event
///
public LogLevel Severity { get; }
///
/// The type of event
///
public EventId? EventId { get; }
///
/// Gets this event data as a BSON document
///
public IReadOnlyList Lines { get; }
///
/// attached to this event
///
public IssueAuditLogger? AuditLogger { get; set; }
///
/// Constructor
///
public IssueEvent(int lineIndex, LogLevel severity, EventId? eventId, IReadOnlyList lines)
{
LineIndex = lineIndex;
Severity = severity;
EventId = eventId;
Lines = lines;
}
///
/// Renders the entire message of this event
///
public string Render()
=> String.Join("\n", Lines.Select(x => x.GetRenderedMessage().ToString()));
///
public override string ToString() => $"[{LineIndex}] {Render()}";
}
///
/// A group of objects with their fingerprint
///
public class IssueEventGroup
{
///
/// The type of issue, which defines the handler to use for it
///
public string Type { get; set; }
///
/// Template string for the issue summary
///
public string SummaryTemplate { get; set; }
///
/// List of keys which identify this issue.
///
public HashSet Keys { get; } = new HashSet();
///
/// Collection of additional metadata added by the handler
///
public HashSet Metadata { get; } = new HashSet();
///
/// Filter for changes that should be included in this issue
///
public string ChangeFilter { get; set; }
///
/// Individual log events
///
public List Events { get; } = new List();
///
/// Constructor
///
/// The type of issue
/// Template for the summary string to display for the issue
/// Filter for changes covered by this issue
public IssueEventGroup(string type, string summaryTemplate, string changeFilter)
{
Type = type;
SummaryTemplate = summaryTemplate;
ChangeFilter = changeFilter;
}
///
/// Constructor
///
/// The type of issue
/// Template for the summary string to display for the issue
/// Filter for changes covered by this issue
public IssueEventGroup(string type, string summaryTemplate, IReadOnlyList changeFilter)
: this(type, summaryTemplate, String.Join(";", changeFilter))
{
}
}
///
/// Temporary log buffer to store information about an before it's assigned to a build health issue
///
public class IssueAuditLogger : ILogger
{
///
public IDisposable? BeginScope(TState state) where TState : notnull => null;
///
public bool IsEnabled(LogLevel logLevel) => true;
private readonly List _entries;
///
/// Constructor
///
public IssueAuditLogger()
{
_entries = new List();
}
///
/// Gets list of objects in the buffer
///
/// List of log entries
public List GetEntries()
{
return _entries;
}
///
/// Stores a in the log buffer
///
/// Entry will be written on this level.
/// Id of the event.
/// The entry to be written. Can be also an object.
/// The exception related to this entry.
/// Function to create a message of the and .
/// The type of the object to be written.
public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter)
{
// extract and store message template and args
string? messageTemplate = null;
List