TypeScript
Install and configure the @parseable/temporal plugin for Temporal TypeScript workers
The @parseable/temporal plugin is a Temporal middleware that ships workflow and activity execution events to Parseable. See the Temporal overview for the full schema, example queries, and shared caveats.
Prerequisites
- Node.js 20+
- A Temporal worker built on
@temporalio/workerv1.13+ (plugin API based) - A reachable Parseable instance
Installation
npm install @parseable/temporalConfiguration
Install Temporal runtime telemetry once, before you create the Worker or Client. The Parseable plugin configuration stays inside Worker.create.
import { Runtime, Worker } from '@temporalio/worker';
import { ParseablePlugin } from '@parseable/temporal';
Runtime.install({
telemetryOptions: {
metrics: {
prometheus: {
bindAddress: '0.0.0.0:9464',
},
},
},
});
const worker = await Worker.create({
taskQueue: 'hello-world',
workflowsPath: require.resolve('./workflows'),
activities,
// highlight-start
plugins: [
new ParseablePlugin({
serviceName: 'temporal-worker',
endpoint: process.env.PARSEABLE_URL, // e.g. https://parseable.example:8000
auth: {
username: process.env.PARSEABLE_USERNAME,
password: process.env.PARSEABLE_PASSWORD,
},
// optional, defaults shown:
logs: { stream: 'temporal-logs' },
traces: { stream: 'temporal-traces' },
}),
],
// highlight-end
});
await worker.run();ParseablePlugin sends workflow logs and traces to Parseable. The Runtime.install() block enables Temporal SDK metrics on the worker process and exposes them in Prometheus format at :9464/metrics. Scrape that endpoint with Prometheus and forward it to Parseable using Prometheus Remote Write.
Options
| Option | Type | Default | Notes |
|---|---|---|---|
serviceName | string | required | Becomes the service.name resource attribute and service_name log field. |
endpoint | string | required if logs/traces enabled | Parseable host base URL. |
auth | { username, password } | required if logs/traces enabled | HTTP basic auth. |
logs | false | { stream?: string } | { stream: 'temporal-logs' } | Set to false to disable log emission. |
traces | false | { stream?: string } | { stream: 'temporal-traces' } | Set to false to disable trace emission. |
Metrics
Temporal TypeScript workers can expose SDK metrics from the worker runtime. These metrics are separate from the Parseable plugin logs and traces. They help you see worker level behavior such as activity execution, workflow task execution, polling, latency, and other SDK runtime signals.
The bindAddress in the example above exposes a Prometheus scrape endpoint on the worker host:
http://<worker-host>:9464/metricsPrometheus can scrape this endpoint and remote write the samples to Parseable:
scrape_configs:
- job_name: temporal-typescript-worker
static_configs:
- targets: ['temporal-worker:9464']
remote_write:
- url: "https://<parseable-host>:8000/v1/prometheus/write"
authorization:
type: Bearer
credentials: <parseable-api-key>
headers:
X-P-Stream: temporal-metricsAfter Prometheus starts writing to Parseable, open the temporal-metrics dataset in the Metrics page. Temporal keeps the full SDK metrics reference in its SDK metrics documentation, which is useful when deciding which worker and workflow metrics to dashboard.
Custom domain events from workflow code
Workflows can emit replay-safe domain events via the workflowEvent helper. Each call lands as a log record with type: 'user_event', event_name, and an arbitrary serializable event_data payload.
import { workflowEvent } from '@parseable/temporal/workflow';
import { proxyActivities } from '@temporalio/workflow';
const { planActivity, runStep } = proxyActivities<typeof activities>({
startToCloseTimeout: '1 minute',
});
export async function agentWorkflow(input: AgentInput): Promise<AgentResult> {
workflowEvent('agent.started', { user_id: input.userId });
const plan = await planActivity(input);
workflowEvent('agent.plan.chosen', { steps: plan.steps.length });
for (const step of plan.steps) {
workflowEvent('agent.step.start', { tool: step.tool });
await runStep(step);
}
workflowEvent('agent.completed', { total_steps: plan.steps.length });
return { ok: true };
}Events flow through the same sink as the built-in workflow lifecycle events, so they are deduplicated on replay.
Links
- npm package: npmjs.com/package/@parseable/temporal
- Plugin source: github.com/parseablehq/temporal-plugin
- Temporal TypeScript observability docs: docs.temporal.io/develop/typescript/platform/observability
Was this page helpful?