OpenParable
Skip to content
← Back to skills

Horse Telemetry Observability

DevOps & Security
horse-telemetry-observability

Horse Telemetry Observability is an Agent Skill for devops & security published in the HashLoad/horse repository on GitHub: a SKILL.md instruction file an AI agent can load to do this task.

Guidelines for registering, executing, and optimizing native high-precision telemetry hooks (AddOnTelemetry) in the Horse Web Framework.

View on GitHub ↗
QUICK START

How to use this skill

Bring this guide into your coding agent with a prompt tailored to the tool you use.

  1. Open your project in Codex.
  2. Copy and paste the prompt below.
  3. Review files and risks before approving any action.
Prompt to paste
Inspect the Agent Skill at https://github.com/HashLoad/horse/blob/HEAD/doc/skills/horse-telemetry-observability/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/horse-telemetry-observability, but wait for my approval before writing files or running scripts.

Copying this prompt does not install or run the skill. Review third-party files before use.

Horse Telemetry & Observability

Native Telemetry Hook (AddOnTelemetry)

Horse provides a high-precision, native, and Zero-Allocation telemetry hook based on stack-allocated TStopwatch. This hook allows monitoring and logging the total processing latency of all requests passing through the server pipeline.

The telemetry callback is defined as follows:

THorseOnTelemetry = {$IF DEFINED(FPC)}procedure{$ELSE}reference to procedure{$ENDIF}(const ARequest: THorseRequest; const AResponse: THorseResponse; const AExecutionTimeMS: Double);

Registering the Telemetry Hook

1. Global Registration

For applications using the standard static THorse facade, register the telemetry hook globally during the bootstrap process:

uses
  Horse, System.SysUtils;

begin
  THorse.AddOnTelemetry(
    procedure(const Req: THorseRequest; const Res: THorseResponse; const ExecutionTimeMS: Double)
    begin
      Writeln(Format('[Telemetry] %s %s - Status: %d - Latency: %.2f ms', 
        [Req.Method, Req.PathInfo, Res.Status, ExecutionTimeMS]));
    end);

  THorse.Get('/ping',
    procedure(Req: THorseRequest; Res: THorseResponse)
    begin
      Res.Send('pong');
    end);

  THorse.Listen(9000);
end.

2. Multi-Instance Registration

For applications utilizing THorseInstance, register telemetry hooks directly on each instance. Telemetry is fully isolated per port and polymorphically resolved based on the incoming request port:

var
  LInstance1, LInstance2: THorseInstance;
begin
  LInstance1 := THorseInstance.Create;
  LInstance1.AddOnTelemetry(
    procedure(const Req: THorseRequest; const Res: THorseResponse; const ExecutionTimeMS: Double)
    begin
      Writeln(Format('[Instance 1 - Port %d] Latency: %.2f ms', [Req.RawWebRequest.ServerPort, ExecutionTimeMS]));
    end);

  LInstance2 := THorseInstance.Create;
  LInstance2.AddOnTelemetry(
    procedure(const Req: THorseRequest; const Res: THorseResponse; const ExecutionTimeMS: Double)
    begin
      Writeln(Format('[Instance 2 - Port %d] Latency: %.2f ms', [Req.RawWebRequest.ServerPort, ExecutionTimeMS]));
    end);
end;

Design Safeguards & AI Best Practices

  1. Catch Internal Exceptions: Always wrap the code inside custom telemetry callbacks with a try-except block (or rely on Horse's native try-except boundary) to ensure failures during metrics collecting (like database logging or APM networking errors) never interrupt the HTTP response loop or crash the socket execution thread.
  2. Zero-Allocation Logging: To maintain Horse's zero-allocation characteristics, avoid dynamic heap allocations (such as concatenating strings or creating new logger objects) inside the telemetry callback. Prefer reusing static buffers or writing to stack-allocated variables.
  3. Multi-Instance Port Resolution: Always use Req.RawWebRequest.ServerPort if you need to determine the active port of the incoming request dynamically inside the telemetry handler.
  4. FPC/Lazarus Compatibility: In FPC (Lazarus), the callback type is a standard procedural pointer. Do not use inline anonymous methods (procedure begin end) when compiling libraries or handlers for Lazarus.