Overview
Tracer is Atlas Engine’s lightweight TCP-based diagnostics system that provides real-time telemetry, logging, and profiling data. It enables you to monitor render performance, track resource usage, and debug issues without impacting production builds.
Architecture
Tracer uses a client-server model:
Engine Client : Sends telemetry packets over TCP (default port 5123)
Tracer Server : External tool that receives and visualizes diagnostic data
NetworkPipe : TCP connection managing message streaming
Getting Started
Starting Tracer
#include <atlas/tracer/log.h>
// Start tracer connection on default port (5123)
TracerServices :: getInstance (). startTracing (TRACER_PORT);
// Check connection status
if ( TracerServices :: getInstance (). isOk ()) {
atlas_log ( "Tracer connected successfully" );
}
Basic Logging
// Log an informational message
atlas_log ( "Application started" );
// Log a warning
atlas_warning ( "Texture quality reduced for performance" );
// Log an error
atlas_error ( "Failed to load model: file not found" );
Log messages automatically include:
Timestamp
Source file and line number (log.h:80, log.h:82, log.h:85)
Severity level
Message content
Timing Scopes
Use DebugTimer to measure execution time:
{
DebugTimer timer ( "ShadowPass" );
renderShadows ();
} // Timer stops and reports duration automatically
{
DebugTimer timer ( "PhysicsUpdate" );
physics . update (deltaTime);
}
Manual Timing
DebugTimer timer ( "CustomOperation" );
performExpensiveOperation ();
uint64_t microseconds = timer . stop ();
atlas_log ( "Operation took " + std :: to_string (microseconds) + "us" );
Timing Events
Send structured timing data to the tracer:
TimingEventPacket event;
event . name = "TerrainGeneration" ;
event . subsystem = TimingEventSubsystem ::Rendering;
event . durationMs = 16.7 f ;
event . frameNumber = currentFrame;
event . send ();
Available Subsystems
Rendering - Graphics and shader execution
Physics - Physics simulation and collision
AI - Pathfinding and behavior trees
Scripting - Script execution and VM operations
Animation - Skeletal animation and blending
Audio - Sound mixing and streaming
Networking - Network I/O and synchronization
Io - File system operations
Scene - Scene graph updates
Other - Uncategorized operations
Graphics Debugging
Draw Call Tracking
DrawCallInfo drawCall;
drawCall . callerObject = "TerrainRenderer" ;
drawCall . type = DrawCallType ::Indexed;
drawCall . frameNumber = currentFrame;
drawCall . send ();
Frame Statistics
FrameDrawInfo frameInfo;
frameInfo . frameNumber = currentFrame;
frameInfo . drawCallCount = totalDrawCalls;
frameInfo . frameTimeMs = 16.6 f ;
frameInfo . fps = 60.0 f ;
frameInfo . send ();
Frame Timing
FrameTimingPacket timing;
timing . frameNumber = currentFrame;
timing . cpuFrameTimeMs = 12.3 f ;
timing . gpuFrameTimeMs = 14.2 f ;
timing . mainThreadTimeMs = 10.5 f ;
timing . workerThreadTimeMs = 1.8 f ;
timing . memoryMb = 512.0 f ;
timing . cpuUsagePercent = 45.0 f ;
timing . gpuUsagePercent = 78.0 f ;
timing . send ();
Resource Monitoring
Resource Events
ResourceEventInfo event;
event . callerObject = "TextureManager" ;
event . resourceType = DebugResourceType ::Texture;
event . operation = DebugResourceOperation ::Loaded;
event . frameNumber = currentFrame;
event . sizeMb = 4.5 f ;
event . send ();
Resource Types
Texture - 2D/3D textures and cube maps
Buffer - Vertex, index, and uniform buffers
Shader - Compiled shader programs
Mesh - Geometry and vertex data
Resource Operations
Created - Resource allocated
Loaded - Resource data uploaded
Unloaded - Resource freed
Frame Resource Summary
FrameResourcesInfo resourceInfo;
resourceInfo . frameNumber = currentFrame;
resourceInfo . resourcesCreated = 5 ;
resourceInfo . resourcesLoaded = 12 ;
resourceInfo . resourcesUnloaded = 3 ;
resourceInfo . totalMemoryMb = 245.6 f ;
resourceInfo . send ();
Resource Tracking
Use the singleton tracker for aggregate statistics:
auto & tracker = ResourceTracker :: getInstance ();
atlas_log ( "Total resources loaded: " +
std :: to_string ( tracker . loadedResources ));
atlas_log ( "Total memory: " +
std :: to_string ( tracker . totalMemoryMb ) + " MB" );
Memory Profiling
Allocation Tracking
AllocationPacket alloc;
alloc . description = "Shadow map depth buffer" ;
alloc . owner = "ShadowRenderer" ;
alloc . domain = DebugMemoryDomain ::GPU;
alloc . kind = DebugResourceKind ::RenderTarget;
alloc . sizeMb = 16.0 f ;
alloc . frameNumber = currentFrame;
alloc . send ();
Memory Domains
GPU - Graphics memory (VRAM)
CPU - System memory (RAM)
Resource Kinds
VertexBuffer - Vertex attribute data
IndexBuffer - Index data for indexed draws
UniformBuffer - Shader uniform data
StorageBuffer - Shader storage buffers (SSBO)
Texture2d - 2D texture data
Texture3d - 3D volume textures
TextureCube - Cube map faces
RenderTarget - Color attachments
DepthStencil - Depth/stencil buffers
Sampler - Texture samplers
PipelineCache - Cached pipeline state
AccelerationStructure - Ray tracing structures
Other - Uncategorized allocations
Frame Memory Summary
FrameMemoryPacket memoryStats;
memoryStats . frameNumber = currentFrame;
memoryStats . totalAllocatedMb = 512.0 f ;
memoryStats . totalGPUMb = 384.0 f ;
memoryStats . totalCPUMb = 128.0 f ;
memoryStats . allocationCount = 45 ;
memoryStats . deallocationCount = 12 ;
memoryStats . send ();
Object-Level Debugging
Object Telemetry
DebugObjectPacket objInfo;
objInfo . objectId = model . getId ();
objInfo . objectType = DebugObjectType ::StaticMesh;
objInfo . triangleCount = 15420 ;
objInfo . materialCount = 3 ;
objInfo . vertexBufferSizeMb = 2.1 f ;
objInfo . indexBufferSizeMb = 0.8 f ;
objInfo . textureCount = 5 ;
objInfo . drawCallsForObject = 3 ;
objInfo . frameCount = currentFrame;
objInfo . send ();
Object Types
StaticMesh - Static geometry
SkeletalMesh - Animated skinned mesh
ParticleSystem - Particle emitters
LightProbe - Light probe volumes
Terrain - Terrain patches
Other - Custom object types
Network Communication
NetworkPipe API
#include <atlas/network/pipe.h>
// Create and configure pipe
NetworkPipe pipe;
pipe . setPort ( 5123 );
// Register message handler
pipe . onReceive ([]( const std :: string & msg ) {
std ::cout << "Received: " << msg << std ::endl;
});
// Start connection
pipe . start ();
// Send messages
pipe . send ( "Hello from Atlas \n " );
// Get message history
auto messages = pipe . getMessages ();
// Clean shutdown
pipe . stop ();
Tracer uses newline-delimited JSON packets:
{
"type" : "timing_event" ,
"name" : "ShadowPass" ,
"subsystem" : "rendering" ,
"duration_ms" : 3.4 ,
"frame" : 1234
}
Console Filtering
Control which log levels appear in console output:
Logger :: getInstance (). setConsoleFilter (
true , // Show info logs
true , // Show warnings
false // Hide errors from console (still sent to tracer)
);
Real-World Example
Complete profiling setup for a game loop:
#include <atlas/tracer/log.h>
#include <atlas/tracer/data.h>
void initTracer () {
TracerServices :: getInstance (). startTracing (TRACER_PORT);
if ( TracerServices :: getInstance (). isOk ()) {
atlas_log ( "Tracer connected on port 5123" );
}
}
void gameLoop () {
unsigned int frame = 0 ;
while (running) {
DebugTimer frameTimer ( "FullFrame" );
{
DebugTimer timer ( "Input" );
processInput ();
}
{
DebugTimer timer ( "Physics" );
physics . update (deltaTime);
}
{
DebugTimer timer ( "Rendering" );
renderer . render ();
// Track draw calls
FrameDrawInfo drawInfo;
drawInfo . frameNumber = frame;
drawInfo . drawCallCount = renderer . getDrawCallCount ();
drawInfo . frameTimeMs = deltaTime * 1000.0 f ;
drawInfo . fps = 1.0 f / deltaTime;
drawInfo . send ();
}
frame ++ ;
}
}
Integration with Workspace
The Workspace system uses Tracer for asset loading feedback:
// From workspace.cpp:17-19
atlas_log ( "Creating resource: " + name);
// From workspace.cpp:52
atlas_warning ( "Resource not found: " + name);
// From workspace.cpp:88
atlas_error ( "Resource not found in group: " + name);
Best Practices
Profile Early Start profiling during development to catch performance issues early
Use Scoped Timers Prefer DebugTimer RAII over manual timing for automatic cleanup
Track Resources Monitor resource creation/deletion to detect memory leaks
Filter Noise Use console filtering to focus on relevant diagnostics
Tracer is an alpha API and may change in future versions. The protocol and packet formats are subject to evolution.
The NetworkPipe class manages connection retry and automatic reconnection. If the tracer server disconnects, the pipe will attempt to reconnect in the background (pipe.h:68-69).