A versatile Edge Runtime-compatible package for JavaScript and TypeScript backend systems and scripts.
npm install @sailfish-ai/sf-veritasSailfish's veritas library captures all of the data to enable engineers to properly debug issues.
As of September 2025, we support the most widely-used JS/TS backend frameworks and others (in both JavaScript and TypeScript):
- Most-widely Used
- Node.js
- Next.js
- Express
- Angular
- NestJS
- NuxtJS
- Others
- Apollo Server
- Mercurius
- MeteorJS
- GraphQL over HTTP (formerly Express GraphQL)
#### Install the Package
Install via your package manager; for reference, here is how you can install our package via npm and yarn:
``sh title="Install via npm"`
npm install --save @sailfish-ai/sf-veritas
`sh title="Install via yarn"`
yarn add @sailfish-ai/sf-veritas
Once you have installed the sf-veritas package, it's time to integrate it into your project.
Below are the configuration parameters for sf-veritas. These options are passed as an object to the setupInterceptors function.
- apiKey: string
- This can be seen and copied from your Settings Configuration page in the "Sailfish Configuration" section.
- serviceIdentifier: string
- This identifies the service that is running.
- The value is extremely important because Sailfish uses the serviceIdentifier to link sevices to the location in code. Without this, Sailfish can have issues locating code and automatically fixing issues.gitOrg
- e.g. /gitRepo/pathToFile
- serviceVersion: string
- This identifies the version of your service - this is a human-readable version and is not required.
- gitSha: string
- This is the Git SHA of your releases - populating this via this argument or an environment variable helps your team tie issues to code changes quickly.
- serviceAdditionalMetadata: Record
- Add extra metadata such as cluster information or environment details.
- domainsToNotPropagateHeadersTo: string[]
- Prevents adding tracing headers (X-Sf3-Rid) to certain domains.
- Supports wildcard characters, subdomains, and paths.
- nodeModulesToCollectLocalVariablesOn: string[] (_coming soon_)
- Specify packages or modules for capturing local variable values during errors or exceptions.
To integrate and start, place the following into your application's entry point, as early as possible:
`ts title="JS/TS integration code"
import { setupInterceptors } from "@sailfish-ai/sf-veritas";
setupInterceptors({
apiKey: "your-api-key",
serviceIdentifier: "
domainsToNotPropagateHeadersTo: ["example.com"],
});
`
For local development and debugging without a build step, sf-veritas provides runtime hooks that automatically instrument your code on-the-fly.
⚠️ Important: Runtime hooks are intended for development only. For production, use the build plugins (webpack, vite, rollup, esbuild, or tsc) which provide better performance.
#### Node 20+ with ESM Loader (Recommended)
Use the --import flag with the loader registration:
`bashWith Node.js directly
node --import @sailfish-ai/sf-veritas/runtime/register-loader app.js
#### Configuration
Runtime hooks respect the same configuration as build plugins:
Environment Variables:
`bash
SF_FUNCSPAN_CONSOLE_OUTPUT=true # Output function spans to console (for development)
SF_FUNCSPAN_JSONL_FILE=true # Write function spans to funcspans.jsonl (default)
SF_FUNCSPAN_JSONL_FILE=/path/to/spans.jsonl # Write function spans to custom JSONL file
SF_FUNCSPAN_SKIP_BACKEND=true # Skip sending spans to backend (for local-only)
SF_FUNCSPAN_DEBUG=true # Enable debug logging
SF_FUNCSPAN_SAMPLE_RATE=1.0 # Override sampling rate (0.0-1.0)
SF_FUNCSPAN_INCLUDE_NODE_MODULES=express,axios # Instrument specific packages
`Console Output Example:
When
SF_FUNCSPAN_CONSOLE_OUTPUT=true is set, you'll see clean output like:`
📊 Function Span: {
function: 'add (src/utils.ts:10:0)',
duration: '0.05ms',
arguments: { a: 2, b: 3 },
result: 5,
spanId: 'a05a6dea-90ac-4c86-9d74-7815d8de87d2',
parentSpanId: 'none'
}
`JSONL File Output:
When
SF_FUNCSPAN_JSONL_FILE=/path/to/file.jsonl is set, each function span is written as a JSON line:`json
{"timestamp":"2025-11-27T18:06:26.821Z","functionName":"add","filePath":"src/utils.ts","line":10,"column":0,"duration":0.05,"arguments":{"a":2,"b":3},"result":5,"spanId":"abc123","parentSpanId":"parent-id","async":false}
`This format is ideal for log processing tools and can be easily analyzed with
jq:`bash
Pretty print a span
cat spans.jsonl | head -1 | jq .Find slow functions
cat spans.jsonl | jq 'select(.duration > 100)'Group by function name
cat spans.jsonl | jq -s 'group_by(.functionName) | map({function: .[0].functionName, count: length})'
`
.sailfish Configuration Files:Create a
.sailfish file in your project directory:`json
{
"default": {
"sample_rate": 1.0,
"capture_arguments": true,
"capture_return_value": true
}
}
`#### Programmatic API
You can also register hooks programmatically:
`typescript
import { registerFuncspanRuntime } from '@sailfish-ai/sf-veritas/runtime/register';// Must be called before importing any modules you want to instrument
registerFuncspanRuntime({
debug: true,
includeNodeModules: ['express'],
sampleRate: 1.0
});
// Now import your application code
import './app';
`#### Requirements
- Node.js 16.12+ (stable in Node 18+, recommended: Node 20+)
- For ESM loader: Node 20.6+ for full support
#### Limitations
- Runtime transformation adds ~20-50ms per module on first load
- Not recommended for production use
- Cannot transform
eval() or vm.runInContext() code
- May conflict with other custom loaders$3
#### Identify Users
You can also associate data (logs, exceptions, and network requests) with specific users using the identify method. This is particularly helpful for user-centric debugging.
#### Identify Signature
Here's the argument signature:
`ts
type Identify = (
userId: string,
traits: Record,
override: boolean,
) => void;
`#### Identify Example
In order to identify, you will need to call the
identify method. You can also force an override of stored values by setting the override argument to true.`ts title="Link a user to a recording"
import { identify } from "@sailfish-ai/sf-veritas";identify("user-123", { lastAction: "2024-11-18" });
`#### Add or Update Metadata
In order to add or update metadata associated with specific users and the recordings, you can use the
addOrUpdateMetadata method. This will associate all information with the recording by calling this method on any Node.js backend.-
userId: string - This associates the logs (and recording, if there is an associated recording) with a specific user.
-
traits: Record - This is a custom dictionary of traits to values for a specific user or customer. Everything is searchable!
-
traitsJson: string - This is a custom JSON, just like
traits, but using the JSON format.-
override: boolean
- This tells whether any of the information we pass along should be overridden or not.#### AddOrUpdateMetadata Signature
`ts
type AddOrUpdateMetadataFunction = (
userId: string,
traits: Record,
override: boolean,
) => void;
`#### Add/Update Metadata Example
`ts title="Add/Update Metadata for a recording"
import { addOrUpdateMetadata } from "@sailfish-ai/sf-veritas";addOrUpdateMetadata("user-123", { birthday: "2000-01-01" }, true);
`$3
- Non-Blocking Execution: All operations are executed in non-blocking, isolated threads, ensuring less than 20 µs of overhead.
- Contextual Awareness: Tracks context across threads, processes, and async tasks to associate logs with the correct sequence of events.
By following these steps, you can seamlessly integrate
sf-veritas` into your Node.js project and start capturing LEaPS (Logs, Exceptions, and Print Statements) effectively!