Quick question - is it possible to save stats to file or FString?
I’m currently working on dedicated server and there are some statistics shown with “stat net” command that I’d like to collect. I need them to check if the server behaves well. I need them to be saved to file or to be displayed on console.
Unfortunatelly I can’t find any code to do such thing, the stat system is kinda complicated here.
Unfortunatelly this is not what I’m looking for. Stat file gathers all of the information and I can’t see a clue how to strip it so it can get only stats I need. It also requires an application to read where I need a text format file.
The more I look on it the less I understand how it works… Are these data stored somewhere anyway?
I would have a look at StatsCommand.cpp (to add your custom command line) and StatsFile.cpp (to write out the correct stats to a file through something similar as what happens in FCommandStatsFile::Start and filter out the necessary stats in FStatsWriteFile::WriteFrame) in that case. I’ve never done this as well but I think that should work.
And now time for some magic. Here’s complete code to get all net stats (with comments):
// Get the reference to the stats thread
FStatsThreadStateOverlay& Stats = FStatsThreadStateOverlay&)FStatsThreadState::GetLocalState();
// Get the number of the last processed frame and check if it is valid (just for sure)
int64 LastGoodGameFrame = Stats.GetLastFullFrameProcessed();
if (Stats.IsFrameValid(LastGoodGameFrame) == false)
{
return;
}
// This is the name of the group where stats are.
FName GroupName = FName(TEXT("STATGROUP_net"));
// Gather the names of the stats that are in this group.
TArray<FName> GroupItems;
Stats.Groups.MultiFind(GroupName, GroupItems);
// Prepare the set of names and raw names of the stats we want to get
TSet<FName> EnabledItems;
for (const FName& ShortName : GroupItems)
{
EnabledItems.Add(ShortName);
if (FStatMessage const* LongName = Stats.ShortNameToLongName.Find(ShortName))
{
EnabledItems.Add(LongName->NameAndInfo.GetRawName());
}
}
// Create a filter (needed by stats gathering function)
FGroupFilter Filter(EnabledItems);
// Create empty stat stack node (needed by stats gathering function)
FRawStatStackNode HierarchyInclusive;
// Prepare the array for stat messages
TArray<FStatMessage> NonStackStats;
// COLLECT ALL STATS TO THE ARRAY HERE
Stats.UncondenseStackStats(LastGoodGameFrame, HierarchyInclusive, &Filter, &NonStackStats);
// Go through all stats
// There are many ways to display them, dig around the code to display it as you want :)
for (auto Stat : NonStackStats)
{
// Here we are getting the raw name
FName StatName = Stat.NameAndInfo.GetRawName();
UE_LOG(MyLog, Log, TEXT("Received Stat: %s"), *StatName.ToString());
// Here we are getting values
int64 iVal = 0;
double dVal = 0;
switch (Stat.NameAndInfo.GetField<EStatDataType>())
{
case EStatDataType::ST_int64:
iVal = Stat.GetValue_int64();
UE_LOG(DTLog, Log, TEXT("Value int64: %lld"), iVal);
break;
case EStatDataType::ST_double:
dVal = Stat.GetValue_double();
UE_LOG(MyLog, Log, TEXT("Value double: %f"), dVal);
break;
default:
check(0);
}
}
One important thing! The function will work only when the “stat net” has been enabled from console. Without it stats won’t be gathered.
I was hoping someone was trying to do the same thing and could show how to do this, but I’ve managed to write stat gathering function based on StatsCommand.cpp file you’ve mention Thanks for helping.
No, I was running it on GameThread. You only have to remember that You must run stat command to make it work. Without it the code will have nothing to parse.
The method I’ve shown simply copy the data that are displayed on the screen when you type ‘stat net’ into the game console. You can also get any kind of stat you want - memory, memoryplatform, engine, there are a lot of STATGROUPs. I needed this to save data about ping and packet lost during the online game to the file for QA reasons.
I’m not sure what more can I tell
Thing is, the “stat net” command doesn’t even work for me, any idea why?
I also need info about ping and packet loss … basically I need about everything I can do evaluate my system
The only reason ‘stat net’ would not work is even you run your game in shipping build or there is no net driver running. To see ‘stat net’ you must be during an online game.
Thanks man, packaging the game and joining a session made it work. No idea why I didn’t think of that before.
Can you guide me through adding the code to save the data to a csv file?
I’m not very familiar with C++ in UE 4, although, I do know C++.
I thnik You just have to put the code inside the plugin and run it… that’s all. Plugin can also enable stats by launching the command:
GetWorld()->Exec(GetWorld(), TEXT(“stat net”));