pinojs / pino

🌲 super fast, all natural json logger
http://getpino.io
MIT License
14.23k stars 876 forks source link

Custom transport requires file absolute path, so it's impossible to use it in Vercel #1736

Open nemanjam opened 1 year ago

nemanjam commented 1 year ago

I am using this custom Slack transport:

https://github.com/ChrisLahaye/pino-slack-transport

I have Next.js app and I am unable to load transport by relative path even in local dev environment, but with absolute path it works. So I try to use absolute file path for transport.mjs but absolute paths are problematic in Vercel so it can't find file and it breaks.

There are some hacky solutions to get Vercel to include .js file in the bundle and reference it by absolute path but it doesn't work for me:

https://github.com/vercel/next.js/discussions/32236#discussioncomment-5429091

import path from 'node';
import { LoggerOptions, TransportTargetOptions, pino } from 'pino';

const transportAbsolutePath = path.join(process.cwd(), '/lib/transport.mjs');

const targets: TransportTargetOptions[] = [
  { target: 'pino-pretty', level: 'info', options: { colorize: true } },
];

// breaks both locally and in Vercel
const transportRelativePath = '../transport.mjs';

// breaks in Vercel, can't find file on that path
targets.push({ target: transportAbsolutePath, level: 'info', options: {} });

const destination = pino.transport({ targets });

const pinoOptions: LoggerOptions = {
  enabled: true,
  timestamp: pino.stdTimeFunctions.isoTime,
};

export const logger = pino(pinoOptions, destination);

transport.mjs

import { createTransport } from 'pino-slack-transport';

export default createTransport;
  1. I have tried to use CopyWebpackPlugin to include transport.js file in the bundle and reference it by absolute path but again it works locally and breaks in Vercel.

next.config.js

const CopyWebpackPlugin = require('copy-webpack-plugin');

const nextConfig = {
  reactStrictMode: true,
  webpack(config, options) {

    if (options.isServer) {

      config.plugins.push(
        new CopyWebpackPlugin({
          patterns: [
            {
              from: path.join(__dirname, 'lib/logger/transport.mjs'),
              to: path.join(__dirname, '.next/server'),
            },
          ],
        })
      );
    }

    return config;
  },
};
  1. I have also tried to load transport through PinoWebpackPlugin and not through code but it doesn't even compile in dev as soon as I import it.

next.config.js

// it breaks build on this import
const { PinoWebpackPlugin } = require('pino-webpack-plugin');

const nextConfig = {
  reactStrictMode: true,
  webpack(config, options) {

    config.plugins.push(
      new PinoWebpackPlugin({
        transports: [
          'pino-pretty',
          path.join(__dirname, 'lib/logger/transport.mjs'),
        ],
      })
    );

    return config;
  },
};

So even that Pino is officially recommended library by Vercel in Next.js docs I am unable to use it with custom transport in Vercel with Next.js?

https://nextjs.org/docs/pages/building-your-application/deploying/production-checklist#logging

Can you tell me how to load custom transport in Vercel and Next.js?

mcollina commented 1 year ago

Please contact Vercel support. We do not have the resources to provide for them at the minute. Maybe @ethan-arrowood can help.

nemanjam commented 1 year ago

What are alternatives to load custom transport in Pino without using transport.js absolute file path? I must publish it as npm package? Are there any more practical ways?

mcollina commented 1 year ago

You should be able to use any transports as a stream. This is possible with pino-pretty but I do not maintain the slack one you linked.

Take a look at https://github.com/pinojs/pino-pretty#usage-as-a-stream.

nemanjam commented 1 year ago

Using a custom transport as a stream I can avoid relative or absolute paths and I can just use regular import statement? Is that the idea?

mcollina commented 1 year ago

Transports spins up a separate thread, which is not a great idea on sserverless.

astanciu commented 2 months ago

Are there any plans to address this issue? Is Pino is not a good choice if you're deploying to a serverless environment, or has anyone found a way to do it?

jsumners commented 2 months ago

People work on the things that are important to them. If this is important to you, you are welcome to work on it.

Ethan-Arrowood commented 2 months ago

FWIW I no longer work at Vercel, but still have somewhat of an answer for this issue.

As @mcollina mentioned, Transports spin up a separate thread. So in order to be used, the specific environment you're running your code in must (a) support Node.js and (b) support worker threads

Depending where you are using this with a Next.js app it could be running in Node.js or Edge Runtime, and its in the later that many this will not work (https://edge-runtime.vercel.app/features/available-apis#unsupported-apis).

If you are certain your code is running with a Node.js serverless function, and worker threads are not working, you should contact Vercel support for more help