@sailfish-ai/sf-veritas
v0.2.11
Published
A versatile Edge Runtime-compatible package for JavaScript and TypeScript backend systems and scripts.
Downloads
23,414
Maintainers
Readme
Sailfish's Backend Data Collector for JavaScript and TypeScript
Sailfish's veritas library captures all of the data to enable engineers to properly debug issues.
Supported Frameworks
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)
Installation
Install the Package
Install via your package manager; for reference, here is how you can install our package via npm and yarn:
npm install --save @sailfish-ai/sf-veritasyarn add @sailfish-ai/sf-veritasIntegration
Once you have installed the sf-veritas package, it's time to integrate it into your project.
Arguments/Parameters
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
serviceIdentifierto link sevices to the location in code. Without this, Sailfish can have issues locating code and automatically fixing issues.- e.g.
gitOrg/gitRepo/pathToFile
- e.g.
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<string, string | number | boolean | null>- 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.
- Prevents adding tracing headers (
nodeModulesToCollectLocalVariablesOn:string[](coming soon)- Specify packages or modules for capturing local variable values during errors or exceptions.
Integration
To integrate and start, place the following into your application's entry point, as early as possible:
import { setupInterceptors } from "@sailfish-ai/sf-veritas";
setupInterceptors({
apiKey: "your-api-key",
serviceIdentifier: "<gitOrg>/<gitRepo>/<pathToFile>",
domainsToNotPropagateHeadersTo: ["example.com"],
});Runtime Hooks for Local Development
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:
# With Node.js directly
node --import @sailfish-ai/sf-veritas/runtime/register-loader app.js
# With tsx (TypeScript)
tsx --import @sailfish-ai/sf-veritas/runtime/register-loader app.ts
# In package.json scripts
{
"scripts": {
"dev": "node --import @sailfish-ai/sf-veritas/runtime/register-loader src/app.js"
}
}Configuration
Runtime hooks respect the same configuration as build plugins:
Environment Variables:
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 packagesConsole 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:
{"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:
# 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:
{
"default": {
"sample_rate": 1.0,
"capture_arguments": true,
"capture_return_value": true
}
}Programmatic API
You can also register hooks programmatically:
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()orvm.runInContext()code - May conflict with other custom loaders
Features
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:
type Identify = (
userId: string,
traits: Record<string, any>,
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.
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<string, any>- 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.
- This is a custom JSON, just like
override:boolean- This tells whether any of the information we pass along should be overridden or not.
AddOrUpdateMetadata Signature
type AddOrUpdateMetadataFunction = (
userId: string,
traits: Record<string, any>,
override: boolean,
) => void;Add/Update Metadata Example
import { addOrUpdateMetadata } from "@sailfish-ai/sf-veritas";
addOrUpdateMetadata("user-123", { birthday: "2000-01-01" }, true);Technical Details
- 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!
