Files
codeql/csharp/extractor/Semmle.Extraction.CSharp/Entities/ExtractionMessage.cs

59 lines
2.1 KiB
C#

using System.Collections.Concurrent;
using System.IO;
using System.Threading;
using Semmle.Util;
namespace Semmle.Extraction.CSharp.Entities
{
internal class ExtractionMessage : FreshEntity
{
private static readonly int limit = EnvironmentVariables.TryGetExtractorNumberOption<int>("MESSAGE_LIMIT") ?? 10000;
internal static readonly ConcurrentDictionary<string, int> groupedMessageCounts = [];
private static int messageCount = 0;
private readonly Message msg;
private readonly bool bypassLimit;
public ExtractionMessage(Context cx, Message msg) : this(cx, msg, bypassLimit: false)
{
}
private ExtractionMessage(Context cx, Message msg, bool bypassLimit) : base(cx)
{
this.bypassLimit = bypassLimit;
this.msg = msg;
TryPopulate();
}
protected override void Populate(TextWriter trapFile)
{
if (Context.OnlyScaffold)
{
return;
}
// For the time being we're counting the number of messages per severity, we could introduce other groupings in the future
var key = msg.Severity.ToString();
groupedMessageCounts.AddOrUpdate(key, 1, (_, c) => c + 1);
if (!bypassLimit)
{
var val = Interlocked.Increment(ref messageCount);
if (val > limit)
{
if (val == limit + 1)
{
Context.ExtractionContext.Logger.LogWarning($"Stopped logging extractor messages after reaching {limit}");
_ = new ExtractionMessage(Context, new Message($"Stopped logging extractor messages after reaching {limit}", null, null, null, Semmle.Util.Logging.Severity.Warning), bypassLimit: true);
}
return;
}
}
trapFile.extractor_messages(this, msg.Severity, msg.Text, msg.EntityText ?? string.Empty,
msg.Location ?? Context.CreateLocation(), msg.StackTrace ?? string.Empty);
}
}
}