# Better Stack Pino transport

## Start logging in 3 steps

### 1. Install

Install the `@logtail/pino` npm package:

```sh
[label Install @logtail/pino]
npm install @logtail/pino
```

### 2. Set up

Set up the Pino logger with the Better Stack transport:

```javascript
[label Set up Pino logger]
const token = '$SOURCE_TOKEN'; 
const pino = require('pino');
const transport = pino.transport({
  target: "@logtail/pino",
  options: {
    sourceToken: token,
    options: { endpoint: 'https://$INGESTING_HOST' },
  },
});
const logger = pino(transport);
```



### 3. Start logging

Use the Pino logger as usual:

```javascript
[label Send logs to Better Stack]
logger.error("Something bad happened.");
logger.info({
    item: "Orange Soda",
    price: 100.00
}, "Log message with structured logging. ->");
```

You should see your logs in [Better Stack → Live tail](https://telemetry.betterstack.com/team/0/tail ";_blank").

[warning]
#### Pino 7.0.0 or higher is required
The `@logtail/pino` transport supports Pino v7 and above.
[/warning]

## Custom log levels

Pino lets you define your own levels with its `customLevels` option. On Pino 8.21 and newer, those levels reach Better Stack under their own names. On older versions, a custom number falls back to the nearest default level, so pass the same levels to the transport's `customLevels` option to keep their names:

```javascript
[label Send custom levels under their own names]
const logger = pino(
  { customLevels: { notice: 35, critical: 55 } },
  pino.transport({
    target: "@logtail/pino",
    options: {
      sourceToken: token,
      options: { endpoint: 'https://$INGESTING_HOST' },
      customLevels: { notice: 35, critical: 55 },
    },
  }),
);

logger.notice("Service started");
```

The transport's `customLevels` option also accepts a comma-separated string, `"notice:35,critical:55"`, and takes precedence over the names Pino reports, so you can send different names to Better Stack than the ones you use in your code.

## Logging from serverless functions

The Pino transport sends logs from a worker thread, which serverless platforms like AWS Lambda freeze as soon as your handler returns. Its last logs may never reach Better Stack.

In serverless functions, use `LogtailStream` instead and flush the logs before the handler returns:

```sh
[label Install @logtail/pino and @logtail/node]
npm install @logtail/pino @logtail/node
```

```javascript
[label Log from a serverless function]
const pino = require('pino');
const { Logtail } = require('@logtail/node');
const { LogtailStream } = require('@logtail/pino');

const logtail = new Logtail('$SOURCE_TOKEN', {
  endpoint: 'https://$INGESTING_HOST',
});
const logger = pino(new LogtailStream(logtail));

exports.handler = async (event) => {
  logger.info('Handling event');

  // Send all logs before the function is frozen
  await logtail.flush();
  return { statusCode: 200 };
};
```

`LogtailStream` requires `@logtail/pino` 0.5.12 or newer.

## Need help?

Please let us know at hello@betterstack.com.  
We're happy to help! 🙏

## Additional resources

Want to learn more about **Pino log levels** and **adding contextual data** to your logs?  
Check out our [Complete Guide to Pino Logging in Node.js](https://betterstack.com/community/guides/logging/how-to-install-setup-and-use-pino-to-log-node-js-applications/).