vite icon indicating copy to clipboard operation
vite copied to clipboard

Developer Server Access Log Option

Open cawoodm opened this issue 2 years ago • 4 comments

Description

As a developer it can be very useful to see the "hits", access requests in the vite console.

Suggested solution

When running vite --access-logs vite should log each hit as is typical with web servers (like apache/nginx) or web frameworks (like flask):

image

Alternative

No response

Additional context

No response

Validations

cawoodm avatar Nov 02 '23 11:11 cawoodm

You can do it like this. https://x.com/kiliman/status/1719488313692766582

sapphi-red avatar Nov 03 '23 05:11 sapphi-red

You can do it like this. https://x.com/kiliman/status/1719488313692766582

Bad link. Does any know what the workaround is and can post it here?

virullius avatar Apr 09 '24 17:04 virullius

You can add in plugin

   {
      name: 'requestLogger',
      configureServer(server) {
        server.middlewares.use((req, res, next) => {
          console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
          next();
        });
      },
    },

Added requestLogger Plugin: A custom plugin named requestLogger is added to the plugins array. This plugin uses the configureServer method to add a middleware that logs the request method and URL.

Console Log for Requests: Logs requests to the terminal in the format: "[timestamp] METHOD URL".

Result: When you run the Vite dev server, it will now log all incoming HTTP requests to the console. This helps in debugging and monitoring access during development.

YogSottot avatar Jan 22 '25 12:01 YogSottot

@YogSottot thanks! Worth noting that for preview mode one also needs to add configurePreviewServer.

My config:

export default defineConfig({
  plugins: [
    {
      name: 'requestLogger',
      configurePreviewServer: logRequests, // log in preview mode
      configureServer: logRequests,        // log in development mode
    },
  ],
  ...
});

function logRequests(server : PreviewServer | ViteDevServer) {
  server.middlewares.use((req, _, next) => {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    next();
  });
}

lazamar avatar May 30 '25 16:05 lazamar

here is sample access-log middle-ware plugin which logs like vite event-logs, useful in dev environment(filter garbage logs with regex):

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { URL } from 'url';

const filters: RegExp[] = [
  /\/src(\/|$)/,
  /\/node_modules(\/|$)/,
  /\/@vite(\/|$)/,
  /\/@react-refresh(\/|$)/,
];

function matchesAny(target: string | undefined, regexList: RegExp[]) {
  if (!target) return false;
  for (const r of regexList) if (r.test(target)) return true;
  return false;
}

const colors = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  cyan: '\x1b[36m',
  dim: '\x1b[2m',
  bold: '\x1b[1m',
  blue: '\x1b[38;5;38m',
  gray: '\x1b[90m',
};

function colorForStatus(code: number) {
  if (code >= 200 && code < 300) return colors.green;
  if (code >= 300 && code < 400) return colors.yellow;
  if (code >= 400) return colors.red;
  return colors.cyan;
}

function log(msg: string) {
  const ts = `${colors.gray}${timeString()}${colors.reset}`;
  const tag = `${colors.bold}${colors.blue}[vite]${colors.reset}`;
  // produce: 10:07:20 AM [vite] server restarted.
  console.log(`${ts} ${tag} ${msg}`);
}

function timeString() {
  const d = new Date();
  return d.toLocaleTimeString(undefined, { hour12: true });
}

const logPlugin = () => ({
  name: 'vite:dev-logger',
  configureServer(server: any) {
    server.middlewares.use((req: any, res: any, next: any) => {
      const start = process.hrtime.bigint();

      res.on('finish', () => {
        // normalize to pathname so query strings don't break filter matching
        let pathname = req.url;
        try {
          // req.url may be a path only; URL requires base
          pathname = new URL(req.url, 'http://localhost').pathname;
        } catch {
          /* keep req.url as-is */
        }

        if (matchesAny(pathname, filters)) return;

        const end = process.hrtime.bigint();
        const ms = Number(end - start) / 1_000_000;
        const status = res.statusCode ?? 0;
        const col = colorForStatus(status);

        log(
          `${req.method} ${col}${req.url}${colors.reset} => ${col}${status}${colors.reset} - ${ms.toFixed(2)}ms`
        );
      });

      next();
    });
  },
});

export default defineConfig({
  plugins: [react(), logPlugin()],
});

hmmftg avatar Aug 23 '25 06:08 hmmftg