Palanteer
Visual Python and C++ nanosecond profiler, logger, tests enabler
Install / Use
/learn @dfeneyrou/PalanteerREADME
Look into Palanteer and get an omniscient view of your program
Palanteer is a set of lean and efficient tools to improve the quality of software, for C++ and Python programs.
<img src="docs/images/views.gif " alt="Palanteer viewer image" width="1000"/>Simple code instrumentation, mostly automatic in Python, delivers powerful features:
- Collection of meaningful atomic events on timings, memory, locks wait and usage, context switches, data values..
- Efficient logging with a printf-compatible interface
- Visual and interactive observation of records: hierarchical logs, timeline, plot, histogram, flame graph...
- Remote command call and events observation can be scripted in Python: deep testing has never been simpler
- C++:
- ultralight single-header cross-platform instrumentation library
- printf-like nanosecond logging with level, category and graphable arguments
- compile time selection of groups of instrumentation
- compile-time hashing of static strings to minimize their cost
- compile-time striping of all instrumentation static strings
- enhanced assertions, stack trace dump...
- automatic code instrumentation (Linux GCC only)
- Python:
- Automatic instrumentation of functions enter/leave, memory allocations, raised exceptions, garbage collection runs
- Seamless support of multithreading, asyncio/gevent
Recording simultaneously up to 8 streams (i.e., from different processes) is supported.
Palanteer is an efficient, lean and comprehensive solution for better and enjoyable software development!
C++ instrumentation example
Below is a simple example of a C++ program instrumented with Palanteer and generating 100 000 random integers. The range can be remotely configured with a user-defined CLI.
The Python scripting module can control this program, in particular:
- call the setBoundsCliHandler to change the configuration
- temporarily stop the program at the freeze point
- see all "random data" values and the timing of the scope event "Generate some random values"
// File: example.cpp
// On Linux, build with: g++ -DUSE_PL=1 -I <palanteer C++ instrumentation folder> example.cpp -lpthread -o example
#include <stdlib.h> // For "rand"
#define PL_IMPLEMENTATION 1 // The instrumentation library shall be "implemented" once
#include "palanteer.h"
int globalMinValue = 0, globalMaxValue = 10;
// Handler (=user implementation) of the example CLI, which sets the range
void setBoundsCliHandler(plCliIo& cio) // 'cio' is a communication helper passed to each C++ CLI handler
{
int minValue = cio.getParamInt(0); // Get the 2 CLI parameters as integers (as declared)
int maxValue = cio.getParamInt(1);
if(minValue>maxValue) { // Case where the CLI execution fails. The text answer contains some information about it
cio.setErrorState("Minimum value (%d) shall be lower than the maximum value (%d)", minValue, maxValue);
return;
}
// Modify the state of the program. No care about thread-safety here, to keep the example simple
globalMinValue = minValue;
globalMaxValue = maxValue;
// CLI execution was successful (because no call to cio.setErrorState())
}
int main(int argc, char** argv)
{
plInitAndStart("example"); // Start the instrumentation, for the program named "example"
plDeclareThread("Main"); // Declare the current thread as "Main" so that it can be identified more easily in the script
plRegisterCli(setBoundsCliHandler, "config:setRange", "min=int max=int", "Sets the value bounds of the random generator"); // Declare our CLI
plFreezePoint(); // Add a freeze point here to be able to configure the program at a controlled moment
plBegin("Generate some random values");
for(int i=0; i<100000; ++i) {
int value = globalMinValue + rand()%(globalMaxValue+1-globalMinValue);
plData("random data", value); // Here are the "useful" values
}
plEnd(""); // Shortcut for plEnd("Generate some random values")
plStopAndUninit(); // Stop and uninitialize the instrumentation
return 0;
}
</details>
Some C++ performance figures (see here for more details):
- nanosecond resolution and ~25 nanoseconds cost per event on a standard x64 machine
- up to ~5 millions events per second when recording, bottleneck on the server processing side
- up to ~150 000 events per second when processing the flow through a Python script, bottleneck on the Python script side
Python instrumentation example
Execution of unmodified Python programs can be analyzed directly with a syntax similar to the one of cProfile, as a large part of the instrumentation is automated by default:
- Functions enter/leave
- Interpreter memory allocations
- All raised exceptions
- Garbage collection runs
- Coroutines
In some cases, a manual instrumentation which enhances or replaces the automatic one is desired. <br/> The example below is an equivalent of the C++ code above, but in Python:
<details> <summary> See Python manual instrumentation example code </summary>#! /usr/bin/env python3
import sys
import random
from palanteer import *
globalMinValue, globalMaxValue = 0, 10
# Handler (=implementation) of the example CLI, which sets the range
def setBoundsCliHandler(minValue, maxValue): # 2 parameters (both integer) as declared
global globalMinValue, globalMaxValue
if minValue>maxValue: # Case where the CLI execution fails (non null status). The text answer contains some information about it
return 1, "Minimum value (%d) shall be lower than the maximum value (%d)" % (minValue, maxValue)
# Modify the state of the program
globalMinValue, globalMaxValue = minValue, maxValue
# CLI execution was successful (null status)
return 0, ""
def main(argv):
global globalMinValue, globalMaxValue
plInitAndStart("example") # Start the instrumentation
plDeclareThread("Main") # Declare the current thread as "Main", so that it can be identified more easily in the script
plRegisterCli(setBoundsCliHandler, "config:setRange", "min=int max=int", "Sets the value bounds of the random generator") # Declare the CLI
plFreezePoint() # Add a freeze point here to be able to configure the program at a controlled moment
plBegin("Generate some random values")
for i in range(100000):
value = int(globalMinValue + random.random()*(globalMaxValue+1-globalMinValue))
plData("random data", value) # Here are the "useful" values
plEnd("") # Shortcut for plEnd("Generate some random values")
plStopAndUninit() # Stop and uninitialize the instrumentation
# Bootstrap
if __name__ == "__main__":
main(sys.argv)
</details>
Scripting example
Both examples above (C++ and Python) can be remotely controlled with a simple Python script.
Typical usages are:
- Tests based on stimulation/configuration with CLI and events observation, as data can also be traced
- Evaluation of the program performance
- Monitoring
- ...
#! /usr/bin/env python3
import sys
import palanteer_scripting as ps
def main(argv):
if len(sys.argv)<2:
print("Error: missing parameters (the program to launch)")
sys.exit(1)
# Initialize the scripting module
ps.initialize_scripting()
# Enable the freeze mode so that we can safely configure the program once stopped on its freeze point
ps.program_set_freeze_mode(True)
# Launch the program under test
ps.process_launch(sys.argv[1], args=sys.argv[2:])
# From here, we are connected to the remote program
# Configure the selection of events to receive
my_selection = ps.EvtSpec(thread="Main", events=["random data"]) # Thread "Main", only the event "random data"
ps.data_configure_events(my_selection)
# Configure the program
status, response = ps.program_cli("config:setRange min=300 max=500")
if status!=0:
print("Error when configuring: %s\nKeeping original settings." % response)
# Disable the freeze mode so that the program resumes its execution
ps.program_set_freeze_mode(False)
# Collect the events as long as the program is alive or we got some events in the last round
qty, sum_values, min_value, max_value, has_worked = 0, 0, 1e9, 0, True
while ps.process_is_running() or
Related Skills
node-connect
341.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
claude-opus-4-5-migration
84.5kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
frontend-design
84.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
model-usage
341.2kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
