How to save logs in NextJS server components ??
Logging is a crucial part before deploying any application to production as console.log() doesn't cut work in the server, even if it did we have better tools :)
At the end of this article, you will learn how to save your application logs to either your NextJS project or to your Linux Server log file (/var/log)
Step 0 : Assuming you have a basic next project ( Nextjs 13 ) set up
npm install winston
Step 1: Create a file called logger.js
.
It should be in the root of your project. For example
PROJECT_NAME
|_ app
|_ public
|_ logger.js 👈
Add the following code in logger.js file
// logger.js
import winston from "winston";
const { combine, timestamp, json } = winston.format;
const logger = winston.createLogger({
level: "info",
format: combine(timestamp(), json()),
transports: [
new winston.transports.File({
filename: "app.log"
}),
],
});
export { logger };
What you need to focus on are three things
- level : there are different log levels, and we want info and above
- format : The format at which our logs will be stored
- transports: This is important, we use it to transport our logs to a file.
Step 2: Create a app.log
file in the root of your project.
PROJECT_NAME
|_ app
|_ public
|_ logger.js
|_ app.log 👈
Moving on, we will try to use this logger that we have created on NextJS Server Components and API routes and check if our logs are saved or not.
Step 3: Use our logger in a Server Component
- Create a home folder inside app folder
- Create a
page.jsx
file inside home
PROJECT_NAME
|_ app
| |_ home 👈
| |_ page.jsx 👈
|
|
|_ public
|_ logger.js
|_ app.log
// app/home/page.jsx
import { logger } from "@/logger"; // our logger import
export default function HomePage() {
logger.info("Home Page called "); // calling our logger
return (
<div>
<h3>Home page</h3>
</div>
);
}
- Now check you
app.log
file, If you get a log with message "Home Page Called" you have successfully configured logging.
Step 4: Use our logger in an API route
Next JS 13 lets us write our backend in api folder, let's write a basic GET endpoint that returns "hello" as a response
- Create a file
api/test/route.js
insideapp
PROJECT_NAME
|_ app
| |_ api
| | |_ test 👈
| | |_ route.js 👈
| |_ home
|
|_ public
|_ logger.js
|_ app.log
import { NextRequest, NextResponse } from "next/server";
import { logger } from "@/logger"; // our logger import
export async function GET(req: NextRequest) {
logger.info(`GET /api/gethome ${req}`);
return NextResponse.json({
message: "success",
status: 200,
});
}
Now from your browser ( Assuming you are on localhost:3000) go to /api/test
Now check the logs in
app.log
.Logging for API's are particularly very powerful because we can log request and request parameters which we can check to debug issues that may arise in our production application
Logging in Linux or EC2
Now suppose you have your project running on AWS EC2 or other Linux servers, and you want to save your logs, not on your next project but on the servers log folder
You would need to do the following steps
Change the logger transport to point to your Linux log
import winston from "winston";
const { combine, timestamp, json } = winston.format;
const logger = winston.createLogger({
level: "info",
format: combine(timestamp(), json()),
transports: [
new winston.transports.File({
filename: "/var/log/NEXT_APP/app.log", 👈
}),
],
});
export { logger };
Create a directory in your server
With the same folder name as in your logger transports filename
sudo mkdir /var/log/NEXT_APP/app.log
NOTE: your logger now has the file location, but it still doesn't have the permission to write in this file. So we will have to give the log file appropriate permission
sudo chmod a+w /var/log/NEXT_APP/app.log
Logging is a very good topic to dive deep into, and if you have more time do read about log levels, log rotation and other topics.
If you think this article needs some edits, or additions feel free to comment. Thanks !
Top comments (1)
Thanks the article was very helpful to get a quick start on logging. In the api logging example you provided, logging the req variable just logged [object Request] in my case. The details like body of the request could be used for useful logging. For example