Full Integration for Node.js Logs
About Shipbook
ShipBook gives you the power to remotely gather, search and analyze your user logs and exceptions in the cloud, on a per-user & session basis.
Requirements
Node.js version 18.0.0 and up.
Installation
ShipBookSDK is available through: NPM
npm install @shipbook/node
Integrating ShipBook into your code
To initialize, add the following:
import { Shipbook } from '@shipbook/node';
await Shipbook.start("YOUR_APP_ID", "YOUR_APP_KEY");
You can optionally provide the app version:
await Shipbook.start("YOUR_APP_ID", "YOUR_APP_KEY", "1.0.0");
To have a log on each module you need to create a logger:
import { Shipbook } from '@shipbook/node';
const log = Shipbook.getLogger("MODULE_NAME");
The usage of the log:
log.e("the log message"); // Error log
log.w("the log message"); // Warning log
log.i("the log message"); // Info log
log.d("the log message"); // Debug log
log.v("the log message"); // Verbose log
Enable Shipbook debug logging
If your logs weren't uploaded to Shipbook, or you're experiencing some other issue with Shipbook, you can enable Shipbook debug logging to track down the problem.
Shipbook.enableInnerLog(true);
Linking ShipBook to a user's information
The SDK allows the option to associate each session with specific user information.
Register user:
The best practice is to set registerUser before Shipbook.start. It will also work after this point however, it will require an additional api request.
Shipbook.registerUser("USER_ID", "USER_NAME", "FULL_NAME", "USER_EMAIL", "USER_PHONE_NUMBER", { role: "admin" });
The only required parameter is userId.
Logout
To logout the user, add the following code to your app's logout function.
Shipbook.logout();
Screen
To log the user's screen information, add the following code
Shipbook.screen("SCREEN_NAME");
Flush
Flush all logs on the device and send them now to the server.
Shipbook.flush()
Get the UUID
The SDK creates it's own UUID. So to get the UUID call the following code.
Shipbook.getUUID()
Express Middleware
Shipbook provides an Express middleware for grouping logs by HTTP request:
import { Shipbook } from '@shipbook/node';
import express from 'express';
const app = express();
app.use(Shipbook.expressMiddleware());
NestJS Interceptor
For NestJS applications, use the built-in interceptor:
import { Shipbook } from '@shipbook/node';
// In your module or main.ts
app.useGlobalInterceptors(Shipbook.nestjsInterceptor());
Background Jobs
For background jobs and workers, wrap your code to get organized session grouping:
await Shipbook.runInContext({ jobName: 'send-emails' }, async () => {
// All logs inside here are grouped under this job
log.i('Processing email batch');
});
Graceful Shutdown
Call shutdown when your server is stopping to flush pending logs:
await Shipbook.shutdown();
Using Wrappers with ShipBook
If you wrap ShipBook in your own logging class (e.g., a custom Logger or Winston integration), the SDK will report your wrapper's filename and line number instead of the actual caller. To fix this, register your wrapper class:
// Pass the class itself (recommended - works with minification)
Shipbook.addWrapperClass(MyLogWrapper);
// Or pass a string for third-party internals
Shipbook.addWrapperClass('WinstonInternalClass');
The SDK will skip any stack frames from registered classes when determining the caller location.
Stack Offset
For cases where addWrapperClass isn't sufficient (e.g., deeply nested third-party wrappers in minified code), you can set a manual stack offset:
// Skip 1 additional stack frame beyond SDK internals
Shipbook.setStackOffset(1);
Custom Appenders
You can create custom appenders to route logs to additional destinations such as analytics services, local databases, or test harnesses. Register your custom appender before calling start().
class AnalyticsAppender {
constructor(name, config) {
this.name = name;
}
update(config) {}
push(log) {
if (log.type === 'message') {
// Send to your analytics service
}
}
flush() {}
destructor() {}
}
// Register before start
Shipbook.registerAppender('AnalyticsAppender', AnalyticsAppender);
await Shipbook.start('YOUR_APP_ID', 'YOUR_APP_KEY');
Once registered, your custom appender can be configured through the Shipbook console by its type name, and assigned to loggers with the desired severity level.