Zero
Zero
Back

Monitor a Node.js App with Datadog and Winston

Quickly set up error logging in SvelteKit or any another Node.js-based framework.

Sam Magura

Sam Magura

A pattern of window shades

Implementing error logging in your application is critical, because it allows you to take action on errors before your customers report them. And even if a customer does report an issue, you'll need error logs to get the context necessary to fix the issue.

In this post, we demonstrate how to log to Datadog , one of the leading cloud monitoring platforms. To do this, we'll create a Winston  logger that sends events to Datadog. Once an event is logged, it will be visible in the Datadog cloud dashboard.

We'll implement this in a full stack SvelteKit  app, though the same steps would be used for any app with a Node.js backend, such as Next.js or Express. The Datadog API key will be stored in Zero, and we'll use the Zero TypeScript SDK  to fetch the API key at runtime.

Secure your secrets conveniently

Zero is a modern secrets manager built with usability at its core. Reliable and secure, it saves time and effort.

Zero dashboard

Signing Up for Datadog

You can sign up for a Datadog free trial by clicking the "Get started free" button on the Datadog homepage . Even after the free trial expires, you can convert your account to a free plan to continue using the service.

Before continuing, we should create a Zero project to house the Datadog API key. Log in to Zero and create a new project, making sure to save the project's token to a safe location on your local PC.

Now, return to the Datadog console and navigate to the API keys page by hovering over your username in the bottom left corner. The link can be hard to find — see this docs page  for a screenshot. Once you're on the API keys page, create an API key and copy it to your clipboard. Then, paste the API key into a new Zero secret like so:

Putting the Datadog API key into Zero
Putting the Datadog API key into Zero

Creating a SvelteKit App

Now that the Datadog API key is safely stored in Zero, we can proceed to create a barebones SvelteKit app to demonstrate the logging functionality. To bootstrap the app, run

Terminal
npm create svelte@latest datadog-app

At the prompts, select "Skeleton project" and enable TypeScript.

Scaffolding the App

In this sample project, we are trying to log from the backend, so the frontend can simply be a button that calls the backend. To do this, we'll use a form action , one of the core features of SvelteKit. The frontend is simply an HTML form with a submit button, no JavaScript required:

+page.svelte
<form method="POST"> <button>Submit action</button> </form>

The corresponding server file, +page.server.ts, will export a default action that throws an error. Once we have a logger, we'll update this code to log the error.

+page.server.ts
import {fail, type Actions} from '@sveltejs/kit' export const actions: Actions = { default: async (event) => { try { throw new Error('An error occurred.') } catch (error: any) { // TODO Log the error return fail(500) } }, }

Fetching the API Key from Zero

Next, we'll integrate with Zero using the TypeScript SDK. Run

Terminal
npm install @zerosecrets/zero @types/node

to install the requisite packages.

In a new file called lib/logger.ts, we'll use the standard pattern for bringing down secrets from Zero:

lib/logger.ts
import {zero} from '@zerosecrets/zero' async function getSecrets() { if (!process.env.ZERO_TOKEN) { throw new Error('Did you forget to set the ZERO_TOKEN environment variable?') } try { const result = await zero({ token: process.env.ZERO_TOKEN, pick: ['datadog'], callerName: 'production', }).fetch() return result?.datadog // { api_key: "your-datadog-api-key" } } catch (error) { console.error('Error fetching secrets from Zero:', error) throw error } } const secrets = await getSecrets() if (!secrets || !secrets.api_key) { throw new Error('Datadog API key not found in secrets.') }

Creating the Winston Logger

Now, we'll set up a Winston logger with a transport that sends log events to Datadog, with the help of the datadog-winston  npm package.

To proceed, install these packages:

Terminal
npm i winston datadog-winston @types/datadog-winston

The code is very straightforward. If implementing this in a production app, you may wish to customize the ddtags based on the environment your app is running in.

lib/logger.ts
export const logger = winston.createLogger({ level: 'info', transports: [ new DatadogWinston({ apiKey: secrets.api_key, service: 'svelte-app', ddsource: 'nodejs', ddtags: 'env:staging,version:1.0.0', }), // new winston.transports.Console(), ], })

Putting it All Together

To complete the app, update the server action to log the error with the Winston logger:

+page.server.ts
export const actions: Actions = { default: async (event) => { try { throw new Error('An error occurred.') } catch (error: any) { logger.error(error.message, {stack: error.stack}) return fail(500) } }, }

Now, run the app with

Terminal
ZERO_TOKEN='YOUR_ZERO_TOKEN' npm run dev

Open it in your browser and click the submit button that the app displays. Now, navigate to the Datadog console and select "Logs" from the main menu. You should see the error that the application created!

The logs appearing in Datadog
The logs appearing in Datadog

Conclusion

This post showed how straightforward it is to set up error logging to Datadog in a Node.js application with the help of Zero and Winston. That said, Datadog is an immensely powerful platform, and we really just scratched the surface of what it can do. You can go much further by capturing metrics in Datadog (e.g. CPU usage) and settings up custom dashboards and alarms.


Other articles

A sandy beach

Add Error Monitoring to an Express.js App with Rollbar

Stay on top of errors in your Node.js apps to find and fix bugs faster.

A cube made of smaller cubes

Build an Email Summary Bot using Claude AI, Gmail, and Slack (Part 2)

Use the Claude AI assistant to summarize emails in just a few lines of code.

Secure your secrets

Zero is a modern secrets manager built with usability at its core. Reliable and secure, it saves time and effort.