Skip to content

Conversation

@ashokbytebytego
Copy link

Add Heartbeat-Based Dynamic Profiling Control Data Model

Overview

This PR introduces the database schema for a new heartbeat-based profiling control system that enables remote, dynamic control of gProfiler agents through API commands. This feature allows operators to start and stop profiling sessions on demand without manual intervention on target hosts.

Problem Statement

Previously, gProfiler agents ran continuously with fixed configurations, making it difficult to:

  • Dynamically start/stop profiling sessions based on operational needs
  • Profile specific processes or time windows on demand
  • Coordinate profiling across multiple hosts
  • Track profiling execution history and audit trails

Solution

This PR adds four new core tables and supporting types to enable a robust heartbeat-based command-and-control system

Note : This is simplified version of the dynamic profiling data model. A more robust and scalable will be added in near future

duration integer NULL DEFAULT 60,
frequency integer NULL DEFAULT 11,
profiling_mode ProfilingMode NOT NULL DEFAULT 'cpu',
target_hostnames text[] NOT NULL,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be extended to container names, pod names, namespace name



-- Additional Types for Profiling System
CREATE TYPE ProfilingMode AS ENUM ('cpu', 'allocation', 'none');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also need those de-normalized tables to help with look up to map between namespace , services, jobs, pod, containers, and host

@mlim19
Copy link
Contributor

mlim19 commented Nov 6, 2025

@dkorlovs and @skamerintel, let's review this PR together.

@dkorlovs dkorlovs requested a review from Copilot November 18, 2025 10:08
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements the database schema and documentation for a heartbeat-based dynamic profiling control system. The new system enables remote start/stop control of gProfiler agents through API commands, replacing the previous continuous profiling model with on-demand profiling capabilities.

Key Changes:

  • Added four core database tables (HostHeartbeats, ProfilingRequests, ProfilingCommands, ProfilingExecutions) with supporting enums to track agent status and profiling command lifecycle
  • Created comprehensive documentation covering architecture, API endpoints, configuration, and troubleshooting guidance

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
scripts/setup/postgres/gprofiler_recreate.sql Adds database schema for heartbeat-based profiling control with four new tables, custom enum types, and essential indexes
heartbeat_doc/README_HEARTBEAT.md Provides complete documentation of the heartbeat system including architecture diagrams, API examples, configuration options, and operational guidance

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +355 to +356
-- FUNCTIONS

Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment header appears misplaced or misleading. The FUNCTIONS section is separated from the new profiling tables by the existing function definitions that start at line 357. Consider either moving this comment to just before line 357 where calc_profiler_usage_history begins, or removing it if it's not serving a structural purpose for the new schema additions.

Suggested change
-- FUNCTIONS
-- FUNCTIONS

Copilot uses AI. Check for mistakes.
Comment on lines +330 to +335
-- Profiling Executions Table (optional - for audit trail)
CREATE TABLE ProfilingExecutions (
ID bigserial PRIMARY KEY,
command_id uuid NOT NULL,
hostname text NOT NULL,
profiling_request_id uuid NOT NULL CONSTRAINT "fk_profiling_execution_request" REFERENCES ProfilingRequests(request_id),
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Foreign key constraint references ProfilingRequests(request_id) but ProfilingRequests uses ID as the primary key. The constraint should reference the primary key column ID, not the UUID column request_id. Change to: REFERENCES ProfilingRequests(ID) and add a separate index on request_id if UUID lookups are needed.

Suggested change
-- Profiling Executions Table (optional - for audit trail)
CREATE TABLE ProfilingExecutions (
ID bigserial PRIMARY KEY,
command_id uuid NOT NULL,
hostname text NOT NULL,
profiling_request_id uuid NOT NULL CONSTRAINT "fk_profiling_execution_request" REFERENCES ProfilingRequests(request_id),
-- Add index for UUID lookups on ProfilingRequests
CREATE INDEX idx_profilingrequests_request_id ON ProfilingRequests(request_id);
-- Profiling Executions Table (optional - for audit trail)
CREATE TABLE ProfilingExecutions (
ID bigserial PRIMARY KEY,
command_id uuid NOT NULL,
hostname text NOT NULL,
profiling_request_id bigint NOT NULL CONSTRAINT "fk_profiling_execution_request" REFERENCES ProfilingRequests(ID),

Copilot uses AI. Check for mistakes.
-- Check command execution history
SELECT pe.hostname, pr.request_type, pe.status, pe.execution_time
FROM ProfilingExecutions pe
JOIN ProfilingRequests pr ON pe.profiling_request_id = pr.ID
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This JOIN condition is inconsistent with the foreign key definition in the schema. The schema's foreign key constraint references ProfilingRequests(request_id), but this query joins on pr.ID. This query will fail since profiling_request_id contains UUID values from the request_id column, not bigint IDs. The correct join should be: JOIN ProfilingRequests pr ON pe.profiling_request_id = pr.request_id

Suggested change
JOIN ProfilingRequests pr ON pe.profiling_request_id = pr.ID
JOIN ProfilingRequests pr ON pe.profiling_request_id = pr.request_id

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants