142 lines
4.0 KiB
C
142 lines
4.0 KiB
C
/*
|
|
* Scenario 6: USDT Probes - Custom Instrumentation
|
|
* =================================================
|
|
* This program demonstrates User Statically Defined Tracepoints (USDT).
|
|
* USDT probes allow you to add custom tracing points to your code
|
|
* that have near-zero overhead when not actively traced.
|
|
*
|
|
* Compile:
|
|
* gcc -O2 -g -o server server.c
|
|
*
|
|
* The probes use sys/sdt.h which is provided by systemtap-sdt-dev on Ubuntu.
|
|
* Install: sudo apt install systemtap-sdt-dev
|
|
*
|
|
* EXERCISES:
|
|
* 1. Run normally: ./server
|
|
* 2. List probes: perf probe -x ./server --list
|
|
* 3. Trace probes: See README.md for bpftrace examples
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
|
|
/*
|
|
* USDT probe macros from systemtap-sdt-dev
|
|
* If not available, we define dummy macros
|
|
*/
|
|
#ifdef HAVE_SDT
|
|
#include <sys/sdt.h>
|
|
#else
|
|
/* Dummy macros when SDT isn't available */
|
|
#define DTRACE_PROBE(provider, name)
|
|
#define DTRACE_PROBE1(provider, name, arg1)
|
|
#define DTRACE_PROBE2(provider, name, arg1, arg2)
|
|
#define DTRACE_PROBE3(provider, name, arg1, arg2, arg3)
|
|
#endif
|
|
|
|
/* Simulated request structure */
|
|
struct request {
|
|
int id;
|
|
int type; /* 0=read, 1=write, 2=delete */
|
|
int size; /* payload size */
|
|
char data[64];
|
|
};
|
|
|
|
/* Statistics */
|
|
static unsigned long total_requests = 0;
|
|
static unsigned long total_errors = 0;
|
|
|
|
/*
|
|
* Process a single request
|
|
* We add USDT probes at entry, exit, and error points
|
|
*/
|
|
int process_request(struct request *req) {
|
|
/* Probe: request processing started */
|
|
DTRACE_PROBE2(myserver, request_start, req->id, req->type);
|
|
|
|
total_requests++;
|
|
|
|
/* Simulate variable processing time based on request type */
|
|
int delay_ms;
|
|
switch (req->type) {
|
|
case 0: delay_ms = 10 + (rand() % 20); break; /* read: 10-30ms */
|
|
case 1: delay_ms = 50 + (rand() % 50); break; /* write: 50-100ms */
|
|
case 2: delay_ms = 5 + (rand() % 10); break; /* delete: 5-15ms */
|
|
default: delay_ms = 100;
|
|
}
|
|
|
|
/* Simulate some work */
|
|
usleep(delay_ms * 1000);
|
|
|
|
/* Simulate occasional errors (10% chance) */
|
|
if (rand() % 10 == 0) {
|
|
DTRACE_PROBE2(myserver, request_error, req->id, -1);
|
|
total_errors++;
|
|
return -1;
|
|
}
|
|
|
|
/* Probe: request completed successfully */
|
|
DTRACE_PROBE3(myserver, request_end, req->id, req->type, delay_ms);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Batch processing function
|
|
*/
|
|
void process_batch(int batch_id, int count) {
|
|
DTRACE_PROBE2(myserver, batch_start, batch_id, count);
|
|
|
|
printf("Processing batch %d with %d requests...\n", batch_id, count);
|
|
|
|
struct request req;
|
|
for (int i = 0; i < count; i++) {
|
|
req.id = batch_id * 1000 + i;
|
|
req.type = rand() % 3;
|
|
req.size = 64;
|
|
snprintf(req.data, sizeof(req.data), "request_%d", req.id);
|
|
|
|
process_request(&req);
|
|
}
|
|
|
|
DTRACE_PROBE1(myserver, batch_end, batch_id);
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
int num_batches = 5;
|
|
int requests_per_batch = 20;
|
|
|
|
if (argc > 1) num_batches = atoi(argv[1]);
|
|
if (argc > 2) requests_per_batch = atoi(argv[2]);
|
|
|
|
srand(time(NULL));
|
|
|
|
printf("USDT Probe Demo Server\n");
|
|
printf("======================\n");
|
|
printf("Batches: %d, Requests per batch: %d\n\n", num_batches, requests_per_batch);
|
|
|
|
#ifndef HAVE_SDT
|
|
printf("Note: Compiled without USDT support.\n");
|
|
printf("To enable probes: sudo apt install systemtap-sdt-dev\n");
|
|
printf("Then compile with: gcc -DHAVE_SDT -O2 -g -o server server.c\n\n");
|
|
#endif
|
|
|
|
DTRACE_PROBE(myserver, server_start);
|
|
|
|
for (int i = 0; i < num_batches; i++) {
|
|
process_batch(i, requests_per_batch);
|
|
}
|
|
|
|
DTRACE_PROBE(myserver, server_stop);
|
|
|
|
printf("\n=== Summary ===\n");
|
|
printf("Total requests: %lu\n", total_requests);
|
|
printf("Total errors: %lu (%.1f%%)\n",
|
|
total_errors, 100.0 * total_errors / total_requests);
|
|
|
|
return 0;
|
|
}
|