Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
53f8d62
refactor: migrate to Zend Memory API, add comprehensive tests, fix st…
xMlex Jul 1, 2026
b8996c1
Remove unnecessary <zend.h> include from tr_network.h
xMlex Jul 1, 2026
ae8c889
Add php.h stub for standalone unit tests
xMlex Jul 1, 2026
d951282
Update README: mark request_id as done, remove local path
xMlex Jul 1, 2026
94a3665
Rewrite README: build instructions, function reference, quick start
xMlex Jul 1, 2026
1324db0
Add install test script and fix Dockerfile
xMlex Jul 1, 2026
5acbd4d
Add overflow checks in tr_array ensure_capacity and init
xMlex Jul 1, 2026
b35199b
Update README: add INI config, how-it-works, remove TODO and .travis.yml
xMlex Jul 1, 2026
678eb1b
add opencode
xMlex Jul 1, 2026
4037b4e
Fix size tracking in tr_array write helpers after set_position
xMlex Jul 1, 2026
3e097ce
Add tests for size tracking after set_position + writes
xMlex Jul 1, 2026
fa9d4d3
Fix NULL/overflow safety in parse_domain_port_pairs
xMlex Jul 1, 2026
8b5c752
Fix docs and install test for trochilidae_timer_get_info()
xMlex Jul 1, 2026
baa8f30
Fix memory leaks and unsafe patterns
xMlex Jul 1, 2026
6ca0f9e
Add UDP test server for E2E integration testing
xMlex Jul 1, 2026
328ab3c
Generate random request_id for CLI mode
xMlex Jul 1, 2026
76b9349
Use uint64_t for generate_random_ulong and seed srand fallback
xMlex Jul 1, 2026
bedd581
Add internal hooks system for curl_exec and SoapClient->__soapCall
xMlex Jul 1, 2026
149eb69
Add trochilidae.chunk_size INI (default 65507, clamps to MAX_CHUNK_SIZE)
xMlex Jul 1, 2026
09c98b1
Add docs/protocol.md with wire format specification
xMlex Jul 1, 2026
d5b14bd
Add protocol TODO section to README.md
xMlex Jul 1, 2026
93d35f2
Update TODO: add code stability/scalability items alongside protocol …
xMlex Jul 1, 2026
21da586
S1: Move setsockopt SO_SNDBUF to init, set to 256KB
xMlex Jul 2, 2026
459eeb9
S2: Replace gethostbyname with getaddrinfo (thread-safe DNS)
xMlex Jul 2, 2026
e0aab17
S6: Fix DNS refresh guard condition
xMlex Jul 2, 2026
101c871
S11: Mark as by design — totalSentSize counts wire bytes
xMlex Jul 2, 2026
42ef668
S9: Heap-allocate chunk packet instead of stack
xMlex Jul 2, 2026
022e333
S7: Replace fprintf(stderr)/perror with php_error_docref
xMlex Jul 2, 2026
af4526e
S8: Use client->chunk_count in error message
xMlex Jul 2, 2026
03118af
S3+S4: Non-blocking sendto with drop counter
xMlex Jul 2, 2026
dbd92b2
Add chunking test (004_chunking)
xMlex Jul 2, 2026
e54de32
S5: Replace strcpy/strncpy with strlcpy/bounded memcpy
xMlex Jul 2, 2026
9ee5338
P1+P3+P6: Magic+version and payload_len in chunk header (reusing rese…
xMlex Jul 2, 2026
bfe87fa
Update protocol.md: chunk header now has magic+version+payload_len
xMlex Jul 2, 2026
5e998b6
update readme
xMlex Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,13 @@ jobs:
run: ./configure --enable-trochilidae
- name: make
run: make
- name: run test.php
run: php -d extension=`pwd`/modules/trochilidae.so -f test.php
- name: make test
run: make test
- name: Compile unit tests
run: gcc -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/Zend -I/usr/include/php/TSRM -I/usr/include/php/ext -I. -DHAVE_CONFIG_H -D_GNU_SOURCE -g -O0 tests/unit_test.c trochilidae/tr_network.c trochilidae/utils.c -o tests/unit_test
Comment on lines +30 to +31

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Проверка корректности путей к PHP-заголовкам
php-config --include-dir
php-config --includes

Repository: xMlex/php_trochilidae

Length of output: 251


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow outline =="
ast-grep outline .github/workflows/build.yml || true

echo "== relevant workflow lines =="
nl -ba .github/workflows/build.yml | sed -n '1,220p'

echo "== search for php setup and matrix references =="
rg -n --hidden --glob '.github/workflows/*.yml' --glob '.github/workflows/*.yaml' 'php-config|phpize|setup-php|include-dir|matrix|ubuntu-latest|PHP' .github/workflows || true

echo "== search repo for php-config usage =="
rg -n --hidden 'php-config|phpize|setup-php|/usr/include/php|/usr/include/php/' . || true

Repository: xMlex/php_trochilidae

Length of output: 294


🏁 Script executed:

#!/bin/bash
set -euo pipefail

nl -ba .github/workflows/build.yml | sed -n '1,120p'

Repository: xMlex/php_trochilidae

Length of output: 199


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== build.yml lines =="
sed -n '1,220p' .github/workflows/build.yml

echo "== workflow file size =="
wc -l .github/workflows/build.yml

echo "== php-related searches =="
grep -RIn --exclude-dir=.git -E 'php-config|phpize|setup-php|/usr/include/php|ubuntu-latest|matrix' .github/workflows . || true

Repository: xMlex/php_trochilidae

Length of output: 4213


Заменить хардкод путей на php-config --includes
setup-php поднимает разные версии PHP из матрицы, а /usr/include/php/... зависит от API-версии и может отсутствовать. Для этого шага лучше брать include-флаги из php-config (как в CMakeLists.txt), иначе сборка unit-теста сломается на части версий PHP.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build.yml around lines 30 - 31, The unit test compile step
hardcodes PHP include directories, which can break across the PHP versions
installed by setup-php. Update the compile command in the build workflow to use
include flags from php-config --includes instead of the /usr/include/php paths,
matching the approach used in CMakeLists.txt and keeping tests building across
the version matrix.

- name: Run unit tests
run: ./tests/unit_test
- name: Compile internal unit tests (tr_array, tr_timer)
run: gcc -I. -Itests/stubs -DHAVE_CONFIG_H -g -O0 -Wall tests/tr_internal_test.c -o tests/tr_internal_test -lm
- name: Run internal unit tests
run: ./tests/tr_internal_test
33 changes: 33 additions & 0 deletions .github/workflows/opencode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: opencode

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]

jobs:
opencode:
if: |
contains(github.event.comment.body, ' /oc') ||
startsWith(github.event.comment.body, '/oc') ||
contains(github.event.comment.body, ' /opencode') ||
startsWith(github.event.comment.body, '/opencode')
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
pull-requests: read
issues: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
persist-credentials: false

- name: Run opencode
uses: anomalyco/opencode/github@latest
env:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
with:
model: opencode/deepseek-v4-flash-free
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@
!test.php
!/trochilidae
!package.xml
!Dockerfile
!Dockerfile
!.opencode
!/docs

!/tests/stubs/php.h
!/tests/install_test.sh
35 changes: 35 additions & 0 deletions .opencode/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Project Guidelines: php_trochilidae

This project is a C-based PHP extension for metrics collection.

## Project Structure
- `trochilidae/`: Contains core functional sub-components.
- `tr_array.c/h`: Buffer and array manipulation (binary serialization).
- `tr_network.c/h`: TCP/UDP socket communication.
- `tr_timer.c/h`: High-resolution timers and Zend resource management.
- `tr_hooks.c`: Hooks for SAPI integration (intercepting output/execution).
- `utils.c/h`: Helper functions and utility macros.
- `docs/protocol.md`: Wire format specification for the UDP protocol.
- `tests/`: Contains `.phpt` files for integration testing.

## Core Conventions
- **Naming:**
- Internal functions: `tr_` prefix.
- PHP-exposed functions: `trochilidae_` prefix.
- **State Management:** Use `ZEND_DECLARE_MODULE_GLOBALS` and access globals via the `TR_G()` macro.
- **Resources:** Use Zend resource registration (`zend_register_list_destructors_ex`) for automated lifecycle management.
- **Performance:** Maintain low overhead; use custom binary serialization over JSON where possible.
- **Error Handling:** Use `php_error_docref`.

## Build & Test Workflow
1. **Configuration:** `phpize && ./configure --enable-trochilidae`
2. **Compilation:** `make`
3. **PHP tests:** `make test`
4. **C unit tests (network):**
`gcc -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/Zend -I/usr/include/php/TSRM -I/usr/include/php/ext -I. -DHAVE_CONFIG_H -D_GNU_SOURCE -g -O0 tests/unit_test.c trochilidae/tr_network.c trochilidae/utils.c -o tests/unit_test && ./tests/unit_test`
5. **C unit tests (internal — tr_array, tr_timer):**
`gcc -I. -Itests/stubs -DHAVE_CONFIG_H -g -O0 tests/tr_internal_test.c -o tests/tr_internal_test -lm && ./tests/tr_internal_test`
*Note:* These use `tests/stubs/php.h` to mock the Zend API outside of PHP context.

## Stubs
- `tests/stubs/php.h`: Minimal stub for `emalloc`/`erealloc`/`efree`/`estrdup` and `zend_resource` — used by `tr_internal_test.c` to compile without the real PHP headers.
11 changes: 0 additions & 11 deletions .travis.yml

This file was deleted.

14 changes: 7 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ RUN apk add --no-cache unzip git && \
# trochilidae
RUN apk add --no-cache build-base autoconf unzip git curl
ADD . /app
# php /app/test.php && \
RUN phpize && ./configure --enable-trochilidae && make clean && make install && docker-php-ext-enable trochilidae && \
php -m && \
php -r "echo 'Test TR at ',date('c'), PHP_EOL;" && \
echo "OK - exit" && \
composer install --prefer-dist && \
exit 1
RUN phpize && \
./configure --enable-trochilidae && \
make -j$(nproc) && \
make install && \
docker-php-ext-enable trochilidae && \
php -m | grep trochilidae && \
tests/install_test.sh

99 changes: 88 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,96 @@
# PHP Trochilidae extension
A PHP extension for metrics collect
# PHP Trochilidae

[![CodeFactor](https://www.codefactor.io/repository/github/xmlex/php_trochilidae/badge/main)](https://www.codefactor.io/repository/github/xmlex/php_trochilidae/overview/main)
[![Build Status](https://app.travis-ci.com/xMlex/php_trochilidae.svg?branch=main)](https://app.travis-ci.com/xMlex/php_trochilidae)
A PHP extension for collecting and sending application metrics (timers, tags, request data) to a remote collector via UDP.

## Requirements

- PHP 7.4+
- php-dev (for compilation)

## Install

```bash
phpize
./configure --enable-trochilidae
make
make test
make install
```

Enable the extension in `php.ini`:

```ini
extension=trochilidae.so
trochilidae.enabled=1
trochilidae.server_list=collector1.local:30002,collector2.local:30002
```
phpize && ./configure --enable-trochilidae && make && make test
php -d extension=`pwd`/modules/trochilidae.so -f test.php
run /home/mlex/CLionProjects/php_trochilidae/test.php

## Configuration

| INI directive | Type | Default | Description |
|---|---|---|---|
| `trochilidae.enabled` | bool | `1` | Enable or disable the extension |
| `trochilidae.server_list` | string | empty | Comma-separated `host:port` pairs of collector servers |

## How it works

Trochilidae hooks into the PHP request lifecycle:

1. **RINIT** — resets metrics, collects pre-request data (tags, server vars)
2. During the request, you can add tags and use timers via PHP functions
3. **RSHUTDOWN** — automatically serialises and sends all collected metrics to the configured collector(s) via UDP

For CLI scripts, metrics are also sent on shutdown; call `trochilidae_flush()` explicitly if you need to send data before the end of the script.

## Quick start

```php
<?php

// Set tags and hostname
trochilidae_set_tag('env', 'production');
trochilidae_set_hostname('app01');

// Profile a section of code
trochilidae_timer_start('db_query');
// ... do work ...
trochilidae_timer_stop('db_query');

// Get stats for all timers
$info = trochilidae_timer_get_info();
// $info['timers'][0]['startCount'] – start count
// $info['timers'][0]['stopCount'] – stop count
// $info['timers'][0]['totalExecutionTime'] – total time in seconds
// $info['timers'][0]['lastExecutionTime'] – last lap in seconds

//[optional] Send collected metrics (send by default, after execute script/request)
trochilidae_flush();
```

TODO:
- ~~REQUEST_TIME from php~~
- request id
- ~~timers~~
## PHP Functions

| Function | Description |
|---|---|
| `trochilidae_set_tag(string $key, string $value)` | Set a custom tag |
| `trochilidae_set_hostname(string $hostname)` | Override the default hostname |
| `trochilidae_timer_start(string $name)` | Start or resume a named timer |
| `trochilidae_timer_stop(string $name)` | Stop a named timer (no-op if not running) |
| `trochilidae_timer_get_info()` | Get all timer statistics as nested array |
| `trochilidae_flush()` | Send collected metrics to the collector |
| `trochilidae_reset()` | Reset all collected metrics |

## TODO

### 🟢 Protocol (`docs/protocol.md`)

| # | Change | Why |
|---|---|---|---|
| P2 | **tv_sec → 64-bit `long`** | Avoid Y2038 overflow (time_t is 64-bit on modern systems) |

### 🔴 Stability & Scalability (code)

| # | Change | Where | Why |
|---|---|---|---|
| S10 | **IPv6 support (`sockaddr_storage` + `getaddrinfo`)** | `tr_network.h:62` | Currently `sockaddr_in` = IPv4 only |
| S12 | **Fix `tv_usec` calc: `1e6 * 1000` → `1e6`** | `trochilidae.c:502,508` | Double multiplication produces wrong microseconds |

1 change: 1 addition & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ if test "$PHP_TROCHILIDAE" != "no"; then
trochilidae/tr_array.c
trochilidae/tr_network.c
trochilidae/tr_timer.c
trochilidae/tr_hooks.c
trochilidae.c"

PHP_NEW_EXTENSION(trochilidae, $trochilidae_sources, $ext_shared,,)
Expand Down
Loading
Loading