// Copyright Epic Games, Inc. All Rights Reserved.
using System.Collections.Generic;
using EpicGames.Core;
using Microsoft.Extensions.Logging;
namespace EpicGames.Horde.Issues.Handlers
{
///
/// Instance of a particular systemic error
///
[IssueHandler]
public class SystemicIssueHandler : IssueHandler
{
///
/// Known systemic errors
///
static readonly HashSet s_knownSystemic = new HashSet { KnownLogEvents.Horde, KnownLogEvents.Horde_InvalidPreflight };
///
public override int Priority => 10;
///
/// Determines if the given event id matches
///
/// The event id to compare
/// True if the given event id matches
public static bool IsMatchingEventId(EventId eventId)
{
return s_knownSystemic.Contains(eventId) || (eventId.Id >= KnownLogEvents.Systemic.Id && eventId.Id <= KnownLogEvents.Systemic_Max.Id);
}
bool _nonSystemicError = false;
readonly IssueHandlerContext _context;
readonly List _issues = new List();
///
/// Constructor
///
public SystemicIssueHandler(IssueHandlerContext context) => _context = context;
///
public override bool HandleEvent(IssueEvent logEvent)
{
if (logEvent.EventId != null)
{
if (IsMatchingEventId(logEvent.EventId.Value))
{
if (_nonSystemicError)
{
return true;
}
else
{
IssueEventGroup issue = new IssueEventGroup("Systemic", "Systemic {Severity} in {Nodes}", IssueChangeFilter.None);
issue.Keys.Add(IssueKey.FromStep(_context.StreamId, _context.TemplateId, _context.NodeName));
issue.Events.Add(logEvent);
_issues.Add(issue);
logEvent.AuditLogger?.LogDebug("Fingerprint key: '{Key}' generated from event: '{Event}'", $"{_context.StreamId}:{_context.NodeName}", logEvent.Render());
return true;
}
}
else if (logEvent.Severity >= LogLevel.Error)
{
// We've seen a non-systemic error event, so ignore this systemic event to prevent superfluous issues from being created
_nonSystemicError = true;
}
}
return false;
}
///
public override IEnumerable GetIssues() => _issues;
}
}