Skip to content

Commit

Permalink
MultiNodeSpecs: turn off debug logging for all of them #4215 (#4652)
Browse files Browse the repository at this point in the history
* MNTR console logging is now configurable / filterrable via the akka.loglevel

* reverted to direct Console output in TimelineLogCollectorActor

* fixed PR feedback

* fixed typo

* parameter rename
  • Loading branch information
razvangoga authored Dec 9, 2020
1 parent 198b377 commit 7a2ca0e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@
using Akka.Actor;
using Akka.Event;
using Akka.MultiNodeTestRunner.Shared.Reporting;
using Akka.Util.Internal;

namespace Akka.MultiNodeTestRunner.Shared.Sinks
{
public class TimelineLogCollectorActor : ReceiveActor
{
private readonly SortedList<DateTime, HashSet<LogMessageInfo>> _timeline = new SortedList<DateTime, HashSet<LogMessageInfo>>();

public TimelineLogCollectorActor()
{
Receive<LogMessage>(msg =>
{
var parsedInfo = new LogMessageInfo(msg);
if (_timeline.ContainsKey(parsedInfo.When))
_timeline[parsedInfo.When].Add(parsedInfo);
else
_timeline.Add(parsedInfo.When, new HashSet<LogMessageInfo>() { parsedInfo });
});

Receive<SendMeAll>(_ => Sender.Tell(_timeline.Values.ToList()));

Receive<GetSpecLog>(_ =>
Expand All @@ -46,38 +46,41 @@ public TimelineLogCollectorActor()
return (NodeIndex: node.Index, NodeRole: node.Role, Logs: nodeMessages.Select(m => m.ToString()).ToList());
}).ToList()
};
Sender.Tell(log);
});

Receive<DumpToFile>(dump =>
{
// Verify that directory exists
var dir = new DirectoryInfo(Path.GetDirectoryName(dump.FilePath));
if (!dir.Exists)
dir.Create();
File.AppendAllLines(dump.FilePath, _timeline.Select(pairs => pairs.Value).SelectMany(msg => msg).Select(m => m.ToString()));
Sender.Tell(Done.Instance);
});
Receive<PrintToConsole>(_ =>

Receive<PrintToConsole>(m =>
{
LogMessageInfo.TryParseLogLevel(m.MinimumLogLevel, out var minimumLogLevel);
var logsPerTest = _timeline
.Select(pairs => pairs.Value)
.SelectMany(msg => msg)
.GroupBy(m => m.Node.TestName);
.GroupBy(msg => msg.Node.TestName);
foreach (var testLogs in logsPerTest)
{
Console.WriteLine($"Detailed logs for {testLogs.Key}\n");
foreach (var log in testLogs)
{
Console.WriteLine(log);
if (!log.LogLevel.HasValue || log.LogLevel.Value >= minimumLogLevel)
Console.WriteLine(log);
}
Console.WriteLine($"\nEnd logs for {testLogs.Key}\n");
}
Sender.Tell(Done.Instance);
});
}
Expand All @@ -87,26 +90,26 @@ public class LogMessageInfo
public NodeInfo Node { get; }
public string OriginalMessage { get; }
public DateTime When { get; }
public LogLevel LogLevel { get; }
public LogLevel? LogLevel { get; }
public string Message { get; }

public LogMessageInfo(LogMessage msg)
{
OriginalMessage = msg.Message;
Node = msg.Node;
When = DateTime.UtcNow;
LogLevel = LogLevel.InfoLevel; // In case if we could not find log level, assume that it is Info
LogLevel = null; //some log lines coming from nodes have no level (ex: stack traces) => leave the level null and output always
Message = OriginalMessage;

var pieces = Regex.Matches(msg.Message, @"\[([^\]]+)\]");
foreach (Match piece in pieces)
{
Message = Message.Replace(piece.Value, "");
if (DateTime.TryParse(piece.Value, CultureInfo.CurrentCulture, DateTimeStyles.None, out var when))

if (DateTime.TryParse(piece.Groups[1].Value, CultureInfo.CurrentCulture, DateTimeStyles.None, out var when))
When = when;

if (TryParseLogLevel(piece.Value, out var logLevel))
if (TryParseLogLevel(piece.Groups[1].Value, out var logLevel))
LogLevel = logLevel;
}
}
Expand All @@ -116,7 +119,7 @@ public override string ToString()
return $"[Node #{Node.Index}({Node.Role})]{OriginalMessage}";
}

private bool TryParseLogLevel(string str, out LogLevel logLevel)
public static bool TryParseLogLevel(string str, out LogLevel logLevel)
{
var enumValues = Enum.GetValues(typeof(LogLevel)).Cast<LogLevel>().ToList();
foreach (var logLevelInfo in Enum.GetNames(typeof(LogLevel)).Select((name, i) => (Name: name, Index: i)))
Expand All @@ -132,7 +135,7 @@ private bool TryParseLogLevel(string str, out LogLevel logLevel)
return false;
}
}

public class NodeInfo : IEquatable<NodeInfo>
{
public NodeInfo(int index, string role, string platform, string testName)
Expand Down Expand Up @@ -171,7 +174,7 @@ public override int GetHashCode()
return Index;
}
}

public class LogMessage
{
public LogMessage(NodeInfo node, string message)
Expand All @@ -185,8 +188,16 @@ public LogMessage(NodeInfo node, string message)
}

public class SendMeAll { }

public class PrintToConsole { }

public class PrintToConsole
{
public PrintToConsole(string minimumLogLevel)
{
MinimumLogLevel = minimumLogLevel;
}

public string MinimumLogLevel { get; }
}

public class GetSpecLog { }

Expand Down
9 changes: 4 additions & 5 deletions src/core/Akka.MultiNodeTestRunner/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
using Akka.MultiNodeTestRunner.Shared.Reporting;
using Akka.MultiNodeTestRunner.Shared.Sinks;
using Akka.Remote.TestKit;
using Akka.Util;
using JetBrains.TeamCity.ServiceMessages.Write.Special;
using JetBrains.TeamCity.ServiceMessages.Write.Special.Impl;
using Xunit;
#if CORECLR
using System.Runtime.Loader;
Expand Down Expand Up @@ -125,7 +122,9 @@ static void Main(string[] args)
{
OutputDirectory = CommandLine.GetPropertyOrDefault("multinode.output-directory", string.Empty);
FailedSpecsDirectory = CommandLine.GetPropertyOrDefault("multinode.failed-specs-directory", "FAILED_SPECS_LOGS");
TestRunSystem = ActorSystem.Create("TestRunnerLogging");

string logLevel = CommandLine.GetPropertyOrDefault("multinode.loglevel", "WARNING");
TestRunSystem = ActorSystem.Create("TestRunnerLogging", $"akka.loglevel={logLevel}");

var suiteName = Path.GetFileNameWithoutExtension(Path.GetFullPath(args[0].Trim('"')));
var teamCityFormattingOn = CommandLine.GetPropertyOrDefault("multinode.teamcity", "false");
Expand Down Expand Up @@ -369,7 +368,7 @@ static void Main(string[] args)
// Dump aggregated timeline to file for this test
timelineCollector.Ask<Done>(new TimelineLogCollectorActor.DumpToFile(Path.Combine(testOutputDir, "aggregated.txt"))),
// Print aggregated timeline into the console
timelineCollector.Ask<Done>(new TimelineLogCollectorActor.PrintToConsole())
timelineCollector.Ask<Done>(new TimelineLogCollectorActor.PrintToConsole(logLevel))
};

if (specFailed)
Expand Down

0 comments on commit 7a2ca0e

Please sign in to comment.