2018-03-10 00:29:27 +00:00
# ifdef _WIN32
# include <windows.h>
# endif
# include <chrono>
2018-03-10 01:25:29 +00:00
# include <inttypes.h>
2018-03-10 00:29:27 +00:00
# include <mutex>
2019-01-24 18:13:09 +00:00
# include <signal.h>
2018-03-10 01:25:29 +00:00
# include <stdint.h>
2018-03-10 00:29:27 +00:00
# include <stdio.h>
# include <stdlib.h>
2018-09-09 17:28:53 +00:00
# include "../../common/TracyProtocol.hpp"
2018-03-10 00:29:27 +00:00
# include "../../server/TracyFileWrite.hpp"
# include "../../server/TracyMemory.hpp"
2019-06-18 18:43:28 +00:00
# include "../../server/TracyPrint.hpp"
2018-03-10 00:29:27 +00:00
# include "../../server/TracyWorker.hpp"
# include "getopt.h"
2019-01-24 19:04:08 +00:00
# ifndef _MSC_VER
2019-01-24 18:13:09 +00:00
struct sigaction oldsigint ;
bool disconnect = false ;
void SigInt ( int )
{
disconnect = true ;
}
2019-01-24 19:04:08 +00:00
# endif
2019-01-24 18:13:09 +00:00
2018-03-10 01:25:29 +00:00
2018-03-10 00:29:27 +00:00
void Usage ( )
{
2019-09-21 13:43:01 +00:00
printf ( " Usage: capture -a address -o output.tracy [-p port] \n " ) ;
2018-03-10 00:29:27 +00:00
exit ( 1 ) ;
}
int main ( int argc , char * * argv )
{
# ifdef _WIN32
if ( ! AttachConsole ( ATTACH_PARENT_PROCESS ) )
{
AllocConsole ( ) ;
SetConsoleMode ( GetStdHandle ( STD_OUTPUT_HANDLE ) , 0x07 ) ;
}
# endif
const char * address = nullptr ;
const char * output = nullptr ;
2019-09-21 13:43:01 +00:00
int port = 8086 ;
2018-03-10 00:29:27 +00:00
int c ;
2019-09-21 13:43:01 +00:00
while ( ( c = getopt ( argc , argv , " a:o:p: " ) ) ! = - 1 )
2018-03-10 00:29:27 +00:00
{
switch ( c )
{
case ' a ' :
address = optarg ;
break ;
case ' o ' :
output = optarg ;
break ;
2019-09-21 13:43:01 +00:00
case ' p ' :
port = atoi ( optarg ) ;
break ;
2018-03-10 00:29:27 +00:00
default :
Usage ( ) ;
break ;
}
}
if ( ! address | | ! output ) Usage ( ) ;
2019-09-21 13:43:01 +00:00
printf ( " Connecting to %s:%i... " , address , port ) ;
2018-03-10 00:29:27 +00:00
fflush ( stdout ) ;
2019-09-21 13:43:01 +00:00
tracy : : Worker worker ( address , port ) ;
2019-02-12 10:13:53 +00:00
while ( ! worker . IsConnected ( ) )
2018-09-09 17:28:53 +00:00
{
const auto handshake = worker . GetHandshakeStatus ( ) ;
if ( handshake = = tracy : : HandshakeProtocolMismatch )
{
printf ( " \n The client you are trying to connect to uses incompatible protocol version. \n Make sure you are using the same Tracy version on both client and server. \n " ) ;
return 1 ;
}
2018-09-09 17:42:06 +00:00
if ( handshake = = tracy : : HandshakeNotAvailable )
{
printf ( " \n The client you are trying to connect to is no longer able to sent profiling data, \n because another server was already connected to it. \n You can do the following: \n \n 1. Restart the client application. \n 2. Rebuild the client application with on-demand mode enabled. \n " ) ;
return 2 ;
}
2019-02-12 10:13:53 +00:00
if ( handshake = = tracy : : HandshakeDropped )
{
printf ( " \n The client you are trying to connect to has disconnected during the initial \n connection handshake. Please check your network configuration. \n " ) ;
return 3 ;
}
2018-09-09 17:28:53 +00:00
}
2018-03-10 00:29:27 +00:00
while ( ! worker . HasData ( ) ) std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 100 ) ) ;
2019-06-18 18:43:28 +00:00
printf ( " \n Queue delay: %s \n Timer resolution: %s \n " , tracy : : TimeToString ( worker . GetDelay ( ) ) , tracy : : TimeToString ( worker . GetResolution ( ) ) ) ;
2018-03-10 00:29:27 +00:00
2019-01-24 19:04:08 +00:00
# ifndef _MSC_VER
2019-01-24 18:13:09 +00:00
struct sigaction sigint ;
memset ( & sigint , 0 , sizeof ( sigint ) ) ;
sigint . sa_handler = SigInt ;
sigaction ( SIGINT , & sigint , & oldsigint ) ;
2019-01-24 19:04:08 +00:00
# endif
2019-01-24 18:13:09 +00:00
2018-03-10 00:29:27 +00:00
auto & lock = worker . GetMbpsDataLock ( ) ;
while ( worker . IsConnected ( ) )
{
2019-01-24 19:04:08 +00:00
# ifndef _MSC_VER
2019-01-24 18:13:09 +00:00
if ( disconnect )
{
worker . Disconnect ( ) ;
disconnect = false ;
}
2019-01-24 19:04:08 +00:00
# endif
2019-01-24 18:13:09 +00:00
2018-03-10 00:29:27 +00:00
lock . lock ( ) ;
const auto mbps = worker . GetMbpsData ( ) . back ( ) ;
const auto compRatio = worker . GetCompRatio ( ) ;
2019-10-26 14:14:18 +00:00
const auto netTotal = worker . GetDataTransferred ( ) ;
2018-03-10 00:29:27 +00:00
lock . unlock ( ) ;
if ( mbps < 0.1f )
{
printf ( " \33 [2K \r \033 [36;1m%7.2f Kbps " , mbps * 1000.f ) ;
}
else
{
printf ( " \33 [2K \r \033 [36;1m%7.2f Mbps " , mbps ) ;
}
2019-10-26 14:14:18 +00:00
printf ( " \033 [0m / \033 [36;1m%5.1f%% \033 [0m= \033 [33;1m%7.2f Mbps \033 [0m| \033 [33mNet: \033 [32m%s \033 [0m| \033 [33mMem: \033 [31;1m%.2f MB \033 [0m | \033 [33mTime: %s \033 [0m " ,
compRatio * 100.f ,
mbps / compRatio ,
tracy : : MemSizeToString ( netTotal ) ,
tracy : : memUsage . load ( std : : memory_order_relaxed ) / ( 1024.f * 1024.f ) ,
tracy : : TimeToString ( worker . GetLastTime ( ) ) ) ;
2018-03-10 00:29:27 +00:00
fflush ( stdout ) ;
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 100 ) ) ;
}
2019-01-14 22:52:38 +00:00
const auto & failure = worker . GetFailureType ( ) ;
if ( failure ! = tracy : : Worker : : Failure : : None )
{
2019-01-15 17:42:15 +00:00
printf ( " \n \033 [31;1mInstrumentation failure: %s \033 [0m " , tracy : : Worker : : GetFailureString ( failure ) ) ;
2019-01-14 22:52:38 +00:00
}
2019-08-15 19:04:20 +00:00
printf ( " \n Frames: % " PRIu64 " \n Time span: %s \n Zones: %s \n Saving trace... " , worker . GetFrameCount ( * worker . GetFramesBase ( ) ) , tracy : : TimeToString ( worker . GetLastTime ( ) ) , tracy : : RealToString ( worker . GetZoneCount ( ) , true ) ) ;
2018-03-10 00:29:27 +00:00
fflush ( stdout ) ;
2018-03-28 23:11:54 +00:00
auto f = std : : unique_ptr < tracy : : FileWrite > ( tracy : : FileWrite : : Open ( output ) ) ;
2018-03-10 00:29:27 +00:00
if ( f )
{
worker . Write ( * f ) ;
printf ( " \033 [32;1mdone! \033 [0m \n " ) ;
}
else
{
printf ( " \033 [31;1failed! \033 [0m \n " ) ;
}
return 0 ;
}