Skip to content

Commit

Permalink
Add instrumentation to RPC calls to other workers (#374)
Browse files Browse the repository at this point in the history
* add worker instrumentation still wip

* Update the service-binding example to use hono-otel from workspace

* Remove packagemanager from root package.json

* Try using an instanceof check on potential service binding

* Format new examples

* Rename together to service-bindings and make sure they are picked up by the pnpm workspace. Also remove cruft

* Update service binding example to be more thematically consistent

* Commit semi-working example

* Remove the apply trap

* Remove swc and clean up cloudflare binding patching for service bound workers

* Instrument the `fetch` method for a bound worker

* Update lockfile after removing swc

* Experiment to make service binding work async...

* Fix span duration=0 for async stuff

* Bump package.json

* Ignore cursorrules

* Update service binding README

* Update readme for meow

* use PromiseLike to describe both Cloudflare RPC promises and JS promises

* format

---------

Co-authored-by: Mari <[email protected]>
Co-authored-by: Laurynas Keturakis <[email protected]>
  • Loading branch information
3 people authored Dec 2, 2024
1 parent aa4dc4c commit 42d9f90
Show file tree
Hide file tree
Showing 22 changed files with 628 additions and 584 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
shared/dist
.env
.envrc
.cursorrules

# Fpx
.fpxconfig
Expand Down
11 changes: 11 additions & 0 deletions examples/service-bindings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Service Bindings Example

In this folder there are two Workers, `woof` and `meow`.

`meow` is a Hono api that uses `woof` as a [service binding](https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/), which is, it calls

`woof` is a simple service that can bark and sniff.

To run the example, run `pnpm dev` in the `meow` directory, and then in a separate terminal run `pnpm dev` in the `woof` directory.

In your terminal for `meow`, it should list `WOOF` as being a connected service, once `woof` is running.
1 change: 1 addition & 0 deletions examples/service-bindings/meow/.dev.vars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FPX_ENDPOINT=
39 changes: 39 additions & 0 deletions examples/service-bindings/meow/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# prod
dist/

# dev
.yarn/
!.yarn/releases
.vscode/*
!.vscode/launch.json
!.vscode/*.code-snippets
.idea/workspace.xml
.idea/usage.statistics.xml
.idea/shelf

# deps
node_modules/
.wrangler

# env
.env
.env.production
.dev.vars
.prod.vars

# logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

# misc
.DS_Store

# drizzle
drizzle

.wrangler
26 changes: 26 additions & 0 deletions examples/service-bindings/meow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Meow: Part of Service Bindings Example

This is a very simple Hono api that uses a service binding to call the `woof` service.

To run the example, first run `pnpm dev` in the `meow` directory, and then in a separate terminal run `pnpm dev` in the `woof` directory.

Notice that in `meow`'s `wrangler.toml`, we have:

```toml
bindings = [
{ name = "WOOF", binding = "woof" }
]
```

The name `"WOOF"` must match the `name` field in `woof`'s `wrangler.toml`.

Then, we expose `WOOF` as the binding, and tell Hono it's available via `c.env.WOOF`

```typescript
import type { WoofWorker } from "../../woof/src";

type Bindings = {
WOOF: WoofWorker;
};
const app = new Hono<{ Bindings: Bindings }>();
```
18 changes: 18 additions & 0 deletions examples/service-bindings/meow/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "meow",
"scripts": {
"dev": "wrangler dev src/index.ts",
"deploy": "wrangler deploy --minify src/index.ts"
},
"dependencies": {
"dotenv": "^16.4.5",
"drizzle-orm": "^0.36.0",
"hono": "^4.6.7"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20241106.0",
"@fiberplane/hono-otel": "workspace:*",
"tsx": "^4.19.2",
"wrangler": "^3.87.0"
}
}
18 changes: 18 additions & 0 deletions examples/service-bindings/meow/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { instrument } from "@fiberplane/hono-otel";
import { Hono } from "hono";

import type { WoofWorker } from "../../woof/src";

type Bindings = {
WOOF: WoofWorker;
};

const app = new Hono<{ Bindings: Bindings }>();

app.get("/", async (c) => {
const bark = await c.env.WOOF.bark({ volume: 10 });
c.env.WOOF.sniff();
return c.text(`Meow from above! ☁️🪿🐈 (But dog says "${bark}")`);
});

export default instrument(app);
13 changes: 13 additions & 0 deletions examples/service-bindings/meow/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
"lib": ["ESNext"],
"types": ["@cloudflare/workers-types"],
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx"
}
}
27 changes: 27 additions & 0 deletions examples/service-bindings/meow/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name = "meow"
compatibility_date = "2024-11-11"
compatibility_flags = [ "nodejs_compat" ]

services = [
{ binding = "WOOF", service = "woof" }
]

# [vars]
# MY_VAR = "my-variable"

# Workers Logs
# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/
# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs
[observability]
enabled = true

# [[kv_namespaces]]
# binding = "MY_KV_NAMESPACE"
# id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# [[r2_buckets]]
# binding = "MY_BUCKET"
# bucket_name = "my-bucket"

# [ai]
# binding = "AI"
39 changes: 39 additions & 0 deletions examples/service-bindings/woof/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# prod
dist/

# dev
.yarn/
!.yarn/releases
.vscode/*
!.vscode/launch.json
!.vscode/*.code-snippets
.idea/workspace.xml
.idea/usage.statistics.xml
.idea/shelf

# deps
node_modules/
.wrangler

# env
.env
.env.production
.dev.vars
.prod.vars

# logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

# misc
.DS_Store

# drizzle
drizzle

.wrangler
19 changes: 19 additions & 0 deletions examples/service-bindings/woof/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Woof: Part of Service Bindings Example

`Woof` is a simple worker that is bound to `meow` via [Cloudflare's worker service bindings](https://developers.cloudflare.com/workers/runtime-apis/service-bindings/).

Note that the `name` field in `wrangler.toml` must match the name used in `meow` to bind to this worker.

So in this worker's `wrangler.toml`, we have:

```toml
name = "woof" # NOTE - Use this name inside `meow` to bind to this worker
```

And in `meow`'s `wrangler.toml`, we have:

```toml
bindings = [
{ name = "WOOF", binding = "woof" }
]
```
15 changes: 15 additions & 0 deletions examples/service-bindings/woof/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "woof",
"scripts": {
"dev": "wrangler dev src/index.ts",
"deploy": "wrangler deploy --minify src/index.ts"
},
"dependencies": {
"dotenv": "^16.4.5",
"drizzle-orm": "^0.36.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20241106.0",
"wrangler": "^3.87.0"
}
}
25 changes: 25 additions & 0 deletions examples/service-bindings/woof/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { WorkerEntrypoint } from "cloudflare:workers";

export class WoofWorker extends WorkerEntrypoint {
async bark(options: { volume: number }): Promise<string> {
await new Promise((resolve) => setTimeout(resolve, 200));

if (options.volume > 5) {
return "WOOF";
}

return "woof";
}

sniff() {
return "sniff";
}

// From Cloudflare docs: "Currently, entrypoints without a named handler are not supported"
// TODO - Check if this is still the case that we need a fetch handler?
async fetch() {
return new Response(null, { status: 404 });
}
}

export default WoofWorker;
13 changes: 13 additions & 0 deletions examples/service-bindings/woof/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true,
"lib": ["ESNext"],
"types": ["@cloudflare/workers-types"],
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx"
}
}
2 changes: 2 additions & 0 deletions examples/service-bindings/woof/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name = "woof" # NOTE - Use this name inside `meow` to bind to this worker
compatibility_date = "2024-11-11"
18 changes: 0 additions & 18 deletions packages/client-library-otel/.swcrc

This file was deleted.

8 changes: 2 additions & 6 deletions packages/client-library-otel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"author": "Fiberplane<[email protected]>",
"type": "module",
"main": "dist/index.js",
"version": "0.4.0-canary.0",
"version": "0.5.0",
"dependencies": {
"@opentelemetry/api": "~1.9.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
Expand All @@ -18,9 +18,6 @@
"devDependencies": {
"@biomejs/biome": "^1.7.3",
"@cloudflare/workers-types": "^4.20240403.0",
"@swc/cli": "^0.4.0",
"@swc/core": "^1.5.22",
"@swc/plugin-transform-imports": "^2.0.4",
"hono": "^4.6.5",
"nodemon": "^3.1.7",
"rimraf": "^6.0.1",
Expand All @@ -44,10 +41,9 @@
"format": "biome check . --write",
"lint": "biome lint .",
"typecheck": "tsc --noEmit",
"build": "pnpm run clean && npm run build:types && pnpm run build:swc && pnpm run build:alias",
"build": "pnpm run clean && npm run build:types && pnpm run build:alias",
"build:types": "tsc --project tsconfig.json",
"build:alias": "tsc-alias -p tsconfig.json -f",
"build:swc": "cd src && swc . -d ../dist --source-maps",
"dev": "wrangler dev sample/index.ts",
"prepublishOnly": "pnpm run build",
"clean": "rimraf dist",
Expand Down
Loading

0 comments on commit 42d9f90

Please sign in to comment.