Skip to content

Commit 91e46cc

Browse files
feat: grpc instrumentation for outbound requests (#26)
* working instrumentation * clean up * readme, cleanup, esm e2e tests * integration tests, readme update, clean up package.json * fix build, address bug bot comment * another attempt at fixing build * remove bak file
1 parent f832394 commit 91e46cc

49 files changed

Lines changed: 5954 additions & 364 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
${{ runner.os }}-npm-
3333
3434
- name: Install dependencies
35-
run: npm install
35+
run: npm ci
3636

3737
- name: Start Docker Compose services
3838
run: docker compose -f docker-compose.test.yml up -d --wait

CONTRIBUTING.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,27 @@ An instrumentation needs custom ESM support if it:
9696
**Why**: In ESM, default exports are in the `.default` property of the namespace object, not directly accessible.
9797

9898
**Example** (postgres):
99+
99100
- **CommonJS**: `const postgres = require('postgres')``postgres` IS the function
100101
- **ESM**: `import postgres from 'postgres'``postgres.default` IS the function
101102

102103
**Detection**:
104+
103105
```typescript
104-
const isESM = (moduleExports as any)[Symbol.toStringTag] === 'Module';
106+
const isESM = (moduleExports as any)[Symbol.toStringTag] === "Module";
105107
```
106108

107109
**Solution**:
110+
108111
```typescript
109112
if (isESM) {
110113
// Wrap the .default property
111-
this._wrap(moduleExports, 'default', wrapper);
114+
this._wrap(moduleExports, "default", wrapper);
112115
} else {
113116
// Create wrapped function and return it
114-
const wrappedFn = function(...args) { /* ... */ };
117+
const wrappedFn = function (...args) {
118+
/* ... */
119+
};
115120
// Copy all properties...
116121
return wrappedFn;
117122
}
@@ -145,19 +150,22 @@ Each instrumentation typically:
145150
We have unit tests and integration tests with [ava](https://github.com/avajs/ava).
146151
Some integration tests (pg, mongo, etc.) require external dependencies.
147152
A docker compose is provided for you to get these dependencies up easily:
148-
```
153+
154+
```yaml
149155
docker compose -f docker-compose.test.yml up -d --wait
150156
```
151157

152158
After it's done setting up you can run `npm test` as usual.
153159
You can leave it up, and tests should clean up after themselves so that we can
154160
leave these services up during development without restarting all the time.
155161
To bring them down, run
156-
```
162+
163+
```yaml
157164
docker compose -f docker-compose.test.yml down
158165
```
159166

160167
Some important notes during testing, especially integration tests:
168+
161169
- The tusk sdk needs to be initialized before importing anything that is going
162170
to be patched.
163171
- Since the TuskDrift object is a singleton, each integration test (or at least
@@ -173,14 +181,14 @@ Some important notes during testing, especially integration tests:
173181
The SDK includes comprehensive end-to-end (E2E) tests that verify instrumentations work correctly in real Docker environments. These tests record actual network traffic and replay it to ensure consistent behavior.
174182

175183
**Quick Overview:**
184+
176185
- E2E tests are located in `src/instrumentation/libraries/{library}/e2e-tests/`
177186
- Each test runs in a Docker container with the full SDK
178187
- Tests record network interactions, then replay them to verify correctness
179188
- Use these tests when debugging instrumentation issues or adding new features
180189

181190
**For detailed instructions on running and debugging E2E tests, see the [E2E Testing Guide](./E2E_TESTING_GUIDE.md).**
182191

183-
184192
#### Code Quality
185193

186194
- Follow existing code patterns and conventions
@@ -203,12 +211,14 @@ The SDK communicates with the Tusk CLI using socket connections, supporting both
203211
### Connection Types
204212

205213
#### Unix Socket (Default)
214+
206215
- **Use case**: Local development and non-containerized environments
207216
- **How it works**: SDK connects to the CLI via a Unix domain socket file
208217
- **Environment variable**: `TUSK_MOCK_SOCKET` (optional, defaults to `/tmp/tusk-connect.sock`)
209218
- **Benefits**: Lower overhead, faster communication for same-machine connections
210219

211220
#### TCP Socket (Docker/Remote)
221+
212222
- **Use case**: Dockerized applications where Unix sockets can't be shared
213223
- **How it works**: SDK connects to the CLI via TCP (host:port)
214224
- **Environment variables**:

E2E_TESTING_GUIDE.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The SDK instruments various Node.js libraries (http, https, fetch, pg, postgres,
99
## Purpose of This Guide
1010

1111
This guide provides step-by-step instructions for iterating on SDK instrumentations when debugging E2E tests. Use this when:
12+
1213
- An E2E test endpoint is failing
1314
- You need to debug or fix instrumentation code
1415
- You want to verify that SDK changes work correctly
@@ -18,6 +19,7 @@ This guide provides step-by-step instructions for iterating on SDK instrumentati
1819
E2E tests are located in `src/instrumentation/libraries/{library}/e2e-tests/{module-type}-{library}/`:
1920

2021
Each test directory contains:
22+
2123
- `src/` - Test application source code
2224
- `Dockerfile` - Container configuration
2325
- `docker-compose.yml` - Container orchestration
@@ -33,6 +35,7 @@ cd src/instrumentation/libraries/{library}/e2e-tests/{test-name}
3335
```
3436

3537
Example:
38+
3639
```bash
3740
cd src/instrumentation/libraries/http/e2e-tests/cjs-http
3841
```
@@ -65,6 +68,7 @@ docker-compose exec -e TUSK_DRIFT_MODE=RECORD app sh -c "npm run build && npm ru
6568
```
6669

6770
Wait a few seconds for the server to fully start (5-10 seconds recommended):
71+
6872
```bash
6973
sleep 5
7074
```
@@ -111,18 +115,21 @@ docker-compose exec -T app tusk run --print --output-format "json" --enable-serv
111115
```
112116

113117
**Flags explained:**
118+
114119
- `--print` - Print test results to stdout
115120
- `--output-format "json"` - Output results in JSON format
116121
- `--enable-service-logs` - Write detailed service logs to `.tusk/logs/` for debugging
117122

118123
To see all available flags, run:
124+
119125
```bash
120126
tusk run --help
121127
```
122128

123129
**Interpreting Results:**
124130

125131
The output will be JSON with test results:
132+
126133
```json
127134
[
128135
{
@@ -156,9 +163,11 @@ When you need to fix instrumentation code:
156163

157164
1. **Make changes to the SDK source code**
158165
2. **Rebuild the SDK** from the repository root:
166+
159167
```bash
160168
npm run build
161169
```
170+
162171
3. **NO need to rebuild Docker containers** - the SDK is mounted as a volume, so changes propagate automatically
163172
4. **Clean up traces and logs** (Step 2)
164173
5. **Restart the server in RECORD mode** (Step 4)
@@ -182,10 +191,11 @@ The Docker Compose configuration mounts the SDK source code as a read-only volum
182191

183192
```yaml
184193
volumes:
185-
- ../../../../../..:/sdk:ro # SDK source mounted at /sdk
194+
- ../../../../../..:/sdk:ro # SDK source mounted at /sdk
186195
```
187196
188197
This means:
198+
189199
- ✅ **SDK changes propagate automatically** - no need to rebuild containers
190200
- ✅ **Fast iteration** - just run `npm run build` in the SDK root
191201
- ❌ **Must rebuild SDK** - changes won't take effect until you run `npm run build`
@@ -212,6 +222,7 @@ Each E2E test directory has a `run.sh` script that automates the entire workflow
212222
```
213223

214224
This script:
225+
215226
1. Cleans traces and logs
216227
2. Starts containers
217228
3. Starts server in RECORD mode

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ For comprehensive guides and API reference, visit our [full documentation](https
1919
Tusk Drift currently supports the following packages and versions:
2020

2121
- **HTTP/HTTPS**: All versions (Node.js built-in)
22+
- **GRPC**: `@grpc/grpc-js@1.x` (Outbound requests only)
2223
- **PG**: `pg@8.x`, `pg-pool@2.x-3.x`
2324
- **Postgres**: `postgres@3.x`
2425
- **MySQL**: `mysql2@3.x`

docker-compose.test.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,18 @@ services:
5151
interval: 5s
5252
timeout: 5s
5353
retries: 5
54+
55+
grpc-server:
56+
image: node:20
57+
working_dir: /workspace
58+
volumes:
59+
- .:/workspace
60+
command: sh -c "apt-get update && apt-get install -y netcat-openbsd && node /workspace/src/instrumentation/libraries/grpc/integration-tests/server.cjs"
61+
ports:
62+
- "50051:50051"
63+
healthcheck:
64+
test: ["CMD", "nc", "-z", "localhost", "50051"]
65+
interval: 5s
66+
timeout: 5s
67+
retries: 10
68+
start_period: 10s

0 commit comments

Comments
 (0)