Skip to content

A simple logger that lets you log from both the frontend and the backend

Notifications You must be signed in to change notification settings

navikt/next-logger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

98 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

next-logger

An isomorphic logger that lets you log from both the frontend and the backend. Both will log in a JSON format that logs.adeo.no understands. And all logs are grouped under your application (+application:yourapp) with correct log level.

Now with SecureLogs support!

Getting started

Installation

yarn add @navikt/next-logger pino
npm i @navikt/next-logger pino

if you want to use the secure logger, you also need to install pino-roll:

yarn add pino-roll
npm i pino-roll

Step 1: Prepare Next.js for isomorphic logging

You need an API route that will receive all the log statements from the frontend.

For app dir:

Create a new API route /app/api/logger/route.ts, it should look like this:

export { POST } from '@navikt/next-logger/app-dir'

For pages dir:

Create a new API route /pages/api/logger.ts, it should look like this:

export { loggingRoute as default } from '@navikt/next-logger/pages';

Step 2: Logging

Anywhere in your application where you want to log, you should import import { logger } from '@navikt/next-logger';, this is a pino instance, use it to log, for example: logger.warn("Uh oh"). Alternatively, if you need secure logging, use ìmport { secureLogger } from '@navikt/next-logger';. See Securelogs for more information on secure logging.

Step 3: pino-pretty

If you want pino-pretty for local development (and you probably do, simply install it and pipe it:

yarn add -D pino-pretty
npm i --save-dev pino-pretty

Simply pipe the output of your development server into pino pretty:

"scripts": {
  "dev": "next dev | pino-pretty",
}

Step 4 (Optional): Integrating with next-logger

The pino configuration from this library can be shared with next-logger.

Simply create a next-logger.config.js in the root of your project, and re-export the logging config as following:

const { backendLogger } = require('@navikt/next-logger')

module.exports = {
    logger: backendLogger,
}

Configuration

App Dir

You want this configuration to execute as early as possible, but on the actual client. Typically in your app-dir app, you will have for example a <Providers>-client that is "use client"-enabled.

On the root of any "use client"-enabled file that wraps your root layout.tsx, you can configure the library, for example:

"use client"

configureLogger({
    basePath: '/my/base/path',
})

export const MyProviders() {
   ...
}

Pages

If your application is using a base path, or you want to have your logger on a different API-route, you can configure the logger.

In your _app.tsx, on root in the file, you can use configureLogger as such:

configureLogger({
    basePath: '/my/base/path',
    apiPath: '/api/other-logger',
})

Or if you only want to change the base path:

configureLogger({
    basePath: '/my/base/path',
})

Securelogs

If you want to log sensitive information, you can use the secureLogger function. This will instead of logging to stdout log to a file on /secure-logs. This requires some setup, see nais docs for how to enable secure logging in your app.

The log file is setup with pino-roll for rolling the logs based on file size.

Using secure logger as an isomorphic logger requires an additonal API-route in your next app, the configuration is similar to the primary logger route.

For app dir:

Create a new API route /app/api/secure-logger/route.ts, it should look like this:

export { POST } from '@navikt/next-logger/secure-log/app-dir'

For pages dir:

Create a new API route /pages/api/secure-logger.ts, it should look like this:

export { pinoLoggingRoute as default } from '@navikt/next-logger/secure-log/pages';

If you need to add some extra metadata to secure log statements server side, you can add an metadata-middleware to extract info from the request:

App dir

import { withMetadata } from '@navikt/next-logger/secure-log/app-dir'
import { UAParser } from 'ua-parser-js'

export const POST = withMetadata((request) => {
    const userAgent = request.headers.get('user-agent')
    if (!userAgent) return { platform: 'unknown' }

    const ua = UAParser(userAgent)

    return {
        platform: ua.device.type ?? 'unknown',
    }
})

Pages

import { withMetadata } from "@navikt/next-logger/secure-log/pages";
import { UAParser } from 'ua-parser-js'

export default withMetadata((req) => {
    const userAgent = request.headers.get('user-agent')
    if (!userAgent) return { platform: 'unknown' }

    const ua = UAParser(userAgent)

    return {
        platform: ua.device.type ?? 'unknown',
    }
});

Remember not to parse the body using .json() or .text!

This feature is available only for secure-log.

Breaking changes: migrating to v2

The only breaking change is that the paths for the API routes have been updated.

App Dir

app/api/logger/route.ts:

- export { POSTLoggingRouteHandler as POST } from '@navikt/next-logger'
+ export { POST } from '@navikt/next-logger/app-dir'

Pages

pages/api/logger/route.ts:

- export { pinoLoggingRoute as default } from '@navikt/next-logger'
+ export { loggingRoute as default } from '@navikt/next-logger/pages'

If you want to use the new secureLogger feature, refer to the Securelogs docs above.

About

A simple logger that lets you log from both the frontend and the backend

Resources

Security policy

Stars

Watchers

Forks

Packages